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

Side by Side Diff: components/offline_pages/offline_page_metadata_store_impl_unittest.cc

Issue 2489443002: Move all components/offline_pages/ files into component/offline_pages/core (Closed)
Patch Set: update Created 4 years, 1 month 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 2015 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/offline_pages/offline_page_metadata_store.h"
6
7 #include <stdint.h>
8
9 #include <memory>
10
11 #include "base/bind.h"
12 #include "base/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/test/test_simple_task_runner.h"
17 #include "base/threading/thread_task_runner_handle.h"
18 #include "components/offline_pages/offline_page_item.h"
19 #include "components/offline_pages/offline_page_metadata_store_sql.h"
20 #include "components/offline_pages/offline_page_model.h"
21 #include "sql/connection.h"
22 #include "sql/statement.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 namespace offline_pages {
26
27 namespace {
28
29 #define OFFLINE_PAGES_TABLE_V1 "offlinepages_v1"
30
31 const char kTestClientNamespace[] = "CLIENT_NAMESPACE";
32 const char kTestURL[] = "https://example.com";
33 const char kOriginalTestURL[] = "https://example.com/foo";
34 const ClientId kTestClientId1(kTestClientNamespace, "1234");
35 const ClientId kTestClientId2(kTestClientNamespace, "5678");
36 const base::FilePath::CharType kFilePath[] =
37 FILE_PATH_LITERAL("/offline_pages/example_com.mhtml");
38 int64_t kFileSize = 234567LL;
39 int64_t kOfflineId = 12345LL;
40
41 // Build a store with outdated schema to simulate the upgrading process.
42 // TODO(romax): move it to sql_unittests.
43 void BuildTestStoreWithSchemaFromM52(const base::FilePath& file) {
44 sql::Connection connection;
45 ASSERT_TRUE(
46 connection.Open(file.Append(FILE_PATH_LITERAL("OfflinePages.db"))));
47 ASSERT_TRUE(connection.is_open());
48 ASSERT_TRUE(connection.BeginTransaction());
49 ASSERT_TRUE(connection.Execute("CREATE TABLE " OFFLINE_PAGES_TABLE_V1
50 "(offline_id INTEGER PRIMARY KEY NOT NULL, "
51 "creation_time INTEGER NOT NULL, "
52 "file_size INTEGER NOT NULL, "
53 "version INTEGER NOT NULL, "
54 "last_access_time INTEGER NOT NULL, "
55 "access_count INTEGER NOT NULL, "
56 "status INTEGER NOT NULL DEFAULT 0, "
57 "user_initiated INTEGER, "
58 "client_namespace VARCHAR NOT NULL, "
59 "client_id VARCHAR NOT NULL, "
60 "online_url VARCHAR NOT NULL, "
61 "offline_url VARCHAR NOT NULL DEFAULT '', "
62 "file_path VARCHAR NOT NULL "
63 ")"));
64 ASSERT_TRUE(connection.CommitTransaction());
65 sql::Statement statement(connection.GetUniqueStatement(
66 "INSERT INTO " OFFLINE_PAGES_TABLE_V1
67 "(offline_id, creation_time, file_size, version, "
68 "last_access_time, access_count, client_namespace, "
69 "client_id, online_url, file_path) "
70 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
71 statement.BindInt64(0, kOfflineId);
72 statement.BindInt(1, 0);
73 statement.BindInt64(2, kFileSize);
74 statement.BindInt(3, 0);
75 statement.BindInt(4, 0);
76 statement.BindInt(5, 1);
77 statement.BindCString(6, kTestClientNamespace);
78 statement.BindString(7, kTestClientId2.id);
79 statement.BindCString(8, kTestURL);
80 statement.BindString(9, base::FilePath(kFilePath).MaybeAsASCII());
81 ASSERT_TRUE(statement.Run());
82 ASSERT_TRUE(connection.DoesTableExist(OFFLINE_PAGES_TABLE_V1));
83 ASSERT_FALSE(
84 connection.DoesColumnExist(OFFLINE_PAGES_TABLE_V1, "expiration_time"));
85 }
86
87 void BuildTestStoreWithSchemaFromM53(const base::FilePath& file) {
88 sql::Connection connection;
89 ASSERT_TRUE(
90 connection.Open(file.Append(FILE_PATH_LITERAL("OfflinePages.db"))));
91 ASSERT_TRUE(connection.is_open());
92 ASSERT_TRUE(connection.BeginTransaction());
93 ASSERT_TRUE(connection.Execute("CREATE TABLE " OFFLINE_PAGES_TABLE_V1
94 "(offline_id INTEGER PRIMARY KEY NOT NULL, "
95 "creation_time INTEGER NOT NULL, "
96 "file_size INTEGER NOT NULL, "
97 "version INTEGER NOT NULL, "
98 "last_access_time INTEGER NOT NULL, "
99 "access_count INTEGER NOT NULL, "
100 "status INTEGER NOT NULL DEFAULT 0, "
101 "user_initiated INTEGER, "
102 "expiration_time INTEGER NOT NULL DEFAULT 0, "
103 "client_namespace VARCHAR NOT NULL, "
104 "client_id VARCHAR NOT NULL, "
105 "online_url VARCHAR NOT NULL, "
106 "offline_url VARCHAR NOT NULL DEFAULT '', "
107 "file_path VARCHAR NOT NULL "
108 ")"));
109 ASSERT_TRUE(connection.CommitTransaction());
110 sql::Statement statement(connection.GetUniqueStatement(
111 "INSERT INTO " OFFLINE_PAGES_TABLE_V1
112 "(offline_id, creation_time, file_size, version, "
113 "last_access_time, access_count, client_namespace, "
114 "client_id, online_url, file_path, expiration_time) "
115 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
116 statement.BindInt64(0, kOfflineId);
117 statement.BindInt(1, 0);
118 statement.BindInt64(2, kFileSize);
119 statement.BindInt(3, 0);
120 statement.BindInt(4, 0);
121 statement.BindInt(5, 1);
122 statement.BindCString(6, kTestClientNamespace);
123 statement.BindString(7, kTestClientId2.id);
124 statement.BindCString(8, kTestURL);
125 statement.BindString(9, base::FilePath(kFilePath).MaybeAsASCII());
126 statement.BindInt64(10, base::Time::Now().ToInternalValue());
127 ASSERT_TRUE(statement.Run());
128 ASSERT_TRUE(connection.DoesTableExist(OFFLINE_PAGES_TABLE_V1));
129 ASSERT_FALSE(connection.DoesColumnExist(OFFLINE_PAGES_TABLE_V1, "title"));
130 }
131
132 void BuildTestStoreWithSchemaFromM54(const base::FilePath& file) {
133 sql::Connection connection;
134 ASSERT_TRUE(
135 connection.Open(file.Append(FILE_PATH_LITERAL("OfflinePages.db"))));
136 ASSERT_TRUE(connection.is_open());
137 ASSERT_TRUE(connection.BeginTransaction());
138 ASSERT_TRUE(connection.Execute("CREATE TABLE " OFFLINE_PAGES_TABLE_V1
139 "(offline_id INTEGER PRIMARY KEY NOT NULL, "
140 "creation_time INTEGER NOT NULL, "
141 "file_size INTEGER NOT NULL, "
142 "version INTEGER NOT NULL, "
143 "last_access_time INTEGER NOT NULL, "
144 "access_count INTEGER NOT NULL, "
145 "status INTEGER NOT NULL DEFAULT 0, "
146 "user_initiated INTEGER, "
147 "expiration_time INTEGER NOT NULL DEFAULT 0, "
148 "client_namespace VARCHAR NOT NULL, "
149 "client_id VARCHAR NOT NULL, "
150 "online_url VARCHAR NOT NULL, "
151 "offline_url VARCHAR NOT NULL DEFAULT '', "
152 "file_path VARCHAR NOT NULL "
153 "title VARCHAR NOT NULL DEFAULT ''"
154 ")"));
155 ASSERT_TRUE(connection.CommitTransaction());
156 sql::Statement statement(connection.GetUniqueStatement(
157 "INSERT INTO " OFFLINE_PAGES_TABLE_V1
158 "(offline_id, creation_time, file_size, version, "
159 "last_access_time, access_count, client_namespace, "
160 "client_id, online_url, file_path, expiration_time, title) "
161 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
162 statement.BindInt64(0, kOfflineId);
163 statement.BindInt(1, 0);
164 statement.BindInt64(2, kFileSize);
165 statement.BindInt(3, 0);
166 statement.BindInt(4, 0);
167 statement.BindInt(5, 1);
168 statement.BindCString(6, kTestClientNamespace);
169 statement.BindString(7, kTestClientId2.id);
170 statement.BindCString(8, kTestURL);
171 statement.BindString(9, base::FilePath(kFilePath).MaybeAsASCII());
172 statement.BindInt64(10, base::Time::Now().ToInternalValue());
173 statement.BindString16(11, base::UTF8ToUTF16("Test title"));
174 ASSERT_TRUE(statement.Run());
175 ASSERT_TRUE(connection.DoesTableExist(OFFLINE_PAGES_TABLE_V1));
176 ASSERT_TRUE(connection.DoesColumnExist(OFFLINE_PAGES_TABLE_V1, "version"));
177 ASSERT_TRUE(connection.DoesColumnExist(OFFLINE_PAGES_TABLE_V1, "status"));
178 ASSERT_TRUE(
179 connection.DoesColumnExist(OFFLINE_PAGES_TABLE_V1, "user_initiated"));
180 ASSERT_TRUE(
181 connection.DoesColumnExist(OFFLINE_PAGES_TABLE_V1, "offline_url"));
182 }
183
184 void BuildTestStoreWithSchemaFromM55(const base::FilePath& file) {
185 sql::Connection connection;
186 ASSERT_TRUE(
187 connection.Open(file.Append(FILE_PATH_LITERAL("OfflinePages.db"))));
188 ASSERT_TRUE(connection.is_open());
189 ASSERT_TRUE(connection.BeginTransaction());
190 ASSERT_TRUE(connection.Execute("CREATE TABLE " OFFLINE_PAGES_TABLE_V1
191 "(offline_id INTEGER PRIMARY KEY NOT NULL, "
192 "creation_time INTEGER NOT NULL, "
193 "file_size INTEGER NOT NULL, "
194 "last_access_time INTEGER NOT NULL, "
195 "access_count INTEGER NOT NULL, "
196 "expiration_time INTEGER NOT NULL DEFAULT 0, "
197 "client_namespace VARCHAR NOT NULL, "
198 "client_id VARCHAR NOT NULL, "
199 "online_url VARCHAR NOT NULL, "
200 "file_path VARCHAR NOT NULL, "
201 "title VARCHAR NOT NULL DEFAULT ''"
202 ")"));
203 ASSERT_TRUE(connection.CommitTransaction());
204 sql::Statement statement(connection.GetUniqueStatement(
205 "INSERT INTO " OFFLINE_PAGES_TABLE_V1
206 "(offline_id, creation_time, file_size, "
207 "last_access_time, access_count, client_namespace, "
208 "client_id, online_url, file_path, expiration_time, title) "
209 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"));
210 statement.BindInt64(0, kOfflineId);
211 statement.BindInt(1, 0);
212 statement.BindInt64(2, kFileSize);
213 statement.BindInt(3, 0);
214 statement.BindInt(4, 1);
215 statement.BindCString(5, kTestClientNamespace);
216 statement.BindString(6, kTestClientId2.id);
217 statement.BindCString(7, kTestURL);
218 statement.BindString(8, base::FilePath(kFilePath).MaybeAsASCII());
219 statement.BindInt64(9, base::Time::Now().ToInternalValue());
220 statement.BindString16(10, base::UTF8ToUTF16("Test title"));
221 ASSERT_TRUE(statement.Run());
222 ASSERT_TRUE(connection.DoesTableExist(OFFLINE_PAGES_TABLE_V1));
223 ASSERT_TRUE(connection.DoesColumnExist(OFFLINE_PAGES_TABLE_V1, "title"));
224 }
225
226 class OfflinePageMetadataStoreFactory {
227 public:
228 OfflinePageMetadataStore* BuildStore(const base::FilePath& file_path) {
229 OfflinePageMetadataStoreSQL* store = new OfflinePageMetadataStoreSQL(
230 base::ThreadTaskRunnerHandle::Get(), file_path);
231 return store;
232 }
233
234 OfflinePageMetadataStore* BuildStoreM52(const base::FilePath& file_path) {
235 BuildTestStoreWithSchemaFromM52(file_path);
236 OfflinePageMetadataStoreSQL* store = new OfflinePageMetadataStoreSQL(
237 base::ThreadTaskRunnerHandle::Get(), file_path);
238 return store;
239 }
240
241 OfflinePageMetadataStore* BuildStoreM53(const base::FilePath& file_path) {
242 BuildTestStoreWithSchemaFromM53(file_path);
243 OfflinePageMetadataStoreSQL* store = new OfflinePageMetadataStoreSQL(
244 base::ThreadTaskRunnerHandle::Get(), file_path);
245 return store;
246 }
247
248 OfflinePageMetadataStore* BuildStoreM54(const base::FilePath& file_path) {
249 BuildTestStoreWithSchemaFromM54(file_path);
250 OfflinePageMetadataStoreSQL* store = new OfflinePageMetadataStoreSQL(
251 base::ThreadTaskRunnerHandle::Get(), file_path);
252 return store;
253 }
254
255 OfflinePageMetadataStore* BuildStoreM55(const base::FilePath& file_path) {
256 BuildTestStoreWithSchemaFromM55(file_path);
257 OfflinePageMetadataStoreSQL* store = new OfflinePageMetadataStoreSQL(
258 base::ThreadTaskRunnerHandle::Get(), file_path);
259 return store;
260 }
261 };
262
263 enum CalledCallback { NONE, LOAD, ADD, UPDATE, REMOVE, RESET };
264 enum Status { STATUS_NONE, STATUS_TRUE, STATUS_FALSE };
265
266 class OfflinePageMetadataStoreTest : public testing::Test {
267 public:
268 OfflinePageMetadataStoreTest();
269 ~OfflinePageMetadataStoreTest() override;
270
271 void TearDown() override {
272 // Wait for all the pieces of the store to delete itself properly.
273 PumpLoop();
274 }
275
276 std::unique_ptr<OfflinePageMetadataStore> BuildStore();
277 std::unique_ptr<OfflinePageMetadataStore> BuildStoreWithSchemaFromM52();
278 std::unique_ptr<OfflinePageMetadataStore> BuildStoreWithSchemaFromM53();
279 std::unique_ptr<OfflinePageMetadataStore> BuildStoreWithSchemaFromM54();
280 std::unique_ptr<OfflinePageMetadataStore> BuildStoreWithSchemaFromM55();
281
282 void PumpLoop();
283
284 void GetOfflinePagesCallback(
285 OfflinePageMetadataStore::LoadStatus load_status,
286 const std::vector<OfflinePageItem>& offline_pages);
287 void AddCallback(ItemActionStatus status);
288 void UpdateCallback(CalledCallback called_callback,
289 std::unique_ptr<OfflinePagesUpdateResult> result);
290 void ResetCallback(bool status);
291
292 void ClearResults();
293
294 OfflinePageItem CheckThatStoreHasOneItem();
295 void CheckThatOfflinePageCanBeSaved(
296 std::unique_ptr<OfflinePageMetadataStore> store);
297
298 OfflinePagesUpdateResult* last_update_result() {
299 return last_update_result_.get();
300 }
301
302 protected:
303 CalledCallback last_called_callback_;
304 Status last_status_;
305 std::unique_ptr<OfflinePagesUpdateResult> last_update_result_;
306 std::vector<OfflinePageItem> offline_pages_;
307 OfflinePageMetadataStoreFactory factory_;
308
309 base::ScopedTempDir temp_directory_;
310 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
311 base::ThreadTaskRunnerHandle task_runner_handle_;
312 };
313
314 OfflinePageMetadataStoreTest::OfflinePageMetadataStoreTest()
315 : last_called_callback_(NONE),
316 last_status_(STATUS_NONE),
317 task_runner_(new base::TestSimpleTaskRunner),
318 task_runner_handle_(task_runner_) {
319 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir());
320 }
321
322 OfflinePageMetadataStoreTest::~OfflinePageMetadataStoreTest() {}
323
324 void OfflinePageMetadataStoreTest::PumpLoop() {
325 task_runner_->RunUntilIdle();
326 }
327
328 void OfflinePageMetadataStoreTest::GetOfflinePagesCallback(
329 OfflinePageMetadataStore::LoadStatus load_status,
330 const std::vector<OfflinePageItem>& offline_pages) {
331 last_called_callback_ = LOAD;
332 last_status_ = load_status == OfflinePageMetadataStore::LOAD_SUCCEEDED ?
333 STATUS_TRUE : STATUS_FALSE;
334 offline_pages_.swap(const_cast<std::vector<OfflinePageItem>&>(offline_pages));
335 }
336
337 void OfflinePageMetadataStoreTest::AddCallback(ItemActionStatus status) {
338 last_called_callback_ = ADD;
339 // TODO(fgorski): Add specific add status.
340 // last_item_status_ = status;
341 last_status_ =
342 status == ItemActionStatus::SUCCESS ? STATUS_TRUE : STATUS_FALSE;
343 }
344
345 void OfflinePageMetadataStoreTest::UpdateCallback(
346 CalledCallback called_callback,
347 std::unique_ptr<OfflinePagesUpdateResult> result) {
348 last_called_callback_ = called_callback;
349 last_status_ = result->updated_items.size() > 0 ? STATUS_TRUE : STATUS_FALSE;
350 last_update_result_ = std::move(result);
351 }
352
353 void OfflinePageMetadataStoreTest::ResetCallback(bool status) {
354 last_called_callback_ = RESET;
355 last_status_ = status ? STATUS_TRUE : STATUS_FALSE;
356 }
357
358 void OfflinePageMetadataStoreTest::ClearResults() {
359 last_called_callback_ = NONE;
360 last_status_ = STATUS_NONE;
361 offline_pages_.clear();
362 last_update_result_.reset(nullptr);
363 }
364
365 OfflinePageItem OfflinePageMetadataStoreTest::CheckThatStoreHasOneItem() {
366 EXPECT_EQ(LOAD, last_called_callback_);
367 EXPECT_EQ(STATUS_TRUE, last_status_);
368 EXPECT_EQ(1U, offline_pages_.size());
369
370 return offline_pages_[0];
371 }
372
373 void OfflinePageMetadataStoreTest::CheckThatOfflinePageCanBeSaved(
374 std::unique_ptr<OfflinePageMetadataStore> store) {
375 size_t store_size = offline_pages_.size();
376 OfflinePageItem offline_page(GURL(kTestURL), 1234LL, kTestClientId1,
377 base::FilePath(kFilePath), kFileSize);
378 offline_page.title = base::UTF8ToUTF16("a title");
379 base::Time expiration_time = base::Time::Now();
380 offline_page.expiration_time = expiration_time;
381 offline_page.original_url = GURL(kOriginalTestURL);
382
383 store->AddOfflinePage(offline_page,
384 base::Bind(&OfflinePageMetadataStoreTest::AddCallback,
385 base::Unretained(this)));
386 PumpLoop();
387 EXPECT_EQ(ADD, last_called_callback_);
388 EXPECT_EQ(STATUS_TRUE, last_status_);
389 ClearResults();
390
391 // Close the store first to ensure file lock is removed.
392 store.reset();
393 store = BuildStore();
394 PumpLoop();
395
396 EXPECT_EQ(LOAD, last_called_callback_);
397 EXPECT_EQ(STATUS_TRUE, last_status_);
398 ASSERT_EQ(store_size + 1, offline_pages_.size());
399 if (store_size > 0 &&
400 offline_pages_[0].offline_id != offline_page.offline_id) {
401 std::swap(offline_pages_[0], offline_pages_[1]);
402 }
403 EXPECT_EQ(offline_page, offline_pages_[0]);
404 }
405
406 std::unique_ptr<OfflinePageMetadataStore>
407 OfflinePageMetadataStoreTest::BuildStore() {
408 std::unique_ptr<OfflinePageMetadataStore> store(
409 factory_.BuildStore(temp_directory_.GetPath()));
410 PumpLoop();
411 store->GetOfflinePages(
412 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
413 base::Unretained(this)));
414 PumpLoop();
415 return store;
416 }
417
418 std::unique_ptr<OfflinePageMetadataStore>
419 OfflinePageMetadataStoreTest::BuildStoreWithSchemaFromM52() {
420 std::unique_ptr<OfflinePageMetadataStore> store(
421 factory_.BuildStoreM52(temp_directory_.GetPath()));
422 PumpLoop();
423 store->GetOfflinePages(
424 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
425 base::Unretained(this)));
426 PumpLoop();
427 return store;
428 }
429
430 std::unique_ptr<OfflinePageMetadataStore>
431 OfflinePageMetadataStoreTest::BuildStoreWithSchemaFromM53() {
432 std::unique_ptr<OfflinePageMetadataStore> store(
433 factory_.BuildStoreM53(temp_directory_.GetPath()));
434 PumpLoop();
435 store->GetOfflinePages(
436 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
437 base::Unretained(this)));
438 PumpLoop();
439 return store;
440 }
441
442 std::unique_ptr<OfflinePageMetadataStore>
443 OfflinePageMetadataStoreTest::BuildStoreWithSchemaFromM54() {
444 std::unique_ptr<OfflinePageMetadataStore> store(
445 factory_.BuildStoreM53(temp_directory_.GetPath()));
446 PumpLoop();
447 store->GetOfflinePages(
448 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
449 base::Unretained(this)));
450 PumpLoop();
451 return store;
452 }
453
454 std::unique_ptr<OfflinePageMetadataStore>
455 OfflinePageMetadataStoreTest::BuildStoreWithSchemaFromM55() {
456 std::unique_ptr<OfflinePageMetadataStore> store(
457 factory_.BuildStoreM55(temp_directory_.GetPath()));
458 PumpLoop();
459 store->GetOfflinePages(
460 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
461 base::Unretained(this)));
462 PumpLoop();
463 return store;
464 }
465
466 // Loads empty store and makes sure that there are no offline pages stored in
467 // it.
468 TEST_F(OfflinePageMetadataStoreTest, LoadEmptyStore) {
469 std::unique_ptr<OfflinePageMetadataStore> store(BuildStore());
470 EXPECT_EQ(LOAD, last_called_callback_);
471 EXPECT_EQ(STATUS_TRUE, last_status_);
472 EXPECT_EQ(0U, offline_pages_.size());
473 }
474
475 TEST_F(OfflinePageMetadataStoreTest, GetOfflinePagesFromInvalidStore) {
476 std::unique_ptr<OfflinePageMetadataStore> store(BuildStore());
477 OfflinePageMetadataStoreSQL* sql_store =
478 static_cast<OfflinePageMetadataStoreSQL*>(store.get());
479
480 sql_store->SetStateForTesting(StoreState::NOT_LOADED, false);
481 store->GetOfflinePages(
482 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
483 base::Unretained(this)));
484 PumpLoop();
485 EXPECT_EQ(LOAD, last_called_callback_);
486 EXPECT_EQ(0UL, offline_pages_.size());
487 EXPECT_EQ(STATUS_FALSE, last_status_);
488
489 sql_store->SetStateForTesting(StoreState::FAILED_LOADING, false);
490 store->GetOfflinePages(
491 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
492 base::Unretained(this)));
493 PumpLoop();
494 EXPECT_EQ(LOAD, last_called_callback_);
495 EXPECT_EQ(0UL, offline_pages_.size());
496 EXPECT_EQ(STATUS_FALSE, last_status_);
497
498 sql_store->SetStateForTesting(StoreState::FAILED_RESET, false);
499 store->GetOfflinePages(
500 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
501 base::Unretained(this)));
502 PumpLoop();
503 EXPECT_EQ(LOAD, last_called_callback_);
504 EXPECT_EQ(0UL, offline_pages_.size());
505 EXPECT_EQ(STATUS_FALSE, last_status_);
506
507 sql_store->SetStateForTesting(StoreState::LOADED, true);
508 store->GetOfflinePages(
509 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
510 base::Unretained(this)));
511 PumpLoop();
512 EXPECT_EQ(LOAD, last_called_callback_);
513 EXPECT_EQ(0UL, offline_pages_.size());
514 EXPECT_EQ(STATUS_FALSE, last_status_);
515
516 sql_store->SetStateForTesting(StoreState::NOT_LOADED, true);
517 store->GetOfflinePages(
518 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
519 base::Unretained(this)));
520 PumpLoop();
521 EXPECT_EQ(LOAD, last_called_callback_);
522 EXPECT_EQ(0UL, offline_pages_.size());
523 EXPECT_EQ(STATUS_FALSE, last_status_);
524
525 sql_store->SetStateForTesting(StoreState::FAILED_LOADING, false);
526 store->GetOfflinePages(
527 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
528 base::Unretained(this)));
529 PumpLoop();
530 EXPECT_EQ(LOAD, last_called_callback_);
531 EXPECT_EQ(0UL, offline_pages_.size());
532 EXPECT_EQ(STATUS_FALSE, last_status_);
533
534 sql_store->SetStateForTesting(StoreState::FAILED_RESET, false);
535 store->GetOfflinePages(
536 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
537 base::Unretained(this)));
538 PumpLoop();
539 EXPECT_EQ(LOAD, last_called_callback_);
540 EXPECT_EQ(0UL, offline_pages_.size());
541 EXPECT_EQ(STATUS_FALSE, last_status_);
542
543 }
544
545 // Loads a store which has an outdated schema.
546 // This test case would crash if it's not handling correctly when we're loading
547 // old version stores.
548 // TODO(romax): Move this to sql_unittest.
549 TEST_F(OfflinePageMetadataStoreTest, LoadVersion52Store) {
550 std::unique_ptr<OfflinePageMetadataStore> store(
551 BuildStoreWithSchemaFromM52());
552
553 CheckThatStoreHasOneItem();
554 CheckThatOfflinePageCanBeSaved(std::move(store));
555 }
556
557 // Loads a store which has an outdated schema.
558 // This test case would crash if it's not handling correctly when we're loading
559 // old version stores.
560 // TODO(romax): Move this to sql_unittest.
561 TEST_F(OfflinePageMetadataStoreTest, LoadVersion53Store) {
562 std::unique_ptr<OfflinePageMetadataStore> store(
563 BuildStoreWithSchemaFromM53());
564
565 OfflinePageItem item = CheckThatStoreHasOneItem();
566 // We should have a valid expiration time after upgrade.
567 EXPECT_NE(base::Time::FromInternalValue(0),
568 offline_pages_[0].expiration_time);
569
570 CheckThatOfflinePageCanBeSaved(std::move(store));
571 }
572
573 // Loads a string with schema from M54.
574 // Because for now we only reduce the number of fields it just makes sure there
575 // are no crashes in the process.
576 // TODO(romax): Move this to sql_unittest.
577 TEST_F(OfflinePageMetadataStoreTest, LoadVersion54Store) {
578 std::unique_ptr<OfflinePageMetadataStore> store(
579 BuildStoreWithSchemaFromM54());
580
581 OfflinePageItem item = CheckThatStoreHasOneItem();
582
583 CheckThatOfflinePageCanBeSaved(std::move(store));
584 }
585
586 // Loads a string with schema from M55.
587 // Because for now we only reduce the number of fields it just makes sure there
588 // are no crashes in the process.
589 // TODO(romax): Move this to sql_unittest.
590 TEST_F(OfflinePageMetadataStoreTest, LoadVersion55Store) {
591 std::unique_ptr<OfflinePageMetadataStore> store(
592 BuildStoreWithSchemaFromM55());
593
594 OfflinePageItem item = CheckThatStoreHasOneItem();
595
596 CheckThatOfflinePageCanBeSaved(std::move(store));
597 }
598
599 // Adds metadata of an offline page into a store and then opens the store
600 // again to make sure that stored metadata survives store restarts.
601 TEST_F(OfflinePageMetadataStoreTest, AddOfflinePage) {
602 CheckThatOfflinePageCanBeSaved(BuildStore());
603 }
604
605 TEST_F(OfflinePageMetadataStoreTest, AddSameOfflinePageTwice) {
606 std::unique_ptr<OfflinePageMetadataStore> store(BuildStore());
607
608 OfflinePageItem offline_page(GURL(kTestURL), 1234LL, kTestClientId1,
609 base::FilePath(kFilePath), kFileSize);
610 offline_page.title = base::UTF8ToUTF16("a title");
611 base::Time expiration_time = base::Time::Now();
612 offline_page.expiration_time = expiration_time;
613
614 store->AddOfflinePage(offline_page,
615 base::Bind(&OfflinePageMetadataStoreTest::AddCallback,
616 base::Unretained(this)));
617 PumpLoop();
618 EXPECT_EQ(ADD, last_called_callback_);
619 EXPECT_EQ(STATUS_TRUE, last_status_);
620 ClearResults();
621
622 store->AddOfflinePage(offline_page,
623 base::Bind(&OfflinePageMetadataStoreTest::AddCallback,
624 base::Unretained(this)));
625 PumpLoop();
626 EXPECT_EQ(ADD, last_called_callback_);
627 EXPECT_EQ(STATUS_FALSE, last_status_);
628 }
629
630 // Tests removing offline page metadata from the store, for which it first adds
631 // metadata of an offline page.
632 TEST_F(OfflinePageMetadataStoreTest, RemoveOfflinePage) {
633 std::unique_ptr<OfflinePageMetadataStore> store(BuildStore());
634
635 // Add an offline page.
636 OfflinePageItem offline_page(GURL(kTestURL), 1234LL, kTestClientId1,
637 base::FilePath(kFilePath), kFileSize);
638 store->AddOfflinePage(offline_page,
639 base::Bind(&OfflinePageMetadataStoreTest::AddCallback,
640 base::Unretained(this)));
641 PumpLoop();
642 EXPECT_EQ(ADD, last_called_callback_);
643 EXPECT_EQ(STATUS_TRUE, last_status_);
644
645 ClearResults();
646
647 // Load the store.
648 store->GetOfflinePages(
649 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
650 base::Unretained(this)));
651 PumpLoop();
652 EXPECT_EQ(LOAD, last_called_callback_);
653 EXPECT_EQ(1U, offline_pages_.size());
654
655 // Remove the offline page.
656 std::vector<int64_t> ids_to_remove;
657 ids_to_remove.push_back(offline_page.offline_id);
658 store->RemoveOfflinePages(
659 ids_to_remove, base::Bind(&OfflinePageMetadataStoreTest::UpdateCallback,
660 base::Unretained(this), REMOVE));
661 PumpLoop();
662 EXPECT_EQ(REMOVE, last_called_callback_);
663 EXPECT_EQ(STATUS_TRUE, last_status_);
664 ASSERT_TRUE(last_update_result() != nullptr);
665 EXPECT_EQ(1UL, last_update_result()->item_statuses.size());
666 EXPECT_EQ(ItemActionStatus::SUCCESS,
667 last_update_result()->item_statuses.begin()->second);
668 EXPECT_EQ(1UL, last_update_result()->updated_items.size());
669 EXPECT_EQ(offline_page, *(last_update_result()->updated_items.begin()));
670
671 ClearResults();
672
673 // Load the store.
674 store->GetOfflinePages(
675 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
676 base::Unretained(this)));
677 PumpLoop();
678 EXPECT_EQ(LOAD, last_called_callback_);
679 EXPECT_EQ(0U, offline_pages_.size());
680
681 ClearResults();
682
683 // Close and reload the store.
684 store.reset();
685 store = BuildStore();
686 EXPECT_EQ(LOAD, last_called_callback_);
687 EXPECT_EQ(STATUS_TRUE, last_status_);
688 EXPECT_EQ(0U, offline_pages_.size());
689 }
690
691 // Adds metadata of multiple offline pages into a store and removes some.
692 TEST_F(OfflinePageMetadataStoreTest, AddRemoveMultipleOfflinePages) {
693 std::unique_ptr<OfflinePageMetadataStore> store(BuildStore());
694
695 // Add an offline page.
696 OfflinePageItem offline_page_1(GURL(kTestURL), 12345LL, kTestClientId1,
697 base::FilePath(kFilePath), kFileSize);
698 store->AddOfflinePage(offline_page_1,
699 base::Bind(&OfflinePageMetadataStoreTest::AddCallback,
700 base::Unretained(this)));
701 PumpLoop();
702 EXPECT_EQ(ADD, last_called_callback_);
703 EXPECT_EQ(STATUS_TRUE, last_status_);
704
705 ClearResults();
706
707 // Add anther offline page.
708 base::FilePath file_path_2 =
709 base::FilePath(FILE_PATH_LITERAL("//other.page.com.mhtml"));
710 OfflinePageItem offline_page_2(GURL("https://other.page.com"), 5678LL,
711 kTestClientId2, file_path_2, 12345,
712 base::Time::Now());
713 offline_page_2.expiration_time = base::Time::Now();
714 offline_page_2.original_url = GURL("https://example.com/bar");
715 store->AddOfflinePage(offline_page_2,
716 base::Bind(&OfflinePageMetadataStoreTest::AddCallback,
717 base::Unretained(this)));
718 PumpLoop();
719 EXPECT_EQ(ADD, last_called_callback_);
720 EXPECT_EQ(STATUS_TRUE, last_status_);
721
722 ClearResults();
723
724 // Load the store.
725 store->GetOfflinePages(
726 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
727 base::Unretained(this)));
728 PumpLoop();
729
730 EXPECT_EQ(LOAD, last_called_callback_);
731 EXPECT_EQ(STATUS_TRUE, last_status_);
732 EXPECT_EQ(2U, offline_pages_.size());
733
734 // Remove the offline page.
735 std::vector<int64_t> ids_to_remove;
736 ids_to_remove.push_back(offline_page_1.offline_id);
737 store->RemoveOfflinePages(
738 ids_to_remove, base::Bind(&OfflinePageMetadataStoreTest::UpdateCallback,
739 base::Unretained(this), REMOVE));
740 PumpLoop();
741 EXPECT_EQ(REMOVE, last_called_callback_);
742 EXPECT_EQ(STATUS_TRUE, last_status_);
743 ASSERT_TRUE(last_update_result() != nullptr);
744 EXPECT_EQ(1UL, last_update_result()->item_statuses.size());
745 EXPECT_EQ(ItemActionStatus::SUCCESS,
746 last_update_result()->item_statuses.begin()->second);
747 EXPECT_EQ(1UL, last_update_result()->updated_items.size());
748 EXPECT_EQ(offline_page_1, *(last_update_result()->updated_items.begin()));
749
750 ClearResults();
751
752 // Close and reload the store.
753 store.reset();
754 store = BuildStore();
755 store->GetOfflinePages(
756 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
757 base::Unretained(this)));
758 PumpLoop();
759
760 EXPECT_EQ(LOAD, last_called_callback_);
761 EXPECT_EQ(STATUS_TRUE, last_status_);
762 ASSERT_EQ(1U, offline_pages_.size());
763 EXPECT_EQ(offline_page_2.url, offline_pages_[0].url);
764 EXPECT_EQ(offline_page_2.offline_id, offline_pages_[0].offline_id);
765 EXPECT_EQ(offline_page_2.file_path, offline_pages_[0].file_path);
766 EXPECT_EQ(offline_page_2.file_size, offline_pages_[0].file_size);
767 EXPECT_EQ(offline_page_2.creation_time, offline_pages_[0].creation_time);
768 EXPECT_EQ(offline_page_2.last_access_time,
769 offline_pages_[0].last_access_time);
770 EXPECT_EQ(offline_page_2.expiration_time, offline_pages_[0].expiration_time);
771 EXPECT_EQ(offline_page_2.access_count, offline_pages_[0].access_count);
772 EXPECT_EQ(offline_page_2.client_id, offline_pages_[0].client_id);
773 }
774
775 // Tests updating offline page metadata from the store.
776 TEST_F(OfflinePageMetadataStoreTest, UpdateOfflinePage) {
777 std::unique_ptr<OfflinePageMetadataStore> store(BuildStore());
778
779 // First, adds a fresh page.
780 OfflinePageItem offline_page(GURL(kTestURL), 1234LL, kTestClientId1,
781 base::FilePath(kFilePath), kFileSize);
782 store->AddOfflinePage(offline_page,
783 base::Bind(&OfflinePageMetadataStoreTest::AddCallback,
784 base::Unretained(this)));
785 PumpLoop();
786 EXPECT_EQ(ADD, last_called_callback_);
787 EXPECT_EQ(STATUS_TRUE, last_status_);
788
789 ClearResults();
790 store->GetOfflinePages(
791 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
792 base::Unretained(this)));
793 PumpLoop();
794
795 EXPECT_EQ(LOAD, last_called_callback_);
796 EXPECT_EQ(STATUS_TRUE, last_status_);
797 ASSERT_EQ(1U, offline_pages_.size());
798 EXPECT_EQ(offline_page, offline_pages_[0]);
799
800 // Then update some data.
801 offline_page.file_size = kFileSize + 1;
802 offline_page.access_count++;
803 offline_page.expiration_time = base::Time::Now();
804 offline_page.original_url = GURL("https://example.com/bar");
805 std::vector<OfflinePageItem> items_to_update;
806 items_to_update.push_back(offline_page);
807 store->UpdateOfflinePages(
808 items_to_update, base::Bind(&OfflinePageMetadataStoreTest::UpdateCallback,
809 base::Unretained(this), UPDATE));
810 PumpLoop();
811 EXPECT_EQ(UPDATE, last_called_callback_);
812 EXPECT_EQ(STATUS_TRUE, last_status_);
813 ASSERT_TRUE(last_update_result() != nullptr);
814 EXPECT_EQ(1UL, last_update_result()->item_statuses.size());
815 EXPECT_EQ(ItemActionStatus::SUCCESS,
816 last_update_result()->item_statuses.begin()->second);
817 EXPECT_EQ(1UL, last_update_result()->updated_items.size());
818 EXPECT_EQ(offline_page, *(last_update_result()->updated_items.begin()));
819
820 ClearResults();
821 store->GetOfflinePages(
822 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
823 base::Unretained(this)));
824 PumpLoop();
825
826 EXPECT_EQ(LOAD, last_called_callback_);
827 EXPECT_EQ(STATUS_TRUE, last_status_);
828 ASSERT_EQ(1U, offline_pages_.size());
829 EXPECT_EQ(offline_page, offline_pages_[0]);
830 }
831
832 TEST_F(OfflinePageMetadataStoreTest, ClearAllOfflinePages) {
833 std::unique_ptr<OfflinePageMetadataStore> store(BuildStore());
834
835 // Add 2 offline pages.
836 OfflinePageItem offline_page(GURL(kTestURL), 1234LL, kTestClientId1,
837 base::FilePath(kFilePath), kFileSize);
838 store->AddOfflinePage(offline_page,
839 base::Bind(&OfflinePageMetadataStoreTest::AddCallback,
840 base::Unretained(this)));
841 PumpLoop();
842 EXPECT_EQ(ADD, last_called_callback_);
843 EXPECT_EQ(STATUS_TRUE, last_status_);
844
845 ClearResults();
846
847 OfflinePageItem offline_page2(GURL("http://test.com"), 5678LL, kTestClientId2,
848 base::FilePath(kFilePath), kFileSize);
849 store->AddOfflinePage(offline_page2,
850 base::Bind(&OfflinePageMetadataStoreTest::AddCallback,
851 base::Unretained(this)));
852 PumpLoop();
853 EXPECT_EQ(ADD, last_called_callback_);
854 EXPECT_EQ(STATUS_TRUE, last_status_);
855
856 ClearResults();
857
858 // Load the store.
859 store->GetOfflinePages(
860 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
861 base::Unretained(this)));
862 PumpLoop();
863
864 EXPECT_EQ(LOAD, last_called_callback_);
865 EXPECT_EQ(STATUS_TRUE, last_status_);
866 EXPECT_EQ(2U, offline_pages_.size());
867
868 // Clear all records from the store.
869 store->Reset(base::Bind(&OfflinePageMetadataStoreTest::ResetCallback,
870 base::Unretained(this)));
871 PumpLoop();
872 EXPECT_EQ(RESET, last_called_callback_);
873 EXPECT_EQ(STATUS_TRUE, last_status_);
874
875 // Load the store.
876 store->GetOfflinePages(
877 base::Bind(&OfflinePageMetadataStoreTest::GetOfflinePagesCallback,
878 base::Unretained(this)));
879 PumpLoop();
880
881 EXPECT_EQ(LOAD, last_called_callback_);
882 EXPECT_EQ(STATUS_TRUE, last_status_);
883 ASSERT_EQ(0U, offline_pages_.size());
884 }
885
886 } // namespace
887 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698