| 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
|
|
|