history_data_store_unittest.cc revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
1// Copyright 2013 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 "base/basictypes.h" 6#include "base/bind.h" 7#include "base/file_util.h" 8#include "base/files/scoped_temp_dir.h" 9#include "base/memory/ref_counted.h" 10#include "base/message_loop/message_loop.h" 11#include "base/run_loop.h" 12#include "chrome/browser/ui/app_list/search/history_data.h" 13#include "chrome/browser/ui/app_list/search/history_data_store.h" 14#include "content/public/test/test_browser_thread.h" 15#include "testing/gtest/include/gtest/gtest.h" 16 17namespace app_list { 18namespace test { 19 20namespace { 21 22std::string GetDataContent(const HistoryData::Data& data) { 23 std::string str = std::string("p:") + data.primary + ";s:"; 24 bool first = true; 25 for (HistoryData::SecondaryDeque::const_iterator it = data.secondary.begin(); 26 it != data.secondary.end(); ++it) { 27 if (first) 28 first = false; 29 else 30 str += ','; 31 32 str += *it; 33 } 34 35 return str; 36} 37 38} // namespace 39 40class HistoryDataStoreTest : public testing::Test { 41 public: 42 HistoryDataStoreTest() 43 : ui_thread_(content::BrowserThread::UI, &message_loop_) {} 44 virtual ~HistoryDataStoreTest() {} 45 46 // testing::Test overrides: 47 virtual void SetUp() OVERRIDE { 48 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 49 } 50 virtual void TearDown() OVERRIDE { 51 // Release |store_| while ui loop is still running. 52 store_ = NULL; 53 } 54 55 void OpenStore(const std::string& file_name) { 56 data_file_ = temp_dir_.path().AppendASCII(file_name); 57 store_ = new HistoryDataStore(data_file_); 58 Load(); 59 } 60 61 void Flush() { 62 store_->Flush(HistoryDataStore::OnFlushedCallback()); 63 } 64 65 void Load() { 66 store_->Load(base::Bind(&HistoryDataStoreTest::OnRead, 67 base::Unretained(this))); 68 run_loop_.reset(new base::RunLoop); 69 run_loop_->Run(); 70 run_loop_.reset(); 71 } 72 73 void WriteDataFile(const std::string& file_name, 74 const std::string& data) { 75 file_util::WriteFile( 76 temp_dir_.path().AppendASCII(file_name), data.c_str(), data.size()); 77 } 78 79 HistoryDataStore* store() { return store_.get(); } 80 const HistoryData::Associations& associations() const { 81 return associations_; 82 } 83 84 private: 85 void OnRead(scoped_ptr<HistoryData::Associations> associations) { 86 associations_.clear(); 87 if (associations) 88 associations->swap(associations_); 89 90 if (run_loop_) 91 run_loop_->Quit(); 92 } 93 94 base::MessageLoopForUI message_loop_; 95 content::TestBrowserThread ui_thread_; 96 base::ScopedTempDir temp_dir_; 97 base::FilePath data_file_; 98 scoped_ptr<base::RunLoop> run_loop_; 99 100 scoped_refptr<HistoryDataStore> store_; 101 HistoryData::Associations associations_; 102 103 DISALLOW_COPY_AND_ASSIGN(HistoryDataStoreTest); 104}; 105 106TEST_F(HistoryDataStoreTest, NewFile) { 107 OpenStore("new_data_file.json"); 108 EXPECT_TRUE(associations().empty()); 109} 110 111TEST_F(HistoryDataStoreTest, BadFile) { 112 const char kDataFile[] = "invalid_data_file"; 113 WriteDataFile(kDataFile, "invalid json"); 114 115 OpenStore(kDataFile); 116 EXPECT_TRUE(associations().empty()); 117} 118 119TEST_F(HistoryDataStoreTest, GoodFile) { 120 const char kDataFile[] = "good_data_file.json"; 121 const char kGoodJson[] = "{" 122 "\"version\": \"1\"," 123 "\"associations\": {" 124 "\"query\": {" 125 "\"p\": \"primary\"," 126 "\"s\": [\"secondary1\",\"secondary2\"]," 127 "\"t\": \"123\"" 128 "}" 129 "}" 130 "}"; 131 WriteDataFile(kDataFile, kGoodJson); 132 133 OpenStore(kDataFile); 134 EXPECT_FALSE(associations().empty()); 135 EXPECT_EQ(1u, associations().size()); 136 137 HistoryData::Associations::const_iterator it = associations().find("query"); 138 EXPECT_TRUE(it != associations().end()); 139 EXPECT_EQ("p:primary;s:secondary1,secondary2", GetDataContent(it->second)); 140} 141 142TEST_F(HistoryDataStoreTest, Change) { 143 const char kDataFile[] = "change_test.json"; 144 145 OpenStore(kDataFile); 146 EXPECT_TRUE(associations().empty()); 147 148 const char kQuery[] = "query"; 149 const base::Time now = base::Time::Now(); 150 store()->SetPrimary(kQuery, "primary"); 151 store()->SetUpdateTime(kQuery, now); 152 Flush(); 153 Load(); 154 EXPECT_EQ(1u, associations().size()); 155 HistoryData::Associations::const_iterator it = associations().find(kQuery); 156 EXPECT_TRUE(it != associations().end()); 157 EXPECT_EQ("primary", it->second.primary); 158 EXPECT_EQ(0u, it->second.secondary.size()); 159 EXPECT_EQ(now, it->second.update_time); 160 161 HistoryData::SecondaryDeque secondary; 162 secondary.push_back("s1"); 163 secondary.push_back("s2"); 164 store()->SetSecondary(kQuery, secondary); 165 Flush(); 166 Load(); 167 EXPECT_EQ(1u, associations().size()); 168 it = associations().find(kQuery); 169 EXPECT_TRUE(it != associations().end()); 170 EXPECT_EQ("p:primary;s:s1,s2", GetDataContent(it->second)); 171 EXPECT_EQ(now, it->second.update_time); 172 173 store()->Delete(kQuery); 174 Flush(); 175 Load(); 176 EXPECT_TRUE(associations().empty()); 177} 178 179} // namespace test 180} // namespace app_list 181