// Copyright (c) 2012 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 "net/cookies/cookie_store_unittest.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_samples.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_monster_store_test.h"  // For CookieStore mock
#include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace net {

using base::Time;
using base::TimeDelta;

namespace {

// TODO(erikwright): Replace the pre-existing MockPersistentCookieStore (and
// brethren) with this one, and remove the 'New' prefix.
class NewMockPersistentCookieStore
    : public CookieMonster::PersistentCookieStore {
 public:
  MOCK_METHOD1(Load, void(const LoadedCallback& loaded_callback));
  MOCK_METHOD2(LoadCookiesForKey,
               void(const std::string& key,
                    const LoadedCallback& loaded_callback));
  MOCK_METHOD1(AddCookie, void(const CanonicalCookie& cc));
  MOCK_METHOD1(UpdateCookieAccessTime, void(const CanonicalCookie& cc));
  MOCK_METHOD1(DeleteCookie, void(const CanonicalCookie& cc));
  virtual void Flush(const base::Closure& callback) {
    if (!callback.is_null())
      base::MessageLoop::current()->PostTask(FROM_HERE, callback);
  }
  MOCK_METHOD0(SetForceKeepSessionState, void());

 private:
  virtual ~NewMockPersistentCookieStore() {}
};

const char kTopLevelDomainPlus1[] = "http://www.harvard.edu";
const char kTopLevelDomainPlus2[] = "http://www.math.harvard.edu";
const char kTopLevelDomainPlus2Secure[] = "https://www.math.harvard.edu";
const char kTopLevelDomainPlus3[] = "http://www.bourbaki.math.harvard.edu";
const char kOtherDomain[] = "http://www.mit.edu";
const char kUrlGoogleSpecific[] = "http://www.gmail.google.izzle";

class GetCookieListCallback : public CookieCallback {
 public:
  GetCookieListCallback() {}
  explicit GetCookieListCallback(Thread* run_in_thread)
      : CookieCallback(run_in_thread) {}

  void Run(const CookieList& cookies) {
    cookies_ = cookies;
    CallbackEpilogue();
  }

  const CookieList& cookies() { return cookies_; }

 private:
  CookieList cookies_;
};

struct CookieMonsterTestTraits {
  static scoped_refptr<CookieStore> Create() {
    return new CookieMonster(NULL, NULL);
  }

  static const bool is_cookie_monster = true;
  static const bool supports_http_only = true;
  static const bool supports_non_dotted_domains = true;
  static const bool supports_trailing_dots = true;
  static const bool filters_schemes = true;
  static const bool has_path_prefix_bug = false;
  static const int creation_time_granularity_in_ms = 0;
};

INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
                              CookieStoreTest,
                              CookieMonsterTestTraits);

INSTANTIATE_TYPED_TEST_CASE_P(CookieMonster,
                              MultiThreadedCookieStoreTest,
                              CookieMonsterTestTraits);

class CookieMonsterTest : public CookieStoreTest<CookieMonsterTestTraits> {
 protected:
  CookieList GetAllCookies(CookieMonster* cm) {
    DCHECK(cm);
    GetCookieListCallback callback;
    cm->GetAllCookiesAsync(
        base::Bind(&GetCookieListCallback::Run, base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.cookies();
  }

  CookieList GetAllCookiesForURL(CookieMonster* cm, const GURL& url) {
    DCHECK(cm);
    GetCookieListCallback callback;
    cm->GetAllCookiesForURLAsync(url, base::Bind(&GetCookieListCallback::Run,
                                                 base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.cookies();
  }

  CookieList GetAllCookiesForURLWithOptions(CookieMonster* cm,
                                            const GURL& url,
                                            const CookieOptions& options) {
    DCHECK(cm);
    GetCookieListCallback callback;
    cm->GetAllCookiesForURLWithOptionsAsync(
        url, options,
        base::Bind(&GetCookieListCallback::Run, base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.cookies();
  }

  bool SetCookieWithDetails(CookieMonster* cm,
                            const GURL& url,
                            const std::string& name,
                            const std::string& value,
                            const std::string& domain,
                            const std::string& path,
                            const base::Time& expiration_time,
                            bool secure,
                            bool http_only,
                            bool first_party_only,
                            CookiePriority priority) {
    DCHECK(cm);
    ResultSavingCookieCallback<bool> callback;
    cm->SetCookieWithDetailsAsync(
        url, name, value, domain, path, expiration_time, secure, http_only,
        first_party_only, priority,
        base::Bind(&ResultSavingCookieCallback<bool>::Run,
                   base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.result();
  }

  bool SetAllCookies(CookieMonster* cm, const CookieList& list) {
    DCHECK(cm);
    ResultSavingCookieCallback<bool> callback;
    cm->SetAllCookiesAsync(list,
                           base::Bind(&ResultSavingCookieCallback<bool>::Run,
                                      base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.result();
  }

  int DeleteAll(CookieMonster* cm) {
    DCHECK(cm);
    ResultSavingCookieCallback<int> callback;
    cm->DeleteAllAsync(base::Bind(&ResultSavingCookieCallback<int>::Run,
                                  base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.result();
  }

  int DeleteAllCreatedBetween(CookieMonster* cm,
                              const base::Time& delete_begin,
                              const base::Time& delete_end) {
    DCHECK(cm);
    ResultSavingCookieCallback<int> callback;
    cm->DeleteAllCreatedBetweenAsync(
        delete_begin, delete_end,
        base::Bind(&ResultSavingCookieCallback<int>::Run,
                   base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.result();
  }

  int DeleteAllCreatedBetweenForHost(CookieMonster* cm,
                                     const base::Time delete_begin,
                                     const base::Time delete_end,
                                     const GURL& url) {
    DCHECK(cm);
    ResultSavingCookieCallback<int> callback;
    cm->DeleteAllCreatedBetweenForHostAsync(
        delete_begin, delete_end, url,
        base::Bind(&ResultSavingCookieCallback<int>::Run,
                   base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.result();
  }

  int DeleteAllForHost(CookieMonster* cm, const GURL& url) {
    DCHECK(cm);
    ResultSavingCookieCallback<int> callback;
    cm->DeleteAllForHostAsync(url,
                              base::Bind(&ResultSavingCookieCallback<int>::Run,
                                         base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.result();
  }

  bool DeleteCanonicalCookie(CookieMonster* cm, const CanonicalCookie& cookie) {
    DCHECK(cm);
    ResultSavingCookieCallback<bool> callback;
    cm->DeleteCanonicalCookieAsync(
        cookie, base::Bind(&ResultSavingCookieCallback<bool>::Run,
                           base::Unretained(&callback)));
    RunFor(kTimeout);
    EXPECT_TRUE(callback.did_run());
    return callback.result();
  }

  // Helper for DeleteAllForHost test; repopulates CM with same layout
  // each time.
  void PopulateCmForDeleteAllForHost(scoped_refptr<CookieMonster> cm) {
    GURL url_top_level_domain_plus_1(kTopLevelDomainPlus1);
    GURL url_top_level_domain_plus_2(kTopLevelDomainPlus2);
    GURL url_top_level_domain_plus_2_secure(kTopLevelDomainPlus2Secure);
    GURL url_top_level_domain_plus_3(kTopLevelDomainPlus3);
    GURL url_other(kOtherDomain);

    DeleteAll(cm.get());

    // Static population for probe:
    //    * Three levels of domain cookie (.b.a, .c.b.a, .d.c.b.a)
    //    * Three levels of host cookie (w.b.a, w.c.b.a, w.d.c.b.a)
    //    * http_only cookie (w.c.b.a)
    //    * first-party cookie (w.c.b.a)
    //    * Two secure cookies (.c.b.a, w.c.b.a)
    //    * Two domain path cookies (.c.b.a/dir1, .c.b.a/dir1/dir2)
    //    * Two host path cookies (w.c.b.a/dir1, w.c.b.a/dir1/dir2)

    // Domain cookies
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_1, "dom_1", "X", ".harvard.edu",
        "/", base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2, "dom_2", "X",
        ".math.harvard.edu", "/", base::Time(), false, false, false,
        COOKIE_PRIORITY_DEFAULT));
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_3, "dom_3", "X",
        ".bourbaki.math.harvard.edu", "/", base::Time(), false, false, false,
        COOKIE_PRIORITY_DEFAULT));

    // Host cookies
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_1, "host_1", "X", std::string(),
        "/", base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2, "host_2", "X", std::string(),
        "/", base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_3, "host_3", "X", std::string(),
        "/", base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));

    // http_only cookie
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2, "httpo_check", "x",
        std::string(), "/", base::Time(), false, true, false,
        COOKIE_PRIORITY_DEFAULT));

    // first-party cookie
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2, "firstp_check", "x",
        std::string(), "/", base::Time(), false, false, true,
        COOKIE_PRIORITY_DEFAULT));

    // Secure cookies
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2_secure, "sec_dom", "X",
        ".math.harvard.edu", "/", base::Time(), true, false, false,
        COOKIE_PRIORITY_DEFAULT));
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2_secure, "sec_host", "X",
        std::string(), "/", base::Time(), true, false, false,
        COOKIE_PRIORITY_DEFAULT));

    // Domain path cookies
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2, "dom_path_1", "X",
        ".math.harvard.edu", "/dir1", base::Time(), false, false, false,
        COOKIE_PRIORITY_DEFAULT));
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2, "dom_path_2", "X",
        ".math.harvard.edu", "/dir1/dir2", base::Time(), false, false, false,
        COOKIE_PRIORITY_DEFAULT));

    // Host path cookies
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2, "host_path_1", "X",
        std::string(), "/dir1", base::Time(), false, false, false,
        COOKIE_PRIORITY_DEFAULT));
    EXPECT_TRUE(this->SetCookieWithDetails(
        cm.get(), url_top_level_domain_plus_2, "host_path_2", "X",
        std::string(), "/dir1/dir2", base::Time(), false, false, false,
        COOKIE_PRIORITY_DEFAULT));

    EXPECT_EQ(14U, this->GetAllCookies(cm.get()).size());
  }

  Time GetFirstCookieAccessDate(CookieMonster* cm) {
    const CookieList all_cookies(this->GetAllCookies(cm));
    return all_cookies.front().LastAccessDate();
  }

  bool FindAndDeleteCookie(CookieMonster* cm,
                           const std::string& domain,
                           const std::string& name) {
    CookieList cookies = this->GetAllCookies(cm);
    for (CookieList::iterator it = cookies.begin(); it != cookies.end(); ++it)
      if (it->Domain() == domain && it->Name() == name)
        return this->DeleteCanonicalCookie(cm, *it);
    return false;
  }

  int CountInString(const std::string& str, char c) {
    return std::count(str.begin(), str.end(), c);
  }

  void TestHostGarbageCollectHelper() {
    int domain_max_cookies = CookieMonster::kDomainMaxCookies;
    int domain_purge_cookies = CookieMonster::kDomainPurgeCookies;
    const int more_than_enough_cookies =
        (domain_max_cookies + domain_purge_cookies) * 2;
    // Add a bunch of cookies on a single host, should purge them.
    {
      scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
      for (int i = 0; i < more_than_enough_cookies; ++i) {
        std::string cookie = base::StringPrintf("a%03d=b", i);
        EXPECT_TRUE(SetCookie(cm.get(), url_google_, cookie));
        std::string cookies = this->GetCookies(cm.get(), url_google_);
        // Make sure we find it in the cookies.
        EXPECT_NE(cookies.find(cookie), std::string::npos);
        // Count the number of cookies.
        EXPECT_LE(CountInString(cookies, '='), domain_max_cookies);
      }
    }

    // Add a bunch of cookies on multiple hosts within a single eTLD.
    // Should keep at least kDomainMaxCookies - kDomainPurgeCookies
    // between them.  We shouldn't go above kDomainMaxCookies for both together.
    GURL url_google_specific(kUrlGoogleSpecific);
    {
      scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
      for (int i = 0; i < more_than_enough_cookies; ++i) {
        std::string cookie_general = base::StringPrintf("a%03d=b", i);
        EXPECT_TRUE(SetCookie(cm.get(), url_google_, cookie_general));
        std::string cookie_specific = base::StringPrintf("c%03d=b", i);
        EXPECT_TRUE(SetCookie(cm.get(), url_google_specific, cookie_specific));
        std::string cookies_general = this->GetCookies(cm.get(), url_google_);
        EXPECT_NE(cookies_general.find(cookie_general), std::string::npos);
        std::string cookies_specific =
            this->GetCookies(cm.get(), url_google_specific);
        EXPECT_NE(cookies_specific.find(cookie_specific), std::string::npos);
        EXPECT_LE((CountInString(cookies_general, '=') +
                   CountInString(cookies_specific, '=')),
                  domain_max_cookies);
      }
      // After all this, there should be at least
      // kDomainMaxCookies - kDomainPurgeCookies for both URLs.
      std::string cookies_general = this->GetCookies(cm.get(), url_google_);
      std::string cookies_specific =
          this->GetCookies(cm.get(), url_google_specific);
      int total_cookies = (CountInString(cookies_general, '=') +
                           CountInString(cookies_specific, '='));
      EXPECT_GE(total_cookies, domain_max_cookies - domain_purge_cookies);
      EXPECT_LE(total_cookies, domain_max_cookies);
    }
  }

  CookiePriority CharToPriority(char ch) {
    switch (ch) {
      case 'L':
        return COOKIE_PRIORITY_LOW;
      case 'M':
        return COOKIE_PRIORITY_MEDIUM;
      case 'H':
        return COOKIE_PRIORITY_HIGH;
    }
    NOTREACHED();
    return COOKIE_PRIORITY_DEFAULT;
  }

  // Instantiates a CookieMonster, adds multiple cookies (to url_google_) with
  // priorities specified by |coded_priority_str|, and tests priority-aware
  // domain cookie eviction.
  // |coded_priority_str| specifies a run-length-encoded string of priorities.
  // Example: "2M 3L M 4H" means "MMLLLMHHHH", and speicifies sequential (i.e.,
  // from least- to most-recently accessed) insertion of 2 medium-priority
  // cookies, 3 low-priority cookies, 1 medium-priority cookie, and 4
  // high-priority cookies.
  // Within each priority, only the least-accessed cookies should be evicted.
  // Thus, to describe expected suriving cookies, it suffices to specify the
  // expected population of surviving cookies per priority, i.e.,
  // |expected_low_count|, |expected_medium_count|, and |expected_high_count|.
  void TestPriorityCookieCase(CookieMonster* cm,
                              const std::string& coded_priority_str,
                              size_t expected_low_count,
                              size_t expected_medium_count,
                              size_t expected_high_count) {
    DeleteAll(cm);
    int next_cookie_id = 0;
    std::vector<CookiePriority> priority_list;
    std::vector<int> id_list[3];  // Indexed by CookiePriority.

    // Parse |coded_priority_str| and add cookies.
    std::vector<std::string> priority_tok_list;
    base::SplitString(coded_priority_str, ' ', &priority_tok_list);
    for (std::vector<std::string>::iterator it = priority_tok_list.begin();
         it != priority_tok_list.end(); ++it) {
      size_t len = it->length();
      DCHECK_NE(len, 0U);
      // Take last character as priority.
      CookiePriority priority = CharToPriority((*it)[len - 1]);
      std::string priority_str = CookiePriorityToString(priority);
      // The rest of the string (possibly empty) specifies repetition.
      int rep = 1;
      if (!it->empty()) {
        bool result = base::StringToInt(
            base::StringPiece(it->begin(), it->end() - 1), &rep);
        DCHECK(result);
      }
      for (; rep > 0; --rep, ++next_cookie_id) {
        std::string cookie = base::StringPrintf(
            "a%d=b;priority=%s", next_cookie_id, priority_str.c_str());
        EXPECT_TRUE(SetCookie(cm, url_google_, cookie));
        priority_list.push_back(priority);
        id_list[priority].push_back(next_cookie_id);
      }
    }

    int num_cookies = static_cast<int>(priority_list.size());
    std::vector<int> surviving_id_list[3];  // Indexed by CookiePriority.

    // Parse the list of cookies
    std::string cookie_str = this->GetCookies(cm, url_google_);
    std::vector<std::string> cookie_tok_list;
    base::SplitString(cookie_str, ';', &cookie_tok_list);
    for (std::vector<std::string>::iterator it = cookie_tok_list.begin();
         it != cookie_tok_list.end(); ++it) {
      // Assuming *it is "a#=b", so extract and parse "#" portion.
      int id = -1;
      bool result = base::StringToInt(
          base::StringPiece(it->begin() + 1, it->end() - 2), &id);
      DCHECK(result);
      DCHECK_GE(id, 0);
      DCHECK_LT(id, num_cookies);
      surviving_id_list[priority_list[id]].push_back(id);
    }

    // Validate each priority.
    size_t expected_count[3] = {
        expected_low_count, expected_medium_count, expected_high_count};
    for (int i = 0; i < 3; ++i) {
      DCHECK_LE(surviving_id_list[i].size(), id_list[i].size());
      EXPECT_EQ(expected_count[i], surviving_id_list[i].size());
      // Verify that the remaining cookies are the most recent among those
      // with the same priorities.
      if (expected_count[i] == surviving_id_list[i].size()) {
        std::sort(surviving_id_list[i].begin(), surviving_id_list[i].end());
        EXPECT_TRUE(std::equal(surviving_id_list[i].begin(),
                               surviving_id_list[i].end(),
                               id_list[i].end() - expected_count[i]));
      }
    }
  }

  void TestPriorityAwareGarbageCollectHelper() {
    // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
    DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
    DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies -
                        CookieMonster::kDomainPurgeCookies);
    DCHECK_EQ(30U, CookieMonster::kDomainCookiesQuotaLow);
    DCHECK_EQ(50U, CookieMonster::kDomainCookiesQuotaMedium);
    DCHECK_EQ(70U, CookieMonster::kDomainCookiesQuotaHigh);

    scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));

    // Each test case adds 181 cookies, so 31 cookies are evicted.
    // Cookie same priority, repeated for each priority.
    TestPriorityCookieCase(cm.get(), "181L", 150U, 0U, 0U);
    TestPriorityCookieCase(cm.get(), "181M", 0U, 150U, 0U);
    TestPriorityCookieCase(cm.get(), "181H", 0U, 0U, 150U);

    // Pairwise scenarios.
    // Round 1 => none; round2 => 31M; round 3 => none.
    TestPriorityCookieCase(cm.get(), "10H 171M", 0U, 140U, 10U);
    // Round 1 => 10L; round2 => 21M; round 3 => none.
    TestPriorityCookieCase(cm.get(), "141M 40L", 30U, 120U, 0U);
    // Round 1 => none; round2 => none; round 3 => 31H.
    TestPriorityCookieCase(cm.get(), "101H 80M", 0U, 80U, 70U);

    // For {low, medium} priorities right on quota, different orders.
    // Round 1 => 1L; round 2 => none, round3 => 30L.
    TestPriorityCookieCase(cm.get(), "31L 50M 100H", 0U, 50U, 100U);
    // Round 1 => none; round 2 => 1M, round3 => 30M.
    TestPriorityCookieCase(cm.get(), "51M 100H 30L", 30U, 20U, 100U);
    // Round 1 => none; round 2 => none; round3 => 31H.
    TestPriorityCookieCase(cm.get(), "101H 50M 30L", 30U, 50U, 70U);

    // Round 1 => 10L; round 2 => 10M; round3 => 11H.
    TestPriorityCookieCase(cm.get(), "81H 60M 40L", 30U, 50U, 70U);

    // More complex scenarios.
    // Round 1 => 10L; round 2 => 10M; round 3 => 11H.
    TestPriorityCookieCase(cm.get(), "21H 60M 40L 60H", 30U, 50U, 70U);
    // Round 1 => 10L; round 2 => 11M, 10L; round 3 => none.
    TestPriorityCookieCase(cm.get(), "11H 10M 20L 110M 20L 10H", 20U, 109U,
                           21U);
    // Round 1 => none; round 2 => none; round 3 => 11L, 10M, 10H.
    TestPriorityCookieCase(cm.get(), "11L 10M 140H 10M 10L", 10U, 10U, 130U);
    // Round 1 => none; round 2 => 1M; round 3 => 10L, 10M, 10H.
    TestPriorityCookieCase(cm.get(), "11M 10H 10L 60M 90H", 0U, 60U, 90U);
    // Round 1 => none; round 2 => 10L, 21M; round 3 => none.
    TestPriorityCookieCase(cm.get(), "11M 10H 10L 90M 60H", 0U, 80U, 70U);
  }

  // Function for creating a CM with a number of cookies in it,
  // no store (and hence no ability to affect access time).
  CookieMonster* CreateMonsterForGC(int num_cookies) {
    CookieMonster* cm(new CookieMonster(NULL, NULL));
    for (int i = 0; i < num_cookies; i++) {
      SetCookie(cm, GURL(base::StringPrintf("http://h%05d.izzle", i)), "a=1");
    }
    return cm;
  }

  bool IsCookieInList(const CanonicalCookie& cookie, const CookieList& list) {
    for (CookieList::const_iterator it = list.begin(); it != list.end(); ++it) {
      if (it->Source() == cookie.Source() && it->Name() == cookie.Name() &&
          it->Value() == cookie.Value() && it->Domain() == cookie.Domain() &&
          it->Path() == cookie.Path() &&
          it->CreationDate() == cookie.CreationDate() &&
          it->ExpiryDate() == cookie.ExpiryDate() &&
          it->LastAccessDate() == cookie.LastAccessDate() &&
          it->IsSecure() == cookie.IsSecure() &&
          it->IsHttpOnly() == cookie.IsHttpOnly() &&
          it->Priority() == cookie.Priority()) {
        return true;
      }
    }

    return false;
  }
};

// TODO(erikwright): Replace the other callbacks and synchronous helper methods
// in this test suite with these Mocks.
template <typename T, typename C>
class MockCookieCallback {
 public:
  C AsCallback() {
    return base::Bind(&T::Invoke, base::Unretained(static_cast<T*>(this)));
  }
};

class MockGetCookiesCallback
    : public MockCookieCallback<MockGetCookiesCallback,
                                CookieStore::GetCookiesCallback> {
 public:
  MOCK_METHOD1(Invoke, void(const std::string& cookies));
};

class MockSetCookiesCallback
    : public MockCookieCallback<MockSetCookiesCallback,
                                CookieStore::SetCookiesCallback> {
 public:
  MOCK_METHOD1(Invoke, void(bool success));
};

class MockClosure : public MockCookieCallback<MockClosure, base::Closure> {
 public:
  MOCK_METHOD0(Invoke, void(void));
};

class MockGetCookieListCallback
    : public MockCookieCallback<MockGetCookieListCallback,
                                CookieMonster::GetCookieListCallback> {
 public:
  MOCK_METHOD1(Invoke, void(const CookieList& cookies));
};

class MockDeleteCallback
    : public MockCookieCallback<MockDeleteCallback,
                                CookieMonster::DeleteCallback> {
 public:
  MOCK_METHOD1(Invoke, void(int num_deleted));
};

class MockDeleteCookieCallback
    : public MockCookieCallback<MockDeleteCookieCallback,
                                CookieMonster::DeleteCookieCallback> {
 public:
  MOCK_METHOD1(Invoke, void(bool success));
};

struct CookiesInputInfo {
  const GURL url;
  const std::string name;
  const std::string value;
  const std::string domain;
  const std::string path;
  const base::Time expiration_time;
  bool secure;
  bool http_only;
  bool first_party_only;
  CookiePriority priority;
};

ACTION(QuitCurrentMessageLoop) {
  base::MessageLoop::current()->PostTask(FROM_HERE,
                                         base::MessageLoop::QuitClosure());
}

// TODO(erikwright): When the synchronous helpers 'GetCookies' etc. are removed,
// rename these, removing the 'Action' suffix.
ACTION_P4(DeleteCookieAction, cookie_monster, url, name, callback) {
  cookie_monster->DeleteCookieAsync(url, name, callback->AsCallback());
}
ACTION_P3(GetCookiesAction, cookie_monster, url, callback) {
  cookie_monster->GetCookiesWithOptionsAsync(url, CookieOptions(),
                                             callback->AsCallback());
}
ACTION_P4(SetCookieAction, cookie_monster, url, cookie_line, callback) {
  cookie_monster->SetCookieWithOptionsAsync(url, cookie_line, CookieOptions(),
                                            callback->AsCallback());
}
ACTION_P3(SetAllCookiesAction, cookie_monster, list, callback) {
  cookie_monster->SetAllCookiesAsync(list, callback->AsCallback());
}
ACTION_P4(DeleteAllCreatedBetweenAction,
          cookie_monster,
          delete_begin,
          delete_end,
          callback) {
  cookie_monster->DeleteAllCreatedBetweenAsync(delete_begin, delete_end,
                                               callback->AsCallback());
}
ACTION_P3(SetCookieWithDetailsAction, cookie_monster, cc, callback) {
  cookie_monster->SetCookieWithDetailsAsync(
      cc.url, cc.name, cc.value, cc.domain, cc.path, cc.expiration_time,
      cc.secure, cc.http_only, cc.first_party_only, cc.priority,
      callback->AsCallback());
}

ACTION_P2(GetAllCookiesAction, cookie_monster, callback) {
  cookie_monster->GetAllCookiesAsync(callback->AsCallback());
}

ACTION_P3(DeleteAllForHostAction, cookie_monster, url, callback) {
  cookie_monster->DeleteAllForHostAsync(url, callback->AsCallback());
}

ACTION_P3(DeleteCanonicalCookieAction, cookie_monster, cookie, callback) {
  cookie_monster->DeleteCanonicalCookieAsync(cookie, callback->AsCallback());
}

ACTION_P2(DeleteAllAction, cookie_monster, callback) {
  cookie_monster->DeleteAllAsync(callback->AsCallback());
}

ACTION_P3(GetAllCookiesForUrlWithOptionsAction, cookie_monster, url, callback) {
  cookie_monster->GetAllCookiesForURLWithOptionsAsync(url, CookieOptions(),
                                                      callback->AsCallback());
}

ACTION_P3(GetAllCookiesForUrlAction, cookie_monster, url, callback) {
  cookie_monster->GetAllCookiesForURLAsync(url, callback->AsCallback());
}

ACTION_P(PushCallbackAction, callback_vector) {
  callback_vector->push(arg1);
}

ACTION_P2(DeleteSessionCookiesAction, cookie_monster, callback) {
  cookie_monster->DeleteSessionCookiesAsync(callback->AsCallback());
}

}  // namespace

// This test suite verifies the task deferral behaviour of the CookieMonster.
// Specifically, for each asynchronous method, verify that:
// 1. invoking it on an uninitialized cookie store causes the store to begin
//    chain-loading its backing data or loading data for a specific domain key
//    (eTLD+1).
// 2. The initial invocation does not complete until the loading completes.
// 3. Invocations after the loading has completed complete immediately.
class DeferredCookieTaskTest : public CookieMonsterTest {
 protected:
  DeferredCookieTaskTest() {
    persistent_store_ = new NewMockPersistentCookieStore();
    cookie_monster_ = new CookieMonster(persistent_store_.get(), NULL);
  }

  // Defines a cookie to be returned from PersistentCookieStore::Load
  void DeclareLoadedCookie(const std::string& key,
                           const std::string& cookie_line,
                           const base::Time& creation_time) {
    AddCookieToList(key, cookie_line, creation_time, &loaded_cookies_);
  }

  // Runs the message loop, waiting until PersistentCookieStore::Load is called.
  // Call CompleteLoadingAndWait to cause the load to complete.
  void WaitForLoadCall() {
    RunFor(kTimeout);

    // Verify that PeristentStore::Load was called.
    testing::Mock::VerifyAndClear(persistent_store_.get());
  }

  // Invokes the PersistentCookieStore::LoadCookiesForKey completion callbacks
  // and PersistentCookieStore::Load completion callback and waits
  // until the message loop is quit.
  void CompleteLoadingAndWait() {
    while (!loaded_for_key_callbacks_.empty()) {
      loaded_for_key_callbacks_.front().Run(loaded_cookies_);
      loaded_cookies_.clear();
      loaded_for_key_callbacks_.pop();
    }

    loaded_callback_.Run(loaded_cookies_);
    RunFor(kTimeout);
  }

  // Performs the provided action, expecting it to cause a call to
  // PersistentCookieStore::Load. Call WaitForLoadCall to verify the load call
  // is received.
  void BeginWith(testing::Action<void(void)> action) {
    EXPECT_CALL(*this, Begin()).WillOnce(action);
    ExpectLoadCall();
    Begin();
  }

  void BeginWithForDomainKey(std::string key,
                             testing::Action<void(void)> action) {
    EXPECT_CALL(*this, Begin()).WillOnce(action);
    ExpectLoadCall();
    ExpectLoadForKeyCall(key, false);
    Begin();
  }

  // Declares an expectation that PersistentCookieStore::Load will be called,
  // saving the provided callback and sending a quit to the message loop.
  void ExpectLoadCall() {
    EXPECT_CALL(*persistent_store_.get(), Load(testing::_))
        .WillOnce(testing::DoAll(testing::SaveArg<0>(&loaded_callback_),
                                 QuitCurrentMessageLoop()));
  }

  // Declares an expectation that PersistentCookieStore::LoadCookiesForKey
  // will be called, saving the provided callback and sending a quit to the
  // message loop.
  void ExpectLoadForKeyCall(std::string key, bool quit_queue) {
    if (quit_queue)
      EXPECT_CALL(*persistent_store_.get(), LoadCookiesForKey(key, testing::_))
          .WillOnce(
              testing::DoAll(PushCallbackAction(&loaded_for_key_callbacks_),
                             QuitCurrentMessageLoop()));
    else
      EXPECT_CALL(*persistent_store_.get(), LoadCookiesForKey(key, testing::_))
          .WillOnce(PushCallbackAction(&loaded_for_key_callbacks_));
  }

  // Invokes the initial action.
  MOCK_METHOD0(Begin, void(void));

  // Returns the CookieMonster instance under test.
  CookieMonster& cookie_monster() { return *cookie_monster_.get(); }

 private:
  // Declares that mock expectations in this test suite are strictly ordered.
  testing::InSequence in_sequence_;
  // Holds cookies to be returned from PersistentCookieStore::Load or
  // PersistentCookieStore::LoadCookiesForKey.
  std::vector<CanonicalCookie*> loaded_cookies_;
  // Stores the callback passed from the CookieMonster to the
  // PersistentCookieStore::Load
  CookieMonster::PersistentCookieStore::LoadedCallback loaded_callback_;
  // Stores the callback passed from the CookieMonster to the
  // PersistentCookieStore::LoadCookiesForKey
  std::queue<CookieMonster::PersistentCookieStore::LoadedCallback>
      loaded_for_key_callbacks_;

  // Stores the CookieMonster under test.
  scoped_refptr<CookieMonster> cookie_monster_;
  // Stores the mock PersistentCookieStore.
  scoped_refptr<NewMockPersistentCookieStore> persistent_store_;
};

TEST_F(DeferredCookieTaskTest, DeferredGetCookies) {
  DeclareLoadedCookie("www.google.izzle",
                      "X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                      Time::Now() + TimeDelta::FromDays(3));

  MockGetCookiesCallback get_cookies_callback;

  BeginWithForDomainKey(
      "google.izzle",
      GetCookiesAction(&cookie_monster(), url_google_, &get_cookies_callback));

  WaitForLoadCall();

  EXPECT_CALL(get_cookies_callback, Invoke("X=1"))
      .WillOnce(GetCookiesAction(&cookie_monster(), url_google_,
                                 &get_cookies_callback));
  EXPECT_CALL(get_cookies_callback, Invoke("X=1"))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredSetCookie) {
  MockSetCookiesCallback set_cookies_callback;

  BeginWithForDomainKey("google.izzle",
                        SetCookieAction(&cookie_monster(), url_google_, "A=B",
                                        &set_cookies_callback));

  WaitForLoadCall();

  EXPECT_CALL(set_cookies_callback, Invoke(true))
      .WillOnce(SetCookieAction(&cookie_monster(), url_google_, "X=Y",
                                &set_cookies_callback));
  EXPECT_CALL(set_cookies_callback, Invoke(true))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredSetAllCookies) {
  MockSetCookiesCallback set_cookies_callback;
  CookieList list;
  list.push_back(CanonicalCookie(url_google_, "A", "B", "google.izzle", "/",
                                 base::Time::Now(), base::Time(), base::Time(),
                                 false, true, false, COOKIE_PRIORITY_DEFAULT));
  list.push_back(CanonicalCookie(url_google_, "C", "D", "google.izzle", "/",
                                 base::Time::Now(), base::Time(), base::Time(),
                                 false, true, false, COOKIE_PRIORITY_DEFAULT));

  BeginWith(
      SetAllCookiesAction(&cookie_monster(), list, &set_cookies_callback));

  WaitForLoadCall();

  EXPECT_CALL(set_cookies_callback, Invoke(true))
      .WillOnce(
          SetAllCookiesAction(&cookie_monster(), list, &set_cookies_callback));
  EXPECT_CALL(set_cookies_callback, Invoke(true))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredDeleteCookie) {
  MockClosure delete_cookie_callback;

  BeginWithForDomainKey("google.izzle",
                        DeleteCookieAction(&cookie_monster(), url_google_, "A",
                                           &delete_cookie_callback));

  WaitForLoadCall();

  EXPECT_CALL(delete_cookie_callback, Invoke())
      .WillOnce(DeleteCookieAction(&cookie_monster(), url_google_, "X",
                                   &delete_cookie_callback));
  EXPECT_CALL(delete_cookie_callback, Invoke())
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredSetCookieWithDetails) {
  MockSetCookiesCallback set_cookies_callback;

  CookiesInputInfo cookie_info = {url_google_foo_,
                                  "A",
                                  "B",
                                  std::string(),
                                  "/foo",
                                  base::Time(),
                                  false,
                                  false,
                                  false,
                                  COOKIE_PRIORITY_DEFAULT};
  BeginWithForDomainKey(
      "google.izzle", SetCookieWithDetailsAction(&cookie_monster(), cookie_info,
                                                 &set_cookies_callback));

  WaitForLoadCall();

  CookiesInputInfo cookie_info_exp = {url_google_foo_,
                                      "A",
                                      "B",
                                      std::string(),
                                      "/foo",
                                      base::Time(),
                                      false,
                                      false,
                                      false,
                                      COOKIE_PRIORITY_DEFAULT};
  EXPECT_CALL(set_cookies_callback, Invoke(true))
      .WillOnce(SetCookieWithDetailsAction(&cookie_monster(), cookie_info_exp,
                                           &set_cookies_callback));
  EXPECT_CALL(set_cookies_callback, Invoke(true))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredGetAllCookies) {
  DeclareLoadedCookie("www.google.izzle",
                      "X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                      Time::Now() + TimeDelta::FromDays(3));

  MockGetCookieListCallback get_cookie_list_callback;

  BeginWith(GetAllCookiesAction(&cookie_monster(), &get_cookie_list_callback));

  WaitForLoadCall();

  EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
      .WillOnce(
          GetAllCookiesAction(&cookie_monster(), &get_cookie_list_callback));
  EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredGetAllForUrlCookies) {
  DeclareLoadedCookie("www.google.izzle",
                      "X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                      Time::Now() + TimeDelta::FromDays(3));

  MockGetCookieListCallback get_cookie_list_callback;

  BeginWithForDomainKey(
      "google.izzle", GetAllCookiesForUrlAction(&cookie_monster(), url_google_,
                                                &get_cookie_list_callback));

  WaitForLoadCall();

  EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
      .WillOnce(GetAllCookiesForUrlAction(&cookie_monster(), url_google_,
                                          &get_cookie_list_callback));
  EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredGetAllForUrlWithOptionsCookies) {
  DeclareLoadedCookie("www.google.izzle",
                      "X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                      Time::Now() + TimeDelta::FromDays(3));

  MockGetCookieListCallback get_cookie_list_callback;

  BeginWithForDomainKey("google.izzle", GetAllCookiesForUrlWithOptionsAction(
                                            &cookie_monster(), url_google_,
                                            &get_cookie_list_callback));

  WaitForLoadCall();

  EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
      .WillOnce(GetAllCookiesForUrlWithOptionsAction(
          &cookie_monster(), url_google_, &get_cookie_list_callback));
  EXPECT_CALL(get_cookie_list_callback, Invoke(testing::_))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredDeleteAllCookies) {
  MockDeleteCallback delete_callback;

  BeginWith(DeleteAllAction(&cookie_monster(), &delete_callback));

  WaitForLoadCall();

  EXPECT_CALL(delete_callback, Invoke(false))
      .WillOnce(DeleteAllAction(&cookie_monster(), &delete_callback));
  EXPECT_CALL(delete_callback, Invoke(false))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredDeleteAllCreatedBetweenCookies) {
  MockDeleteCallback delete_callback;

  BeginWith(DeleteAllCreatedBetweenAction(&cookie_monster(), base::Time(),
                                          base::Time::Now(), &delete_callback));

  WaitForLoadCall();

  EXPECT_CALL(delete_callback, Invoke(false))
      .WillOnce(DeleteAllCreatedBetweenAction(&cookie_monster(), base::Time(),
                                              base::Time::Now(),
                                              &delete_callback));
  EXPECT_CALL(delete_callback, Invoke(false))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredDeleteAllForHostCookies) {
  MockDeleteCallback delete_callback;

  BeginWithForDomainKey(
      "google.izzle",
      DeleteAllForHostAction(&cookie_monster(), url_google_, &delete_callback));

  WaitForLoadCall();

  EXPECT_CALL(delete_callback, Invoke(false))
      .WillOnce(DeleteAllForHostAction(&cookie_monster(), url_google_,
                                       &delete_callback));
  EXPECT_CALL(delete_callback, Invoke(false))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredDeleteCanonicalCookie) {
  std::vector<CanonicalCookie*> cookies;
  CanonicalCookie cookie =
      BuildCanonicalCookie("www.google.com", "X=1; path=/", base::Time::Now());

  MockDeleteCookieCallback delete_cookie_callback;

  BeginWith(DeleteCanonicalCookieAction(&cookie_monster(), cookie,
                                        &delete_cookie_callback));

  WaitForLoadCall();

  EXPECT_CALL(delete_cookie_callback, Invoke(false))
      .WillOnce(DeleteCanonicalCookieAction(&cookie_monster(), cookie,
                                            &delete_cookie_callback));
  EXPECT_CALL(delete_cookie_callback, Invoke(false))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(DeferredCookieTaskTest, DeferredDeleteSessionCookies) {
  MockDeleteCallback delete_callback;

  BeginWith(DeleteSessionCookiesAction(&cookie_monster(), &delete_callback));

  WaitForLoadCall();

  EXPECT_CALL(delete_callback, Invoke(false))
      .WillOnce(
          DeleteSessionCookiesAction(&cookie_monster(), &delete_callback));
  EXPECT_CALL(delete_callback, Invoke(false))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

// Verify that a series of queued tasks are executed in order upon loading of
// the backing store and that new tasks received while the queued tasks are
// being dispatched go to the end of the queue.
TEST_F(DeferredCookieTaskTest, DeferredTaskOrder) {
  DeclareLoadedCookie("www.google.izzle",
                      "X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                      Time::Now() + TimeDelta::FromDays(3));

  MockGetCookiesCallback get_cookies_callback;
  MockSetCookiesCallback set_cookies_callback;
  MockGetCookiesCallback get_cookies_callback_deferred;

  EXPECT_CALL(*this, Begin())
      .WillOnce(testing::DoAll(GetCookiesAction(&cookie_monster(), url_google_,
                                                &get_cookies_callback),
                               SetCookieAction(&cookie_monster(), url_google_,
                                               "A=B", &set_cookies_callback)));
  ExpectLoadCall();
  ExpectLoadForKeyCall("google.izzle", false);
  Begin();

  WaitForLoadCall();
  EXPECT_CALL(get_cookies_callback, Invoke("X=1"))
      .WillOnce(GetCookiesAction(&cookie_monster(), url_google_,
                                 &get_cookies_callback_deferred));
  EXPECT_CALL(set_cookies_callback, Invoke(true));
  EXPECT_CALL(get_cookies_callback_deferred, Invoke("A=B; X=1"))
      .WillOnce(QuitCurrentMessageLoop());

  CompleteLoadingAndWait();
}

TEST_F(CookieMonsterTest, TestCookieDeleteAll) {
  scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
  CookieOptions options;
  options.set_include_httponly();

  EXPECT_TRUE(SetCookie(cm.get(), url_google_, kValidCookieLine));
  EXPECT_EQ("A=B", GetCookies(cm.get(), url_google_));

  EXPECT_TRUE(
      SetCookieWithOptions(cm.get(), url_google_, "C=D; httponly", options));
  EXPECT_EQ("A=B; C=D", GetCookiesWithOptions(cm.get(), url_google_, options));

  EXPECT_EQ(2, DeleteAll(cm.get()));
  EXPECT_EQ("", GetCookiesWithOptions(cm.get(), url_google_, options));
  EXPECT_EQ(0u, store->commands().size());

  // Create a persistent cookie.
  EXPECT_TRUE(SetCookie(
      cm.get(), url_google_,
      std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT"));
  ASSERT_EQ(1u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);

  EXPECT_EQ(1, DeleteAll(cm.get()));  // sync_to_store = true.
  ASSERT_EQ(2u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);

  EXPECT_EQ("", GetCookiesWithOptions(cm.get(), url_google_, options));
}

TEST_F(CookieMonsterTest, TestCookieDeleteAllCreatedBetweenTimestamps) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  Time now = Time::Now();

  // Nothing has been added so nothing should be deleted.
  EXPECT_EQ(0, DeleteAllCreatedBetween(cm.get(), now - TimeDelta::FromDays(99),
                                       Time()));

  // Create 3 cookies with creation date of today, yesterday and the day before.
  EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-0=Now", now));
  EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-1=Yesterday",
                                            now - TimeDelta::FromDays(1)));
  EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-2=DayBefore",
                                            now - TimeDelta::FromDays(2)));
  EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-3=ThreeDays",
                                            now - TimeDelta::FromDays(3)));
  EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "T-7=LastWeek",
                                            now - TimeDelta::FromDays(7)));

  // Try to delete threedays and the daybefore.
  EXPECT_EQ(2, DeleteAllCreatedBetween(cm.get(), now - TimeDelta::FromDays(3),
                                       now - TimeDelta::FromDays(1)));

  // Try to delete yesterday, also make sure that delete_end is not
  // inclusive.
  EXPECT_EQ(
      1, DeleteAllCreatedBetween(cm.get(), now - TimeDelta::FromDays(2), now));

  // Make sure the delete_begin is inclusive.
  EXPECT_EQ(
      1, DeleteAllCreatedBetween(cm.get(), now - TimeDelta::FromDays(7), now));

  // Delete the last (now) item.
  EXPECT_EQ(1, DeleteAllCreatedBetween(cm.get(), Time(), Time()));

  // Really make sure everything is gone.
  EXPECT_EQ(0, DeleteAll(cm.get()));
}

static const int kAccessDelayMs = kLastAccessThresholdMilliseconds + 20;

TEST_F(CookieMonsterTest, TestLastAccess) {
  scoped_refptr<CookieMonster> cm(
      new CookieMonster(NULL, NULL, kLastAccessThresholdMilliseconds));

  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
  const Time last_access_date(GetFirstCookieAccessDate(cm.get()));

  // Reading the cookie again immediately shouldn't update the access date,
  // since we're inside the threshold.
  EXPECT_EQ("A=B", GetCookies(cm.get(), url_google_));
  EXPECT_TRUE(last_access_date == GetFirstCookieAccessDate(cm.get()));

  // Reading after a short wait should update the access date.
  base::PlatformThread::Sleep(
      base::TimeDelta::FromMilliseconds(kAccessDelayMs));
  EXPECT_EQ("A=B", GetCookies(cm.get(), url_google_));
  EXPECT_FALSE(last_access_date == GetFirstCookieAccessDate(cm.get()));
}

TEST_F(CookieMonsterTest, TestHostGarbageCollection) {
  TestHostGarbageCollectHelper();
}

TEST_F(CookieMonsterTest, TestPriorityAwareGarbageCollection) {
  TestPriorityAwareGarbageCollectHelper();
}

TEST_F(CookieMonsterTest, TestDeleteSingleCookie) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));

  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "C=D"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "E=F"));
  EXPECT_EQ("A=B; C=D; E=F", GetCookies(cm.get(), url_google_));

  EXPECT_TRUE(FindAndDeleteCookie(cm.get(), url_google_.host(), "C"));
  EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), url_google_));

  EXPECT_FALSE(FindAndDeleteCookie(cm.get(), "random.host", "E"));
  EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), url_google_));
}

TEST_F(CookieMonsterTest, SetCookieableSchemes) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  scoped_refptr<CookieMonster> cm_foo(new CookieMonster(NULL, NULL));

  // Only cm_foo should allow foo:// cookies.
  const char* const kSchemes[] = {"foo"};
  cm_foo->SetCookieableSchemes(kSchemes, 1);

  GURL foo_url("foo://host/path");
  GURL http_url("http://host/path");

  EXPECT_TRUE(SetCookie(cm.get(), http_url, "x=1"));
  EXPECT_FALSE(SetCookie(cm.get(), foo_url, "x=1"));
  EXPECT_TRUE(SetCookie(cm_foo.get(), foo_url, "x=1"));
  EXPECT_FALSE(SetCookie(cm_foo.get(), http_url, "x=1"));
}

TEST_F(CookieMonsterTest, GetAllCookiesForURL) {
  scoped_refptr<CookieMonster> cm(
      new CookieMonster(NULL, NULL, kLastAccessThresholdMilliseconds));

  // Create an httponly cookie.
  CookieOptions options;
  options.set_include_httponly();

  EXPECT_TRUE(
      SetCookieWithOptions(cm.get(), url_google_, "A=B; httponly", options));
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_,
                                   "C=D; domain=.google.izzle", options));
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_secure_,
                                   "E=F; domain=.google.izzle; secure",
                                   options));

  const Time last_access_date(GetFirstCookieAccessDate(cm.get()));

  base::PlatformThread::Sleep(
      base::TimeDelta::FromMilliseconds(kAccessDelayMs));

  // Check cookies for url.
  CookieList cookies = GetAllCookiesForURL(cm.get(), url_google_);
  CookieList::iterator it = cookies.begin();

  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_EQ("A", it->Name());

  ASSERT_TRUE(++it != cookies.end());
  EXPECT_EQ(".google.izzle", it->Domain());
  EXPECT_EQ("C", it->Name());

  ASSERT_TRUE(++it == cookies.end());

  // Check cookies for url excluding http-only cookies.
  cookies =
      GetAllCookiesForURLWithOptions(cm.get(), url_google_, CookieOptions());
  it = cookies.begin();

  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ(".google.izzle", it->Domain());
  EXPECT_EQ("C", it->Name());

  ASSERT_TRUE(++it == cookies.end());

  // Test secure cookies.
  cookies = GetAllCookiesForURL(cm.get(), url_google_secure_);
  it = cookies.begin();

  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_EQ("A", it->Name());

  ASSERT_TRUE(++it != cookies.end());
  EXPECT_EQ(".google.izzle", it->Domain());
  EXPECT_EQ("C", it->Name());

  ASSERT_TRUE(++it != cookies.end());
  EXPECT_EQ(".google.izzle", it->Domain());
  EXPECT_EQ("E", it->Name());

  ASSERT_TRUE(++it == cookies.end());

  // Reading after a short wait should not update the access date.
  EXPECT_TRUE(last_access_date == GetFirstCookieAccessDate(cm.get()));
}

TEST_F(CookieMonsterTest, GetAllCookiesForURLPathMatching) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  CookieOptions options;

  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_foo_, "A=B; path=/foo;",
                                   options));
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_bar_, "C=D; path=/bar;",
                                   options));
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "E=F;", options));

  CookieList cookies = GetAllCookiesForURL(cm.get(), url_google_foo_);
  CookieList::iterator it = cookies.begin();

  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("A", it->Name());
  EXPECT_EQ("/foo", it->Path());

  ASSERT_TRUE(++it != cookies.end());
  EXPECT_EQ("E", it->Name());
  EXPECT_EQ("/", it->Path());

  ASSERT_TRUE(++it == cookies.end());

  cookies = GetAllCookiesForURL(cm.get(), url_google_bar_);
  it = cookies.begin();

  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("C", it->Name());
  EXPECT_EQ("/bar", it->Path());

  ASSERT_TRUE(++it != cookies.end());
  EXPECT_EQ("E", it->Name());
  EXPECT_EQ("/", it->Path());

  ASSERT_TRUE(++it == cookies.end());
}

TEST_F(CookieMonsterTest, DeleteCookieByName) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));

  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=A1; path=/"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=A2; path=/foo"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=A3; path=/bar"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B1; path=/"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B2; path=/foo"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=B3; path=/bar"));

  DeleteCookie(cm.get(), GURL(std::string(kUrlGoogle) + "/foo/bar"), "A");

  CookieList cookies = GetAllCookies(cm.get());
  size_t expected_size = 4;
  EXPECT_EQ(expected_size, cookies.size());
  for (CookieList::iterator it = cookies.begin(); it != cookies.end(); ++it) {
    EXPECT_NE("A1", it->Value());
    EXPECT_NE("A2", it->Value());
  }
}

TEST_F(CookieMonsterTest, ImportCookiesFromCookieMonster) {
  scoped_refptr<CookieMonster> cm_1(new CookieMonster(NULL, NULL));
  CookieOptions options;

  EXPECT_TRUE(SetCookieWithOptions(cm_1.get(), url_google_foo_,
                                   "A1=B; path=/foo;", options));
  EXPECT_TRUE(SetCookieWithOptions(cm_1.get(), url_google_bar_,
                                   "A2=D; path=/bar;", options));
  EXPECT_TRUE(SetCookieWithOptions(cm_1.get(), url_google_, "A3=F;", options));

  CookieList cookies_1 = GetAllCookies(cm_1.get());
  scoped_refptr<CookieMonster> cm_2(new CookieMonster(NULL, NULL));
  ASSERT_TRUE(cm_2->ImportCookies(cookies_1));
  CookieList cookies_2 = GetAllCookies(cm_2.get());

  size_t expected_size = 3;
  EXPECT_EQ(expected_size, cookies_2.size());

  CookieList::iterator it = cookies_2.begin();

  ASSERT_TRUE(it != cookies_2.end());
  EXPECT_EQ("A1", it->Name());
  EXPECT_EQ("/foo", it->Path());

  ASSERT_TRUE(++it != cookies_2.end());
  EXPECT_EQ("A2", it->Name());
  EXPECT_EQ("/bar", it->Path());

  ASSERT_TRUE(++it != cookies_2.end());
  EXPECT_EQ("A3", it->Name());
  EXPECT_EQ("/", it->Path());
}

// Tests importing from a persistent cookie store that contains duplicate
// equivalent cookies. This situation should be handled by removing the
// duplicate cookie (both from the in-memory cache, and from the backing store).
//
// This is a regression test for: http://crbug.com/17855.
TEST_F(CookieMonsterTest, DontImportDuplicateCookies) {
  scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);

  // We will fill some initial cookies into the PersistentCookieStore,
  // to simulate a database with 4 duplicates.  Note that we need to
  // be careful not to have any duplicate creation times at all (as it's a
  // violation of a CookieMonster invariant) even if Time::Now() doesn't
  // move between calls.
  std::vector<CanonicalCookie*> initial_cookies;

  // Insert 4 cookies with name "X" on path "/", with varying creation
  // dates. We expect only the most recent one to be preserved following
  // the import.

  AddCookieToList("www.google.com",
                  "X=1; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                  Time::Now() + TimeDelta::FromDays(3), &initial_cookies);

  AddCookieToList("www.google.com",
                  "X=2; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                  Time::Now() + TimeDelta::FromDays(1), &initial_cookies);

  // ===> This one is the WINNER (biggest creation time).  <====
  AddCookieToList("www.google.com",
                  "X=3; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                  Time::Now() + TimeDelta::FromDays(4), &initial_cookies);

  AddCookieToList("www.google.com",
                  "X=4; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                  Time::Now(), &initial_cookies);

  // Insert 2 cookies with name "X" on path "/2", with varying creation
  // dates. We expect only the most recent one to be preserved the import.

  // ===> This one is the WINNER (biggest creation time).  <====
  AddCookieToList("www.google.com",
                  "X=a1; path=/2; expires=Mon, 18-Apr-22 22:50:14 GMT",
                  Time::Now() + TimeDelta::FromDays(9), &initial_cookies);

  AddCookieToList("www.google.com",
                  "X=a2; path=/2; expires=Mon, 18-Apr-22 22:50:14 GMT",
                  Time::Now() + TimeDelta::FromDays(2), &initial_cookies);

  // Insert 1 cookie with name "Y" on path "/".
  AddCookieToList("www.google.com",
                  "Y=a; path=/; expires=Mon, 18-Apr-22 22:50:14 GMT",
                  Time::Now() + TimeDelta::FromDays(10), &initial_cookies);

  // Inject our initial cookies into the mock PersistentCookieStore.
  store->SetLoadExpectation(true, initial_cookies);

  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));

  // Verify that duplicates were not imported for path "/".
  // (If this had failed, GetCookies() would have also returned X=1, X=2, X=4).
  EXPECT_EQ("X=3; Y=a", GetCookies(cm.get(), GURL("http://www.google.com/")));

  // Verify that same-named cookie on a different path ("/x2") didn't get
  // messed up.
  EXPECT_EQ("X=a1; X=3; Y=a",
            GetCookies(cm.get(), GURL("http://www.google.com/2/x")));

  // Verify that the PersistentCookieStore was told to kill its 4 duplicates.
  ASSERT_EQ(4u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[0].type);
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[2].type);
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
}

// Tests importing from a persistent cookie store that contains cookies
// with duplicate creation times.  This situation should be handled by
// dropping the cookies before insertion/visibility to user.
//
// This is a regression test for: http://crbug.com/43188.
TEST_F(CookieMonsterTest, DontImportDuplicateCreationTimes) {
  scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);

  Time now(Time::Now());
  Time earlier(now - TimeDelta::FromDays(1));

  // Insert 8 cookies, four with the current time as creation times, and
  // four with the earlier time as creation times.  We should only get
  // two cookies remaining, but which two (other than that there should
  // be one from each set) will be random.
  std::vector<CanonicalCookie*> initial_cookies;
  AddCookieToList("www.google.com", "X=1; path=/", now, &initial_cookies);
  AddCookieToList("www.google.com", "X=2; path=/", now, &initial_cookies);
  AddCookieToList("www.google.com", "X=3; path=/", now, &initial_cookies);
  AddCookieToList("www.google.com", "X=4; path=/", now, &initial_cookies);

  AddCookieToList("www.google.com", "Y=1; path=/", earlier, &initial_cookies);
  AddCookieToList("www.google.com", "Y=2; path=/", earlier, &initial_cookies);
  AddCookieToList("www.google.com", "Y=3; path=/", earlier, &initial_cookies);
  AddCookieToList("www.google.com", "Y=4; path=/", earlier, &initial_cookies);

  // Inject our initial cookies into the mock PersistentCookieStore.
  store->SetLoadExpectation(true, initial_cookies);

  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));

  CookieList list(GetAllCookies(cm.get()));
  EXPECT_EQ(2U, list.size());
  // Confirm that we have one of each.
  std::string name1(list[0].Name());
  std::string name2(list[1].Name());
  EXPECT_TRUE(name1 == "X" || name2 == "X");
  EXPECT_TRUE(name1 == "Y" || name2 == "Y");
  EXPECT_NE(name1, name2);
}

TEST_F(CookieMonsterTest, CookieMonsterDelegate) {
  scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
  scoped_refptr<MockCookieMonsterDelegate> delegate(
      new MockCookieMonsterDelegate);
  scoped_refptr<CookieMonster> cm(
      new CookieMonster(store.get(), delegate.get()));

  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "C=D"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "E=F"));
  EXPECT_EQ("A=B; C=D; E=F", GetCookies(cm.get(), url_google_));
  ASSERT_EQ(3u, delegate->changes().size());
  EXPECT_FALSE(delegate->changes()[0].second);
  EXPECT_EQ(url_google_.host(), delegate->changes()[0].first.Domain());
  EXPECT_EQ("A", delegate->changes()[0].first.Name());
  EXPECT_EQ("B", delegate->changes()[0].first.Value());
  EXPECT_EQ(url_google_.host(), delegate->changes()[1].first.Domain());
  EXPECT_FALSE(delegate->changes()[1].second);
  EXPECT_EQ("C", delegate->changes()[1].first.Name());
  EXPECT_EQ("D", delegate->changes()[1].first.Value());
  EXPECT_EQ(url_google_.host(), delegate->changes()[2].first.Domain());
  EXPECT_FALSE(delegate->changes()[2].second);
  EXPECT_EQ("E", delegate->changes()[2].first.Name());
  EXPECT_EQ("F", delegate->changes()[2].first.Value());
  delegate->reset();

  EXPECT_TRUE(FindAndDeleteCookie(cm.get(), url_google_.host(), "C"));
  EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), url_google_));
  ASSERT_EQ(1u, delegate->changes().size());
  EXPECT_EQ(url_google_.host(), delegate->changes()[0].first.Domain());
  EXPECT_TRUE(delegate->changes()[0].second);
  EXPECT_EQ("C", delegate->changes()[0].first.Name());
  EXPECT_EQ("D", delegate->changes()[0].first.Value());
  delegate->reset();

  EXPECT_FALSE(FindAndDeleteCookie(cm.get(), "random.host", "E"));
  EXPECT_EQ("A=B; E=F", GetCookies(cm.get(), url_google_));
  EXPECT_EQ(0u, delegate->changes().size());

  // Insert a cookie "a" for path "/path1"
  EXPECT_TRUE(SetCookie(cm.get(), url_google_,
                        "a=val1; path=/path1; "
                        "expires=Mon, 18-Apr-22 22:50:13 GMT"));
  ASSERT_EQ(1u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
  ASSERT_EQ(1u, delegate->changes().size());
  EXPECT_FALSE(delegate->changes()[0].second);
  EXPECT_EQ(url_google_.host(), delegate->changes()[0].first.Domain());
  EXPECT_EQ("a", delegate->changes()[0].first.Name());
  EXPECT_EQ("val1", delegate->changes()[0].first.Value());
  delegate->reset();

  // Insert a cookie "a" for path "/path1", that is httponly. This should
  // overwrite the non-http-only version.
  CookieOptions allow_httponly;
  allow_httponly.set_include_httponly();
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_,
                                   "a=val2; path=/path1; httponly; "
                                   "expires=Mon, 18-Apr-22 22:50:14 GMT",
                                   allow_httponly));
  ASSERT_EQ(3u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
  EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
  ASSERT_EQ(2u, delegate->changes().size());
  EXPECT_EQ(url_google_.host(), delegate->changes()[0].first.Domain());
  EXPECT_TRUE(delegate->changes()[0].second);
  EXPECT_EQ("a", delegate->changes()[0].first.Name());
  EXPECT_EQ("val1", delegate->changes()[0].first.Value());
  EXPECT_EQ(url_google_.host(), delegate->changes()[1].first.Domain());
  EXPECT_FALSE(delegate->changes()[1].second);
  EXPECT_EQ("a", delegate->changes()[1].first.Name());
  EXPECT_EQ("val2", delegate->changes()[1].first.Value());
  delegate->reset();
}

TEST_F(CookieMonsterTest, SetCookieWithDetails) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));

  EXPECT_TRUE(SetCookieWithDetails(cm.get(), url_google_foo_, "A", "B",
                                   std::string(), "/foo", base::Time(), false,
                                   false, false, COOKIE_PRIORITY_DEFAULT));
  EXPECT_TRUE(SetCookieWithDetails(cm.get(), url_google_bar_, "C", "D",
                                   "google.izzle", "/bar", base::Time(), false,
                                   true, false, COOKIE_PRIORITY_DEFAULT));
  EXPECT_TRUE(SetCookieWithDetails(
      cm.get(), url_google_, "E", "F", std::string(), std::string(),
      base::Time(), true, false, false, COOKIE_PRIORITY_DEFAULT));

  // Test that malformed attributes fail to set the cookie.
  EXPECT_FALSE(SetCookieWithDetails(cm.get(), url_google_foo_, " A", "B",
                                    std::string(), "/foo", base::Time(), false,
                                    false, false, COOKIE_PRIORITY_DEFAULT));
  EXPECT_FALSE(SetCookieWithDetails(cm.get(), url_google_foo_, "A;", "B",
                                    std::string(), "/foo", base::Time(), false,
                                    false, false, COOKIE_PRIORITY_DEFAULT));
  EXPECT_FALSE(SetCookieWithDetails(cm.get(), url_google_foo_, "A=", "B",
                                    std::string(), "/foo", base::Time(), false,
                                    false, false, COOKIE_PRIORITY_DEFAULT));
  EXPECT_FALSE(SetCookieWithDetails(
      cm.get(), url_google_foo_, "A", "B", "google.ozzzzzzle", "foo",
      base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT));
  EXPECT_FALSE(SetCookieWithDetails(cm.get(), url_google_foo_, "A=", "B",
                                    std::string(), "foo", base::Time(), false,
                                    false, false, COOKIE_PRIORITY_DEFAULT));

  CookieList cookies = GetAllCookiesForURL(cm.get(), url_google_foo_);
  CookieList::iterator it = cookies.begin();

  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("A", it->Name());
  EXPECT_EQ("B", it->Value());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_EQ("/foo", it->Path());
  EXPECT_FALSE(it->IsPersistent());
  EXPECT_FALSE(it->IsSecure());
  EXPECT_FALSE(it->IsHttpOnly());

  ASSERT_TRUE(++it == cookies.end());

  cookies = GetAllCookiesForURL(cm.get(), url_google_bar_);
  it = cookies.begin();

  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("C", it->Name());
  EXPECT_EQ("D", it->Value());
  EXPECT_EQ(".google.izzle", it->Domain());
  EXPECT_EQ("/bar", it->Path());
  EXPECT_FALSE(it->IsSecure());
  EXPECT_TRUE(it->IsHttpOnly());

  ASSERT_TRUE(++it == cookies.end());

  cookies = GetAllCookiesForURL(cm.get(), url_google_secure_);
  it = cookies.begin();

  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("E", it->Name());
  EXPECT_EQ("F", it->Value());
  EXPECT_EQ("/", it->Path());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_TRUE(it->IsSecure());
  EXPECT_FALSE(it->IsHttpOnly());

  ASSERT_TRUE(++it == cookies.end());
}

TEST_F(CookieMonsterTest, DeleteAllForHost) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));

  // Test probes:
  //    * Non-secure URL, mid-level (http://w.c.b.a)
  //    * Secure URL, mid-level (https://w.c.b.a)
  //    * URL with path, mid-level (https:/w.c.b.a/dir1/xx)
  // All three tests should nuke only the midlevel host cookie,
  // the http_only cookie, the host secure cookie, and the two host
  // path cookies.  http_only, secure, and paths are ignored by
  // this call, and domain cookies arent touched.
  PopulateCmForDeleteAllForHost(cm);
  EXPECT_EQ("dom_1=X; dom_2=X; dom_3=X; host_3=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus3)));
  EXPECT_EQ("dom_1=X; dom_2=X; host_2=X; sec_dom=X; sec_host=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure)));
  EXPECT_EQ("dom_1=X; host_1=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus1)));
  EXPECT_EQ(
      "dom_path_2=X; host_path_2=X; dom_path_1=X; host_path_1=X; "
      "dom_1=X; dom_2=X; host_2=X; sec_dom=X; sec_host=X",
      GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure +
                                std::string("/dir1/dir2/xxx"))));

  EXPECT_EQ(6, DeleteAllForHost(cm.get(), GURL(kTopLevelDomainPlus2)));
  EXPECT_EQ(8U, GetAllCookies(cm.get()).size());

  EXPECT_EQ("dom_1=X; dom_2=X; dom_3=X; host_3=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus3)));
  EXPECT_EQ("dom_1=X; dom_2=X; sec_dom=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure)));
  EXPECT_EQ("dom_1=X; host_1=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus1)));
  EXPECT_EQ("dom_path_2=X; dom_path_1=X; dom_1=X; dom_2=X; sec_dom=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure +
                                      std::string("/dir1/dir2/xxx"))));

  PopulateCmForDeleteAllForHost(cm);
  EXPECT_EQ(6, DeleteAllForHost(cm.get(), GURL(kTopLevelDomainPlus2Secure)));
  EXPECT_EQ(8U, GetAllCookies(cm.get()).size());

  EXPECT_EQ("dom_1=X; dom_2=X; dom_3=X; host_3=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus3)));
  EXPECT_EQ("dom_1=X; dom_2=X; sec_dom=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure)));
  EXPECT_EQ("dom_1=X; host_1=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus1)));
  EXPECT_EQ("dom_path_2=X; dom_path_1=X; dom_1=X; dom_2=X; sec_dom=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure +
                                      std::string("/dir1/dir2/xxx"))));

  PopulateCmForDeleteAllForHost(cm);
  EXPECT_EQ(6, DeleteAllForHost(cm.get(), GURL(kTopLevelDomainPlus2Secure +
                                               std::string("/dir1/xxx"))));
  EXPECT_EQ(8U, GetAllCookies(cm.get()).size());

  EXPECT_EQ("dom_1=X; dom_2=X; dom_3=X; host_3=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus3)));
  EXPECT_EQ("dom_1=X; dom_2=X; sec_dom=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure)));
  EXPECT_EQ("dom_1=X; host_1=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus1)));
  EXPECT_EQ("dom_path_2=X; dom_path_1=X; dom_1=X; dom_2=X; sec_dom=X",
            GetCookies(cm.get(), GURL(kTopLevelDomainPlus2Secure +
                                      std::string("/dir1/dir2/xxx"))));
}

TEST_F(CookieMonsterTest, UniqueCreationTime) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  CookieOptions options;

  // Add in three cookies through every public interface to the
  // CookieMonster and confirm that none of them have duplicate
  // creation times.

  // SetCookieWithCreationTime and SetCookieWithCreationTimeAndOptions
  // are not included as they aren't going to be public for very much
  // longer.

  // SetCookie, SetCookieWithOptions, SetCookieWithDetails

  SetCookie(cm.get(), url_google_, "SetCookie1=A");
  SetCookie(cm.get(), url_google_, "SetCookie2=A");
  SetCookie(cm.get(), url_google_, "SetCookie3=A");

  SetCookieWithOptions(cm.get(), url_google_, "setCookieWithOptions1=A",
                       options);
  SetCookieWithOptions(cm.get(), url_google_, "setCookieWithOptions2=A",
                       options);
  SetCookieWithOptions(cm.get(), url_google_, "setCookieWithOptions3=A",
                       options);

  SetCookieWithDetails(cm.get(), url_google_, "setCookieWithDetails1", "A",
                       ".google.com", "/", Time(), false, false, false,
                       COOKIE_PRIORITY_DEFAULT);
  SetCookieWithDetails(cm.get(), url_google_, "setCookieWithDetails2", "A",
                       ".google.com", "/", Time(), false, false, false,
                       COOKIE_PRIORITY_DEFAULT);
  SetCookieWithDetails(cm.get(), url_google_, "setCookieWithDetails3", "A",
                       ".google.com", "/", Time(), false, false, false,
                       COOKIE_PRIORITY_DEFAULT);

  // Now we check
  CookieList cookie_list(GetAllCookies(cm.get()));
  typedef std::map<int64, CanonicalCookie> TimeCookieMap;
  TimeCookieMap check_map;
  for (CookieList::const_iterator it = cookie_list.begin();
       it != cookie_list.end(); it++) {
    const int64 creation_date = it->CreationDate().ToInternalValue();
    TimeCookieMap::const_iterator existing_cookie_it(
        check_map.find(creation_date));
    EXPECT_TRUE(existing_cookie_it == check_map.end())
        << "Cookie " << it->Name() << " has same creation date ("
        << it->CreationDate().ToInternalValue()
        << ") as previously entered cookie "
        << existing_cookie_it->second.Name();

    if (existing_cookie_it == check_map.end()) {
      check_map.insert(
          TimeCookieMap::value_type(it->CreationDate().ToInternalValue(), *it));
    }
  }
}

// Mainly a test of GetEffectiveDomain, or more specifically, of the
// expected behavior of GetEffectiveDomain within the CookieMonster.
TEST_F(CookieMonsterTest, GetKey) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));

  // This test is really only interesting if GetKey() actually does something.
  EXPECT_EQ("google.com", cm->GetKey("www.google.com"));
  EXPECT_EQ("google.izzie", cm->GetKey("www.google.izzie"));
  EXPECT_EQ("google.izzie", cm->GetKey(".google.izzie"));
  EXPECT_EQ("bbc.co.uk", cm->GetKey("bbc.co.uk"));
  EXPECT_EQ("bbc.co.uk", cm->GetKey("a.b.c.d.bbc.co.uk"));
  EXPECT_EQ("apple.com", cm->GetKey("a.b.c.d.apple.com"));
  EXPECT_EQ("apple.izzie", cm->GetKey("a.b.c.d.apple.izzie"));

  // Cases where the effective domain is null, so we use the host
  // as the key.
  EXPECT_EQ("co.uk", cm->GetKey("co.uk"));
  const std::string extension_name("iehocdgbbocmkdidlbnnfbmbinnahbae");
  EXPECT_EQ(extension_name, cm->GetKey(extension_name));
  EXPECT_EQ("com", cm->GetKey("com"));
  EXPECT_EQ("hostalias", cm->GetKey("hostalias"));
  EXPECT_EQ("localhost", cm->GetKey("localhost"));
}

// Test that cookies transfer from/to the backing store correctly.
TEST_F(CookieMonsterTest, BackingStoreCommunication) {
  // Store details for cookies transforming through the backing store interface.

  base::Time current(base::Time::Now());
  scoped_refptr<MockSimplePersistentCookieStore> store(
      new MockSimplePersistentCookieStore);
  base::Time new_access_time;
  base::Time expires(base::Time::Now() + base::TimeDelta::FromSeconds(100));

  const CookiesInputInfo input_info[] = {
      {GURL("http://a.b.google.com"),
       "a",
       "1",
       "",
       "/path/to/cookie",
       expires,
       false,
       false,
       false,
       COOKIE_PRIORITY_DEFAULT},
      {GURL("https://www.google.com"),
       "b",
       "2",
       ".google.com",
       "/path/from/cookie",
       expires + TimeDelta::FromSeconds(10),
       true,
       true,
       false,
       COOKIE_PRIORITY_DEFAULT},
      {GURL("https://google.com"),
       "c",
       "3",
       "",
       "/another/path/to/cookie",
       base::Time::Now() + base::TimeDelta::FromSeconds(100),
       true,
       false,
       true,
       COOKIE_PRIORITY_DEFAULT}};
  const int INPUT_DELETE = 1;

  // Create new cookies and flush them to the store.
  {
    scoped_refptr<CookieMonster> cmout(new CookieMonster(store.get(), NULL));
    for (const CookiesInputInfo* p = input_info;
         p < &input_info[arraysize(input_info)]; p++) {
      EXPECT_TRUE(SetCookieWithDetails(cmout.get(), p->url, p->name, p->value,
                                       p->domain, p->path, p->expiration_time,
                                       p->secure, p->http_only,
                                       p->first_party_only, p->priority));
    }
    GURL del_url(input_info[INPUT_DELETE]
                     .url.Resolve(input_info[INPUT_DELETE].path)
                     .spec());
    DeleteCookie(cmout.get(), del_url, input_info[INPUT_DELETE].name);
  }

  // Create a new cookie monster and make sure that everything is correct
  {
    scoped_refptr<CookieMonster> cmin(new CookieMonster(store.get(), NULL));
    CookieList cookies(GetAllCookies(cmin.get()));
    ASSERT_EQ(2u, cookies.size());
    // Ordering is path length, then creation time.  So second cookie
    // will come first, and we need to swap them.
    std::swap(cookies[0], cookies[1]);
    for (int output_index = 0; output_index < 2; output_index++) {
      int input_index = output_index * 2;
      const CookiesInputInfo* input = &input_info[input_index];
      const CanonicalCookie* output = &cookies[output_index];

      EXPECT_EQ(input->name, output->Name());
      EXPECT_EQ(input->value, output->Value());
      EXPECT_EQ(input->url.host(), output->Domain());
      EXPECT_EQ(input->path, output->Path());
      EXPECT_LE(current.ToInternalValue(),
                output->CreationDate().ToInternalValue());
      EXPECT_EQ(input->secure, output->IsSecure());
      EXPECT_EQ(input->http_only, output->IsHttpOnly());
      EXPECT_EQ(input->first_party_only, output->IsFirstPartyOnly());
      EXPECT_TRUE(output->IsPersistent());
      EXPECT_EQ(input->expiration_time.ToInternalValue(),
                output->ExpiryDate().ToInternalValue());
    }
  }
}

TEST_F(CookieMonsterTest, CookieListOrdering) {
  // Put a random set of cookies into a monster and make sure
  // they're returned in the right order.
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  EXPECT_TRUE(
      SetCookie(cm.get(), GURL("http://d.c.b.a.google.com/aa/x.html"), "c=1"));
  EXPECT_TRUE(SetCookie(cm.get(), GURL("http://b.a.google.com/aa/bb/cc/x.html"),
                        "d=1; domain=b.a.google.com"));
  EXPECT_TRUE(SetCookie(cm.get(), GURL("http://b.a.google.com/aa/bb/cc/x.html"),
                        "a=4; domain=b.a.google.com"));
  EXPECT_TRUE(SetCookie(cm.get(),
                        GURL("http://c.b.a.google.com/aa/bb/cc/x.html"),
                        "e=1; domain=c.b.a.google.com"));
  EXPECT_TRUE(SetCookie(cm.get(),
                        GURL("http://d.c.b.a.google.com/aa/bb/x.html"), "b=1"));
  EXPECT_TRUE(SetCookie(cm.get(), GURL("http://news.bbc.co.uk/midpath/x.html"),
                        "g=10"));
  {
    unsigned int i = 0;
    CookieList cookies(GetAllCookiesForURL(
        cm.get(), GURL("http://d.c.b.a.google.com/aa/bb/cc/dd")));
    ASSERT_EQ(5u, cookies.size());
    EXPECT_EQ("d", cookies[i++].Name());
    EXPECT_EQ("a", cookies[i++].Name());
    EXPECT_EQ("e", cookies[i++].Name());
    EXPECT_EQ("b", cookies[i++].Name());
    EXPECT_EQ("c", cookies[i++].Name());
  }

  {
    unsigned int i = 0;
    CookieList cookies(GetAllCookies(cm.get()));
    ASSERT_EQ(6u, cookies.size());
    EXPECT_EQ("d", cookies[i++].Name());
    EXPECT_EQ("a", cookies[i++].Name());
    EXPECT_EQ("e", cookies[i++].Name());
    EXPECT_EQ("g", cookies[i++].Name());
    EXPECT_EQ("b", cookies[i++].Name());
    EXPECT_EQ("c", cookies[i++].Name());
  }
}

// This test and CookieMonstertest.TestGCTimes (in cookie_monster_perftest.cc)
// are somewhat complementary twins.  This test is probing for whether
// garbage collection always happens when it should (i.e. that we actually
// get rid of cookies when we should).  The perftest is probing for
// whether garbage collection happens when it shouldn't.  See comments
// before that test for more details.

// Disabled on Windows, see crbug.com/126095
#if defined(OS_WIN)
#define MAYBE_GarbageCollectionTriggers DISABLED_GarbageCollectionTriggers
#else
#define MAYBE_GarbageCollectionTriggers GarbageCollectionTriggers
#endif

TEST_F(CookieMonsterTest, MAYBE_GarbageCollectionTriggers) {
  // First we check to make sure that a whole lot of recent cookies
  // doesn't get rid of anything after garbage collection is checked for.
  {
    scoped_refptr<CookieMonster> cm(
        CreateMonsterForGC(CookieMonster::kMaxCookies * 2));
    EXPECT_EQ(CookieMonster::kMaxCookies * 2, GetAllCookies(cm.get()).size());
    SetCookie(cm.get(), GURL("http://newdomain.com"), "b=2");
    EXPECT_EQ(CookieMonster::kMaxCookies * 2 + 1,
              GetAllCookies(cm.get()).size());
  }

  // Now we explore a series of relationships between cookie last access
  // time and size of store to make sure we only get rid of cookies when
  // we really should.
  const struct TestCase {
    size_t num_cookies;
    size_t num_old_cookies;
    size_t expected_initial_cookies;
    // Indexed by ExpiryAndKeyScheme
    size_t expected_cookies_after_set;
  } test_cases[] = {
      {// A whole lot of recent cookies; gc shouldn't happen.
       CookieMonster::kMaxCookies * 2,
       0,
       CookieMonster::kMaxCookies * 2,
       CookieMonster::kMaxCookies * 2 + 1},
      {// Some old cookies, but still overflowing max.
       CookieMonster::kMaxCookies * 2,
       CookieMonster::kMaxCookies / 2,
       CookieMonster::kMaxCookies * 2,
       CookieMonster::kMaxCookies * 2 - CookieMonster::kMaxCookies / 2 + 1},
      {// Old cookies enough to bring us right down to our purge line.
       CookieMonster::kMaxCookies * 2,
       CookieMonster::kMaxCookies + CookieMonster::kPurgeCookies + 1,
       CookieMonster::kMaxCookies * 2,
       CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies},
      {// Old cookies enough to bring below our purge line (which we
       // shouldn't do).
       CookieMonster::kMaxCookies * 2,
       CookieMonster::kMaxCookies * 3 / 2,
       CookieMonster::kMaxCookies * 2,
       CookieMonster::kMaxCookies - CookieMonster::kPurgeCookies}};

  for (int ci = 0; ci < static_cast<int>(arraysize(test_cases)); ++ci) {
    const TestCase* test_case = &test_cases[ci];
    scoped_refptr<CookieMonster> cm(CreateMonsterFromStoreForGC(
        test_case->num_cookies, test_case->num_old_cookies,
        CookieMonster::kSafeFromGlobalPurgeDays * 2));
    EXPECT_EQ(test_case->expected_initial_cookies,
              GetAllCookies(cm.get()).size())
        << "For test case " << ci;
    // Will trigger GC
    SetCookie(cm.get(), GURL("http://newdomain.com"), "b=2");
    EXPECT_EQ(test_case->expected_cookies_after_set,
              GetAllCookies(cm.get()).size())
        << "For test case " << ci;
  }
}

// This test checks that keep expired cookies flag is working.
TEST_F(CookieMonsterTest, KeepExpiredCookies) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  cm->SetKeepExpiredCookies();
  CookieOptions options;

  // Set a persistent cookie.
  ASSERT_TRUE(SetCookieWithOptions(
      cm.get(), url_google_,
      std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT",
      options));

  // Get the canonical cookie.
  CookieList cookie_list = GetAllCookies(cm.get());
  ASSERT_EQ(1U, cookie_list.size());

  // Use a past expiry date to delete the cookie.
  ASSERT_TRUE(SetCookieWithOptions(
      cm.get(), url_google_,
      std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-1977 22:50:13 GMT",
      options));

  // Check that the cookie with the past expiry date is still there.
  // GetAllCookies() also triggers garbage collection.
  cookie_list = GetAllCookies(cm.get());
  ASSERT_EQ(1U, cookie_list.size());
  ASSERT_TRUE(cookie_list[0].IsExpired(Time::Now()));
}

namespace {

// Mock PersistentCookieStore that keeps track of the number of Flush() calls.
class FlushablePersistentStore : public CookieMonster::PersistentCookieStore {
 public:
  FlushablePersistentStore() : flush_count_(0) {}

  void Load(const LoadedCallback& loaded_callback) override {
    std::vector<CanonicalCookie*> out_cookies;
    base::MessageLoop::current()->PostTask(
        FROM_HERE,
        base::Bind(&LoadedCallbackTask::Run,
                   new LoadedCallbackTask(loaded_callback, out_cookies)));
  }

  void LoadCookiesForKey(const std::string& key,
                         const LoadedCallback& loaded_callback) override {
    Load(loaded_callback);
  }

  void AddCookie(const CanonicalCookie&) override {}
  void UpdateCookieAccessTime(const CanonicalCookie&) override {}
  void DeleteCookie(const CanonicalCookie&) override {}
  void SetForceKeepSessionState() override {}

  void Flush(const base::Closure& callback) override {
    ++flush_count_;
    if (!callback.is_null())
      callback.Run();
  }

  int flush_count() { return flush_count_; }

 private:
  ~FlushablePersistentStore() override {}

  volatile int flush_count_;
};

// Counts the number of times Callback() has been run.
class CallbackCounter : public base::RefCountedThreadSafe<CallbackCounter> {
 public:
  CallbackCounter() : callback_count_(0) {}

  void Callback() { ++callback_count_; }

  int callback_count() { return callback_count_; }

 private:
  friend class base::RefCountedThreadSafe<CallbackCounter>;
  ~CallbackCounter() {}

  volatile int callback_count_;
};

}  // namespace

// Test that FlushStore() is forwarded to the store and callbacks are posted.
TEST_F(CookieMonsterTest, FlushStore) {
  scoped_refptr<CallbackCounter> counter(new CallbackCounter());
  scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));

  ASSERT_EQ(0, store->flush_count());
  ASSERT_EQ(0, counter->callback_count());

  // Before initialization, FlushStore() should just run the callback.
  cm->FlushStore(base::Bind(&CallbackCounter::Callback, counter.get()));
  base::MessageLoop::current()->RunUntilIdle();

  ASSERT_EQ(0, store->flush_count());
  ASSERT_EQ(1, counter->callback_count());

  // NULL callback is safe.
  cm->FlushStore(base::Closure());
  base::MessageLoop::current()->RunUntilIdle();

  ASSERT_EQ(0, store->flush_count());
  ASSERT_EQ(1, counter->callback_count());

  // After initialization, FlushStore() should delegate to the store.
  GetAllCookies(cm.get());  // Force init.
  cm->FlushStore(base::Bind(&CallbackCounter::Callback, counter.get()));
  base::MessageLoop::current()->RunUntilIdle();

  ASSERT_EQ(1, store->flush_count());
  ASSERT_EQ(2, counter->callback_count());

  // NULL callback is still safe.
  cm->FlushStore(base::Closure());
  base::MessageLoop::current()->RunUntilIdle();

  ASSERT_EQ(2, store->flush_count());
  ASSERT_EQ(2, counter->callback_count());

  // If there's no backing store, FlushStore() is always a safe no-op.
  cm = new CookieMonster(NULL, NULL);
  GetAllCookies(cm.get());  // Force init.
  cm->FlushStore(base::Closure());
  base::MessageLoop::current()->RunUntilIdle();

  ASSERT_EQ(2, counter->callback_count());

  cm->FlushStore(base::Bind(&CallbackCounter::Callback, counter.get()));
  base::MessageLoop::current()->RunUntilIdle();

  ASSERT_EQ(3, counter->callback_count());
}

TEST_F(CookieMonsterTest, SetAllCookies) {
  scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
  cm->SetPersistSessionCookies(true);

  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "U=V; path=/"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "W=X; path=/foo"));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "Y=Z; path=/"));

  CookieList list;
  list.push_back(CanonicalCookie(url_google_, "A", "B", url_google_.host(), "/",
                                 base::Time::Now(), base::Time(), base::Time(),
                                 false, false, false, COOKIE_PRIORITY_DEFAULT));
  list.push_back(CanonicalCookie(url_google_, "W", "X", url_google_.host(),
                                 "/bar", base::Time::Now(), base::Time(),
                                 base::Time(), false, false, false,
                                 COOKIE_PRIORITY_DEFAULT));
  list.push_back(CanonicalCookie(url_google_, "Y", "Z", url_google_.host(), "/",
                                 base::Time::Now(), base::Time(), base::Time(),
                                 false, false, false, COOKIE_PRIORITY_DEFAULT));

  // SetAllCookies must not flush.
  ASSERT_EQ(0, store->flush_count());
  EXPECT_TRUE(SetAllCookies(cm.get(), list));
  EXPECT_EQ(0, store->flush_count());

  CookieList cookies = GetAllCookies(cm.get());
  size_t expected_size = 3;  // "A", "W" and "Y". "U" is gone.
  EXPECT_EQ(expected_size, cookies.size());
  CookieList::iterator it = cookies.begin();

  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("W", it->Name());
  EXPECT_EQ("X", it->Value());
  EXPECT_EQ("/bar", it->Path());  // The path has been updated.

  ASSERT_TRUE(++it != cookies.end());
  EXPECT_EQ("A", it->Name());
  EXPECT_EQ("B", it->Value());

  ASSERT_TRUE(++it != cookies.end());
  EXPECT_EQ("Y", it->Name());
  EXPECT_EQ("Z", it->Value());
}

TEST_F(CookieMonsterTest, ComputeCookieDiff) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));

  base::Time now = base::Time::Now();
  base::Time creation_time = now - base::TimeDelta::FromSeconds(1);

  CanonicalCookie cookie1(url_google_, "A", "B", url_google_.host(), "/",
                          creation_time, base::Time(), base::Time(), false,
                          false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie2(url_google_, "C", "D", url_google_.host(), "/",
                          creation_time, base::Time(), base::Time(), false,
                          false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie3(url_google_, "E", "F", url_google_.host(), "/",
                          creation_time, base::Time(), base::Time(), false,
                          false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie4(url_google_, "G", "H", url_google_.host(), "/",
                          creation_time, base::Time(), base::Time(), false,
                          false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie4_with_new_value(
      url_google_, "G", "iamnew", url_google_.host(), "/", creation_time,
      base::Time(), base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie5(url_google_, "I", "J", url_google_.host(), "/",
                          creation_time, base::Time(), base::Time(), false,
                          false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie5_with_new_creation_time(
      url_google_, "I", "J", url_google_.host(), "/", now, base::Time(),
      base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie6(url_google_, "K", "L", url_google_.host(), "/foo",
                          creation_time, base::Time(), base::Time(), false,
                          false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie6_with_new_path(
      url_google_, "K", "L", url_google_.host(), "/bar", creation_time,
      base::Time(), base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie7(url_google_, "M", "N", url_google_.host(), "/foo",
                          creation_time, base::Time(), base::Time(), false,
                          false, false, COOKIE_PRIORITY_DEFAULT);
  CanonicalCookie cookie7_with_new_path(
      url_google_, "M", "N", url_google_.host(), "/bar", creation_time,
      base::Time(), base::Time(), false, false, false, COOKIE_PRIORITY_DEFAULT);

  CookieList old_cookies;
  old_cookies.push_back(cookie1);
  old_cookies.push_back(cookie2);
  old_cookies.push_back(cookie4);
  old_cookies.push_back(cookie5);
  old_cookies.push_back(cookie6);
  old_cookies.push_back(cookie7);

  CookieList new_cookies;
  new_cookies.push_back(cookie1);
  new_cookies.push_back(cookie3);
  new_cookies.push_back(cookie4_with_new_value);
  new_cookies.push_back(cookie5_with_new_creation_time);
  new_cookies.push_back(cookie6_with_new_path);
  new_cookies.push_back(cookie7);
  new_cookies.push_back(cookie7_with_new_path);

  CookieList cookies_to_add;
  CookieList cookies_to_delete;

  cm->ComputeCookieDiff(&old_cookies, &new_cookies, &cookies_to_add,
                        &cookies_to_delete);

  // |cookie1| has not changed.
  EXPECT_FALSE(IsCookieInList(cookie1, cookies_to_add));
  EXPECT_FALSE(IsCookieInList(cookie1, cookies_to_delete));

  // |cookie2| has been deleted.
  EXPECT_FALSE(IsCookieInList(cookie2, cookies_to_add));
  EXPECT_TRUE(IsCookieInList(cookie2, cookies_to_delete));

  // |cookie3| has been added.
  EXPECT_TRUE(IsCookieInList(cookie3, cookies_to_add));
  EXPECT_FALSE(IsCookieInList(cookie3, cookies_to_delete));

  // |cookie4| has a new value: new cookie overrides the old one (which does not
  // need to be explicitly removed).
  EXPECT_FALSE(IsCookieInList(cookie4, cookies_to_add));
  EXPECT_FALSE(IsCookieInList(cookie4, cookies_to_delete));
  EXPECT_TRUE(IsCookieInList(cookie4_with_new_value, cookies_to_add));
  EXPECT_FALSE(IsCookieInList(cookie4_with_new_value, cookies_to_delete));

  // |cookie5| has a new creation time: new cookie overrides the old one (which
  // does not need to be explicitly removed).
  EXPECT_FALSE(IsCookieInList(cookie5, cookies_to_add));
  EXPECT_FALSE(IsCookieInList(cookie5, cookies_to_delete));
  EXPECT_TRUE(IsCookieInList(cookie5_with_new_creation_time, cookies_to_add));
  EXPECT_FALSE(
      IsCookieInList(cookie5_with_new_creation_time, cookies_to_delete));

  // |cookie6| has a new path: the new cookie does not overrides the old one,
  // which needs to be explicitly removed.
  EXPECT_FALSE(IsCookieInList(cookie6, cookies_to_add));
  EXPECT_TRUE(IsCookieInList(cookie6, cookies_to_delete));
  EXPECT_TRUE(IsCookieInList(cookie6_with_new_path, cookies_to_add));
  EXPECT_FALSE(IsCookieInList(cookie6_with_new_path, cookies_to_delete));

  // |cookie7| is kept and |cookie7_with_new_path| is added as a new cookie.
  EXPECT_FALSE(IsCookieInList(cookie7, cookies_to_add));
  EXPECT_FALSE(IsCookieInList(cookie7, cookies_to_delete));
  EXPECT_TRUE(IsCookieInList(cookie7_with_new_path, cookies_to_add));
  EXPECT_FALSE(IsCookieInList(cookie7_with_new_path, cookies_to_delete));
}

// Check that DeleteAll does flush (as a sanity check that flush_count()
// works).
TEST_F(CookieMonsterTest, DeleteAll) {
  scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
  cm->SetPersistSessionCookies(true);

  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "X=Y; path=/"));

  ASSERT_EQ(0, store->flush_count());
  EXPECT_EQ(1, DeleteAll(cm.get()));
  EXPECT_EQ(1, store->flush_count());
}

TEST_F(CookieMonsterTest, HistogramCheck) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  // Should match call in InitializeHistograms, but doesn't really matter
  // since the histogram should have been initialized by the CM construction
  // above.
  base::HistogramBase* expired_histogram = base::Histogram::FactoryGet(
      "Cookie.ExpirationDurationMinutes", 1, 10 * 365 * 24 * 60, 50,
      base::Histogram::kUmaTargetedHistogramFlag);

  scoped_ptr<base::HistogramSamples> samples1(
      expired_histogram->SnapshotSamples());
  ASSERT_TRUE(SetCookieWithDetails(
      cm.get(), GURL("http://fake.a.url"), "a", "b", "a.url", "/",
      base::Time::Now() + base::TimeDelta::FromMinutes(59), false, false, false,
      COOKIE_PRIORITY_DEFAULT));

  scoped_ptr<base::HistogramSamples> samples2(
      expired_histogram->SnapshotSamples());
  EXPECT_EQ(samples1->TotalCount() + 1, samples2->TotalCount());

  // kValidCookieLine creates a session cookie.
  ASSERT_TRUE(SetCookie(cm.get(), url_google_, kValidCookieLine));

  scoped_ptr<base::HistogramSamples> samples3(
      expired_histogram->SnapshotSamples());
  EXPECT_EQ(samples2->TotalCount(), samples3->TotalCount());
}

namespace {

class MultiThreadedCookieMonsterTest : public CookieMonsterTest {
 public:
  MultiThreadedCookieMonsterTest() : other_thread_("CMTthread") {}

  // Helper methods for calling the asynchronous CookieMonster methods
  // from a different thread.

  void GetAllCookiesTask(CookieMonster* cm, GetCookieListCallback* callback) {
    cm->GetAllCookiesAsync(
        base::Bind(&GetCookieListCallback::Run, base::Unretained(callback)));
  }

  void GetAllCookiesForURLTask(CookieMonster* cm,
                               const GURL& url,
                               GetCookieListCallback* callback) {
    cm->GetAllCookiesForURLAsync(url, base::Bind(&GetCookieListCallback::Run,
                                                 base::Unretained(callback)));
  }

  void GetAllCookiesForURLWithOptionsTask(CookieMonster* cm,
                                          const GURL& url,
                                          const CookieOptions& options,
                                          GetCookieListCallback* callback) {
    cm->GetAllCookiesForURLWithOptionsAsync(
        url, options,
        base::Bind(&GetCookieListCallback::Run, base::Unretained(callback)));
  }

  void SetCookieWithDetailsTask(CookieMonster* cm,
                                const GURL& url,
                                ResultSavingCookieCallback<bool>* callback) {
    // Define the parameters here instead of in the calling fucntion.
    // The maximum number of parameters for Bind function is 6.
    std::string name = "A";
    std::string value = "B";
    std::string domain = std::string();
    std::string path = "/foo";
    base::Time expiration_time = base::Time();
    bool secure = false;
    bool http_only = false;
    bool first_party_only = false;
    CookiePriority priority = COOKIE_PRIORITY_DEFAULT;
    cm->SetCookieWithDetailsAsync(
        url, name, value, domain, path, expiration_time, secure, http_only,
        first_party_only, priority,
        base::Bind(&ResultSavingCookieCallback<bool>::Run,
                   base::Unretained(callback)));
  }

  void DeleteAllCreatedBetweenTask(CookieMonster* cm,
                                   const base::Time& delete_begin,
                                   const base::Time& delete_end,
                                   ResultSavingCookieCallback<int>* callback) {
    cm->DeleteAllCreatedBetweenAsync(
        delete_begin, delete_end,
        base::Bind(&ResultSavingCookieCallback<int>::Run,
                   base::Unretained(callback)));
  }

  void DeleteAllForHostTask(CookieMonster* cm,
                            const GURL& url,
                            ResultSavingCookieCallback<int>* callback) {
    cm->DeleteAllForHostAsync(url,
                              base::Bind(&ResultSavingCookieCallback<int>::Run,
                                         base::Unretained(callback)));
  }

  void DeleteAllCreatedBetweenForHostTask(
      CookieMonster* cm,
      const base::Time delete_begin,
      const base::Time delete_end,
      const GURL& url,
      ResultSavingCookieCallback<int>* callback) {
    cm->DeleteAllCreatedBetweenForHostAsync(
        delete_begin, delete_end, url,
        base::Bind(&ResultSavingCookieCallback<int>::Run,
                   base::Unretained(callback)));
  }

  void DeleteCanonicalCookieTask(CookieMonster* cm,
                                 const CanonicalCookie& cookie,
                                 ResultSavingCookieCallback<bool>* callback) {
    cm->DeleteCanonicalCookieAsync(
        cookie, base::Bind(&ResultSavingCookieCallback<bool>::Run,
                           base::Unretained(callback)));
  }

 protected:
  void RunOnOtherThread(const base::Closure& task) {
    other_thread_.Start();
    other_thread_.message_loop()->PostTask(FROM_HERE, task);
    RunFor(kTimeout);
    other_thread_.Stop();
  }

  Thread other_thread_;
};

}  // namespace

TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckGetAllCookies) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
  CookieList cookies = GetAllCookies(cm.get());
  CookieList::const_iterator it = cookies.begin();
  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_EQ("A", it->Name());
  ASSERT_TRUE(++it == cookies.end());
  GetCookieListCallback callback(&other_thread_);
  base::Closure task =
      base::Bind(&MultiThreadedCookieMonsterTest::GetAllCookiesTask,
                 base::Unretained(this), cm, &callback);
  RunOnOtherThread(task);
  EXPECT_TRUE(callback.did_run());
  it = callback.cookies().begin();
  ASSERT_TRUE(it != callback.cookies().end());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_EQ("A", it->Name());
  ASSERT_TRUE(++it == callback.cookies().end());
}

TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckGetAllCookiesForURL) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
  CookieList cookies = GetAllCookiesForURL(cm.get(), url_google_);
  CookieList::const_iterator it = cookies.begin();
  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_EQ("A", it->Name());
  ASSERT_TRUE(++it == cookies.end());
  GetCookieListCallback callback(&other_thread_);
  base::Closure task =
      base::Bind(&MultiThreadedCookieMonsterTest::GetAllCookiesForURLTask,
                 base::Unretained(this), cm, url_google_, &callback);
  RunOnOtherThread(task);
  EXPECT_TRUE(callback.did_run());
  it = callback.cookies().begin();
  ASSERT_TRUE(it != callback.cookies().end());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_EQ("A", it->Name());
  ASSERT_TRUE(++it == callback.cookies().end());
}

TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckGetAllCookiesForURLWithOpt) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
  CookieOptions options;
  CookieList cookies =
      GetAllCookiesForURLWithOptions(cm.get(), url_google_, options);
  CookieList::const_iterator it = cookies.begin();
  ASSERT_TRUE(it != cookies.end());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_EQ("A", it->Name());
  ASSERT_TRUE(++it == cookies.end());
  GetCookieListCallback callback(&other_thread_);
  base::Closure task = base::Bind(
      &MultiThreadedCookieMonsterTest::GetAllCookiesForURLWithOptionsTask,
      base::Unretained(this), cm, url_google_, options, &callback);
  RunOnOtherThread(task);
  EXPECT_TRUE(callback.did_run());
  it = callback.cookies().begin();
  ASSERT_TRUE(it != callback.cookies().end());
  EXPECT_EQ("www.google.izzle", it->Domain());
  EXPECT_EQ("A", it->Name());
  ASSERT_TRUE(++it == callback.cookies().end());
}

TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckSetCookieWithDetails) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  EXPECT_TRUE(SetCookieWithDetails(cm.get(), url_google_foo_, "A", "B",
                                   std::string(), "/foo", base::Time(), false,
                                   false, false, COOKIE_PRIORITY_DEFAULT));
  ResultSavingCookieCallback<bool> callback(&other_thread_);
  base::Closure task =
      base::Bind(&MultiThreadedCookieMonsterTest::SetCookieWithDetailsTask,
                 base::Unretained(this), cm, url_google_foo_, &callback);
  RunOnOtherThread(task);
  EXPECT_TRUE(callback.did_run());
  EXPECT_TRUE(callback.result());
}

TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteAllCreatedBetween) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  CookieOptions options;
  Time now = Time::Now();
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
  EXPECT_EQ(1, DeleteAllCreatedBetween(cm.get(), now - TimeDelta::FromDays(99),
                                       Time()));
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
  ResultSavingCookieCallback<int> callback(&other_thread_);
  base::Closure task =
      base::Bind(&MultiThreadedCookieMonsterTest::DeleteAllCreatedBetweenTask,
                 base::Unretained(this), cm, now - TimeDelta::FromDays(99),
                 Time(), &callback);
  RunOnOtherThread(task);
  EXPECT_TRUE(callback.did_run());
  EXPECT_EQ(1, callback.result());
}

TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteAllForHost) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  CookieOptions options;
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
  EXPECT_EQ(1, DeleteAllForHost(cm.get(), url_google_));
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
  ResultSavingCookieCallback<int> callback(&other_thread_);
  base::Closure task =
      base::Bind(&MultiThreadedCookieMonsterTest::DeleteAllForHostTask,
                 base::Unretained(this), cm, url_google_, &callback);
  RunOnOtherThread(task);
  EXPECT_TRUE(callback.did_run());
  EXPECT_EQ(1, callback.result());
}

TEST_F(MultiThreadedCookieMonsterTest,
       ThreadCheckDeleteAllCreatedBetweenForHost) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  GURL url_not_google("http://www.notgoogle.com");

  CookieOptions options;
  Time now = Time::Now();
  // ago1 < ago2 < ago3 < now.
  Time ago1 = now - TimeDelta::FromDays(101);
  Time ago2 = now - TimeDelta::FromDays(100);
  Time ago3 = now - TimeDelta::FromDays(99);

  // These 3 cookies match the first deletion.
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "C=D", options));
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "Y=Z", options));

  // This cookie does not match host.
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_not_google, "E=F", options));

  // This cookie does not match time range: [ago3, inf], for first deletion, but
  // matches for the second deletion.
  EXPECT_TRUE(cm->SetCookieWithCreationTime(url_google_, "G=H", ago2));

  // 1. First set of deletions.
  EXPECT_EQ(
      3,  // Deletes A=B, C=D, Y=Z
      DeleteAllCreatedBetweenForHost(cm.get(), ago3, Time::Max(), url_google_));

  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
  ResultSavingCookieCallback<int> callback(&other_thread_);

  // 2. Second set of deletions.
  base::Closure task = base::Bind(
      &MultiThreadedCookieMonsterTest::DeleteAllCreatedBetweenForHostTask,
      base::Unretained(this), cm, ago1, Time(), url_google_, &callback);
  RunOnOtherThread(task);
  EXPECT_TRUE(callback.did_run());
  EXPECT_EQ(2, callback.result());  // Deletes A=B, G=H.
}

TEST_F(MultiThreadedCookieMonsterTest, ThreadCheckDeleteCanonicalCookie) {
  scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
  CookieOptions options;
  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
  CookieList cookies = GetAllCookies(cm.get());
  CookieList::iterator it = cookies.begin();
  EXPECT_TRUE(DeleteCanonicalCookie(cm.get(), *it));

  EXPECT_TRUE(SetCookieWithOptions(cm.get(), url_google_, "A=B", options));
  ResultSavingCookieCallback<bool> callback(&other_thread_);
  cookies = GetAllCookies(cm.get());
  it = cookies.begin();
  base::Closure task =
      base::Bind(&MultiThreadedCookieMonsterTest::DeleteCanonicalCookieTask,
                 base::Unretained(this), cm, *it, &callback);
  RunOnOtherThread(task);
  EXPECT_TRUE(callback.did_run());
  EXPECT_TRUE(callback.result());
}

// Ensure that cookies for http, https, ws, and wss all share the same storage
// and policies when GetAllCookiesForURLAsync is used. This test is part of
// MultiThreadedCookieMonsterTest in order to test and use
// GetAllCookiesForURLAsync, but it does not use any additional threads.
TEST_F(MultiThreadedCookieMonsterTest, GetAllCookiesForURLEffectiveDomain) {
  std::vector<CanonicalCookie*> cookies;
  // This cookie will be freed by the CookieMonster.
  cookies.push_back(CanonicalCookie::Create(url_google_, kValidCookieLine,
                                            Time::Now(), CookieOptions()));
  CanonicalCookie cookie = *cookies[0];
  scoped_refptr<NewMockPersistentCookieStore> store(
      new NewMockPersistentCookieStore);
  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));

  CookieMonster::PersistentCookieStore::LoadedCallback loaded_callback;
  ::testing::StrictMock<::testing::MockFunction<void(int)>> checkpoint;
  const std::string key =
      cookie_util::GetEffectiveDomain(url_google_.scheme(), url_google_.host());

  ::testing::InSequence s;
  EXPECT_CALL(checkpoint, Call(0));
  EXPECT_CALL(*store, Load(::testing::_));
  EXPECT_CALL(*store, LoadCookiesForKey(key, ::testing::_))
      .WillOnce(::testing::SaveArg<1>(&loaded_callback));
  EXPECT_CALL(checkpoint, Call(1));
  // LoadCookiesForKey will never be called after checkpoint.Call(1) although
  // we will call GetAllCookiesForURLAsync again, because all URLs below share
  // the same key.
  EXPECT_CALL(*store, LoadCookiesForKey(::testing::_, ::testing::_)).Times(0);

  GetCookieListCallback callback;
  checkpoint.Call(0);
  GetAllCookiesForURLTask(cm.get(), url_google_, &callback);
  checkpoint.Call(1);
  ASSERT_FALSE(callback.did_run());
  // Pass the cookies to the CookieMonster.
  loaded_callback.Run(cookies);
  // Now GetAllCookiesForURLTask is done.
  ASSERT_TRUE(callback.did_run());
  // See that the callback was called with the cookies.
  ASSERT_EQ(1u, callback.cookies().size());
  EXPECT_TRUE(cookie.IsEquivalent(callback.cookies()[0]));

  // All urls in |urls| should share the same cookie domain.
  const GURL kUrls[] = {
      url_google_,
      url_google_secure_,
      GURL(kUrlGoogleWebSocket),
      GURL(kUrlGoogleWebSocketSecure),
  };
  for (const GURL& url : kUrls) {
    // Call the function with |url| and verify it is done synchronously without
    // calling LoadCookiesForKey.
    GetCookieListCallback callback;
    GetAllCookiesForURLTask(cm.get(), url, &callback);
    ASSERT_TRUE(callback.did_run());
    ASSERT_EQ(1u, callback.cookies().size());
    EXPECT_TRUE(cookie.IsEquivalent(callback.cookies()[0]));
  }
}

TEST_F(CookieMonsterTest, InvalidExpiryTime) {
  std::string cookie_line =
      std::string(kValidCookieLine) + "; expires=Blarg arg arg";
  scoped_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
      url_google_, cookie_line, Time::Now(), CookieOptions()));
  ASSERT_FALSE(cookie->IsPersistent());
}

// Test that CookieMonster writes session cookies into the underlying
// CookieStore if the "persist session cookies" option is on.
TEST_F(CookieMonsterTest, PersistSessionCookies) {
  scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));
  cm->SetPersistSessionCookies(true);

  // All cookies set with SetCookie are session cookies.
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B"));
  EXPECT_EQ("A=B", GetCookies(cm.get(), url_google_));

  // The cookie was written to the backing store.
  EXPECT_EQ(1u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
  EXPECT_EQ("A", store->commands()[0].cookie.Name());
  EXPECT_EQ("B", store->commands()[0].cookie.Value());

  // Modify the cookie.
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=C"));
  EXPECT_EQ("A=C", GetCookies(cm.get(), url_google_));
  EXPECT_EQ(3u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);
  EXPECT_EQ("A", store->commands()[1].cookie.Name());
  EXPECT_EQ("B", store->commands()[1].cookie.Value());
  EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
  EXPECT_EQ("A", store->commands()[2].cookie.Name());
  EXPECT_EQ("C", store->commands()[2].cookie.Value());

  // Delete the cookie.
  DeleteCookie(cm.get(), url_google_, "A");
  EXPECT_EQ("", GetCookies(cm.get(), url_google_));
  EXPECT_EQ(4u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
  EXPECT_EQ("A", store->commands()[3].cookie.Name());
  EXPECT_EQ("C", store->commands()[3].cookie.Value());
}

// Test the commands sent to the persistent cookie store.
TEST_F(CookieMonsterTest, PersisentCookieStorageTest) {
  scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));

  // Add a cookie.
  EXPECT_TRUE(SetCookie(cm.get(), url_google_,
                        "A=B; expires=Mon, 18-Apr-22 22:50:13 GMT"));
  this->MatchCookieLines("A=B", GetCookies(cm.get(), url_google_));
  ASSERT_EQ(1u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[0].type);
  // Remove it.
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "A=B; max-age=0"));
  this->MatchCookieLines(std::string(), GetCookies(cm.get(), url_google_));
  ASSERT_EQ(2u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[1].type);

  // Add a cookie.
  EXPECT_TRUE(SetCookie(cm.get(), url_google_,
                        "A=B; expires=Mon, 18-Apr-22 22:50:13 GMT"));
  this->MatchCookieLines("A=B", GetCookies(cm.get(), url_google_));
  ASSERT_EQ(3u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[2].type);
  // Overwrite it.
  EXPECT_TRUE(SetCookie(cm.get(), url_google_,
                        "A=Foo; expires=Mon, 18-Apr-22 22:50:14 GMT"));
  this->MatchCookieLines("A=Foo", GetCookies(cm.get(), url_google_));
  ASSERT_EQ(5u, store->commands().size());
  EXPECT_EQ(CookieStoreCommand::REMOVE, store->commands()[3].type);
  EXPECT_EQ(CookieStoreCommand::ADD, store->commands()[4].type);

  // Create some non-persistent cookies and check that they don't go to the
  // persistent storage.
  EXPECT_TRUE(SetCookie(cm.get(), url_google_, "B=Bar"));
  this->MatchCookieLines("A=Foo; B=Bar", GetCookies(cm.get(), url_google_));
  EXPECT_EQ(5u, store->commands().size());
}

// Test to assure that cookies with control characters are purged appropriately.
// See http://crbug.com/238041 for background.
TEST_F(CookieMonsterTest, ControlCharacterPurge) {
  const Time now1(Time::Now());
  const Time now2(Time::Now() + TimeDelta::FromSeconds(1));
  const Time now3(Time::Now() + TimeDelta::FromSeconds(2));
  const Time later(now1 + TimeDelta::FromDays(1));
  const GURL url("http://host/path");
  const std::string domain("host");
  const std::string path("/path");

  scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);

  std::vector<CanonicalCookie*> initial_cookies;

  AddCookieToList(domain, "foo=bar; path=" + path, now1, &initial_cookies);

  // We have to manually build this cookie because it contains a control
  // character, and our cookie line parser rejects control characters.
  CanonicalCookie* cc =
      new CanonicalCookie(url, "baz",
                          "\x05"
                          "boo",
                          domain, path, now2, later, now2, false, false, false,
                          COOKIE_PRIORITY_DEFAULT);
  initial_cookies.push_back(cc);

  AddCookieToList(domain, "hello=world; path=" + path, now3, &initial_cookies);

  // Inject our initial cookies into the mock PersistentCookieStore.
  store->SetLoadExpectation(true, initial_cookies);

  scoped_refptr<CookieMonster> cm(new CookieMonster(store.get(), NULL));

  EXPECT_EQ("foo=bar; hello=world", GetCookies(cm.get(), url));
}

class CookieMonsterNotificationTest : public CookieMonsterTest {
 public:
  CookieMonsterNotificationTest()
      : test_url_("http://www.google.com/foo"),
        store_(new MockPersistentCookieStore),
        monster_(new CookieMonster(store_.get(), NULL)) {}

  ~CookieMonsterNotificationTest() override {}

  CookieMonster* monster() { return monster_.get(); }

 protected:
  const GURL test_url_;

 private:
  scoped_refptr<MockPersistentCookieStore> store_;
  scoped_refptr<CookieMonster> monster_;
};

void RecordCookieChanges(std::vector<CanonicalCookie>* out_cookies,
                         std::vector<bool>* out_removes,
                         const CanonicalCookie& cookie,
                         bool removed) {
  DCHECK(out_cookies);
  out_cookies->push_back(cookie);
  if (out_removes)
    out_removes->push_back(removed);
}

TEST_F(CookieMonsterNotificationTest, NoNotifyWithNoCookie) {
  std::vector<CanonicalCookie> cookies;
  scoped_ptr<CookieStore::CookieChangedSubscription> sub(
      monster()->AddCallbackForCookie(
          test_url_, "abc",
          base::Bind(&RecordCookieChanges, &cookies, nullptr)));
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(0U, cookies.size());
}

TEST_F(CookieMonsterNotificationTest, NoNotifyWithInitialCookie) {
  std::vector<CanonicalCookie> cookies;
  SetCookie(monster(), test_url_, "abc=def");
  base::MessageLoop::current()->RunUntilIdle();
  scoped_ptr<CookieStore::CookieChangedSubscription> sub(
      monster()->AddCallbackForCookie(
          test_url_, "abc",
          base::Bind(&RecordCookieChanges, &cookies, nullptr)));
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(0U, cookies.size());
}

TEST_F(CookieMonsterNotificationTest, NotifyOnSet) {
  std::vector<CanonicalCookie> cookies;
  std::vector<bool> removes;
  scoped_ptr<CookieStore::CookieChangedSubscription> sub(
      monster()->AddCallbackForCookie(
          test_url_, "abc",
          base::Bind(&RecordCookieChanges, &cookies, &removes)));
  SetCookie(monster(), test_url_, "abc=def");
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(1U, cookies.size());
  EXPECT_EQ(1U, removes.size());

  EXPECT_EQ("abc", cookies[0].Name());
  EXPECT_EQ("def", cookies[0].Value());
  EXPECT_FALSE(removes[0]);
}

TEST_F(CookieMonsterNotificationTest, NotifyOnDelete) {
  std::vector<CanonicalCookie> cookies;
  std::vector<bool> removes;
  scoped_ptr<CookieStore::CookieChangedSubscription> sub(
      monster()->AddCallbackForCookie(
          test_url_, "abc",
          base::Bind(&RecordCookieChanges, &cookies, &removes)));
  SetCookie(monster(), test_url_, "abc=def");
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(1U, cookies.size());
  EXPECT_EQ(1U, removes.size());

  DeleteCookie(monster(), test_url_, "abc");
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(2U, cookies.size());
  EXPECT_EQ(2U, removes.size());

  EXPECT_EQ("abc", cookies[1].Name());
  EXPECT_EQ("def", cookies[1].Value());
  EXPECT_TRUE(removes[1]);
}

TEST_F(CookieMonsterNotificationTest, NotifyOnUpdate) {
  std::vector<CanonicalCookie> cookies;
  std::vector<bool> removes;
  scoped_ptr<CookieStore::CookieChangedSubscription> sub(
      monster()->AddCallbackForCookie(
          test_url_, "abc",
          base::Bind(&RecordCookieChanges, &cookies, &removes)));
  SetCookie(monster(), test_url_, "abc=def");
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(1U, cookies.size());

  // Replacing an existing cookie is actually a two-phase delete + set
  // operation, so we get an extra notification.
  SetCookie(monster(), test_url_, "abc=ghi");
  base::MessageLoop::current()->RunUntilIdle();

  EXPECT_EQ(3U, cookies.size());
  EXPECT_EQ(3U, removes.size());

  EXPECT_EQ("abc", cookies[1].Name());
  EXPECT_EQ("def", cookies[1].Value());
  EXPECT_TRUE(removes[1]);

  EXPECT_EQ("abc", cookies[2].Name());
  EXPECT_EQ("ghi", cookies[2].Value());
  EXPECT_FALSE(removes[2]);
}

TEST_F(CookieMonsterNotificationTest, MultipleNotifies) {
  std::vector<CanonicalCookie> cookies0;
  std::vector<CanonicalCookie> cookies1;
  scoped_ptr<CookieStore::CookieChangedSubscription> sub0(
      monster()->AddCallbackForCookie(
          test_url_, "abc",
          base::Bind(&RecordCookieChanges, &cookies0, nullptr)));
  scoped_ptr<CookieStore::CookieChangedSubscription> sub1(
      monster()->AddCallbackForCookie(
          test_url_, "def",
          base::Bind(&RecordCookieChanges, &cookies1, nullptr)));
  SetCookie(monster(), test_url_, "abc=def");
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(1U, cookies0.size());
  EXPECT_EQ(0U, cookies1.size());
  SetCookie(monster(), test_url_, "def=abc");
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(1U, cookies0.size());
  EXPECT_EQ(1U, cookies1.size());
}

TEST_F(CookieMonsterNotificationTest, MultipleSameNotifies) {
  std::vector<CanonicalCookie> cookies0;
  std::vector<CanonicalCookie> cookies1;
  scoped_ptr<CookieStore::CookieChangedSubscription> sub0(
      monster()->AddCallbackForCookie(
          test_url_, "abc",
          base::Bind(&RecordCookieChanges, &cookies0, nullptr)));
  scoped_ptr<CookieStore::CookieChangedSubscription> sub1(
      monster()->AddCallbackForCookie(
          test_url_, "abc",
          base::Bind(&RecordCookieChanges, &cookies1, nullptr)));
  SetCookie(monster(), test_url_, "abc=def");
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(1U, cookies0.size());
  EXPECT_EQ(1U, cookies0.size());
}

}  // namespace net
