Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: components/download/internal/model_impl_unittest.cc

Issue 2870753003: Add a Model to the download component. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/model_impl.h"
6
7 #include "base/bind.h"
8 #include "base/guid.h"
9 #include "base/test/test_mock_time_task_runner.h"
10 #include "base/threading/thread_task_runner_handle.h"
11 #include "components/download/internal/entry.h"
12 #include "components/download/internal/noop_store.h"
13 #include "components/download/internal/test_support/mock_model_client.h"
14 #include "components/download/internal/test_support/mock_store.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using testing::Return;
19 using testing::_;
20
21 namespace download {
22 namespace {
23
24 class BadStore : public Store {
25 public:
26 BadStore() = default;
27 ~BadStore() override = default;
28
29 // Store implementation.
30 MOCK_METHOD0(IsInitialized, bool());
31 void Initialize(const InitCallback& callback) override {
32 base::ThreadTaskRunnerHandle::Get()->PostTask(
33 FROM_HERE, base::Bind(callback, false, nullptr));
34 }
35
36 void Destroy(const StoreCallback& callback) override {
37 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
38 base::Bind(callback, false));
39 }
40
41 void Update(const Entry& entry, const StoreCallback& callback) override {
42 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
43 base::Bind(callback, false));
44 }
45
46 void Remove(const std::string& guid, const StoreCallback& callback) override {
47 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
48 base::Bind(callback, false));
49 }
50 };
51
52 struct CompareByGuid {
53 bool operator()(const Entry* a, const Entry* b) const {
54 return a->guid < b->guid;
55 }
56 };
57
58 template <typename T>
59 bool VectorContentsEq(const std::vector<T>& list1,
60 const std::vector<T>& list2) {
61 if (list1.size() != list2.size())
62 return false;
63
64 std::map<T, int, CompareByGuid> occurance_counts;
65 for (auto it = list1.begin(); it != list1.end(); it++)
66 occurance_counts[*it]++;
67
68 for (auto it = list2.begin(); it != list2.end(); it++)
69 occurance_counts[*it]--;
70
71 for (auto it = occurance_counts.begin(); it != occurance_counts.end(); it++) {
72 if (it->second != 0)
73 return false;
74 }
75
76 return true;
Peter Beverloo 2017/05/10 12:44:45 I think you could *significantly* simplify this (a
David Trainor- moved to gerrit 2017/05/15 15:59:51 O_o! Yeah way better :).
77 }
78
79 Entry BuildEntry(DownloadClient client, const std::string& guid) {
80 Entry entry;
81 entry.client = client;
82 entry.guid = guid;
83
84 return entry;
85 }
86
87 bool CompareEntryBasics(const Entry& expected, const Entry* const actual) {
88 return actual != nullptr && expected.client == actual->client &&
89 expected.guid == actual->guid && expected.state == actual->state;
90 }
91
92 class ModelImplStoreTestBase : public testing::Test {
93 public:
94 ModelImplStoreTestBase(Store* store)
95 : task_runner_(new base::TestMockTimeTaskRunner),
Peter Beverloo 2017/05/10 12:44:45 qq: would TestSimpleTaskRunner suffice? why is tim
David Trainor- moved to gerrit 2017/05/15 15:59:51 Good call. Done.
96 handle_(task_runner_),
97 store_(store),
98 model_(base::MakeUnique<ModelImpl>(&client_,
99 base::WrapUnique<Store>(store))) {}
100
101 ~ModelImplStoreTestBase() override = default;
102
103 protected:
104 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
105 base::ThreadTaskRunnerHandle handle_;
106 MockModelClient client_;
107 Store* store_;
108 std::unique_ptr<ModelImpl> model_;
109 };
110
111 class ModelImplNoopStoreTest : public ModelImplStoreTestBase {
112 public:
113 ModelImplNoopStoreTest() : ModelImplStoreTestBase(new NoopStore) {}
114 };
115
116 class ModelImplMockStoreTest : public ModelImplStoreTestBase {
117 public:
118 ModelImplMockStoreTest()
119 : ModelImplStoreTestBase(new MockStore),
120 mocked_store_(static_cast<MockStore*>(store_)) {}
121
122 protected:
123 MockStore* mocked_store_;
124 };
125
126 class ModelImplBadStoreTest : public ModelImplStoreTestBase {
127 public:
128 ModelImplBadStoreTest()
129 : ModelImplStoreTestBase(new BadStore),
130 mocked_store_(static_cast<BadStore*>(store_)) {}
131
132 protected:
133 BadStore* mocked_store_;
134 };
135
136 TEST_F(ModelImplNoopStoreTest, Lifecycle) {
137 EXPECT_CALL(client_, OnInitialized(true)).Times(1);
138 model_->Initialize();
139 task_runner_->RunUntilIdle();
140
141 EXPECT_CALL(client_, OnDestroyed(true)).Times(1);
142 model_->Destroy();
143 task_runner_->RunUntilIdle();
144 }
145
146 TEST_F(ModelImplNoopStoreTest, Add) {
147 EXPECT_CALL(client_, OnInitialized(true)).Times(1);
148 model_->Initialize();
149 task_runner_->RunUntilIdle();
150
151 std::string guid1 = base::GenerateGUID();
152 std::string guid2 = base::GenerateGUID();
153
154 DownloadClient client1 = DownloadClient::TEST_1;
155 DownloadClient client2 = DownloadClient::TEST_2;
156
157 Entry entry1 = BuildEntry(client1, guid1);
158 Entry entry2 = BuildEntry(client2, guid2);
159
160 EXPECT_CALL(client_, OnItemAdded(true, client1, guid1)).Times(1);
161 EXPECT_CALL(client_, OnItemAdded(true, client2, guid2)).Times(1);
162
163 EXPECT_EQ(nullptr, model_->Get(guid1));
164 EXPECT_EQ(nullptr, model_->Get(guid2));
165
166 model_->Add(entry1);
167 model_->Add(entry2);
168
169 // Validate that the new item is available immediately after adding.
170 EXPECT_TRUE(CompareEntryBasics(entry1, model_->Get(guid1)));
171 EXPECT_TRUE(CompareEntryBasics(entry2, model_->Get(guid2)));
172
173 task_runner_->RunUntilIdle();
174 }
175
176 TEST_F(ModelImplNoopStoreTest, Update) {
177 EXPECT_CALL(client_, OnInitialized(true)).Times(1);
178 model_->Initialize();
179 task_runner_->RunUntilIdle();
180
181 std::string guid = base::GenerateGUID();
182 DownloadClient client = DownloadClient::TEST_1;
183
184 Entry entry1 = BuildEntry(client, guid);
185 Entry entry2(entry1);
186
187 entry1.state = Entry::State::NEW;
188 entry2.state = Entry::State::ACTIVE;
189
190 EXPECT_CALL(client_, OnItemAdded(true, client, guid)).Times(1);
191
192 EXPECT_EQ(nullptr, model_->Get(guid));
193
194 model_->Add(entry1);
195 task_runner_->RunUntilIdle();
196
197 EXPECT_TRUE(CompareEntryBasics(entry1, model_->Get(guid)));
198
199 model_->Update(entry2);
200
201 // Validate that the updated item is available immediately after updating.
202 EXPECT_TRUE(CompareEntryBasics(entry2, model_->Get(guid)));
203
204 task_runner_->RunUntilIdle();
205 }
206
207 TEST_F(ModelImplNoopStoreTest, Remove) {
208 EXPECT_CALL(client_, OnInitialized(true)).Times(1);
209 model_->Initialize();
210 task_runner_->RunUntilIdle();
211
212 std::string guid = base::GenerateGUID();
213
214 DownloadClient client = DownloadClient::TEST_1;
215
216 Entry entry = BuildEntry(client, guid);
217
218 EXPECT_CALL(client_, OnItemAdded(true, client, guid)).Times(1);
219
220 EXPECT_EQ(nullptr, model_->Get(guid));
221
222 model_->Add(entry);
223 task_runner_->RunUntilIdle();
224
225 EXPECT_TRUE(CompareEntryBasics(entry, model_->Get(guid)));
226
227 model_->Remove(guid);
228
229 // Validate that the removed item is unavailable immediately after updating.
230 EXPECT_EQ(nullptr, model_->Get(guid));
231
232 task_runner_->RunUntilIdle();
233 }
234
235 TEST_F(ModelImplNoopStoreTest, Get) {
236 model_->Initialize();
237 task_runner_->RunUntilIdle();
238
239 std::string guid = base::GenerateGUID();
240 Entry entry = BuildEntry(DownloadClient::TEST_1, guid);
241
242 model_->Add(entry);
243 task_runner_->RunUntilIdle();
244
245 EXPECT_TRUE(CompareEntryBasics(entry, model_->Get(guid)));
246 }
247
248 TEST_F(ModelImplNoopStoreTest, PeekEntries) {
249 model_->Initialize();
250 task_runner_->RunUntilIdle();
251
252 std::string guid1 = base::GenerateGUID();
253 std::string guid2 = base::GenerateGUID();
254 std::string guid3 = base::GenerateGUID();
255
256 Entry entry1 = BuildEntry(DownloadClient::TEST_1, guid1);
257 Entry entry2 = BuildEntry(DownloadClient::TEST_2, guid2);
258 Entry entry3 = BuildEntry(DownloadClient::TEST_3, guid3);
259
260 Model::EntryList entries = {&entry1, &entry2, &entry3};
261
262 model_->Add(entry1);
263 model_->Add(entry2);
264 model_->Add(entry3);
265 task_runner_->RunUntilIdle();
266
267 EXPECT_TRUE(VectorContentsEq(entries, model_->PeekEntries()));
268 }
269
270 TEST_F(ModelImplMockStoreTest, TestStoreCalls) {
271 {
272 EXPECT_CALL(*mocked_store_, IsInitialized()).WillRepeatedly(Return(false));
273 EXPECT_CALL(*mocked_store_, Initialize(_)).Times(1);
274 model_->Initialize();
275 }
276
277 EXPECT_CALL(*mocked_store_, IsInitialized()).WillRepeatedly(Return(true));
278
279 std::string guid = base::GenerateGUID();
280 Entry entry = BuildEntry(DownloadClient::TEST_1, guid);
281
282 EXPECT_CALL(*mocked_store_, Update(_, _)).Times(2);
283 EXPECT_CALL(*mocked_store_, Remove(guid, _)).Times(1);
284 EXPECT_CALL(*mocked_store_, Destroy(_)).Times(1);
285
286 model_->Add(entry);
287 model_->Update(entry);
288 model_->Remove(guid);
289 model_->Destroy();
290 }
291
292 TEST_F(ModelImplBadStoreTest, ModelUpdatesFailed) {
293 {
294 EXPECT_CALL(*mocked_store_, IsInitialized()).WillRepeatedly(Return(false));
295 EXPECT_CALL(client_, OnInitialized(false)).Times(1);
296 model_->Initialize();
297 }
298
299 EXPECT_CALL(*mocked_store_, IsInitialized()).WillRepeatedly(Return(true));
300
301 std::string guid = base::GenerateGUID();
302 DownloadClient client = DownloadClient::TEST_1;
303 Entry entry = BuildEntry(client, guid);
304
305 EXPECT_CALL(client_, OnItemAdded(false, client, guid)).Times(1);
306 EXPECT_CALL(client_, OnStoreUpdateFailed(client, guid)).Times(2);
307 EXPECT_CALL(client_, OnDestroyed(false));
308
309 model_->Add(entry);
310 model_->Update(entry);
311 model_->Remove(guid);
312 model_->Destroy();
313
314 task_runner_->RunUntilIdle();
315 }
316
317 } // namespace
318 } // namespace download
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698