Index: content/common/cookie_service_impl_unittest.cc |
diff --git a/content/common/cookie_service_impl_unittest.cc b/content/common/cookie_service_impl_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..54bc8e228e5c1127d56f5a755fa0432f8bf84ef1 |
--- /dev/null |
+++ b/content/common/cookie_service_impl_unittest.cc |
@@ -0,0 +1,224 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/common/cookie_service_impl.h" |
+ |
+#include <algorithm> |
+ |
+// TODO(rdsmith): Sort below :-}. |
+#include "base/message_loop/message_loop.h" |
+#include "base/run_loop.h" |
+#include "base/time/time.h" |
+#include "content/common/cookie.mojom.h" |
+#include "net/cookies/cookie_constants.h" |
+#include "net/cookies/cookie_monster.h" |
+#include "net/cookies/cookie_store.h" |
+#include "net/cookies/cookie_store_test_callbacks.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace content { |
+ |
+// Wraps a CookieService in synchronous, blocking calls to make it easier to |
+// test. |
+class SynchronousCookieServiceWrapper { |
+ public: |
+ // Caller must guarantee that |*cookie_service| outlives the |
+ // SynchronousCookieServiceWrapper. |
+ explicit SynchronousCookieServiceWrapper(mojom::CookieService* cookie_service) |
+ : cookie_service_(cookie_service) {} |
+ ~SynchronousCookieServiceWrapper() {} |
+ |
+ std::vector<net::CanonicalCookie> GetAllCookies() { |
+ cookie_service_->GetAllCookies( |
+ base::BindOnce(&SynchronousCookieServiceWrapper::GetCookiesCallback, |
+ base::Unretained(this))); |
+ run_loop_.Run(); |
+ return cookies_; |
+ } |
+ |
+ std::vector<net::CanonicalCookie> GetCookieList(const GURL& url, |
+ net::CookieOptions options) { |
+ cookie_service_->GetCookieList( |
+ url, options, |
+ base::BindOnce(&SynchronousCookieServiceWrapper::GetCookiesCallback, |
+ base::Unretained(this))); |
+ run_loop_.Run(); |
+ return cookies_; |
+ } |
+ |
+ bool SetCanonicalCookie(const net::CanonicalCookie& cookie, |
+ bool secure_source, |
+ bool modify_http_only) { |
+ cookie_service_->SetCanonicalCookie( |
+ cookie, secure_source, modify_http_only, |
+ base::BindOnce(&SynchronousCookieServiceWrapper::SetCookieCallback, |
+ base::Unretained(this))); |
+ run_loop_.Run(); |
+ return result_; |
+ } |
+ |
+ uint32_t DeleteCookies(mojom::CookieDeletionFilter filter) { |
+ mojom::CookieDeletionFilterPtr filter_ptr = |
+ mojom::CookieDeletionFilter::New(filter); |
+ |
+ cookie_service_->DeleteCookies( |
+ std::move(filter_ptr), |
+ base::BindOnce(&SynchronousCookieServiceWrapper::DeleteCookiesCallback, |
+ base::Unretained(this))); |
+ run_loop_.Run(); |
+ return num_deleted_; |
+ } |
+ |
+ // TODO(rdsmith): Put in infrastructure for RequestNotification |
+ // and CloneInterface when I know what I want the tests for those to |
+ // look like. |
+ |
+ private: |
+ void GetCookiesCallback(const std::vector<net::CanonicalCookie>& cookies) { |
+ cookies_ = cookies; |
+ run_loop_.Quit(); |
+ } |
+ |
+ void SetCookieCallback(bool result) { |
+ result_ = result; |
+ run_loop_.Quit(); |
+ } |
+ |
+ void DeleteCookiesCallback(uint32_t num_deleted) { |
+ num_deleted_ = num_deleted; |
+ run_loop_.Quit(); |
+ } |
+ |
+ mojom::CookieService* cookie_service_; |
+ base::RunLoop run_loop_; |
+ |
+ std::vector<net::CanonicalCookie> cookies_; |
+ bool result_; |
+ uint32_t num_deleted_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SynchronousCookieServiceWrapper); |
+}; |
+ |
+class CookieServiceTest : public testing::Test { |
+ public: |
+ CookieServiceTest() |
+ : cookie_monster_(nullptr, nullptr), |
+ cookie_service_(&cookie_monster_), |
+ cookie_service_request_(mojo::MakeRequest(&cookie_service_ptr_)), |
+ service_wrapper_(cookie_service_ptr_.get()) {} |
+ ~CookieServiceTest() override {} |
+ |
+ void SetUp() override { |
+ setup_time_ = base::Time::Now(); |
+ |
+ // Set a couple of cookies for tests to play with. |
+ bool result; |
+ result = SetCanonicalCookie( |
+ net::CanonicalCookie("A", "B", "foo_host", "/", base::Time(), |
+ base::Time(), base::Time(), false, false, |
+ net::CookieSameSite::NO_RESTRICTION, |
+ net::COOKIE_PRIORITY_MEDIUM), |
+ true, true); |
+ DCHECK(result); |
+ |
+ result = SetCanonicalCookie( |
+ net::CanonicalCookie("C", "D", "foo_host", "/with/path", base::Time(), |
+ base::Time(), base::Time(), false, false, |
+ net::CookieSameSite::NO_RESTRICTION, |
+ net::COOKIE_PRIORITY_MEDIUM), |
+ true, true); |
+ DCHECK(result); |
+ |
+ result = SetCanonicalCookie( |
+ net::CanonicalCookie("Secure", "E", "foo_host", "/with/path", |
+ base::Time(), base::Time(), base::Time(), true, |
+ false, net::CookieSameSite::NO_RESTRICTION, |
+ net::COOKIE_PRIORITY_MEDIUM), |
+ true, true); |
+ DCHECK(result); |
+ |
+ result = SetCanonicalCookie( |
+ net::CanonicalCookie("HttpOnly", "F", "foo_host", "/with/path", |
+ base::Time(), base::Time(), base::Time(), false, |
+ true, net::CookieSameSite::NO_RESTRICTION, |
+ net::COOKIE_PRIORITY_MEDIUM), |
+ true, true); |
+ DCHECK(result); |
+ } |
+ |
+ // Set a canonical cookie directly into the store. |
+ bool SetCanonicalCookie(const net::CanonicalCookie& cookie, |
+ bool secure_source, |
+ bool can_modify_httponly) { |
+ net::ResultSavingCookieCallback<bool> callback; |
+ cookie_monster_.SetCanonicalCookieAsync( |
+ base::MakeUnique<net::CanonicalCookie>(cookie), secure_source, |
+ can_modify_httponly, |
+ base::Bind(&net::ResultSavingCookieCallback<bool>::Run, |
+ base::Unretained(&callback))); |
+ callback.WaitUntilDone(); |
+ return callback.result(); |
+ } |
+ |
+ net::CookieStore* cookie_store() { return &cookie_monster_; } |
+ |
+ // Return the cookie service at the client end of the mojo pipe. |
+ mojom::CookieService* cookie_service_client() { |
+ return cookie_service_ptr_.get(); |
+ } |
+ |
+ // Synchronous wrapper |
+ SynchronousCookieServiceWrapper* service_wrapper() { |
+ return &service_wrapper_; |
+ } |
+ |
+ base::Time setup_time() { return setup_time_; } |
+ |
+ private: |
+ base::MessageLoopForIO message_loop_; |
+ net::CookieMonster cookie_monster_; |
+ content::CookieServiceImpl cookie_service_; |
+ mojom::CookieServicePtr cookie_service_ptr_; |
+ mojom::CookieServiceRequest cookie_service_request_; |
+ SynchronousCookieServiceWrapper service_wrapper_; |
+ base::Time setup_time_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CookieServiceTest); |
+}; |
+ |
+bool CompareCanonicalCookies(const net::CanonicalCookie& c1, |
+ const net::CanonicalCookie& c2) { |
+ return c1.FullCompare(c2); |
+} |
+ |
+// Test the GetAllCookies accessor. Also tests that canonical |
+// cookies come out of the store unchanged. |
+TEST_F(CookieServiceTest, GetAllCookies) { |
+ base::Time now(base::Time::Now()); |
+ |
+ std::vector<net::CanonicalCookie> cookies = |
+ service_wrapper()->GetAllCookies(); |
+ |
+ ASSERT_EQ(4u, cookies.size()); |
+ std::sort(cookies.begin(), cookies.end(), &CompareCanonicalCookies); |
+ |
+ EXPECT_EQ("A", cookies[0].Name()); |
+ EXPECT_EQ("B", cookies[0].Value()); |
+ EXPECT_EQ("foo_host", cookies[0].Domain()); |
+ EXPECT_EQ("/", cookies[0].Path()); |
+ EXPECT_LT(setup_time(), cookies[0].CreationDate()); |
+ EXPECT_LT(cookies[0].CreationDate(), now); |
+ EXPECT_LT(setup_time(), cookies[0].LastAccessDate()); |
+ EXPECT_LT(cookies[0].LastAccessDate(), now); |
+ EXPECT_EQ(cookies[0].ExpiryDate(), base::Time()); |
+ EXPECT_TRUE(cookies[0].IsPersistent()); |
+ EXPECT_FALSE(cookies[0].IsSecure()); |
+ EXPECT_FALSE(cookies[0].IsHttpOnly()); |
+ EXPECT_EQ(net::CookieSameSite::NO_RESTRICTION, cookies[0].SameSite()); |
+ EXPECT_EQ(net::COOKIE_PRIORITY_MEDIUM, cookies[0].Priority()); |
+ |
+ // TODO(rdsmith): Put in the equivalent for the other three. |
+} |
+ |
+} // namespace content |