1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/base/cookie_monster_store_test.h"
6
7#include "base/message_loop.h"
8#include "base/stringprintf.h"
9#include "base/time.h"
10#include "googleurl/src/gurl.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace net {
14
15MockPersistentCookieStore::MockPersistentCookieStore()
16    : load_return_value_(true) {
17}
18
19MockPersistentCookieStore::~MockPersistentCookieStore() {}
20
21void MockPersistentCookieStore::SetLoadExpectation(
22    bool return_value,
23    const std::vector<CookieMonster::CanonicalCookie*>& result) {
24  load_return_value_ = return_value;
25  load_result_ = result;
26}
27
28bool MockPersistentCookieStore::Load(
29    std::vector<CookieMonster::CanonicalCookie*>* out_cookies) {
30  bool ok = load_return_value_;
31  if (ok)
32    *out_cookies = load_result_;
33  return ok;
34}
35
36void MockPersistentCookieStore::AddCookie(
37    const CookieMonster::CanonicalCookie& cookie) {
38  commands_.push_back(
39      CookieStoreCommand(CookieStoreCommand::ADD, cookie));
40}
41
42void MockPersistentCookieStore::UpdateCookieAccessTime(
43    const CookieMonster::CanonicalCookie& cookie) {
44  commands_.push_back(CookieStoreCommand(
45      CookieStoreCommand::UPDATE_ACCESS_TIME, cookie));
46}
47
48void MockPersistentCookieStore::DeleteCookie(
49    const CookieMonster::CanonicalCookie& cookie) {
50  commands_.push_back(
51      CookieStoreCommand(CookieStoreCommand::REMOVE, cookie));
52}
53
54void MockPersistentCookieStore::Flush(Task* completion_task) {
55  if (completion_task)
56    MessageLoop::current()->PostTask(FROM_HERE, completion_task);
57}
58
59// No files are created so nothing to clear either
60void
61MockPersistentCookieStore::SetClearLocalStateOnExit(bool clear_local_state) {
62}
63
64MockCookieMonsterDelegate::MockCookieMonsterDelegate() {}
65
66void MockCookieMonsterDelegate::OnCookieChanged(
67    const CookieMonster::CanonicalCookie& cookie,
68    bool removed,
69    CookieMonster::Delegate::ChangeCause cause) {
70  CookieNotification notification(cookie, removed);
71  changes_.push_back(notification);
72}
73
74MockCookieMonsterDelegate::~MockCookieMonsterDelegate() {}
75
76void AddCookieToList(
77    const std::string& key,
78    const std::string& cookie_line,
79    const base::Time& creation_time,
80    std::vector<CookieMonster::CanonicalCookie*>* out_list) {
81
82  // Parse the cookie line.
83  CookieMonster::ParsedCookie pc(cookie_line);
84  EXPECT_TRUE(pc.IsValid());
85
86  // This helper is simplistic in interpreting a parsed cookie, in order to
87  // avoid duplicated CookieMonster's CanonPath() and CanonExpiration()
88  // functions. Would be nice to export them, and re-use here.
89  EXPECT_FALSE(pc.HasMaxAge());
90  EXPECT_TRUE(pc.HasPath());
91  base::Time cookie_expires = pc.HasExpires() ?
92      CookieMonster::ParseCookieTime(pc.Expires()) : base::Time();
93  std::string cookie_path = pc.Path();
94
95  scoped_ptr<CookieMonster::CanonicalCookie> cookie(
96      new CookieMonster::CanonicalCookie(
97          GURL(), pc.Name(), pc.Value(), key, cookie_path,
98          creation_time, creation_time, cookie_expires,
99          pc.IsSecure(), pc.IsHttpOnly(),
100          !cookie_expires.is_null()));
101
102  out_list->push_back(cookie.release());
103}
104
105MockSimplePersistentCookieStore::MockSimplePersistentCookieStore() {}
106
107MockSimplePersistentCookieStore::~MockSimplePersistentCookieStore() {}
108
109bool MockSimplePersistentCookieStore::Load(
110    std::vector<CookieMonster::CanonicalCookie*>* out_cookies) {
111  for (CanonicalCookieMap::const_iterator it = cookies_.begin();
112       it != cookies_.end(); it++)
113    out_cookies->push_back(
114        new CookieMonster::CanonicalCookie(it->second));
115  return true;
116}
117
118void MockSimplePersistentCookieStore::AddCookie(
119    const CookieMonster::CanonicalCookie& cookie) {
120  int64 creation_time = cookie.CreationDate().ToInternalValue();
121  EXPECT_TRUE(cookies_.find(creation_time) == cookies_.end());
122  cookies_[creation_time] = cookie;
123}
124
125void MockSimplePersistentCookieStore::UpdateCookieAccessTime(
126    const CookieMonster::CanonicalCookie& cookie) {
127  int64 creation_time = cookie.CreationDate().ToInternalValue();
128  ASSERT_TRUE(cookies_.find(creation_time) != cookies_.end());
129  cookies_[creation_time].SetLastAccessDate(base::Time::Now());
130}
131
132void MockSimplePersistentCookieStore::DeleteCookie(
133    const CookieMonster::CanonicalCookie& cookie) {
134  int64 creation_time = cookie.CreationDate().ToInternalValue();
135  CanonicalCookieMap::iterator it = cookies_.find(creation_time);
136  ASSERT_TRUE(it != cookies_.end());
137  cookies_.erase(it);
138}
139
140void MockSimplePersistentCookieStore::Flush(Task* completion_task) {
141  if (completion_task)
142    MessageLoop::current()->PostTask(FROM_HERE, completion_task);
143}
144
145void MockSimplePersistentCookieStore::SetClearLocalStateOnExit(
146    bool clear_local_state) {
147}
148
149CookieMonster* CreateMonsterFromStoreForGC(
150    int num_cookies,
151    int num_old_cookies,
152    int days_old) {
153  base::Time current(base::Time::Now());
154  base::Time past_creation(base::Time::Now() - base::TimeDelta::FromDays(1000));
155  scoped_refptr<MockSimplePersistentCookieStore> store(
156      new MockSimplePersistentCookieStore);
157  // Must expire to be persistent
158  for (int i = 0; i < num_cookies; i++) {
159    base::Time creation_time =
160        past_creation + base::TimeDelta::FromMicroseconds(i);
161    base::Time expiration_time = current + base::TimeDelta::FromDays(30);
162    base::Time last_access_time =
163        (i < num_old_cookies) ? current - base::TimeDelta::FromDays(days_old) :
164                                current;
165
166    CookieMonster::CanonicalCookie cc(
167        GURL(), "a", "1", base::StringPrintf("h%05d.izzle", i), "/path",
168        creation_time, expiration_time, last_access_time,
169        false, false, true);
170    store->AddCookie(cc);
171  }
172
173  return new CookieMonster(store, NULL);
174}
175
176}  // namespace net
177