OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/common/cookie_service_impl.h" |
| 6 |
| 7 #include <algorithm> |
| 8 |
| 9 // TODO(rdsmith): Sort below :-}. |
| 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/run_loop.h" |
| 12 #include "base/time/time.h" |
| 13 #include "content/common/cookie.mojom.h" |
| 14 #include "net/cookies/cookie_constants.h" |
| 15 #include "net/cookies/cookie_monster.h" |
| 16 #include "net/cookies/cookie_store.h" |
| 17 #include "net/cookies/cookie_store_test_callbacks.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 |
| 20 namespace content { |
| 21 |
| 22 // Wraps a CookieService in synchronous, blocking calls to make it easier to |
| 23 // test. |
| 24 class SynchronousCookieServiceWrapper { |
| 25 public: |
| 26 // Caller must guarantee that |*cookie_service| outlives the |
| 27 // SynchronousCookieServiceWrapper. |
| 28 explicit SynchronousCookieServiceWrapper(mojom::CookieService* cookie_service) |
| 29 : cookie_service_(cookie_service) {} |
| 30 ~SynchronousCookieServiceWrapper() {} |
| 31 |
| 32 std::vector<net::CanonicalCookie> GetAllCookies() { |
| 33 cookie_service_->GetAllCookies( |
| 34 base::BindOnce(&SynchronousCookieServiceWrapper::GetCookiesCallback, |
| 35 base::Unretained(this))); |
| 36 run_loop_.Run(); |
| 37 return cookies_; |
| 38 } |
| 39 |
| 40 std::vector<net::CanonicalCookie> GetCookieList(const GURL& url, |
| 41 net::CookieOptions options) { |
| 42 cookie_service_->GetCookieList( |
| 43 url, options, |
| 44 base::BindOnce(&SynchronousCookieServiceWrapper::GetCookiesCallback, |
| 45 base::Unretained(this))); |
| 46 run_loop_.Run(); |
| 47 return cookies_; |
| 48 } |
| 49 |
| 50 bool SetCanonicalCookie(const net::CanonicalCookie& cookie, |
| 51 bool secure_source, |
| 52 bool modify_http_only) { |
| 53 cookie_service_->SetCanonicalCookie( |
| 54 cookie, secure_source, modify_http_only, |
| 55 base::BindOnce(&SynchronousCookieServiceWrapper::SetCookieCallback, |
| 56 base::Unretained(this))); |
| 57 run_loop_.Run(); |
| 58 return result_; |
| 59 } |
| 60 |
| 61 uint32_t DeleteCookies(mojom::CookieDeletionFilter filter) { |
| 62 mojom::CookieDeletionFilterPtr filter_ptr = |
| 63 mojom::CookieDeletionFilter::New(filter); |
| 64 |
| 65 cookie_service_->DeleteCookies( |
| 66 std::move(filter_ptr), |
| 67 base::BindOnce(&SynchronousCookieServiceWrapper::DeleteCookiesCallback, |
| 68 base::Unretained(this))); |
| 69 run_loop_.Run(); |
| 70 return num_deleted_; |
| 71 } |
| 72 |
| 73 // TODO(rdsmith): Put in infrastructure for RequestNotification |
| 74 // and CloneInterface when I know what I want the tests for those to |
| 75 // look like. |
| 76 |
| 77 private: |
| 78 void GetCookiesCallback(const std::vector<net::CanonicalCookie>& cookies) { |
| 79 cookies_ = cookies; |
| 80 run_loop_.Quit(); |
| 81 } |
| 82 |
| 83 void SetCookieCallback(bool result) { |
| 84 result_ = result; |
| 85 run_loop_.Quit(); |
| 86 } |
| 87 |
| 88 void DeleteCookiesCallback(uint32_t num_deleted) { |
| 89 num_deleted_ = num_deleted; |
| 90 run_loop_.Quit(); |
| 91 } |
| 92 |
| 93 mojom::CookieService* cookie_service_; |
| 94 base::RunLoop run_loop_; |
| 95 |
| 96 std::vector<net::CanonicalCookie> cookies_; |
| 97 bool result_; |
| 98 uint32_t num_deleted_; |
| 99 |
| 100 DISALLOW_COPY_AND_ASSIGN(SynchronousCookieServiceWrapper); |
| 101 }; |
| 102 |
| 103 class CookieServiceTest : public testing::Test { |
| 104 public: |
| 105 CookieServiceTest() |
| 106 : cookie_monster_(nullptr, nullptr), |
| 107 cookie_service_(&cookie_monster_), |
| 108 cookie_service_request_(mojo::MakeRequest(&cookie_service_ptr_)), |
| 109 service_wrapper_(cookie_service_ptr_.get()) {} |
| 110 ~CookieServiceTest() override {} |
| 111 |
| 112 void SetUp() override { |
| 113 setup_time_ = base::Time::Now(); |
| 114 |
| 115 // Set a couple of cookies for tests to play with. |
| 116 bool result; |
| 117 result = SetCanonicalCookie( |
| 118 net::CanonicalCookie("A", "B", "foo_host", "/", base::Time(), |
| 119 base::Time(), base::Time(), false, false, |
| 120 net::CookieSameSite::NO_RESTRICTION, |
| 121 net::COOKIE_PRIORITY_MEDIUM), |
| 122 true, true); |
| 123 DCHECK(result); |
| 124 |
| 125 result = SetCanonicalCookie( |
| 126 net::CanonicalCookie("C", "D", "foo_host", "/with/path", base::Time(), |
| 127 base::Time(), base::Time(), false, false, |
| 128 net::CookieSameSite::NO_RESTRICTION, |
| 129 net::COOKIE_PRIORITY_MEDIUM), |
| 130 true, true); |
| 131 DCHECK(result); |
| 132 |
| 133 result = SetCanonicalCookie( |
| 134 net::CanonicalCookie("Secure", "E", "foo_host", "/with/path", |
| 135 base::Time(), base::Time(), base::Time(), true, |
| 136 false, net::CookieSameSite::NO_RESTRICTION, |
| 137 net::COOKIE_PRIORITY_MEDIUM), |
| 138 true, true); |
| 139 DCHECK(result); |
| 140 |
| 141 result = SetCanonicalCookie( |
| 142 net::CanonicalCookie("HttpOnly", "F", "foo_host", "/with/path", |
| 143 base::Time(), base::Time(), base::Time(), false, |
| 144 true, net::CookieSameSite::NO_RESTRICTION, |
| 145 net::COOKIE_PRIORITY_MEDIUM), |
| 146 true, true); |
| 147 DCHECK(result); |
| 148 } |
| 149 |
| 150 // Set a canonical cookie directly into the store. |
| 151 bool SetCanonicalCookie(const net::CanonicalCookie& cookie, |
| 152 bool secure_source, |
| 153 bool can_modify_httponly) { |
| 154 net::ResultSavingCookieCallback<bool> callback; |
| 155 cookie_monster_.SetCanonicalCookieAsync( |
| 156 base::MakeUnique<net::CanonicalCookie>(cookie), secure_source, |
| 157 can_modify_httponly, |
| 158 base::Bind(&net::ResultSavingCookieCallback<bool>::Run, |
| 159 base::Unretained(&callback))); |
| 160 callback.WaitUntilDone(); |
| 161 return callback.result(); |
| 162 } |
| 163 |
| 164 net::CookieStore* cookie_store() { return &cookie_monster_; } |
| 165 |
| 166 // Return the cookie service at the client end of the mojo pipe. |
| 167 mojom::CookieService* cookie_service_client() { |
| 168 return cookie_service_ptr_.get(); |
| 169 } |
| 170 |
| 171 // Synchronous wrapper |
| 172 SynchronousCookieServiceWrapper* service_wrapper() { |
| 173 return &service_wrapper_; |
| 174 } |
| 175 |
| 176 base::Time setup_time() { return setup_time_; } |
| 177 |
| 178 private: |
| 179 base::MessageLoopForIO message_loop_; |
| 180 net::CookieMonster cookie_monster_; |
| 181 content::CookieServiceImpl cookie_service_; |
| 182 mojom::CookieServicePtr cookie_service_ptr_; |
| 183 mojom::CookieServiceRequest cookie_service_request_; |
| 184 SynchronousCookieServiceWrapper service_wrapper_; |
| 185 base::Time setup_time_; |
| 186 |
| 187 DISALLOW_COPY_AND_ASSIGN(CookieServiceTest); |
| 188 }; |
| 189 |
| 190 bool CompareCanonicalCookies(const net::CanonicalCookie& c1, |
| 191 const net::CanonicalCookie& c2) { |
| 192 return c1.FullCompare(c2); |
| 193 } |
| 194 |
| 195 // Test the GetAllCookies accessor. Also tests that canonical |
| 196 // cookies come out of the store unchanged. |
| 197 TEST_F(CookieServiceTest, GetAllCookies) { |
| 198 base::Time now(base::Time::Now()); |
| 199 |
| 200 std::vector<net::CanonicalCookie> cookies = |
| 201 service_wrapper()->GetAllCookies(); |
| 202 |
| 203 ASSERT_EQ(4u, cookies.size()); |
| 204 std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies); |
| 205 |
| 206 EXPECT_EQ("A", cookies[0].Name()); |
| 207 EXPECT_EQ("B", cookies[0].Value()); |
| 208 EXPECT_EQ("foo_host", cookies[0].Domain()); |
| 209 EXPECT_EQ("/", cookies[0].Path()); |
| 210 EXPECT_LT(setup_time(), cookies[0].CreationDate()); |
| 211 EXPECT_LT(cookies[0].CreationDate(), now); |
| 212 EXPECT_LT(setup_time(), cookies[0].LastAccessDate()); |
| 213 EXPECT_LT(cookies[0].LastAccessDate(), now); |
| 214 EXPECT_EQ(cookies[0].ExpiryDate(), base::Time()); |
| 215 EXPECT_TRUE(cookies[0].IsPersistent()); |
| 216 EXPECT_FALSE(cookies[0].IsSecure()); |
| 217 EXPECT_FALSE(cookies[0].IsHttpOnly()); |
| 218 EXPECT_EQ(net::CookieSameSite::NO_RESTRICTION, cookies[0].SameSite()); |
| 219 EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[0].Priority()); |
| 220 |
| 221 // TODO(rdsmith): Put in the equivalent for the other three. |
| 222 } |
| 223 |
| 224 } // namespace content |
OLD | NEW |