OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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 "components/download/internal/download_store.h" |
| 6 |
| 7 #include <algorithm> |
| 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/callback.h" |
| 11 #include "base/guid.h" |
| 12 #include "base/memory/ptr_util.h" |
| 13 #include "components/download/internal/entry.h" |
| 14 #include "components/download/internal/proto/entry.pb.h" |
| 15 #include "components/download/internal/proto_conversions.h" |
| 16 #include "components/download/internal/test/entry_utils.h" |
| 17 #include "components/leveldb_proto/testing/fake_db.h" |
| 18 #include "testing/gmock/include/gmock/gmock.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" |
| 20 |
| 21 using testing::_; |
| 22 |
| 23 namespace download { |
| 24 |
| 25 class DownloadStoreTest : public testing::Test { |
| 26 public: |
| 27 DownloadStoreTest() : db_(nullptr) {} |
| 28 |
| 29 ~DownloadStoreTest() override = default; |
| 30 |
| 31 void CreateDatabase() { |
| 32 auto db = base::MakeUnique<leveldb_proto::test::FakeDB<protodb::Entry>>( |
| 33 &db_entries_); |
| 34 db_ = db.get(); |
| 35 store_.reset(new DownloadStore( |
| 36 base::FilePath(FILE_PATH_LITERAL("/test/db/fakepath")), std::move(db))); |
| 37 } |
| 38 |
| 39 void InitCallback(std::vector<Entry>* loaded_entries, |
| 40 bool success, |
| 41 std::unique_ptr<std::vector<Entry>> entries) { |
| 42 loaded_entries->swap(*entries); |
| 43 } |
| 44 |
| 45 void LoadCallback(std::vector<protodb::Entry>* loaded_entries, |
| 46 bool success, |
| 47 std::unique_ptr<std::vector<protodb::Entry>> entries) { |
| 48 loaded_entries->swap(*entries); |
| 49 } |
| 50 |
| 51 MOCK_METHOD1(StoreCallback, void(bool)); |
| 52 |
| 53 void PrepopulateSampleEntries() { |
| 54 Entry item1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()); |
| 55 Entry item2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()); |
| 56 db_entries_.insert( |
| 57 std::make_pair(item1.guid, ProtoConversions::EntryToProto(item1))); |
| 58 db_entries_.insert( |
| 59 std::make_pair(item2.guid, ProtoConversions::EntryToProto(item2))); |
| 60 } |
| 61 |
| 62 protected: |
| 63 std::map<std::string, protodb::Entry> db_entries_; |
| 64 leveldb_proto::test::FakeDB<protodb::Entry>* db_; |
| 65 std::unique_ptr<DownloadStore> store_; |
| 66 |
| 67 DISALLOW_COPY_AND_ASSIGN(DownloadStoreTest); |
| 68 }; |
| 69 |
| 70 TEST_F(DownloadStoreTest, Initialize) { |
| 71 PrepopulateSampleEntries(); |
| 72 CreateDatabase(); |
| 73 ASSERT_FALSE(store_->IsInitialized()); |
| 74 |
| 75 std::vector<Entry> preloaded_entries; |
| 76 store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback, |
| 77 base::Unretained(this), &preloaded_entries)); |
| 78 db_->InitCallback(true); |
| 79 db_->LoadCallback(true); |
| 80 |
| 81 ASSERT_TRUE(store_->IsInitialized()); |
| 82 ASSERT_EQ(2u, preloaded_entries.size()); |
| 83 } |
| 84 |
| 85 TEST_F(DownloadStoreTest, Update) { |
| 86 PrepopulateSampleEntries(); |
| 87 CreateDatabase(); |
| 88 |
| 89 std::vector<Entry> preloaded_entries; |
| 90 store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback, |
| 91 base::Unretained(this), &preloaded_entries)); |
| 92 db_->InitCallback(true); |
| 93 db_->LoadCallback(true); |
| 94 ASSERT_TRUE(store_->IsInitialized()); |
| 95 ASSERT_EQ(2u, preloaded_entries.size()); |
| 96 |
| 97 Entry item1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()); |
| 98 Entry item2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()); |
| 99 EXPECT_CALL(*this, StoreCallback(true)).Times(2); |
| 100 store_->Update(item1, base::Bind(&DownloadStoreTest::StoreCallback, |
| 101 base::Unretained(this))); |
| 102 db_->UpdateCallback(true); |
| 103 store_->Update(item2, base::Bind(&DownloadStoreTest::StoreCallback, |
| 104 base::Unretained(this))); |
| 105 db_->UpdateCallback(true); |
| 106 |
| 107 // Query the database directly and check for the entry. |
| 108 auto protos = base::MakeUnique<std::vector<protodb::Entry>>(); |
| 109 db_->LoadEntries(base::Bind(&DownloadStoreTest::LoadCallback, |
| 110 base::Unretained(this), protos.get())); |
| 111 db_->LoadCallback(true); |
| 112 ASSERT_EQ(4u, protos->size()); |
| 113 ASSERT_TRUE(test::CompareEntryList( |
| 114 {preloaded_entries[0], preloaded_entries[1], item1, item2}, |
| 115 *ProtoConversions::EntryVectorFromProto(std::move(protos)))); |
| 116 } |
| 117 |
| 118 TEST_F(DownloadStoreTest, Remove) { |
| 119 PrepopulateSampleEntries(); |
| 120 CreateDatabase(); |
| 121 |
| 122 std::vector<Entry> preloaded_entries; |
| 123 store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback, |
| 124 base::Unretained(this), &preloaded_entries)); |
| 125 db_->InitCallback(true); |
| 126 db_->LoadCallback(true); |
| 127 ASSERT_EQ(2u, preloaded_entries.size()); |
| 128 |
| 129 // Remove the entry. |
| 130 EXPECT_CALL(*this, StoreCallback(true)).Times(1); |
| 131 store_->Remove( |
| 132 preloaded_entries[0].guid, |
| 133 base::Bind(&DownloadStoreTest::StoreCallback, base::Unretained(this))); |
| 134 db_->UpdateCallback(true); |
| 135 |
| 136 // Query the database directly and check for the entry removed. |
| 137 auto protos = base::MakeUnique<std::vector<protodb::Entry>>(); |
| 138 db_->LoadEntries(base::Bind(&DownloadStoreTest::LoadCallback, |
| 139 base::Unretained(this), protos.get())); |
| 140 db_->LoadCallback(true); |
| 141 ASSERT_EQ(1u, protos->size()); |
| 142 ASSERT_TRUE(test::CompareEntryList( |
| 143 {preloaded_entries[1]}, |
| 144 *ProtoConversions::EntryVectorFromProto(std::move(protos)))); |
| 145 } |
| 146 |
| 147 TEST_F(DownloadStoreTest, InitializeFailed) { |
| 148 PrepopulateSampleEntries(); |
| 149 CreateDatabase(); |
| 150 |
| 151 std::vector<Entry> preloaded_entries; |
| 152 store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback, |
| 153 base::Unretained(this), &preloaded_entries)); |
| 154 db_->InitCallback(false); |
| 155 ASSERT_FALSE(store_->IsInitialized()); |
| 156 ASSERT_TRUE(preloaded_entries.empty()); |
| 157 } |
| 158 |
| 159 TEST_F(DownloadStoreTest, InitialLoadFailed) { |
| 160 PrepopulateSampleEntries(); |
| 161 CreateDatabase(); |
| 162 |
| 163 std::vector<Entry> preloaded_entries; |
| 164 store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback, |
| 165 base::Unretained(this), &preloaded_entries)); |
| 166 db_->InitCallback(true); |
| 167 db_->LoadCallback(false); |
| 168 ASSERT_FALSE(store_->IsInitialized()); |
| 169 ASSERT_TRUE(preloaded_entries.empty()); |
| 170 } |
| 171 |
| 172 TEST_F(DownloadStoreTest, UnsuccessfulUpdateOrRemove) { |
| 173 Entry item1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()); |
| 174 CreateDatabase(); |
| 175 |
| 176 std::vector<Entry> entries; |
| 177 store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback, |
| 178 base::Unretained(this), &entries)); |
| 179 db_->InitCallback(true); |
| 180 db_->LoadCallback(true); |
| 181 ASSERT_TRUE(store_->IsInitialized()); |
| 182 ASSERT_TRUE(entries.empty()); |
| 183 |
| 184 // Update failed. |
| 185 EXPECT_CALL(*this, StoreCallback(false)).Times(1); |
| 186 store_->Update(item1, base::Bind(&DownloadStoreTest::StoreCallback, |
| 187 base::Unretained(this))); |
| 188 db_->UpdateCallback(false); |
| 189 |
| 190 // Remove failed. |
| 191 EXPECT_CALL(*this, StoreCallback(false)).Times(1); |
| 192 store_->Remove(item1.guid, base::Bind(&DownloadStoreTest::StoreCallback, |
| 193 base::Unretained(this))); |
| 194 db_->UpdateCallback(false); |
| 195 } |
| 196 |
| 197 TEST_F(DownloadStoreTest, AddThenRemove) { |
| 198 CreateDatabase(); |
| 199 |
| 200 std::vector<Entry> entries; |
| 201 store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback, |
| 202 base::Unretained(this), &entries)); |
| 203 db_->InitCallback(true); |
| 204 db_->LoadCallback(true); |
| 205 ASSERT_TRUE(entries.empty()); |
| 206 |
| 207 Entry item1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()); |
| 208 Entry item2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()); |
| 209 EXPECT_CALL(*this, StoreCallback(true)).Times(2); |
| 210 store_->Update(item1, base::Bind(&DownloadStoreTest::StoreCallback, |
| 211 base::Unretained(this))); |
| 212 db_->UpdateCallback(true); |
| 213 store_->Update(item2, base::Bind(&DownloadStoreTest::StoreCallback, |
| 214 base::Unretained(this))); |
| 215 db_->UpdateCallback(true); |
| 216 |
| 217 // Query the database directly and check for the entry. |
| 218 auto protos = base::MakeUnique<std::vector<protodb::Entry>>(); |
| 219 db_->LoadEntries(base::Bind(&DownloadStoreTest::LoadCallback, |
| 220 base::Unretained(this), protos.get())); |
| 221 db_->LoadCallback(true); |
| 222 ASSERT_EQ(2u, protos->size()); |
| 223 |
| 224 // Remove the entry. |
| 225 EXPECT_CALL(*this, StoreCallback(true)).Times(1); |
| 226 store_->Remove(item1.guid, base::Bind(&DownloadStoreTest::StoreCallback, |
| 227 base::Unretained(this))); |
| 228 db_->UpdateCallback(true); |
| 229 |
| 230 // Query the database directly and check for the entry removed. |
| 231 protos->clear(); |
| 232 db_->LoadEntries(base::Bind(&DownloadStoreTest::LoadCallback, |
| 233 base::Unretained(this), protos.get())); |
| 234 db_->LoadCallback(true); |
| 235 ASSERT_EQ(1u, protos->size()); |
| 236 ASSERT_TRUE(test::CompareEntryList( |
| 237 {item2}, *ProtoConversions::EntryVectorFromProto(std::move(protos)))); |
| 238 } |
| 239 |
| 240 } // namespace download |
OLD | NEW |