/indra/llplugin/tests/llplugincookiestore_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 206 lines · 125 code · 31 blank · 50 comment · 11 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. #include "linden_common.h"
  29. #include "../test/lltut.h"
  30. #include "../llplugincookiestore.h"
  31. namespace tut
  32. {
  33. // Main Setup
  34. struct LLPluginCookieStoreFixture
  35. {
  36. LLPluginCookieStoreFixture()
  37. {
  38. // We need dates definitively in the past and the future to properly test cookie expiration.
  39. LLDate now = LLDate::now();
  40. LLDate past(now.secondsSinceEpoch() - (60.0 * 60.0 * 24.0)); // 1 day in the past
  41. LLDate future(now.secondsSinceEpoch() + (60.0 * 60.0 * 24.0)); // 1 day in the future
  42. mPastString = past.asRFC1123();
  43. mFutureString = future.asRFC1123();
  44. }
  45. std::string mPastString;
  46. std::string mFutureString;
  47. LLPluginCookieStore mCookieStore;
  48. // List of cookies used for validation
  49. std::list<std::string> mCookies;
  50. // This sets up mCookies from a string returned by one of the functions in LLPluginCookieStore
  51. void setCookies(const std::string &cookies)
  52. {
  53. mCookies.clear();
  54. std::string::size_type start = 0;
  55. while(start != std::string::npos)
  56. {
  57. std::string::size_type end = cookies.find_first_of("\r\n", start);
  58. if(end > start)
  59. {
  60. std::string line(cookies, start, end - start);
  61. if(line.find_first_not_of("\r\n\t ") != std::string::npos)
  62. {
  63. // The line has some non-whitespace characters. Save it to the list.
  64. mCookies.push_back(std::string(cookies, start, end - start));
  65. }
  66. }
  67. start = cookies.find_first_not_of("\r\n ", end);
  68. }
  69. }
  70. // This ensures that a cookie matching the one passed is in the list.
  71. void ensureCookie(const std::string &cookie)
  72. {
  73. std::list<std::string>::iterator iter;
  74. for(iter = mCookies.begin(); iter != mCookies.end(); iter++)
  75. {
  76. if(*iter == cookie)
  77. {
  78. // Found the cookie
  79. // TODO: this should do a smarter equality comparison on the two cookies, instead of just a string compare.
  80. return;
  81. }
  82. }
  83. // Didn't find this cookie
  84. std::string message = "cookie not found: ";
  85. message += cookie;
  86. ensure(message, false);
  87. }
  88. // This ensures that the number of cookies in the list matches what's expected.
  89. void ensureSize(const std::string &message, size_t size)
  90. {
  91. if(mCookies.size() != size)
  92. {
  93. std::stringstream full_message;
  94. full_message << message << " (expected " << size << ", actual " << mCookies.size() << ")";
  95. ensure(full_message.str(), false);
  96. }
  97. }
  98. };
  99. typedef test_group<LLPluginCookieStoreFixture> factory;
  100. typedef factory::object object;
  101. factory tf("LLPluginCookieStore");
  102. // Tests
  103. template<> template<>
  104. void object::test<1>()
  105. {
  106. // Test 1: cookie uniqueness and update lists.
  107. // Valid, distinct cookies:
  108. std::string cookie01 = "cookieA=value; domain=example.com; path=/";
  109. 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.
  110. std::string cookie03 = "cookieA=value; domain=foo.example.com; path=/"; // different domain
  111. std::string cookie04 = "cookieA=value; domain=example.com; path=/bar/"; // different path
  112. std::string cookie05 = "cookieC; domain=example.com; path=/"; // empty value
  113. std::string cookie06 = "cookieD=value; domain=example.com; path=/; expires="; // different name, persistent cookie
  114. cookie06 += mFutureString;
  115. mCookieStore.setCookies(cookie01);
  116. mCookieStore.setCookies(cookie02);
  117. mCookieStore.setCookies(cookie03);
  118. mCookieStore.setCookies(cookie04);
  119. mCookieStore.setCookies(cookie05);
  120. mCookieStore.setCookies(cookie06);
  121. // Invalid cookies (these will get parse errors and not be added to the store)
  122. std::string badcookie01 = "cookieD=value; domain=example.com; path=/; foo=bar"; // invalid field name
  123. std::string badcookie02 = "cookieE=value; path=/"; // no domain
  124. mCookieStore.setCookies(badcookie01);
  125. mCookieStore.setCookies(badcookie02);
  126. // All cookies added so far should have been marked as "changed"
  127. setCookies(mCookieStore.getChangedCookies());
  128. ensureSize("count of changed cookies", 6);
  129. ensureCookie(cookie01);
  130. ensureCookie(cookie02);
  131. ensureCookie(cookie03);
  132. ensureCookie(cookie04);
  133. ensureCookie(cookie05);
  134. ensureCookie(cookie06);
  135. // Save off the current state of the cookie store (we'll restore it later)
  136. std::string savedCookies = mCookieStore.getAllCookies();
  137. // Test replacing cookies
  138. std::string cookie01a = "cookieA=newvalue; domain=example.com; path=/"; // updated value
  139. std::string cookie02a = "cookieB=newvalue; domain=example.com; path=/; expires="; // remove cookie (by setting an expire date in the past)
  140. cookie02a += mPastString;
  141. mCookieStore.setCookies(cookie01a);
  142. mCookieStore.setCookies(cookie02a);
  143. // test for getting changed cookies
  144. setCookies(mCookieStore.getChangedCookies());
  145. ensureSize("count of updated cookies", 2);
  146. ensureCookie(cookie01a);
  147. ensureCookie(cookie02a);
  148. // and for the state of the store after getting changed cookies
  149. setCookies(mCookieStore.getAllCookies());
  150. ensureSize("count of valid cookies", 5);
  151. ensureCookie(cookie01a);
  152. ensureCookie(cookie03);
  153. ensureCookie(cookie04);
  154. ensureCookie(cookie05);
  155. ensureCookie(cookie06);
  156. // Check that only the persistent cookie is returned here
  157. setCookies(mCookieStore.getPersistentCookies());
  158. ensureSize("count of persistent cookies", 1);
  159. ensureCookie(cookie06);
  160. // Restore the cookie store to a previous state and verify
  161. mCookieStore.setAllCookies(savedCookies);
  162. // Since setAllCookies defaults to not marking cookies as changed, this list should be empty.
  163. setCookies(mCookieStore.getChangedCookies());
  164. ensureSize("count of changed cookies after restore", 0);
  165. // Verify that the restore worked as it should have.
  166. setCookies(mCookieStore.getAllCookies());
  167. ensureSize("count of restored cookies", 6);
  168. ensureCookie(cookie01);
  169. ensureCookie(cookie02);
  170. ensureCookie(cookie03);
  171. ensureCookie(cookie04);
  172. ensureCookie(cookie05);
  173. ensureCookie(cookie06);
  174. }
  175. }