/indra/llplugin/tests/llplugincookiestore_test.cpp
C++ | 206 lines | 125 code | 31 blank | 50 comment | 10 complexity | 02852e3978718946955ddf0376e5d1ef MD5 | raw file
Possible License(s): LGPL-2.1
1/** 2 * @file llplugincookiestore_test.cpp 3 * @brief Unit tests for LLPluginCookieStore. 4 * 5 * @cond 6 * $LicenseInfo:firstyear=2010&license=viewerlgpl$ 7 * Second Life Viewer Source Code 8 * Copyright (C) 2010, Linden Research, Inc. 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; 13 * version 2.1 of the License only. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 * 24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 25 * $/LicenseInfo$ 26 * @endcond 27 */ 28 29#include "linden_common.h" 30#include "../test/lltut.h" 31 32#include "../llplugincookiestore.h" 33 34 35namespace tut 36{ 37 // Main Setup 38 struct LLPluginCookieStoreFixture 39 { 40 LLPluginCookieStoreFixture() 41 { 42 // We need dates definitively in the past and the future to properly test cookie expiration. 43 LLDate now = LLDate::now(); 44 LLDate past(now.secondsSinceEpoch() - (60.0 * 60.0 * 24.0)); // 1 day in the past 45 LLDate future(now.secondsSinceEpoch() + (60.0 * 60.0 * 24.0)); // 1 day in the future 46 47 mPastString = past.asRFC1123(); 48 mFutureString = future.asRFC1123(); 49 } 50 51 std::string mPastString; 52 std::string mFutureString; 53 LLPluginCookieStore mCookieStore; 54 55 // List of cookies used for validation 56 std::list<std::string> mCookies; 57 58 // This sets up mCookies from a string returned by one of the functions in LLPluginCookieStore 59 void setCookies(const std::string &cookies) 60 { 61 mCookies.clear(); 62 std::string::size_type start = 0; 63 64 while(start != std::string::npos) 65 { 66 std::string::size_type end = cookies.find_first_of("\r\n", start); 67 if(end > start) 68 { 69 std::string line(cookies, start, end - start); 70 if(line.find_first_not_of("\r\n\t ") != std::string::npos) 71 { 72 // The line has some non-whitespace characters. Save it to the list. 73 mCookies.push_back(std::string(cookies, start, end - start)); 74 } 75 } 76 start = cookies.find_first_not_of("\r\n ", end); 77 } 78 } 79 80 // This ensures that a cookie matching the one passed is in the list. 81 void ensureCookie(const std::string &cookie) 82 { 83 std::list<std::string>::iterator iter; 84 for(iter = mCookies.begin(); iter != mCookies.end(); iter++) 85 { 86 if(*iter == cookie) 87 { 88 // Found the cookie 89 // TODO: this should do a smarter equality comparison on the two cookies, instead of just a string compare. 90 return; 91 } 92 } 93 94 // Didn't find this cookie 95 std::string message = "cookie not found: "; 96 message += cookie; 97 ensure(message, false); 98 } 99 100 // This ensures that the number of cookies in the list matches what's expected. 101 void ensureSize(const std::string &message, size_t size) 102 { 103 if(mCookies.size() != size) 104 { 105 std::stringstream full_message; 106 107 full_message << message << " (expected " << size << ", actual " << mCookies.size() << ")"; 108 ensure(full_message.str(), false); 109 } 110 } 111 }; 112 113 typedef test_group<LLPluginCookieStoreFixture> factory; 114 typedef factory::object object; 115 factory tf("LLPluginCookieStore"); 116 117 // Tests 118 template<> template<> 119 void object::test<1>() 120 { 121 // Test 1: cookie uniqueness and update lists. 122 // Valid, distinct cookies: 123 124 std::string cookie01 = "cookieA=value; domain=example.com; path=/"; 125 std::string cookie02 = "cookieB=value; Domain=example.com; Path=/; Max-Age=10; Secure; Version=1; Comment=foo!; HTTPOnly"; // cookie with every supported field, in different cases. 126 std::string cookie03 = "cookieA=value; domain=foo.example.com; path=/"; // different domain 127 std::string cookie04 = "cookieA=value; domain=example.com; path=/bar/"; // different path 128 std::string cookie05 = "cookieC; domain=example.com; path=/"; // empty value 129 std::string cookie06 = "cookieD=value; domain=example.com; path=/; expires="; // different name, persistent cookie 130 cookie06 += mFutureString; 131 132 mCookieStore.setCookies(cookie01); 133 mCookieStore.setCookies(cookie02); 134 mCookieStore.setCookies(cookie03); 135 mCookieStore.setCookies(cookie04); 136 mCookieStore.setCookies(cookie05); 137 mCookieStore.setCookies(cookie06); 138 139 // Invalid cookies (these will get parse errors and not be added to the store) 140 141 std::string badcookie01 = "cookieD=value; domain=example.com; path=/; foo=bar"; // invalid field name 142 std::string badcookie02 = "cookieE=value; path=/"; // no domain 143 144 mCookieStore.setCookies(badcookie01); 145 mCookieStore.setCookies(badcookie02); 146 147 // All cookies added so far should have been marked as "changed" 148 setCookies(mCookieStore.getChangedCookies()); 149 ensureSize("count of changed cookies", 6); 150 ensureCookie(cookie01); 151 ensureCookie(cookie02); 152 ensureCookie(cookie03); 153 ensureCookie(cookie04); 154 ensureCookie(cookie05); 155 ensureCookie(cookie06); 156 157 // Save off the current state of the cookie store (we'll restore it later) 158 std::string savedCookies = mCookieStore.getAllCookies(); 159 160 // Test replacing cookies 161 std::string cookie01a = "cookieA=newvalue; domain=example.com; path=/"; // updated value 162 std::string cookie02a = "cookieB=newvalue; domain=example.com; path=/; expires="; // remove cookie (by setting an expire date in the past) 163 cookie02a += mPastString; 164 165 mCookieStore.setCookies(cookie01a); 166 mCookieStore.setCookies(cookie02a); 167 168 // test for getting changed cookies 169 setCookies(mCookieStore.getChangedCookies()); 170 ensureSize("count of updated cookies", 2); 171 ensureCookie(cookie01a); 172 ensureCookie(cookie02a); 173 174 // and for the state of the store after getting changed cookies 175 setCookies(mCookieStore.getAllCookies()); 176 ensureSize("count of valid cookies", 5); 177 ensureCookie(cookie01a); 178 ensureCookie(cookie03); 179 ensureCookie(cookie04); 180 ensureCookie(cookie05); 181 ensureCookie(cookie06); 182 183 // Check that only the persistent cookie is returned here 184 setCookies(mCookieStore.getPersistentCookies()); 185 ensureSize("count of persistent cookies", 1); 186 ensureCookie(cookie06); 187 188 // Restore the cookie store to a previous state and verify 189 mCookieStore.setAllCookies(savedCookies); 190 191 // Since setAllCookies defaults to not marking cookies as changed, this list should be empty. 192 setCookies(mCookieStore.getChangedCookies()); 193 ensureSize("count of changed cookies after restore", 0); 194 195 // Verify that the restore worked as it should have. 196 setCookies(mCookieStore.getAllCookies()); 197 ensureSize("count of restored cookies", 6); 198 ensureCookie(cookie01); 199 ensureCookie(cookie02); 200 ensureCookie(cookie03); 201 ensureCookie(cookie04); 202 ensureCookie(cookie05); 203 ensureCookie(cookie06); 204 } 205 206}