PageRenderTime 380ms CodeModel.GetById 2ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llplugin/tests/llplugincookiestore_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 206 lines | 125 code | 31 blank | 50 comment | 10 complexity | 02852e3978718946955ddf0376e5d1ef MD5 | raw file
  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}