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