cookies_tree_model_unittest.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1// Copyright (c) 2010 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 "chrome/browser/cookies_tree_model.h"
6
7#include <string>
8
9#include "chrome/browser/content_settings/stub_settings_observer.h"
10#include "chrome/browser/mock_browsing_data_appcache_helper.h"
11#include "chrome/browser/mock_browsing_data_database_helper.h"
12#include "chrome/browser/mock_browsing_data_indexed_db_helper.h"
13#include "chrome/browser/mock_browsing_data_local_storage_helper.h"
14#include "chrome/common/net/url_request_context_getter.h"
15#include "chrome/common/notification_details.h"
16#include "chrome/common/notification_type.h"
17#include "chrome/test/testing_profile.h"
18#include "net/url_request/url_request_context.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
21
22namespace {
23
24class CookiesTreeModelTest : public testing::Test {
25 public:
26  CookiesTreeModelTest() : ui_thread_(BrowserThread::UI, &message_loop_),
27                           io_thread_(BrowserThread::IO, &message_loop_) {
28  }
29
30  virtual ~CookiesTreeModelTest() {
31  }
32
33  virtual void SetUp() {
34    profile_.reset(new TestingProfile());
35    profile_->CreateRequestContext();
36    mock_browsing_data_database_helper_ =
37      new MockBrowsingDataDatabaseHelper(profile_.get());
38    mock_browsing_data_local_storage_helper_ =
39      new MockBrowsingDataLocalStorageHelper(profile_.get());
40    mock_browsing_data_session_storage_helper_ =
41      new MockBrowsingDataLocalStorageHelper(profile_.get());
42    mock_browsing_data_appcache_helper_ =
43      new MockBrowsingDataAppCacheHelper(profile_.get());
44    mock_browsing_data_indexed_db_helper_ =
45      new MockBrowsingDataIndexedDBHelper(profile_.get());
46  }
47
48  CookiesTreeModel* CreateCookiesTreeModelWithInitialSample() {
49    net::CookieMonster* monster = profile_->GetCookieMonster();
50    monster->SetCookie(GURL("http://foo1"), "A=1");
51    monster->SetCookie(GURL("http://foo2"), "B=1");
52    monster->SetCookie(GURL("http://foo3"), "C=1");
53    CookiesTreeModel* cookies_model = new CookiesTreeModel(
54        monster, mock_browsing_data_database_helper_,
55        mock_browsing_data_local_storage_helper_,
56        mock_browsing_data_session_storage_helper_,
57        mock_browsing_data_appcache_helper_,
58        mock_browsing_data_indexed_db_helper_);
59    mock_browsing_data_database_helper_->AddDatabaseSamples();
60    mock_browsing_data_database_helper_->Notify();
61    mock_browsing_data_local_storage_helper_->AddLocalStorageSamples();
62    mock_browsing_data_local_storage_helper_->Notify();
63    mock_browsing_data_session_storage_helper_->AddLocalStorageSamples();
64    mock_browsing_data_session_storage_helper_->Notify();
65    mock_browsing_data_indexed_db_helper_->AddIndexedDBSamples();
66    mock_browsing_data_indexed_db_helper_->Notify();
67    {
68      SCOPED_TRACE("Initial State 3 cookies, 2 databases, 2 local storages, "
69                   "2 session storages, 2 indexed DBs");
70      // 32 because there's the root, then foo1 -> cookies -> a,
71      // foo2 -> cookies -> b, foo3 -> cookies -> c,
72      // dbhost1 -> database -> db1, dbhost2 -> database -> db2,
73      // host1 -> localstorage -> http://host1:1/,
74      // host2 -> localstorage -> http://host2:2/.
75      // host1 -> sessionstorage -> http://host1:1/,
76      // host2 -> sessionstorage -> http://host2:2/,
77      // idbhost1 -> indexeddb -> http://idbhost1:1/,
78      // idbhost2 -> indexeddb -> http://idbhost2:2/.
79      EXPECT_EQ(32, cookies_model->GetRoot()->GetTotalNodeCount());
80      EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model));
81      EXPECT_EQ("http://host1:1/,http://host2:2/",
82                GetDisplayedLocalStorages(cookies_model));
83      EXPECT_EQ("http://host1:1/,http://host2:2/",
84                GetDisplayedSessionStorages(cookies_model));
85      EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
86                GetDisplayedIndexedDBs(cookies_model));
87    }
88    return cookies_model;
89  }
90
91  // Get the cookie names in the cookie list, as a comma seperated string.
92  // (Note that the CookieMonster cookie list is sorted by domain.)
93  // Ex:
94  //   monster->SetCookie(GURL("http://b"), "X=1")
95  //   monster->SetCookie(GURL("http://a"), "Y=1")
96  //   EXPECT_STREQ("Y,X", GetMonsterCookies(monster).c_str());
97  std::string GetMonsterCookies(net::CookieMonster* monster) {
98    std::vector<std::string> parts;
99    net::CookieList cookie_list = monster->GetAllCookies();
100    for (size_t i = 0; i < cookie_list.size(); ++i)
101      parts.push_back(cookie_list[i].Name());
102    return JoinString(parts, ',');
103  }
104
105  std::string GetNodesOfChildren(
106      const CookieTreeNode* node,
107      CookieTreeNode::DetailedInfo::NodeType node_type) {
108    if (node->GetChildCount()) {
109      std::string retval;
110      for (int i = 0; i < node->GetChildCount(); ++i) {
111        retval += GetNodesOfChildren(node->GetChild(i), node_type);
112      }
113      return retval;
114    } else {
115      if (node->GetDetailedInfo().node_type == node_type) {
116        switch (node_type) {
117          case CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE:
118            return node->GetDetailedInfo().session_storage_info->origin + ",";
119          case CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE:
120            return node->GetDetailedInfo().local_storage_info->origin + ",";
121          case CookieTreeNode::DetailedInfo::TYPE_DATABASE:
122            return node->GetDetailedInfo().database_info->database_name + ",";
123          case CookieTreeNode::DetailedInfo::TYPE_COOKIE:
124            return node->GetDetailedInfo().cookie->Name() + ",";
125          case CookieTreeNode::DetailedInfo::TYPE_APPCACHE:
126            return node->GetDetailedInfo().appcache_info->manifest_url.spec() +
127                   ",";
128          case CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB:
129            return node->GetDetailedInfo().indexed_db_info->origin + ",";
130          default:
131            return "";
132        }
133      } else {
134        return "";
135      }
136    }
137  }
138
139  std::string GetCookiesOfChildren(const CookieTreeNode* node) {
140    return GetNodesOfChildren(node, CookieTreeNode::DetailedInfo::TYPE_COOKIE);
141  }
142
143  std::string GetDatabasesOfChildren(const CookieTreeNode* node) {
144    return GetNodesOfChildren(node,
145                              CookieTreeNode::DetailedInfo::TYPE_DATABASE);
146  }
147
148  std::string GetLocalStoragesOfChildren(const CookieTreeNode* node) {
149    return GetNodesOfChildren(node,
150                              CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE);
151  }
152
153  std::string GetSessionStoragesOfChildren(const CookieTreeNode* node) {
154    return GetNodesOfChildren(
155        node, CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE);
156  }
157
158  std::string GetIndexedDBsOfChildren(const CookieTreeNode* node) {
159    return GetNodesOfChildren(
160        node, CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB);
161  }
162
163  // Get the nodes names displayed in the view (if we had one) in the order
164  // they are displayed, as a comma seperated string.
165  // Ex: EXPECT_STREQ("X,Y", GetDisplayedNodes(cookies_view, type).c_str());
166  std::string GetDisplayedNodes(CookiesTreeModel* cookies_model,
167                                CookieTreeNode::DetailedInfo::NodeType type) {
168    CookieTreeRootNode* root = static_cast<CookieTreeRootNode*>(
169        cookies_model->GetRoot());
170    std::string retval = GetNodesOfChildren(root, type);
171    if (retval.length() && retval[retval.length() - 1] == ',')
172      retval.erase(retval.length() - 1);
173    return retval;
174  }
175
176  std::string GetDisplayedCookies(CookiesTreeModel* cookies_model) {
177    return GetDisplayedNodes(cookies_model,
178                             CookieTreeNode::DetailedInfo::TYPE_COOKIE);
179  }
180
181  std::string GetDisplayedDatabases(CookiesTreeModel* cookies_model) {
182    return GetDisplayedNodes(cookies_model,
183                             CookieTreeNode::DetailedInfo::TYPE_DATABASE);
184  }
185
186  std::string GetDisplayedLocalStorages(CookiesTreeModel* cookies_model) {
187    return GetDisplayedNodes(cookies_model,
188                             CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE);
189  }
190
191  std::string GetDisplayedSessionStorages(CookiesTreeModel* cookies_model) {
192    return GetDisplayedNodes(
193        cookies_model, CookieTreeNode::DetailedInfo::TYPE_SESSION_STORAGE);
194  }
195
196  std::string GetDisplayedAppCaches(CookiesTreeModel* cookies_model) {
197    return GetDisplayedNodes(cookies_model,
198                             CookieTreeNode::DetailedInfo::TYPE_APPCACHE);
199  }
200
201  std::string GetDisplayedIndexedDBs(CookiesTreeModel* cookies_model) {
202    return GetDisplayedNodes(cookies_model,
203                             CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB);
204  }
205
206  // do not call on the root
207  void DeleteStoredObjects(CookieTreeNode* node) {
208    node->DeleteStoredObjects();
209    // find the parent and index
210    CookieTreeNode* parent_node = node->GetParent();
211    DCHECK(parent_node);
212    int ct_node_index = parent_node->IndexOfChild(node);
213    delete parent_node->GetModel()->Remove(parent_node, ct_node_index);
214  }
215 protected:
216  MessageLoop message_loop_;
217  BrowserThread ui_thread_;
218  BrowserThread io_thread_;
219
220  scoped_ptr<TestingProfile> profile_;
221  scoped_refptr<MockBrowsingDataDatabaseHelper>
222      mock_browsing_data_database_helper_;
223  scoped_refptr<MockBrowsingDataLocalStorageHelper>
224      mock_browsing_data_local_storage_helper_;
225  scoped_refptr<MockBrowsingDataLocalStorageHelper>
226      mock_browsing_data_session_storage_helper_;
227  scoped_refptr<MockBrowsingDataAppCacheHelper>
228      mock_browsing_data_appcache_helper_;
229  scoped_refptr<MockBrowsingDataIndexedDBHelper>
230      mock_browsing_data_indexed_db_helper_;
231};
232
233TEST_F(CookiesTreeModelTest, RemoveAll) {
234  scoped_ptr<CookiesTreeModel> cookies_model(
235      CreateCookiesTreeModelWithInitialSample());
236  net::CookieMonster* monster = profile_->GetCookieMonster();
237
238  // Reset the selection of the first row.
239  {
240    SCOPED_TRACE("Before removing");
241    EXPECT_EQ(GetMonsterCookies(monster),
242              GetDisplayedCookies(cookies_model.get()));
243    EXPECT_EQ("db1,db2",
244              GetDisplayedDatabases(cookies_model.get()));
245    EXPECT_EQ("http://host1:1/,http://host2:2/",
246              GetDisplayedLocalStorages(cookies_model.get()));
247    EXPECT_EQ("http://host1:1/,http://host2:2/",
248              GetDisplayedSessionStorages(cookies_model.get()));
249    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
250              GetDisplayedIndexedDBs(cookies_model.get()));
251  }
252
253  mock_browsing_data_database_helper_->Reset();
254  mock_browsing_data_local_storage_helper_->Reset();
255  mock_browsing_data_session_storage_helper_->Reset();
256  mock_browsing_data_indexed_db_helper_->Reset();
257
258  cookies_model->DeleteAllStoredObjects();
259
260  {
261    SCOPED_TRACE("After removing");
262    EXPECT_EQ(1, cookies_model->GetRoot()->GetTotalNodeCount());
263    EXPECT_EQ(0, cookies_model->GetRoot()->GetChildCount());
264    EXPECT_EQ(std::string(""), GetMonsterCookies(monster));
265    EXPECT_EQ(GetMonsterCookies(monster),
266              GetDisplayedCookies(cookies_model.get()));
267    EXPECT_TRUE(mock_browsing_data_database_helper_->AllDeleted());
268    EXPECT_TRUE(mock_browsing_data_local_storage_helper_->AllDeleted());
269    EXPECT_FALSE(mock_browsing_data_session_storage_helper_->AllDeleted());
270    EXPECT_TRUE(mock_browsing_data_indexed_db_helper_->AllDeleted());
271  }
272}
273
274TEST_F(CookiesTreeModelTest, Remove) {
275  scoped_ptr<CookiesTreeModel> cookies_model(
276      CreateCookiesTreeModelWithInitialSample());
277  net::CookieMonster* monster = profile_->GetCookieMonster();
278
279  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(0));
280  {
281    SCOPED_TRACE("First cookie origin removed");
282    EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str());
283    EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str());
284    EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get()));
285    EXPECT_EQ("http://host1:1/,http://host2:2/",
286              GetDisplayedLocalStorages(cookies_model.get()));
287    EXPECT_EQ("http://host1:1/,http://host2:2/",
288              GetDisplayedSessionStorages(cookies_model.get()));
289    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
290              GetDisplayedIndexedDBs(cookies_model.get()));
291    EXPECT_EQ(29, cookies_model->GetRoot()->GetTotalNodeCount());
292  }
293
294  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(2));
295  {
296    SCOPED_TRACE("First database origin removed");
297    EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str());
298    EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str());
299    EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get()));
300    EXPECT_EQ("http://host1:1/,http://host2:2/",
301              GetDisplayedLocalStorages(cookies_model.get()));
302    EXPECT_EQ("http://host1:1/,http://host2:2/",
303              GetDisplayedSessionStorages(cookies_model.get()));
304    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
305              GetDisplayedIndexedDBs(cookies_model.get()));
306    EXPECT_EQ(26, cookies_model->GetRoot()->GetTotalNodeCount());
307  }
308
309  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(3));
310  {
311    SCOPED_TRACE("First local storage origin removed");
312    EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str());
313    EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str());
314    EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get()));
315    EXPECT_EQ("http://host2:2/",
316              GetDisplayedLocalStorages(cookies_model.get()));
317    EXPECT_EQ("http://host2:2/",
318              GetDisplayedSessionStorages(cookies_model.get()));
319    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
320              GetDisplayedIndexedDBs(cookies_model.get()));
321    EXPECT_EQ(21, cookies_model->GetRoot()->GetTotalNodeCount());
322  }
323
324  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(4));
325  {
326    SCOPED_TRACE("First IndexedDB origin removed");
327    EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str());
328    EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str());
329    EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get()));
330    EXPECT_EQ("http://host2:2/",
331              GetDisplayedLocalStorages(cookies_model.get()));
332    EXPECT_EQ("http://host2:2/",
333              GetDisplayedSessionStorages(cookies_model.get()));
334    EXPECT_EQ("http://idbhost2:2/",
335              GetDisplayedIndexedDBs(cookies_model.get()));
336    EXPECT_EQ(18, cookies_model->GetRoot()->GetTotalNodeCount());
337  }
338}
339
340TEST_F(CookiesTreeModelTest, RemoveCookiesNode) {
341  scoped_ptr<CookiesTreeModel> cookies_model(
342      CreateCookiesTreeModelWithInitialSample());
343  net::CookieMonster* monster = profile_->GetCookieMonster();
344
345  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(0)->GetChild(0));
346  {
347    SCOPED_TRACE("First origin removed");
348    EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str());
349    EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str());
350    // 28 because in this case, the origin remains, although the COOKIES
351    // node beneath it has been deleted. So, we have
352    // root -> foo1 -> cookies -> a, foo2, foo3 -> cookies -> c
353    // dbhost1 -> database -> db1, dbhost2 -> database -> db2,
354    // host1 -> localstorage -> http://host1:1/,
355    // host2 -> localstorage -> http://host2:2/,
356    // idbhost1 -> sessionstorage -> http://idbhost1:1/,
357    // idbhost2 -> sessionstorage -> http://idbhost2:2/.
358    EXPECT_EQ(30, cookies_model->GetRoot()->GetTotalNodeCount());
359    EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get()));
360    EXPECT_EQ("http://host1:1/,http://host2:2/",
361              GetDisplayedLocalStorages(cookies_model.get()));
362    EXPECT_EQ("http://host1:1/,http://host2:2/",
363              GetDisplayedSessionStorages(cookies_model.get()));
364    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
365              GetDisplayedIndexedDBs(cookies_model.get()));
366  }
367
368  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(3)->GetChild(0));
369  {
370    SCOPED_TRACE("First database removed");
371    EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str());
372    EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str());
373    EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get()));
374    EXPECT_EQ("http://host1:1/,http://host2:2/",
375              GetDisplayedLocalStorages(cookies_model.get()));
376    EXPECT_EQ("http://host1:1/,http://host2:2/",
377              GetDisplayedSessionStorages(cookies_model.get()));
378    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
379              GetDisplayedIndexedDBs(cookies_model.get()));
380    EXPECT_EQ(28, cookies_model->GetRoot()->GetTotalNodeCount());
381  }
382
383  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(5)->GetChild(0));
384  {
385    SCOPED_TRACE("First origin removed");
386    EXPECT_STREQ("B,C", GetMonsterCookies(monster).c_str());
387    EXPECT_STREQ("B,C", GetDisplayedCookies(cookies_model.get()).c_str());
388    EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get()));
389    EXPECT_EQ("http://host2:2/",
390              GetDisplayedLocalStorages(cookies_model.get()));
391    EXPECT_EQ("http://host1:1/,http://host2:2/",
392              GetDisplayedSessionStorages(cookies_model.get()));
393    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
394              GetDisplayedIndexedDBs(cookies_model.get()));
395    EXPECT_EQ(26, cookies_model->GetRoot()->GetTotalNodeCount());
396  }
397}
398
399TEST_F(CookiesTreeModelTest, RemoveCookieNode) {
400  scoped_ptr<CookiesTreeModel> cookies_model(
401      CreateCookiesTreeModelWithInitialSample());
402  net::CookieMonster* monster = profile_->GetCookieMonster();
403
404  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(1)->GetChild(0));
405  {
406    SCOPED_TRACE("Second origin COOKIES node removed");
407    EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str());
408    EXPECT_STREQ("A,C", GetDisplayedCookies(cookies_model.get()).c_str());
409    EXPECT_EQ("db1,db2", GetDisplayedDatabases(cookies_model.get()));
410    EXPECT_EQ("http://host1:1/,http://host2:2/",
411              GetDisplayedLocalStorages(cookies_model.get()));
412    EXPECT_EQ("http://host1:1/,http://host2:2/",
413              GetDisplayedSessionStorages(cookies_model.get()));
414    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
415              GetDisplayedIndexedDBs(cookies_model.get()));
416    // 28 because in this case, the origin remains, although the COOKIES
417    // node beneath it has been deleted. So, we have
418    // root -> foo1 -> cookies -> a, foo2, foo3 -> cookies -> c
419    // dbhost1 -> database -> db1, dbhost2 -> database -> db2,
420    // host1 -> localstorage -> http://host1:1/,
421    // host2 -> localstorage -> http://host2:2/.
422    // host1 -> sessionstorage -> http://host1:1/,
423    // host2 -> sessionstorage -> http://host2:2/,
424    // idbhost1 -> sessionstorage -> http://idbhost1:1/,
425    // idbhost2 -> sessionstorage -> http://idbhost2:2/.
426    EXPECT_EQ(30, cookies_model->GetRoot()->GetTotalNodeCount());
427  }
428
429  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(3)->GetChild(0));
430  {
431    SCOPED_TRACE("First database removed");
432    EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str());
433    EXPECT_STREQ("A,C", GetDisplayedCookies(cookies_model.get()).c_str());
434    EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get()));
435    EXPECT_EQ("http://host1:1/,http://host2:2/",
436              GetDisplayedLocalStorages(cookies_model.get()));
437    EXPECT_EQ("http://host1:1/,http://host2:2/",
438              GetDisplayedSessionStorages(cookies_model.get()));
439    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
440              GetDisplayedIndexedDBs(cookies_model.get()));
441    EXPECT_EQ(28, cookies_model->GetRoot()->GetTotalNodeCount());
442  }
443
444  DeleteStoredObjects(cookies_model->GetRoot()->GetChild(5)->GetChild(0));
445  {
446    SCOPED_TRACE("First origin removed");
447    EXPECT_STREQ("A,C", GetMonsterCookies(monster).c_str());
448    EXPECT_STREQ("A,C", GetDisplayedCookies(cookies_model.get()).c_str());
449    EXPECT_EQ("db2", GetDisplayedDatabases(cookies_model.get()));
450    EXPECT_EQ("http://host2:2/",
451              GetDisplayedLocalStorages(cookies_model.get()));
452    EXPECT_EQ("http://host1:1/,http://host2:2/",
453              GetDisplayedSessionStorages(cookies_model.get()));
454    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
455              GetDisplayedIndexedDBs(cookies_model.get()));
456    EXPECT_EQ(26, cookies_model->GetRoot()->GetTotalNodeCount());
457  }
458}
459
460TEST_F(CookiesTreeModelTest, RemoveSingleCookieNode) {
461  net::CookieMonster* monster = profile_->GetCookieMonster();
462  monster->SetCookie(GURL("http://foo1"), "A=1");
463  monster->SetCookie(GURL("http://foo2"), "B=1");
464  monster->SetCookie(GURL("http://foo3"), "C=1");
465  monster->SetCookie(GURL("http://foo3"), "D=1");
466  CookiesTreeModel cookies_model(monster,
467                                 mock_browsing_data_database_helper_,
468                                 mock_browsing_data_local_storage_helper_,
469                                 mock_browsing_data_session_storage_helper_,
470                                 mock_browsing_data_appcache_helper_,
471                                 mock_browsing_data_indexed_db_helper_);
472  mock_browsing_data_database_helper_->AddDatabaseSamples();
473  mock_browsing_data_database_helper_->Notify();
474  mock_browsing_data_local_storage_helper_->AddLocalStorageSamples();
475  mock_browsing_data_local_storage_helper_->Notify();
476  mock_browsing_data_session_storage_helper_->AddLocalStorageSamples();
477  mock_browsing_data_session_storage_helper_->Notify();
478  mock_browsing_data_indexed_db_helper_->AddIndexedDBSamples();
479  mock_browsing_data_indexed_db_helper_->Notify();
480
481  {
482    SCOPED_TRACE("Initial State 4 cookies, 2 databases, 2 local storages, "
483        "2 session storages, 2 indexed DBs");
484    // 33 because there's the root, then foo1 -> cookies -> a,
485    // foo2 -> cookies -> b, foo3 -> cookies -> c,d
486    // dbhost1 -> database -> db1, dbhost2 -> database -> db2,
487    // host1 -> localstorage -> http://host1:1/,
488    // host2 -> localstorage -> http://host2:2/.
489    // host1 -> sessionstorage -> http://host1:1/,
490    // host2 -> sessionstorage -> http://host2:2/,
491    // idbhost1 -> sessionstorage -> http://idbhost1:1/,
492    // idbhost2 -> sessionstorage -> http://idbhost2:2/.
493    EXPECT_EQ(33, cookies_model.GetRoot()->GetTotalNodeCount());
494    EXPECT_STREQ("A,B,C,D", GetMonsterCookies(monster).c_str());
495    EXPECT_STREQ("A,B,C,D", GetDisplayedCookies(&cookies_model).c_str());
496    EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model));
497    EXPECT_EQ("http://host1:1/,http://host2:2/",
498              GetDisplayedLocalStorages(&cookies_model));
499    EXPECT_EQ("http://host1:1/,http://host2:2/",
500              GetDisplayedSessionStorages(&cookies_model));
501    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
502              GetDisplayedIndexedDBs(&cookies_model));
503  }
504  DeleteStoredObjects(cookies_model.GetRoot()->GetChild(2));
505  {
506    SCOPED_TRACE("Third origin removed");
507    EXPECT_STREQ("A,B", GetMonsterCookies(monster).c_str());
508    EXPECT_STREQ("A,B", GetDisplayedCookies(&cookies_model).c_str());
509    EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model));
510    EXPECT_EQ("http://host1:1/,http://host2:2/",
511              GetDisplayedLocalStorages(&cookies_model));
512    EXPECT_EQ("http://host1:1/,http://host2:2/",
513              GetDisplayedSessionStorages(&cookies_model));
514    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
515              GetDisplayedIndexedDBs(&cookies_model));
516    EXPECT_EQ(29, cookies_model.GetRoot()->GetTotalNodeCount());
517  }
518}
519
520TEST_F(CookiesTreeModelTest, RemoveSingleCookieNodeOf3) {
521  net::CookieMonster* monster = profile_->GetCookieMonster();
522  monster->SetCookie(GURL("http://foo1"), "A=1");
523  monster->SetCookie(GURL("http://foo2"), "B=1");
524  monster->SetCookie(GURL("http://foo3"), "C=1");
525  monster->SetCookie(GURL("http://foo3"), "D=1");
526  monster->SetCookie(GURL("http://foo3"), "E=1");
527  CookiesTreeModel cookies_model(monster,
528                                 mock_browsing_data_database_helper_,
529                                 mock_browsing_data_local_storage_helper_,
530                                 mock_browsing_data_session_storage_helper_,
531                                 mock_browsing_data_appcache_helper_,
532                                 mock_browsing_data_indexed_db_helper_);
533  mock_browsing_data_database_helper_->AddDatabaseSamples();
534  mock_browsing_data_database_helper_->Notify();
535  mock_browsing_data_local_storage_helper_->AddLocalStorageSamples();
536  mock_browsing_data_local_storage_helper_->Notify();
537  mock_browsing_data_session_storage_helper_->AddLocalStorageSamples();
538  mock_browsing_data_session_storage_helper_->Notify();
539  mock_browsing_data_indexed_db_helper_->AddIndexedDBSamples();
540  mock_browsing_data_indexed_db_helper_->Notify();
541
542  {
543    SCOPED_TRACE("Initial State 5 cookies, 2 databases, 2 local storages, "
544                 "2 session storages, 2 indexed DBs");
545    // 34 because there's the root, then foo1 -> cookies -> a,
546    // foo2 -> cookies -> b, foo3 -> cookies -> c,d,e
547    // dbhost1 -> database -> db1, dbhost2 -> database -> db2,
548    // host1 -> localstorage -> http://host1:1/,
549    // host2 -> localstorage -> http://host2:2/.
550    // host1 -> sessionstorage -> http://host1:1/,
551    // host2 -> sessionstorage -> http://host2:2/,
552    // idbhost1 -> sessionstorage -> http://idbhost1:1/,
553    // idbhost2 -> sessionstorage -> http://idbhost2:2/.
554    EXPECT_EQ(34, cookies_model.GetRoot()->GetTotalNodeCount());
555    EXPECT_STREQ("A,B,C,D,E", GetMonsterCookies(monster).c_str());
556    EXPECT_STREQ("A,B,C,D,E", GetDisplayedCookies(&cookies_model).c_str());
557    EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model));
558    EXPECT_EQ("http://host1:1/,http://host2:2/",
559              GetDisplayedLocalStorages(&cookies_model));
560    EXPECT_EQ("http://host1:1/,http://host2:2/",
561              GetDisplayedSessionStorages(&cookies_model));
562    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
563              GetDisplayedIndexedDBs(&cookies_model));
564  }
565  DeleteStoredObjects(cookies_model.GetRoot()->GetChild(2)->GetChild(0)->
566      GetChild(1));
567  {
568    SCOPED_TRACE("Middle cookie in third origin removed");
569    EXPECT_STREQ("A,B,C,E", GetMonsterCookies(monster).c_str());
570    EXPECT_STREQ("A,B,C,E", GetDisplayedCookies(&cookies_model).c_str());
571    EXPECT_EQ(33, cookies_model.GetRoot()->GetTotalNodeCount());
572    EXPECT_EQ("db1,db2", GetDisplayedDatabases(&cookies_model));
573    EXPECT_EQ("http://host1:1/,http://host2:2/",
574              GetDisplayedLocalStorages(&cookies_model));
575    EXPECT_EQ("http://host1:1/,http://host2:2/",
576              GetDisplayedSessionStorages(&cookies_model));
577    EXPECT_EQ("http://idbhost1:1/,http://idbhost2:2/",
578              GetDisplayedIndexedDBs(&cookies_model));
579  }
580}
581
582TEST_F(CookiesTreeModelTest, RemoveSecondOrigin) {
583  net::CookieMonster* monster = profile_->GetCookieMonster();
584  monster->SetCookie(GURL("http://foo1"), "A=1");
585  monster->SetCookie(GURL("http://foo2"), "B=1");
586  monster->SetCookie(GURL("http://foo3"), "C=1");
587  monster->SetCookie(GURL("http://foo3"), "D=1");
588  monster->SetCookie(GURL("http://foo3"), "E=1");
589  CookiesTreeModel cookies_model(monster,
590                                 mock_browsing_data_database_helper_,
591                                 mock_browsing_data_local_storage_helper_,
592                                 mock_browsing_data_session_storage_helper_,
593                                 mock_browsing_data_appcache_helper_,
594                                 mock_browsing_data_indexed_db_helper_);
595  {
596    SCOPED_TRACE("Initial State 5 cookies");
597    // 11 because there's the root, then foo1 -> cookies -> a,
598    // foo2 -> cookies -> b, foo3 -> cookies -> c,d,e
599    EXPECT_EQ(12, cookies_model.GetRoot()->GetTotalNodeCount());
600    EXPECT_STREQ("A,B,C,D,E", GetMonsterCookies(monster).c_str());
601    EXPECT_STREQ("A,B,C,D,E", GetDisplayedCookies(&cookies_model).c_str());
602  }
603  DeleteStoredObjects(cookies_model.GetRoot()->GetChild(1));
604  {
605    SCOPED_TRACE("Second origin removed");
606    EXPECT_STREQ("A,C,D,E", GetMonsterCookies(monster).c_str());
607    EXPECT_STREQ("A,C,D,E", GetDisplayedCookies(&cookies_model).c_str());
608    // Left with root -> foo1 -> cookies -> a, foo3 -> cookies -> c,d,e
609    EXPECT_EQ(9, cookies_model.GetRoot()->GetTotalNodeCount());
610  }
611}
612
613TEST_F(CookiesTreeModelTest, OriginOrdering) {
614  net::CookieMonster* monster = profile_->GetCookieMonster();
615  monster->SetCookie(GURL("http://a.foo2.com"), "A=1");
616  monster->SetCookie(GURL("http://foo2.com"), "B=1");
617  monster->SetCookie(GURL("http://b.foo1.com"), "C=1");
618  monster->SetCookie(GURL("http://foo4.com"), "D=1; domain=.foo4.com;"
619      " path=/;");  // Leading dot on the foo4
620  monster->SetCookie(GURL("http://a.foo1.com"), "E=1");
621  monster->SetCookie(GURL("http://foo1.com"), "F=1");
622  monster->SetCookie(GURL("http://foo3.com"), "G=1");
623  monster->SetCookie(GURL("http://foo4.com"), "H=1");
624
625  CookiesTreeModel cookies_model(monster,
626      new MockBrowsingDataDatabaseHelper(profile_.get()),
627      new MockBrowsingDataLocalStorageHelper(profile_.get()),
628      new MockBrowsingDataLocalStorageHelper(profile_.get()),
629      new MockBrowsingDataAppCacheHelper(profile_.get()),
630      new MockBrowsingDataIndexedDBHelper(profile_.get()));
631
632  {
633    SCOPED_TRACE("Initial State 8 cookies");
634    // CookieMonster orders cookies by pathlength, then by creation time.
635    // All paths are length 1.
636    EXPECT_STREQ("A,B,C,D,E,F,G,H", GetMonsterCookies(monster).c_str());
637    EXPECT_STREQ("F,E,C,B,A,G,D,H",
638        GetDisplayedCookies(&cookies_model).c_str());
639  }
640  DeleteStoredObjects(cookies_model.GetRoot()->GetChild(1));  // Delete "E"
641  {
642    EXPECT_STREQ("A,B,C,D,F,G,H", GetMonsterCookies(monster).c_str());
643    EXPECT_STREQ("F,C,B,A,G,D,H", GetDisplayedCookies(&cookies_model).c_str());
644  }
645}
646
647TEST_F(CookiesTreeModelTest, ContentSettings) {
648  GURL host("http://example.com/");
649  ContentSettingsPattern pattern("[*.]example.com");
650  net::CookieMonster* monster = profile_->GetCookieMonster();
651  monster->SetCookie(host, "A=1");
652
653  CookiesTreeModel cookies_model(monster,
654      new MockBrowsingDataDatabaseHelper(profile_.get()),
655      new MockBrowsingDataLocalStorageHelper(profile_.get()),
656      new MockBrowsingDataLocalStorageHelper(profile_.get()),
657      new MockBrowsingDataAppCacheHelper(profile_.get()),
658      new MockBrowsingDataIndexedDBHelper(profile_.get()));
659
660  TestingProfile profile;
661  HostContentSettingsMap* content_settings =
662      profile.GetHostContentSettingsMap();
663  StubSettingsObserver observer;
664
665  CookieTreeRootNode* root =
666      static_cast<CookieTreeRootNode*>(cookies_model.GetRoot());
667  CookieTreeOriginNode* origin = root->GetOrCreateOriginNode(host);
668
669  EXPECT_EQ(1, origin->GetChildCount());
670  EXPECT_TRUE(origin->CanCreateContentException());
671  origin->CreateContentException(
672      content_settings, CONTENT_SETTING_SESSION_ONLY);
673
674  EXPECT_EQ(2, observer.counter);
675  EXPECT_EQ(pattern, observer.last_pattern);
676  EXPECT_EQ(CONTENT_SETTING_SESSION_ONLY,
677      content_settings->GetContentSetting(
678          host, CONTENT_SETTINGS_TYPE_COOKIES, ""));
679}
680
681}  // namespace
682