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