15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/thread_test_helper.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browsing_data/browsing_data_helper_browsertest.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/dom_storage_context.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/test/test_utils.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserContext;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DOMStorageContext;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowsingDataHelperCallback<BrowsingDataLocalStorageHelper::LocalStorageInfo>
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestCompletionCallback;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kTestFile0[] =
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE_PATH_LITERAL("http_www.chromium.org_0.localstorage");
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOriginOfTestFile0[] = "http://www.chromium.org/";
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kTestFile1[] =
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE_PATH_LITERAL("http_www.google.com_0.localstorage");
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kTestFileInvalid[] =
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE_PATH_LITERAL("http_www.google.com_localstorage_0.foo");
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is only here to test that extension state is not listed by the helper.
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kTestFileExtension[] = FILE_PATH_LITERAL(
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "chrome-extension_behllobkkfkfnphdnhnkndlbkcpglgmj_0.localstorage");
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowsingDataLocalStorageHelperTest : public InProcessBrowserTest {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateLocalStorageFilesForTest() {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: This helper depends on details of how the dom_storage library
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // stores data in the host file system.
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath storage_path = GetLocalStoragePathForTestingProfile();
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::CreateDirectory(storage_path);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* kFilesToCreate[] = {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kTestFile0, kTestFile1, kTestFileInvalid, kTestFileExtension
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kFilesToCreate); ++i) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath file_path = storage_path.Append(kFilesToCreate[i]);
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::WriteFile(file_path, NULL, 0);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath GetLocalStoragePathForTestingProfile() {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return browser()->profile()->GetPath().AppendASCII("Local Storage");
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is notified by BrowsingDataLocalStorageHelper on the UI thread
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once it finishes fetching the local storage data.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class StopTestOnCallback {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit StopTestOnCallback(
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowsingDataLocalStorageHelper* local_storage_helper)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : local_storage_helper_(local_storage_helper) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(local_storage_helper_);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Callback(
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>&
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      local_storage_info) {
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DCHECK_CURRENTLY_ON(BrowserThread::UI);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // There's no guarantee on the order, ensure these files are there.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* const kTestHosts[] = {"www.chromium.org", "www.google.com"};
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool test_hosts_found[arraysize(kTestHosts)] = {false, false};
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(arraysize(kTestHosts), local_storage_info.size());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LocalStorageInfoList;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kTestHosts); ++i) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (LocalStorageInfoList::const_iterator info =
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           local_storage_info.begin(); info != local_storage_info.end();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ++info) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ASSERT_TRUE(info->origin_url.SchemeIs("http"));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (info->origin_url.host() == kTestHosts[i]) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ASSERT_FALSE(test_hosts_found[i]);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_hosts_found[i] = true;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kTestHosts); ++i) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(test_hosts_found[i]) << kTestHosts[i];
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowsingDataLocalStorageHelper* local_storage_helper_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, CallbackCompletes) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper(
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BrowsingDataLocalStorageHelper(browser()->profile()));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateLocalStorageFilesForTest();
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StopTestOnCallback stop_test_on_callback(local_storage_helper.get());
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  local_storage_helper->StartFetching(base::Bind(
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      &StopTestOnCallback::Callback, base::Unretained(&stop_test_on_callback)));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Blocks until StopTestOnCallback::Callback is notified.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RunMessageLoop();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, DeleteSingleFile) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper(
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BrowsingDataLocalStorageHelper(browser()->profile()));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateLocalStorageFilesForTest();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local_storage_helper->DeleteOrigin(GURL(kOriginOfTestFile0));
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::RunAllBlockingPoolTasksUntilIdle();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the file has been deleted.
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::FileEnumerator file_enumerator(
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetLocalStoragePathForTestingProfile(),
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::FileEnumerator::FILES);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_files = 0;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::FilePath file_path = file_enumerator.Next();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       !file_path.empty();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       file_path = file_enumerator.Next()) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_FALSE(base::FilePath(kTestFile0) == file_path.BaseName());
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++num_files;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, num_files);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       CannedAddLocalStorage) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL origin1("http://host1:1/");
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL origin2("http://host2:1/");
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<CannedBrowsingDataLocalStorageHelper> helper(
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CannedBrowsingDataLocalStorageHelper(browser()->profile()));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper->AddLocalStorage(origin1);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper->AddLocalStorage(origin2);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper->StartFetching(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestCompletionCallback::callback,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&callback)));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo> result =
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.result();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, result.size());
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::iterator info =
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result.begin();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(origin1, info->origin_url);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info++;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(origin2, info->origin_url);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowsingDataLocalStorageHelperTest, CannedUnique) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL origin("http://host1:1/");
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<CannedBrowsingDataLocalStorageHelper> helper(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CannedBrowsingDataLocalStorageHelper(browser()->profile()));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper->AddLocalStorage(origin);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper->AddLocalStorage(origin);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper->StartFetching(
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TestCompletionCallback::callback,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(&callback)));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo> result =
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.result();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, result.size());
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(origin, result.begin()->origin_url);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
194