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 <string>
6
7#include "base/basictypes.h"
8#include "base/callback.h"
9#include "base/file_path.h"
10#include "base/file_util.h"
11#include "base/memory/ref_counted.h"
12#include "chrome/browser/browsing_data_helper_browsertest.h"
13#include "chrome/browser/browsing_data_local_storage_helper.h"
14#include "chrome/test/in_process_browser_test.h"
15#include "chrome/test/testing_profile.h"
16#include "chrome/test/thread_test_helper.h"
17#include "chrome/test/ui_test_utils.h"
18#include "content/browser/in_process_webkit/webkit_context.h"
19#include "content/browser/in_process_webkit/webkit_thread.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
22namespace {
23typedef
24    BrowsingDataHelperCallback<BrowsingDataLocalStorageHelper::LocalStorageInfo>
25    TestCompletionCallback;
26
27const FilePath::CharType kTestFile0[] =
28    FILE_PATH_LITERAL("http_www.chromium.org_0.localstorage");
29
30const FilePath::CharType kTestFile1[] =
31    FILE_PATH_LITERAL("http_www.google.com_0.localstorage");
32
33const FilePath::CharType kTestFileInvalid[] =
34    FILE_PATH_LITERAL("http_www.google.com_localstorage_0.foo");
35
36// This is only here to test that extension state is not listed by the helper.
37const FilePath::CharType kTestFileExtension[] = FILE_PATH_LITERAL(
38    "chrome-extension_behllobkkfkfnphdnhnkndlbkcpglgmj_0.localstorage");
39
40class BrowsingDataLocalStorageHelperTest : public InProcessBrowserTest {
41 protected:
42  void CreateLocalStorageFilesForTest() {
43    FilePath storage_path = GetLocalStoragePathForTestingProfile();
44    file_util::CreateDirectory(storage_path);
45    const FilePath::CharType* kFilesToCreate[] = {
46        kTestFile0, kTestFile1, kTestFileInvalid, kTestFileExtension
47    };
48    for (size_t i = 0; i < arraysize(kFilesToCreate); ++i) {
49      FilePath file_path = storage_path.Append(kFilesToCreate[i]);
50      file_util::WriteFile(file_path, NULL, 0);
51    }
52  }
53
54  FilePath GetLocalStoragePathForTestingProfile() {
55    FilePath storage_path(testing_profile_.GetPath());
56    storage_path = storage_path.Append(
57        DOMStorageContext::kLocalStorageDirectory);
58    return storage_path;
59  }
60  TestingProfile testing_profile_;
61};
62
63// This class is notified by BrowsingDataLocalStorageHelper on the UI thread
64// once it finishes fetching the local storage data.
65class StopTestOnCallback {
66 public:
67  explicit StopTestOnCallback(
68      BrowsingDataLocalStorageHelper* local_storage_helper)
69      : local_storage_helper_(local_storage_helper) {
70    DCHECK(local_storage_helper_);
71  }
72
73  void Callback(
74      const std::vector<BrowsingDataLocalStorageHelper::LocalStorageInfo>&
75      local_storage_info) {
76    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
77    // There's no guarantee on the order, ensure these files are there.
78    const char* const kTestHosts[] = {"www.chromium.org", "www.google.com"};
79    bool test_hosts_found[arraysize(kTestHosts)] = {false, false};
80    ASSERT_EQ(arraysize(kTestHosts), local_storage_info.size());
81    for (size_t i = 0; i < arraysize(kTestHosts); ++i) {
82      for (size_t j = 0; j < local_storage_info.size(); ++j) {
83        BrowsingDataLocalStorageHelper::LocalStorageInfo info =
84            local_storage_info.at(j);
85        ASSERT_EQ("http", info.protocol);
86        if (info.host == kTestHosts[i]) {
87          ASSERT_FALSE(test_hosts_found[i]);
88          test_hosts_found[i] = true;
89        }
90      }
91    }
92    for (size_t i = 0; i < arraysize(kTestHosts); ++i) {
93      ASSERT_TRUE(test_hosts_found[i]) << kTestHosts[i];
94    }
95    MessageLoop::current()->Quit();
96  }
97
98 private:
99  BrowsingDataLocalStorageHelper* local_storage_helper_;
100};
101
102IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, CallbackCompletes) {
103  scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper(
104      new BrowsingDataLocalStorageHelper(&testing_profile_));
105  CreateLocalStorageFilesForTest();
106  StopTestOnCallback stop_test_on_callback(local_storage_helper);
107  local_storage_helper->StartFetching(
108      NewCallback(&stop_test_on_callback, &StopTestOnCallback::Callback));
109  // Blocks until StopTestOnCallback::Callback is notified.
110  ui_test_utils::RunMessageLoop();
111}
112
113IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, DeleteSingleFile) {
114  scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper(
115      new BrowsingDataLocalStorageHelper(&testing_profile_));
116  CreateLocalStorageFilesForTest();
117  local_storage_helper->DeleteLocalStorageFile(
118      GetLocalStoragePathForTestingProfile().Append(FilePath(kTestFile0)));
119  scoped_refptr<ThreadTestHelper> wait_for_webkit_thread(
120      new ThreadTestHelper(BrowserThread::WEBKIT));
121  ASSERT_TRUE(wait_for_webkit_thread->Run());
122  // Ensure the file has been deleted.
123  file_util::FileEnumerator file_enumerator(
124      GetLocalStoragePathForTestingProfile(),
125      false,
126      file_util::FileEnumerator::FILES);
127  int num_files = 0;
128  for (FilePath file_path = file_enumerator.Next();
129       !file_path.empty();
130       file_path = file_enumerator.Next()) {
131    ASSERT_FALSE(FilePath(kTestFile0) == file_path.BaseName());
132    ++num_files;
133  }
134  ASSERT_EQ(3, num_files);
135}
136
137IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest,
138                       CannedAddLocalStorage) {
139  const GURL origin1("http://host1:1/");
140  const GURL origin2("http://host2:1/");
141  const FilePath::CharType file1[] =
142      FILE_PATH_LITERAL("http_host1_1.localstorage");
143  const FilePath::CharType file2[] =
144      FILE_PATH_LITERAL("http_host2_1.localstorage");
145
146  scoped_refptr<CannedBrowsingDataLocalStorageHelper> helper(
147      new CannedBrowsingDataLocalStorageHelper(&testing_profile_));
148  helper->AddLocalStorage(origin1);
149  helper->AddLocalStorage(origin2);
150
151  TestCompletionCallback callback;
152  helper->StartFetching(
153      NewCallback(&callback, &TestCompletionCallback::callback));
154
155  std::vector<BrowsingDataLocalStorageHelper::LocalStorageInfo> result =
156      callback.result();
157
158  ASSERT_EQ(2u, result.size());
159  EXPECT_EQ(FilePath(file1).value(), result[0].file_path.BaseName().value());
160  EXPECT_EQ(FilePath(file2).value(), result[1].file_path.BaseName().value());
161}
162
163IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, CannedUnique) {
164  const GURL origin("http://host1:1/");
165  const FilePath::CharType file[] =
166      FILE_PATH_LITERAL("http_host1_1.localstorage");
167
168  scoped_refptr<CannedBrowsingDataLocalStorageHelper> helper(
169      new CannedBrowsingDataLocalStorageHelper(&testing_profile_));
170  helper->AddLocalStorage(origin);
171  helper->AddLocalStorage(origin);
172
173  TestCompletionCallback callback;
174  helper->StartFetching(
175      NewCallback(&callback, &TestCompletionCallback::callback));
176
177  std::vector<BrowsingDataLocalStorageHelper::LocalStorageInfo> result =
178      callback.result();
179
180  ASSERT_EQ(1u, result.size());
181  EXPECT_EQ(FilePath(file).value(), result[0].file_path.BaseName().value());
182}
183}  // namespace
184