190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/basictypes.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/bind.h" 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/ref_counted.h" 109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/run_loop.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/app_list/search/common/dictionary_data_store.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/history_data.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/history_data_store.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/test/test_browser_thread.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace app_list { 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace test { 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string GetDataContent(const HistoryData::Data& data) { 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string str = std::string("p:") + data.primary + ";s:"; 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool first = true; 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (HistoryData::SecondaryDeque::const_iterator it = data.secondary.begin(); 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != data.secondary.end(); ++it) { 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (first) 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) first = false; 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) str += ','; 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) str += *it; 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return str; 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class HistoryDataStoreTest : public testing::Test { 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HistoryDataStoreTest() 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : ui_thread_(content::BrowserThread::UI, &message_loop_) {} 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~HistoryDataStoreTest() {} 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // testing::Test overrides: 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void SetUp() OVERRIDE { 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void TearDown() OVERRIDE { 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Release |store_| while ui loop is still running. 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) store_ = NULL; 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void OpenStore(const std::string& file_name) { 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_file_ = temp_dir_.path().AppendASCII(file_name); 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci store_ = new HistoryDataStore(scoped_refptr<DictionaryDataStore>( 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new DictionaryDataStore(data_file_))); 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Load(); 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void Flush() { 648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) store_->Flush(DictionaryDataStore::OnFlushedCallback()); 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void Load() { 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) store_->Load(base::Bind(&HistoryDataStoreTest::OnRead, 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(this))); 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) run_loop_.reset(new base::RunLoop); 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) run_loop_->Run(); 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) run_loop_.reset(); 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void WriteDataFile(const std::string& file_name, 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& data) { 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WriteFile( 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) temp_dir_.path().AppendASCII(file_name), data.c_str(), data.size()); 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HistoryDataStore* store() { return store_.get(); } 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const HistoryData::Associations& associations() const { 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return associations_; 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void OnRead(scoped_ptr<HistoryData::Associations> associations) { 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) associations_.clear(); 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (associations) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) associations->swap(associations_); 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (run_loop_) 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) run_loop_->Quit(); 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::MessageLoopForUI message_loop_; 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::TestBrowserThread ui_thread_; 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ScopedTempDir temp_dir_; 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath data_file_; 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<base::RunLoop> run_loop_; 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<HistoryDataStore> store_; 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HistoryData::Associations associations_; 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HistoryDataStoreTest); 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(HistoryDataStoreTest, NewFile) { 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OpenStore("new_data_file.json"); 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(associations().empty()); 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(HistoryDataStoreTest, BadFile) { 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kDataFile[] = "invalid_data_file"; 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteDataFile(kDataFile, "invalid json"); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OpenStore(kDataFile); 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(associations().empty()); 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(HistoryDataStoreTest, GoodFile) { 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kDataFile[] = "good_data_file.json"; 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kGoodJson[] = "{" 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "\"version\": \"1\"," 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "\"associations\": {" 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "\"query\": {" 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "\"p\": \"primary\"," 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "\"s\": [\"secondary1\",\"secondary2\"]," 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "\"t\": \"123\"" 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "}" 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "}" 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "}"; 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteDataFile(kDataFile, kGoodJson); 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OpenStore(kDataFile); 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(associations().empty()); 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(1u, associations().size()); 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HistoryData::Associations::const_iterator it = associations().find("query"); 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(it != associations().end()); 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ("p:primary;s:secondary1,secondary2", GetDataContent(it->second)); 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(HistoryDataStoreTest, Change) { 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kDataFile[] = "change_test.json"; 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OpenStore(kDataFile); 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(associations().empty()); 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kQuery[] = "query"; 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Time now = base::Time::Now(); 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) store()->SetPrimary(kQuery, "primary"); 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) store()->SetUpdateTime(kQuery, now); 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Flush(); 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Load(); 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(1u, associations().size()); 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HistoryData::Associations::const_iterator it = associations().find(kQuery); 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(it != associations().end()); 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ("primary", it->second.primary); 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0u, it->second.secondary.size()); 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(now, it->second.update_time); 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HistoryData::SecondaryDeque secondary; 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) secondary.push_back("s1"); 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) secondary.push_back("s2"); 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) store()->SetSecondary(kQuery, secondary); 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Flush(); 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Load(); 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(1u, associations().size()); 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it = associations().find(kQuery); 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(it != associations().end()); 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ("p:primary;s:s1,s2", GetDataContent(it->second)); 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(now, it->second.update_time); 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) store()->Delete(kQuery); 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Flush(); 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Load(); 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(associations().empty()); 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace test 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace app_list 183