OLD | NEW |
| (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_model_impl.h" | |
6 | |
7 #include <stdint.h> | |
8 #include <algorithm> | |
9 #include <utility> | |
10 | |
11 #include "base/bind.h" | |
12 #include "base/command_line.h" | |
13 #include "base/feature_list.h" | |
14 #include "base/files/file_util.h" | |
15 #include "base/files/scoped_temp_dir.h" | |
16 #include "base/memory/ptr_util.h" | |
17 #include "base/metrics/statistics_recorder.h" | |
18 #include "base/run_loop.h" | |
19 #include "base/single_thread_task_runner.h" | |
20 #include "base/strings/string_number_conversions.h" | |
21 #include "base/strings/utf_string_conversions.h" | |
22 #include "base/test/histogram_tester.h" | |
23 #include "base/test/scoped_feature_list.h" | |
24 #include "base/test/test_mock_time_task_runner.h" | |
25 #include "base/threading/thread_task_runner_handle.h" | |
26 #include "base/time/time.h" | |
27 #include "components/offline_pages/client_namespace_constants.h" | |
28 #include "components/offline_pages/client_policy_controller.h" | |
29 #include "components/offline_pages/offline_page_client_policy.h" | |
30 #include "components/offline_pages/offline_page_feature.h" | |
31 #include "components/offline_pages/offline_page_item.h" | |
32 #include "components/offline_pages/offline_page_storage_manager.h" | |
33 #include "components/offline_pages/offline_page_test_archiver.h" | |
34 #include "components/offline_pages/offline_page_test_store.h" | |
35 #include "components/offline_pages/offline_page_types.h" | |
36 #include "testing/gtest/include/gtest/gtest.h" | |
37 #include "url/gurl.h" | |
38 | |
39 namespace offline_pages { | |
40 | |
41 namespace { | |
42 const char kTestClientNamespace[] = "default"; | |
43 const char kUserRequestedNamespace[] = "download"; | |
44 const GURL kTestUrl("http://example.com"); | |
45 const GURL kTestUrl2("http://other.page.com"); | |
46 const GURL kTestUrl3("http://test.xyz"); | |
47 const GURL kTestUrl4("http://page.net"); | |
48 const GURL kFileUrl("file:///foo"); | |
49 const GURL kTestUrlWithFragment("http://example.com#frag"); | |
50 const GURL kTestUrl2WithFragment("http://other.page.com#frag"); | |
51 const GURL kTestUrl2WithFragment2("http://other.page.com#frag2"); | |
52 const ClientId kTestClientId1(kTestClientNamespace, "1234"); | |
53 const ClientId kTestClientId2(kTestClientNamespace, "5678"); | |
54 const ClientId kTestClientId3(kTestClientNamespace, "42"); | |
55 const ClientId kTestUserRequestedClientId(kUserRequestedNamespace, "714"); | |
56 const int64_t kTestFileSize = 876543LL; | |
57 const base::string16 kTestTitle = base::UTF8ToUTF16("a title"); | |
58 | |
59 bool URLSpecContains(std::string contains_value, const GURL& url) { | |
60 std::string spec = url.spec(); | |
61 return spec.find(contains_value) != std::string::npos; | |
62 } | |
63 | |
64 } // namespace | |
65 | |
66 class OfflinePageModelImplTest | |
67 : public testing::Test, | |
68 public OfflinePageModel::Observer, | |
69 public OfflinePageTestArchiver::Observer, | |
70 public base::SupportsWeakPtr<OfflinePageModelImplTest> { | |
71 public: | |
72 OfflinePageModelImplTest(); | |
73 ~OfflinePageModelImplTest() override; | |
74 | |
75 void SetUp() override; | |
76 void TearDown() override; | |
77 | |
78 // OfflinePageModel::Observer implementation. | |
79 void OfflinePageModelLoaded(OfflinePageModel* model) override; | |
80 void OfflinePageModelChanged(OfflinePageModel* model) override; | |
81 void OfflinePageDeleted(int64_t offline_id, | |
82 const ClientId& client_id) override; | |
83 | |
84 // OfflinePageTestArchiver::Observer implementation. | |
85 void SetLastPathCreatedByArchiver(const base::FilePath& file_path) override; | |
86 | |
87 // OfflinePageModel callbacks. | |
88 void OnSavePageDone(SavePageResult result, int64_t offline_id); | |
89 void OnDeletePageDone(DeletePageResult result); | |
90 void OnCheckPagesExistOfflineDone(const CheckPagesExistOfflineResult& result); | |
91 void OnGetOfflineIdsForClientIdDone(MultipleOfflineIdResult* storage, | |
92 const MultipleOfflineIdResult& result); | |
93 void OnGetSingleOfflinePageItemResult( | |
94 std::unique_ptr<OfflinePageItem>* storage, | |
95 const OfflinePageItem* result); | |
96 void OnGetMultipleOfflinePageItemsResult( | |
97 MultipleOfflinePageItemResult* storage, | |
98 const MultipleOfflinePageItemResult& result); | |
99 void OnPagesExpired(bool result); | |
100 | |
101 // OfflinePageMetadataStore callbacks. | |
102 void OnStoreUpdateDone(bool /* success */); | |
103 | |
104 std::unique_ptr<OfflinePageTestArchiver> BuildArchiver( | |
105 const GURL& url, | |
106 OfflinePageArchiver::ArchiverResult result); | |
107 std::unique_ptr<OfflinePageMetadataStore> BuildStore(); | |
108 std::unique_ptr<OfflinePageModelImpl> BuildModel( | |
109 std::unique_ptr<OfflinePageMetadataStore> store); | |
110 void ResetModel(); | |
111 | |
112 // Utility methods. | |
113 // Runs until all of the tasks that are not delayed are gone from the task | |
114 // queue. | |
115 void PumpLoop(); | |
116 // Fast-forwards virtual time by |delta|, causing tasks with a remaining | |
117 // delay less than or equal to |delta| to be executed. | |
118 void FastForwardBy(base::TimeDelta delta); | |
119 void ResetResults(); | |
120 | |
121 OfflinePageTestStore* GetStore(); | |
122 | |
123 MultipleOfflinePageItemResult GetAllPages(); | |
124 MultipleOfflinePageItemResult GetPagesByClientIds( | |
125 const std::vector<ClientId>& client_ids); | |
126 void DeletePagesByClientIds(const std::vector<ClientId>& client_ids); | |
127 | |
128 // Saves the page without waiting for it to finish. | |
129 void SavePageWithArchiverAsync( | |
130 const GURL& url, | |
131 const ClientId& client_id, | |
132 const GURL& original_url, | |
133 std::unique_ptr<OfflinePageArchiver> archiver); | |
134 | |
135 // All 3 methods below will wait for the save to finish. | |
136 void SavePageWithArchiver( | |
137 const GURL& url, | |
138 const ClientId& client_id, | |
139 std::unique_ptr<OfflinePageArchiver> archiver); | |
140 void SavePageWithArchiverResult(const GURL& url, | |
141 const ClientId& client_id, | |
142 OfflinePageArchiver::ArchiverResult result); | |
143 // Returns the offline ID of the saved page. | |
144 std::pair<SavePageResult, int64_t> SavePage(const GURL& url, | |
145 const ClientId& client_id); | |
146 | |
147 void DeletePage(int64_t offline_id, const DeletePageCallback& callback) { | |
148 std::vector<int64_t> offline_ids; | |
149 offline_ids.push_back(offline_id); | |
150 model()->DeletePagesByOfflineId(offline_ids, callback); | |
151 } | |
152 | |
153 bool HasPages(std::string name_space); | |
154 | |
155 CheckPagesExistOfflineResult CheckPagesExistOffline(std::set<GURL>); | |
156 | |
157 MultipleOfflineIdResult GetOfflineIdsForClientId(const ClientId& client_id); | |
158 | |
159 std::unique_ptr<OfflinePageItem> GetPageByOfflineId(int64_t offline_id); | |
160 | |
161 MultipleOfflinePageItemResult GetPagesByFinalURL(const GURL& url); | |
162 MultipleOfflinePageItemResult GetPagesByAllURLS(const GURL& url); | |
163 | |
164 OfflinePageModelImpl* model() { return model_.get(); } | |
165 | |
166 int64_t last_save_offline_id() const { return last_save_offline_id_; } | |
167 | |
168 SavePageResult last_save_result() const { return last_save_result_; } | |
169 | |
170 DeletePageResult last_delete_result() const { return last_delete_result_; } | |
171 | |
172 int64_t last_deleted_offline_id() const { return last_deleted_offline_id_; } | |
173 | |
174 ClientId last_deleted_client_id() const { return last_deleted_client_id_; } | |
175 | |
176 const base::FilePath& last_archiver_path() { return last_archiver_path_; } | |
177 | |
178 int last_cleared_pages_count() const { return last_cleared_pages_count_; } | |
179 | |
180 DeletePageResult last_clear_page_result() const { | |
181 return last_clear_page_result_; | |
182 } | |
183 | |
184 bool last_expire_page_result() const { return last_expire_page_result_; } | |
185 | |
186 const base::HistogramTester& histograms() const { return histogram_tester_; } | |
187 | |
188 private: | |
189 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; | |
190 base::ThreadTaskRunnerHandle task_runner_handle_; | |
191 base::ScopedTempDir temp_dir_; | |
192 | |
193 std::unique_ptr<OfflinePageModelImpl> model_; | |
194 SavePageResult last_save_result_; | |
195 int64_t last_save_offline_id_; | |
196 DeletePageResult last_delete_result_; | |
197 base::FilePath last_archiver_path_; | |
198 int64_t last_deleted_offline_id_; | |
199 ClientId last_deleted_client_id_; | |
200 CheckPagesExistOfflineResult last_pages_exist_result_; | |
201 int last_cleared_pages_count_; | |
202 DeletePageResult last_clear_page_result_; | |
203 bool last_expire_page_result_; | |
204 | |
205 base::HistogramTester histogram_tester_; | |
206 }; | |
207 | |
208 OfflinePageModelImplTest::OfflinePageModelImplTest() | |
209 : task_runner_(new base::TestMockTimeTaskRunner), | |
210 task_runner_handle_(task_runner_), | |
211 last_save_result_(SavePageResult::CANCELLED), | |
212 last_save_offline_id_(-1), | |
213 last_delete_result_(DeletePageResult::CANCELLED), | |
214 last_deleted_offline_id_(-1) {} | |
215 | |
216 OfflinePageModelImplTest::~OfflinePageModelImplTest() {} | |
217 | |
218 void OfflinePageModelImplTest::SetUp() { | |
219 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
220 model_ = BuildModel(BuildStore()); | |
221 model_->AddObserver(this); | |
222 PumpLoop(); | |
223 } | |
224 | |
225 void OfflinePageModelImplTest::TearDown() { | |
226 model_->RemoveObserver(this); | |
227 model_.reset(); | |
228 PumpLoop(); | |
229 } | |
230 | |
231 void OfflinePageModelImplTest::OfflinePageModelLoaded(OfflinePageModel* model) { | |
232 ASSERT_EQ(model_.get(), model); | |
233 } | |
234 | |
235 void OfflinePageModelImplTest::OfflinePageModelChanged( | |
236 OfflinePageModel* model) { | |
237 ASSERT_EQ(model_.get(), model); | |
238 } | |
239 | |
240 void OfflinePageModelImplTest::OfflinePageDeleted(int64_t offline_id, | |
241 const ClientId& client_id) { | |
242 last_deleted_offline_id_ = offline_id; | |
243 last_deleted_client_id_ = client_id; | |
244 } | |
245 | |
246 void OfflinePageModelImplTest::SetLastPathCreatedByArchiver( | |
247 const base::FilePath& file_path) { | |
248 last_archiver_path_ = file_path; | |
249 } | |
250 | |
251 void OfflinePageModelImplTest::OnSavePageDone(SavePageResult result, | |
252 int64_t offline_id) { | |
253 last_save_result_ = result; | |
254 last_save_offline_id_ = offline_id; | |
255 } | |
256 | |
257 void OfflinePageModelImplTest::OnDeletePageDone(DeletePageResult result) { | |
258 last_delete_result_ = result; | |
259 } | |
260 | |
261 void OfflinePageModelImplTest::OnCheckPagesExistOfflineDone( | |
262 const CheckPagesExistOfflineResult& result) { | |
263 last_pages_exist_result_ = result; | |
264 } | |
265 | |
266 void OfflinePageModelImplTest::OnStoreUpdateDone(bool /* success - ignored */) { | |
267 } | |
268 | |
269 std::unique_ptr<OfflinePageTestArchiver> | |
270 OfflinePageModelImplTest::BuildArchiver( | |
271 const GURL& url, | |
272 OfflinePageArchiver::ArchiverResult result) { | |
273 return std::unique_ptr<OfflinePageTestArchiver>( | |
274 new OfflinePageTestArchiver(this, url, result, kTestTitle, kTestFileSize, | |
275 base::ThreadTaskRunnerHandle::Get())); | |
276 } | |
277 | |
278 std::unique_ptr<OfflinePageMetadataStore> | |
279 OfflinePageModelImplTest::BuildStore() { | |
280 return std::unique_ptr<OfflinePageMetadataStore>( | |
281 new OfflinePageTestStore(base::ThreadTaskRunnerHandle::Get())); | |
282 } | |
283 | |
284 std::unique_ptr<OfflinePageModelImpl> OfflinePageModelImplTest::BuildModel( | |
285 std::unique_ptr<OfflinePageMetadataStore> store) { | |
286 return std::unique_ptr<OfflinePageModelImpl>( | |
287 new OfflinePageModelImpl(std::move(store), temp_dir_.GetPath(), | |
288 base::ThreadTaskRunnerHandle::Get())); | |
289 } | |
290 | |
291 void OfflinePageModelImplTest::ResetModel() { | |
292 model_->RemoveObserver(this); | |
293 OfflinePageTestStore* old_store = GetStore(); | |
294 std::unique_ptr<OfflinePageMetadataStore> new_store( | |
295 new OfflinePageTestStore(*old_store)); | |
296 model_ = BuildModel(std::move(new_store)); | |
297 model_->AddObserver(this); | |
298 PumpLoop(); | |
299 } | |
300 | |
301 void OfflinePageModelImplTest::PumpLoop() { | |
302 task_runner_->RunUntilIdle(); | |
303 } | |
304 | |
305 void OfflinePageModelImplTest::FastForwardBy(base::TimeDelta delta) { | |
306 task_runner_->FastForwardBy(delta); | |
307 } | |
308 | |
309 void OfflinePageModelImplTest::ResetResults() { | |
310 last_save_result_ = SavePageResult::CANCELLED; | |
311 last_delete_result_ = DeletePageResult::CANCELLED; | |
312 last_archiver_path_.clear(); | |
313 last_pages_exist_result_.clear(); | |
314 last_cleared_pages_count_ = 0; | |
315 } | |
316 | |
317 OfflinePageTestStore* OfflinePageModelImplTest::GetStore() { | |
318 return static_cast<OfflinePageTestStore*>(model()->GetStoreForTesting()); | |
319 } | |
320 | |
321 void OfflinePageModelImplTest::SavePageWithArchiverAsync( | |
322 const GURL& url, | |
323 const ClientId& client_id, | |
324 const GURL& original_url, | |
325 std::unique_ptr<OfflinePageArchiver> archiver) { | |
326 OfflinePageModel::SavePageParams save_page_params; | |
327 save_page_params.url = url; | |
328 save_page_params.client_id = client_id; | |
329 save_page_params.original_url = original_url; | |
330 model()->SavePage( | |
331 save_page_params, | |
332 std::move(archiver), | |
333 base::Bind(&OfflinePageModelImplTest::OnSavePageDone, AsWeakPtr())); | |
334 } | |
335 | |
336 void OfflinePageModelImplTest::SavePageWithArchiver( | |
337 const GURL& url, | |
338 const ClientId& client_id, | |
339 std::unique_ptr<OfflinePageArchiver> archiver) { | |
340 SavePageWithArchiverAsync(url, client_id, GURL(), std::move(archiver)); | |
341 PumpLoop(); | |
342 } | |
343 | |
344 void OfflinePageModelImplTest::SavePageWithArchiverResult( | |
345 const GURL& url, | |
346 const ClientId& client_id, | |
347 OfflinePageArchiver::ArchiverResult result) { | |
348 std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(url, result)); | |
349 SavePageWithArchiverAsync(url, client_id, GURL(), std::move(archiver)); | |
350 PumpLoop(); | |
351 } | |
352 | |
353 std::pair<SavePageResult, int64_t> | |
354 OfflinePageModelImplTest::SavePage(const GURL& url, const ClientId& client_id) { | |
355 std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver( | |
356 url, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED)); | |
357 SavePageWithArchiverAsync(url, client_id, GURL(), std::move(archiver)); | |
358 PumpLoop(); | |
359 return std::make_pair(last_save_result_, last_save_offline_id_); | |
360 } | |
361 | |
362 MultipleOfflinePageItemResult OfflinePageModelImplTest::GetAllPages() { | |
363 MultipleOfflinePageItemResult result; | |
364 model()->GetAllPages( | |
365 base::Bind(&OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult, | |
366 AsWeakPtr(), base::Unretained(&result))); | |
367 PumpLoop(); | |
368 return result; | |
369 } | |
370 | |
371 MultipleOfflinePageItemResult OfflinePageModelImplTest::GetPagesByClientIds( | |
372 const std::vector<ClientId>& client_ids) { | |
373 MultipleOfflinePageItemResult result; | |
374 model()->GetPagesByClientIds( | |
375 client_ids, | |
376 base::Bind(&OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult, | |
377 AsWeakPtr(), base::Unretained(&result))); | |
378 PumpLoop(); | |
379 return result; | |
380 } | |
381 | |
382 void OfflinePageModelImplTest::DeletePagesByClientIds( | |
383 const std::vector<ClientId>& client_ids) { | |
384 model()->DeletePagesByClientIds( | |
385 client_ids, | |
386 base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, AsWeakPtr())); | |
387 PumpLoop(); | |
388 } | |
389 | |
390 CheckPagesExistOfflineResult OfflinePageModelImplTest::CheckPagesExistOffline( | |
391 std::set<GURL> pages) { | |
392 model()->CheckPagesExistOffline( | |
393 pages, base::Bind(&OfflinePageModelImplTest::OnCheckPagesExistOfflineDone, | |
394 AsWeakPtr())); | |
395 PumpLoop(); | |
396 return last_pages_exist_result_; | |
397 } | |
398 | |
399 MultipleOfflineIdResult OfflinePageModelImplTest::GetOfflineIdsForClientId( | |
400 const ClientId& client_id) { | |
401 MultipleOfflineIdResult result; | |
402 model()->GetOfflineIdsForClientId( | |
403 client_id, | |
404 base::Bind(&OfflinePageModelImplTest::OnGetOfflineIdsForClientIdDone, | |
405 AsWeakPtr(), base::Unretained(&result))); | |
406 PumpLoop(); | |
407 return result; | |
408 } | |
409 | |
410 void OfflinePageModelImplTest::OnGetOfflineIdsForClientIdDone( | |
411 MultipleOfflineIdResult* storage, | |
412 const MultipleOfflineIdResult& result) { | |
413 *storage = result; | |
414 } | |
415 | |
416 std::unique_ptr<OfflinePageItem> OfflinePageModelImplTest::GetPageByOfflineId( | |
417 int64_t offline_id) { | |
418 std::unique_ptr<OfflinePageItem> result = nullptr; | |
419 model()->GetPageByOfflineId( | |
420 offline_id, | |
421 base::Bind(&OfflinePageModelImplTest::OnGetSingleOfflinePageItemResult, | |
422 AsWeakPtr(), base::Unretained(&result))); | |
423 PumpLoop(); | |
424 return result; | |
425 } | |
426 | |
427 void OfflinePageModelImplTest::OnGetSingleOfflinePageItemResult( | |
428 std::unique_ptr<OfflinePageItem>* storage, | |
429 const OfflinePageItem* result) { | |
430 if (result == nullptr) { | |
431 storage->reset(nullptr); | |
432 return; | |
433 } | |
434 | |
435 *storage = base::MakeUnique<OfflinePageItem>(*result); | |
436 } | |
437 | |
438 void OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult( | |
439 MultipleOfflinePageItemResult* storage, | |
440 const MultipleOfflinePageItemResult& result) { | |
441 *storage = result; | |
442 } | |
443 | |
444 void OfflinePageModelImplTest::OnPagesExpired(bool result) { | |
445 last_expire_page_result_ = result; | |
446 } | |
447 | |
448 MultipleOfflinePageItemResult OfflinePageModelImplTest::GetPagesByFinalURL( | |
449 const GURL& url) { | |
450 MultipleOfflinePageItemResult result; | |
451 model()->GetPagesByURL( | |
452 url, | |
453 OfflinePageModel::URLSearchMode::SEARCH_BY_FINAL_URL_ONLY, | |
454 base::Bind(&OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult, | |
455 AsWeakPtr(), base::Unretained(&result))); | |
456 PumpLoop(); | |
457 return result; | |
458 } | |
459 | |
460 MultipleOfflinePageItemResult OfflinePageModelImplTest::GetPagesByAllURLS( | |
461 const GURL& url) { | |
462 MultipleOfflinePageItemResult result; | |
463 model()->GetPagesByURL( | |
464 url, | |
465 OfflinePageModel::URLSearchMode::SEARCH_BY_ALL_URLS, | |
466 base::Bind(&OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult, | |
467 AsWeakPtr(), base::Unretained(&result))); | |
468 PumpLoop(); | |
469 return result; | |
470 } | |
471 | |
472 bool OfflinePageModelImplTest::HasPages(std::string name_space) { | |
473 MultipleOfflinePageItemResult all_pages = GetAllPages(); | |
474 for (const auto& page : all_pages) { | |
475 if (page.client_id.name_space == name_space) | |
476 return true; | |
477 } | |
478 | |
479 return false; | |
480 } | |
481 | |
482 TEST_F(OfflinePageModelImplTest, SavePageSuccessful) { | |
483 EXPECT_FALSE(HasPages(kTestClientNamespace)); | |
484 | |
485 std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver( | |
486 kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED)); | |
487 SavePageWithArchiverAsync( | |
488 kTestUrl, kTestClientId1, kTestUrl2, std::move(archiver)); | |
489 PumpLoop(); | |
490 EXPECT_TRUE(HasPages(kTestClientNamespace)); | |
491 | |
492 OfflinePageTestStore* store = GetStore(); | |
493 EXPECT_EQ(kTestUrl, store->last_saved_page().url); | |
494 EXPECT_EQ(kTestClientId1.id, store->last_saved_page().client_id.id); | |
495 EXPECT_EQ(kTestClientId1.name_space, | |
496 store->last_saved_page().client_id.name_space); | |
497 // Save last_archiver_path since it will be referred to later. | |
498 base::FilePath archiver_path = last_archiver_path(); | |
499 EXPECT_EQ(archiver_path, store->last_saved_page().file_path); | |
500 EXPECT_EQ(kTestFileSize, store->last_saved_page().file_size); | |
501 EXPECT_EQ(SavePageResult::SUCCESS, last_save_result()); | |
502 ResetResults(); | |
503 | |
504 const std::vector<OfflinePageItem>& offline_pages = GetAllPages(); | |
505 | |
506 ASSERT_EQ(1UL, offline_pages.size()); | |
507 EXPECT_EQ(kTestUrl, offline_pages[0].url); | |
508 EXPECT_EQ(kTestClientId1.id, offline_pages[0].client_id.id); | |
509 EXPECT_EQ(kTestClientId1.name_space, offline_pages[0].client_id.name_space); | |
510 EXPECT_EQ(archiver_path, offline_pages[0].file_path); | |
511 EXPECT_EQ(kTestFileSize, offline_pages[0].file_size); | |
512 EXPECT_EQ(0, offline_pages[0].access_count); | |
513 EXPECT_EQ(0, offline_pages[0].flags); | |
514 EXPECT_EQ(kTestTitle, offline_pages[0].title); | |
515 EXPECT_EQ(kTestUrl2, offline_pages[0].original_url); | |
516 } | |
517 | |
518 TEST_F(OfflinePageModelImplTest, SavePageOfflineArchiverCancelled) { | |
519 SavePageWithArchiverResult( | |
520 kTestUrl, kTestClientId1, | |
521 OfflinePageArchiver::ArchiverResult::ERROR_CANCELED); | |
522 EXPECT_EQ(SavePageResult::CANCELLED, last_save_result()); | |
523 } | |
524 | |
525 TEST_F(OfflinePageModelImplTest, SavePageOfflineArchiverDeviceFull) { | |
526 SavePageWithArchiverResult( | |
527 kTestUrl, kTestClientId1, | |
528 OfflinePageArchiver::ArchiverResult::ERROR_DEVICE_FULL); | |
529 EXPECT_EQ(SavePageResult::DEVICE_FULL, last_save_result()); | |
530 } | |
531 | |
532 TEST_F(OfflinePageModelImplTest, SavePageOfflineArchiverContentUnavailable) { | |
533 SavePageWithArchiverResult( | |
534 kTestUrl, kTestClientId1, | |
535 OfflinePageArchiver::ArchiverResult::ERROR_CONTENT_UNAVAILABLE); | |
536 EXPECT_EQ(SavePageResult::CONTENT_UNAVAILABLE, last_save_result()); | |
537 } | |
538 | |
539 TEST_F(OfflinePageModelImplTest, SavePageOfflineCreationFailed) { | |
540 SavePageWithArchiverResult( | |
541 kTestUrl, kTestClientId1, | |
542 OfflinePageArchiver::ArchiverResult::ERROR_ARCHIVE_CREATION_FAILED); | |
543 EXPECT_EQ(SavePageResult::ARCHIVE_CREATION_FAILED, last_save_result()); | |
544 } | |
545 | |
546 TEST_F(OfflinePageModelImplTest, SavePageOfflineArchiverReturnedWrongUrl) { | |
547 std::unique_ptr<OfflinePageTestArchiver> archiver( | |
548 BuildArchiver(GURL("http://other.random.url.com"), | |
549 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED)); | |
550 SavePageWithArchiver(kTestUrl, kTestClientId1, std::move(archiver)); | |
551 EXPECT_EQ(SavePageResult::ARCHIVE_CREATION_FAILED, last_save_result()); | |
552 } | |
553 | |
554 TEST_F(OfflinePageModelImplTest, SavePageOfflineCreationStoreWriteFailure) { | |
555 GetStore()->set_test_scenario( | |
556 OfflinePageTestStore::TestScenario::WRITE_FAILED); | |
557 SavePageWithArchiverResult( | |
558 kTestUrl, kTestClientId1, | |
559 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED); | |
560 EXPECT_EQ(SavePageResult::STORE_FAILURE, last_save_result()); | |
561 } | |
562 | |
563 TEST_F(OfflinePageModelImplTest, SavePageLocalFileFailed) { | |
564 // Don't create archiver since it will not be needed for pages that are not | |
565 // going to be saved. | |
566 SavePageWithArchiver( | |
567 kFileUrl, kTestClientId1, std::unique_ptr<OfflinePageTestArchiver>()); | |
568 EXPECT_EQ(SavePageResult::SKIPPED, last_save_result()); | |
569 } | |
570 | |
571 TEST_F(OfflinePageModelImplTest, SavePageOfflineArchiverTwoPages) { | |
572 std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver( | |
573 kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED)); | |
574 // archiver_ptr will be valid until after first PumpLoop() call after | |
575 // CompleteCreateArchive() is called. | |
576 OfflinePageTestArchiver* archiver_ptr = archiver.get(); | |
577 archiver_ptr->set_delayed(true); | |
578 SavePageWithArchiverAsync( | |
579 kTestUrl, kTestClientId1, GURL(), std::move(archiver)); | |
580 EXPECT_TRUE(archiver_ptr->create_archive_called()); | |
581 | |
582 // Request to save another page. | |
583 SavePage(kTestUrl2, kTestClientId2); | |
584 | |
585 OfflinePageTestStore* store = GetStore(); | |
586 | |
587 EXPECT_EQ(kTestUrl2, store->last_saved_page().url); | |
588 EXPECT_EQ(kTestClientId2, store->last_saved_page().client_id); | |
589 base::FilePath archiver_path2 = last_archiver_path(); | |
590 EXPECT_EQ(archiver_path2, store->last_saved_page().file_path); | |
591 EXPECT_EQ(kTestFileSize, store->last_saved_page().file_size); | |
592 EXPECT_EQ(SavePageResult::SUCCESS, last_save_result()); | |
593 | |
594 ResetResults(); | |
595 | |
596 archiver_ptr->CompleteCreateArchive(); | |
597 // After this pump loop archiver_ptr is invalid. | |
598 PumpLoop(); | |
599 | |
600 EXPECT_EQ(kTestUrl, store->last_saved_page().url); | |
601 EXPECT_EQ(kTestClientId1, store->last_saved_page().client_id); | |
602 base::FilePath archiver_path = last_archiver_path(); | |
603 EXPECT_EQ(archiver_path, store->last_saved_page().file_path); | |
604 EXPECT_EQ(kTestFileSize, store->last_saved_page().file_size); | |
605 EXPECT_EQ(SavePageResult::SUCCESS, last_save_result()); | |
606 | |
607 ResetResults(); | |
608 | |
609 const std::vector<OfflinePageItem>& offline_pages = GetAllPages(); | |
610 | |
611 EXPECT_EQ(2UL, offline_pages.size()); | |
612 // Offline IDs are random, so the order of the pages is also random | |
613 // So load in the right page for the validation below. | |
614 const OfflinePageItem* page1 = nullptr; | |
615 const OfflinePageItem* page2 = nullptr; | |
616 if (offline_pages[0].client_id == kTestClientId1) { | |
617 page1 = &offline_pages[0]; | |
618 page2 = &offline_pages[1]; | |
619 } else { | |
620 page1 = &offline_pages[1]; | |
621 page2 = &offline_pages[0]; | |
622 } | |
623 | |
624 EXPECT_EQ(kTestUrl, page1->url); | |
625 EXPECT_EQ(kTestClientId1, page1->client_id); | |
626 EXPECT_EQ(archiver_path, page1->file_path); | |
627 EXPECT_EQ(kTestFileSize, page1->file_size); | |
628 EXPECT_EQ(0, page1->access_count); | |
629 EXPECT_EQ(0, page1->flags); | |
630 EXPECT_EQ(kTestUrl2, page2->url); | |
631 EXPECT_EQ(kTestClientId2, page2->client_id); | |
632 EXPECT_EQ(archiver_path2, page2->file_path); | |
633 EXPECT_EQ(kTestFileSize, page2->file_size); | |
634 EXPECT_EQ(0, page2->access_count); | |
635 EXPECT_EQ(0, page2->flags); | |
636 } | |
637 | |
638 TEST_F(OfflinePageModelImplTest, MarkPageAccessed) { | |
639 SavePage(kTestUrl, kTestClientId1); | |
640 | |
641 // This will increase access_count by one. | |
642 model()->MarkPageAccessed(last_save_offline_id()); | |
643 PumpLoop(); | |
644 | |
645 const std::vector<OfflinePageItem>& offline_pages = GetAllPages(); | |
646 | |
647 EXPECT_EQ(1UL, offline_pages.size()); | |
648 EXPECT_EQ(kTestUrl, offline_pages[0].url); | |
649 EXPECT_EQ(kTestClientId1, offline_pages[0].client_id); | |
650 EXPECT_EQ(kTestFileSize, offline_pages[0].file_size); | |
651 EXPECT_EQ(1, offline_pages[0].access_count); | |
652 } | |
653 | |
654 TEST_F(OfflinePageModelImplTest, GetAllPagesStoreEmpty) { | |
655 const std::vector<OfflinePageItem>& offline_pages = GetAllPages(); | |
656 | |
657 EXPECT_EQ(0UL, offline_pages.size()); | |
658 } | |
659 | |
660 TEST_F(OfflinePageModelImplTest, DeletePageSuccessful) { | |
661 OfflinePageTestStore* store = GetStore(); | |
662 | |
663 // Save one page. | |
664 SavePage(kTestUrl, kTestClientId1); | |
665 int64_t offline1 = last_save_offline_id(); | |
666 EXPECT_EQ(SavePageResult::SUCCESS, last_save_result()); | |
667 EXPECT_EQ(1u, store->GetAllPages().size()); | |
668 | |
669 ResetResults(); | |
670 | |
671 // Save another page. | |
672 SavePage(kTestUrl2, kTestClientId2); | |
673 int64_t offline2 = last_save_offline_id(); | |
674 EXPECT_EQ(SavePageResult::SUCCESS, last_save_result()); | |
675 EXPECT_EQ(2u, store->GetAllPages().size()); | |
676 | |
677 ResetResults(); | |
678 | |
679 // Delete one page. | |
680 DeletePage(offline1, base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, | |
681 AsWeakPtr())); | |
682 | |
683 PumpLoop(); | |
684 | |
685 EXPECT_EQ(last_deleted_offline_id(), offline1); | |
686 EXPECT_EQ(last_deleted_client_id(), kTestClientId1); | |
687 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); | |
688 ASSERT_EQ(1u, store->GetAllPages().size()); | |
689 EXPECT_EQ(kTestUrl2, store->GetAllPages()[0].url); | |
690 | |
691 // Delete another page. | |
692 DeletePage(offline2, base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, | |
693 AsWeakPtr())); | |
694 | |
695 ResetResults(); | |
696 | |
697 PumpLoop(); | |
698 | |
699 EXPECT_EQ(last_deleted_offline_id(), offline2); | |
700 EXPECT_EQ(last_deleted_client_id(), kTestClientId2); | |
701 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); | |
702 EXPECT_EQ(0u, store->GetAllPages().size()); | |
703 } | |
704 | |
705 TEST_F(OfflinePageModelImplTest, DeleteCachedPageByPredicateUserRequested) { | |
706 OfflinePageTestStore* store = GetStore(); | |
707 | |
708 // Save one page. | |
709 SavePage(kTestUrl, kTestClientId1); | |
710 int64_t offline1 = last_save_offline_id(); | |
711 EXPECT_EQ(SavePageResult::SUCCESS, last_save_result()); | |
712 EXPECT_EQ(1u, store->GetAllPages().size()); | |
713 | |
714 ResetResults(); | |
715 | |
716 // Save an user-requested page in same domain. | |
717 SavePage(kTestUrl, kTestUserRequestedClientId); | |
718 int64_t offline2 = last_save_offline_id(); | |
719 EXPECT_EQ(SavePageResult::SUCCESS, last_save_result()); | |
720 EXPECT_EQ(2u, store->GetAllPages().size()); | |
721 | |
722 ResetResults(); | |
723 | |
724 // Delete the second page. | |
725 model()->DeleteCachedPagesByURLPredicate( | |
726 base::Bind(&URLSpecContains, "example.com"), | |
727 base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, AsWeakPtr())); | |
728 | |
729 PumpLoop(); | |
730 | |
731 EXPECT_EQ(last_deleted_offline_id(), offline1); | |
732 EXPECT_EQ(last_deleted_client_id(), kTestClientId1); | |
733 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); | |
734 ASSERT_EQ(1u, store->GetAllPages().size()); | |
735 EXPECT_EQ(kTestUrl, store->GetAllPages()[0].url); | |
736 EXPECT_EQ(offline2, store->GetAllPages()[0].offline_id); | |
737 } | |
738 | |
739 TEST_F(OfflinePageModelImplTest, DeleteCachedPageByPredicate) { | |
740 OfflinePageTestStore* store = GetStore(); | |
741 | |
742 // Save one page. | |
743 SavePage(kTestUrl, kTestClientId1); | |
744 int64_t offline1 = last_save_offline_id(); | |
745 EXPECT_EQ(SavePageResult::SUCCESS, last_save_result()); | |
746 EXPECT_EQ(1u, store->GetAllPages().size()); | |
747 | |
748 ResetResults(); | |
749 | |
750 // Save another page. | |
751 SavePage(kTestUrl2, kTestClientId2); | |
752 int64_t offline2 = last_save_offline_id(); | |
753 EXPECT_EQ(SavePageResult::SUCCESS, last_save_result()); | |
754 EXPECT_EQ(2u, store->GetAllPages().size()); | |
755 | |
756 ResetResults(); | |
757 | |
758 // Delete the second page. | |
759 model()->DeleteCachedPagesByURLPredicate( | |
760 base::Bind(&URLSpecContains, "page.com"), | |
761 base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, AsWeakPtr())); | |
762 | |
763 PumpLoop(); | |
764 | |
765 EXPECT_EQ(last_deleted_offline_id(), offline2); | |
766 EXPECT_EQ(last_deleted_client_id(), kTestClientId2); | |
767 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); | |
768 ASSERT_EQ(1u, store->GetAllPages().size()); | |
769 EXPECT_EQ(kTestUrl, store->GetAllPages()[0].url); | |
770 | |
771 ResetResults(); | |
772 | |
773 // Delete the first page. | |
774 model()->DeleteCachedPagesByURLPredicate( | |
775 base::Bind(&URLSpecContains, "example.com"), | |
776 base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, AsWeakPtr())); | |
777 | |
778 PumpLoop(); | |
779 | |
780 EXPECT_EQ(last_deleted_offline_id(), offline1); | |
781 EXPECT_EQ(last_deleted_client_id(), kTestClientId1); | |
782 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); | |
783 EXPECT_EQ(0u, store->GetAllPages().size()); | |
784 } | |
785 | |
786 TEST_F(OfflinePageModelImplTest, DeletePageNotFound) { | |
787 DeletePage(1234LL, base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, | |
788 AsWeakPtr())); | |
789 PumpLoop(); | |
790 | |
791 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); | |
792 | |
793 ResetResults(); | |
794 | |
795 model()->DeleteCachedPagesByURLPredicate( | |
796 base::Bind(&URLSpecContains, "page.com"), | |
797 base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, AsWeakPtr())); | |
798 PumpLoop(); | |
799 | |
800 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); | |
801 } | |
802 | |
803 TEST_F(OfflinePageModelImplTest, DeletePageStoreFailureOnRemove) { | |
804 // Save a page. | |
805 SavePage(kTestUrl, kTestClientId1); | |
806 int64_t offline_id = last_save_offline_id(); | |
807 ResetResults(); | |
808 | |
809 // Try to delete this page. | |
810 GetStore()->set_test_scenario( | |
811 OfflinePageTestStore::TestScenario::REMOVE_FAILED); | |
812 DeletePage(offline_id, base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, | |
813 AsWeakPtr())); | |
814 PumpLoop(); | |
815 EXPECT_EQ(DeletePageResult::STORE_FAILURE, last_delete_result()); | |
816 } | |
817 | |
818 TEST_F(OfflinePageModelImplTest, DetectThatOfflineCopyIsMissing) { | |
819 // Save a page. | |
820 SavePage(kTestUrl, kTestClientId1); | |
821 int64_t offline_id = last_save_offline_id(); | |
822 | |
823 ResetResults(); | |
824 | |
825 std::unique_ptr<OfflinePageItem> page = GetPageByOfflineId(offline_id); | |
826 | |
827 // Delete the offline copy of the page. | |
828 base::DeleteFile(page->file_path, false); | |
829 | |
830 // Resetting the model will cause a consistency check. | |
831 ResetModel(); | |
832 | |
833 PumpLoop(); | |
834 | |
835 // Check if the page has been expired. | |
836 EXPECT_EQ(0UL, GetAllPages().size()); | |
837 } | |
838 | |
839 TEST_F(OfflinePageModelImplTest, DetectThatOfflineCopyIsMissingAfterLoad) { | |
840 // Save a page. | |
841 SavePage(kTestUrl, kTestClientId1); | |
842 PumpLoop(); | |
843 int64_t offline_id = last_save_offline_id(); | |
844 | |
845 ResetResults(); | |
846 | |
847 std::unique_ptr<OfflinePageItem> page = GetPageByOfflineId(offline_id); | |
848 // Delete the offline copy of the page and check the metadata. | |
849 base::DeleteFile(page->file_path, false); | |
850 // Reseting the model should trigger the metadata consistency check as well. | |
851 ResetModel(); | |
852 PumpLoop(); | |
853 | |
854 // Check if the page has been expired. | |
855 EXPECT_EQ(0UL, GetAllPages().size()); | |
856 } | |
857 | |
858 TEST_F(OfflinePageModelImplTest, DetectThatHeadlessPageIsDeleted) { | |
859 // Save a page. | |
860 SavePage(kTestUrl, kTestClientId1); | |
861 PumpLoop(); | |
862 int64_t offline_id = last_save_offline_id(); | |
863 | |
864 ResetResults(); | |
865 std::unique_ptr<OfflinePageItem> page = GetPageByOfflineId(offline_id); | |
866 base::FilePath path = page->file_path; | |
867 EXPECT_TRUE(base::PathExists(path)); | |
868 GetStore()->ClearAllPages(); | |
869 | |
870 EXPECT_TRUE(base::PathExists(path)); | |
871 // Since we've manually changed the store, we have to reload the model to | |
872 // actually refresh the in-memory copy in model. Otherwise GetAllPages() would | |
873 // still have the page we saved above. | |
874 ResetModel(); | |
875 PumpLoop(); | |
876 | |
877 EXPECT_EQ(0UL, GetAllPages().size()); | |
878 EXPECT_FALSE(base::PathExists(path)); | |
879 } | |
880 | |
881 TEST_F(OfflinePageModelImplTest, DeleteMultiplePages) { | |
882 OfflinePageTestStore* store = GetStore(); | |
883 | |
884 // Save 3 pages. | |
885 SavePage(kTestUrl, kTestClientId1); | |
886 int64_t offline1 = last_save_offline_id(); | |
887 | |
888 SavePage(kTestUrl2, kTestClientId2); | |
889 int64_t offline2 = last_save_offline_id(); | |
890 | |
891 SavePage(kTestUrl3, kTestClientId3); | |
892 PumpLoop(); | |
893 | |
894 EXPECT_EQ(3u, store->GetAllPages().size()); | |
895 | |
896 // Delete multiple pages. | |
897 std::vector<int64_t> ids_to_delete; | |
898 ids_to_delete.push_back(offline2); | |
899 ids_to_delete.push_back(offline1); | |
900 ids_to_delete.push_back(23434LL); // Non-existent ID. | |
901 model()->DeletePagesByOfflineId( | |
902 ids_to_delete, | |
903 base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, AsWeakPtr())); | |
904 PumpLoop(); | |
905 | |
906 // Success is expected if at least one page is deleted successfully. | |
907 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); | |
908 EXPECT_EQ(1u, store->GetAllPages().size()); | |
909 } | |
910 | |
911 TEST_F(OfflinePageModelImplTest, GetPageByOfflineId) { | |
912 SavePage(kTestUrl, kTestClientId1); | |
913 int64_t offline1 = last_save_offline_id(); | |
914 SavePage(kTestUrl2, kTestClientId2); | |
915 int64_t offline2 = last_save_offline_id(); | |
916 | |
917 std::unique_ptr<OfflinePageItem> page = GetPageByOfflineId(offline1); | |
918 ASSERT_TRUE(page); | |
919 EXPECT_EQ(kTestUrl, page->url); | |
920 EXPECT_EQ(kTestClientId1, page->client_id); | |
921 EXPECT_EQ(kTestFileSize, page->file_size); | |
922 | |
923 page = GetPageByOfflineId(offline2); | |
924 ASSERT_TRUE(page); | |
925 EXPECT_EQ(kTestUrl2, page->url); | |
926 EXPECT_EQ(kTestClientId2, page->client_id); | |
927 EXPECT_EQ(kTestFileSize, page->file_size); | |
928 | |
929 page = GetPageByOfflineId(-42); | |
930 EXPECT_FALSE(page); | |
931 } | |
932 | |
933 TEST_F(OfflinePageModelImplTest, GetPagesByFinalURL) { | |
934 SavePage(kTestUrl, kTestClientId1); | |
935 SavePage(kTestUrl2, kTestClientId2); | |
936 | |
937 MultipleOfflinePageItemResult pages = GetPagesByFinalURL(kTestUrl2); | |
938 EXPECT_EQ(1U, pages.size()); | |
939 EXPECT_EQ(kTestUrl2, pages[0].url); | |
940 EXPECT_EQ(kTestClientId2, pages[0].client_id); | |
941 | |
942 pages = GetPagesByFinalURL(kTestUrl); | |
943 EXPECT_EQ(1U, pages.size()); | |
944 EXPECT_EQ(kTestUrl, pages[0].url); | |
945 EXPECT_EQ(kTestClientId1, pages[0].client_id); | |
946 | |
947 pages = GetPagesByFinalURL(GURL("http://foo")); | |
948 EXPECT_EQ(0U, pages.size()); | |
949 } | |
950 | |
951 TEST_F(OfflinePageModelImplTest, GetPagesByFinalURLWithFragmentStripped) { | |
952 SavePage(kTestUrl, kTestClientId1); | |
953 SavePage(kTestUrl2WithFragment, kTestClientId2); | |
954 | |
955 MultipleOfflinePageItemResult pages = | |
956 GetPagesByFinalURL(kTestUrlWithFragment); | |
957 EXPECT_EQ(1U, pages.size()); | |
958 EXPECT_EQ(kTestUrl, pages[0].url); | |
959 EXPECT_EQ(kTestClientId1, pages[0].client_id); | |
960 | |
961 pages = GetPagesByFinalURL(kTestUrl2); | |
962 EXPECT_EQ(1U, pages.size()); | |
963 EXPECT_EQ(kTestUrl2WithFragment, pages[0].url); | |
964 EXPECT_EQ(kTestClientId2, pages[0].client_id); | |
965 | |
966 pages = GetPagesByFinalURL(kTestUrl2WithFragment2); | |
967 EXPECT_EQ(1U, pages.size()); | |
968 EXPECT_EQ(kTestUrl2WithFragment, pages[0].url); | |
969 EXPECT_EQ(kTestClientId2, pages[0].client_id); | |
970 } | |
971 | |
972 TEST_F(OfflinePageModelImplTest, GetPagesByAllURLS) { | |
973 std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver( | |
974 kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED)); | |
975 SavePageWithArchiverAsync( | |
976 kTestUrl, kTestClientId1, kTestUrl2, std::move(archiver)); | |
977 PumpLoop(); | |
978 | |
979 SavePage(kTestUrl2, kTestClientId2); | |
980 | |
981 MultipleOfflinePageItemResult pages = GetPagesByAllURLS(kTestUrl2); | |
982 ASSERT_EQ(2U, pages.size()); | |
983 // Validates the items regardless their order. | |
984 int i = -1; | |
985 if (pages[0].url == kTestUrl2) | |
986 i = 0; | |
987 else if (pages[1].url == kTestUrl2) | |
988 i = 1; | |
989 ASSERT_NE(-1, i); | |
990 EXPECT_EQ(kTestUrl2, pages[i].url); | |
991 EXPECT_EQ(kTestClientId2, pages[i].client_id); | |
992 EXPECT_EQ(GURL(), pages[i].original_url); | |
993 EXPECT_EQ(kTestUrl, pages[1 - i].url); | |
994 EXPECT_EQ(kTestClientId1, pages[1 - i].client_id); | |
995 EXPECT_EQ(kTestUrl2, pages[1 - i].original_url); | |
996 } | |
997 | |
998 TEST_F(OfflinePageModelImplTest, CheckPagesExistOffline) { | |
999 SavePage(kTestUrl, kTestClientId1); | |
1000 SavePage(kTestUrl2, kTestClientId2); | |
1001 | |
1002 // TODO(dewittj): Remove the "Last N" restriction in favor of a better query | |
1003 // interface. See https://crbug.com/622763 for information. | |
1004 const ClientId last_n_client_id(kLastNNamespace, "1234"); | |
1005 SavePage(kTestUrl3, last_n_client_id); | |
1006 | |
1007 std::set<GURL> input; | |
1008 input.insert(kTestUrl); | |
1009 input.insert(kTestUrl2); | |
1010 input.insert(kTestUrl3); | |
1011 input.insert(kTestUrl4); | |
1012 | |
1013 CheckPagesExistOfflineResult existing_pages = CheckPagesExistOffline(input); | |
1014 EXPECT_EQ(2U, existing_pages.size()); | |
1015 EXPECT_NE(existing_pages.end(), existing_pages.find(kTestUrl)); | |
1016 EXPECT_NE(existing_pages.end(), existing_pages.find(kTestUrl2)); | |
1017 EXPECT_EQ(existing_pages.end(), existing_pages.find(kTestUrl3)); | |
1018 EXPECT_EQ(existing_pages.end(), existing_pages.find(kTestUrl4)); | |
1019 } | |
1020 | |
1021 TEST_F(OfflinePageModelImplTest, CanSaveURL) { | |
1022 EXPECT_TRUE(OfflinePageModel::CanSaveURL(GURL("http://foo"))); | |
1023 EXPECT_TRUE(OfflinePageModel::CanSaveURL(GURL("https://foo"))); | |
1024 EXPECT_FALSE(OfflinePageModel::CanSaveURL(GURL("file:///foo"))); | |
1025 EXPECT_FALSE(OfflinePageModel::CanSaveURL(GURL("data:image/png;base64,ab"))); | |
1026 EXPECT_FALSE(OfflinePageModel::CanSaveURL(GURL("chrome://version"))); | |
1027 EXPECT_FALSE(OfflinePageModel::CanSaveURL(GURL("chrome-native://newtab/"))); | |
1028 EXPECT_FALSE(OfflinePageModel::CanSaveURL(GURL("/invalid/url.mhtml"))); | |
1029 } | |
1030 | |
1031 TEST_F(OfflinePageModelImplTest, SaveRetrieveMultipleClientIds) { | |
1032 EXPECT_FALSE(HasPages(kTestClientNamespace)); | |
1033 SavePage(kTestUrl, kTestClientId1); | |
1034 int64_t offline1 = last_save_offline_id(); | |
1035 EXPECT_TRUE(HasPages(kTestClientNamespace)); | |
1036 | |
1037 SavePage(kTestUrl2, kTestClientId1); | |
1038 int64_t offline2 = last_save_offline_id(); | |
1039 | |
1040 EXPECT_NE(offline1, offline2); | |
1041 | |
1042 const std::vector<int64_t> ids = GetOfflineIdsForClientId(kTestClientId1); | |
1043 | |
1044 EXPECT_EQ(2UL, ids.size()); | |
1045 | |
1046 std::set<int64_t> id_set; | |
1047 for (size_t i = 0; i < ids.size(); i++) { | |
1048 id_set.insert(ids[i]); | |
1049 } | |
1050 | |
1051 EXPECT_TRUE(id_set.find(offline1) != id_set.end()); | |
1052 EXPECT_TRUE(id_set.find(offline2) != id_set.end()); | |
1053 } | |
1054 | |
1055 TEST_F(OfflinePageModelImplTest, SaveMultiplePagesWithSameURLBySameClientId) { | |
1056 EXPECT_FALSE(HasPages(kTestClientNamespace)); | |
1057 SavePage(kTestUrl, kTestClientId1); | |
1058 int64_t offline1 = last_save_offline_id(); | |
1059 EXPECT_TRUE(HasPages(kTestClientNamespace)); | |
1060 | |
1061 SavePage(kTestUrl, kTestClientId1); | |
1062 int64_t offline2 = last_save_offline_id(); | |
1063 | |
1064 EXPECT_NE(offline1, offline2); | |
1065 | |
1066 const std::vector<int64_t> ids = GetOfflineIdsForClientId(kTestClientId1); | |
1067 | |
1068 EXPECT_EQ(1UL, ids.size()); | |
1069 | |
1070 std::set<int64_t> id_set; | |
1071 for (size_t i = 0; i < ids.size(); i++) { | |
1072 id_set.insert(ids[i]); | |
1073 } | |
1074 | |
1075 EXPECT_TRUE(id_set.find(offline2) != id_set.end()); | |
1076 } | |
1077 | |
1078 TEST_F(OfflinePageModelImplTest, DownloadMetrics) { | |
1079 EXPECT_FALSE(HasPages(kUserRequestedNamespace)); | |
1080 SavePage(kTestUrl, kTestUserRequestedClientId); | |
1081 histograms().ExpectUniqueSample( | |
1082 "OfflinePages.DownloadSavedPageDuplicateCount", 1, 1); | |
1083 FastForwardBy(base::TimeDelta::FromMinutes(1)); | |
1084 histograms().ExpectTotalCount( | |
1085 "OfflinePages.DownloadSavedPageTimeSinceDuplicateSaved", 0); | |
1086 SavePage(kTestUrl, kTestUserRequestedClientId); | |
1087 histograms().ExpectTotalCount("OfflinePages.DownloadSavedPageDuplicateCount", | |
1088 2); | |
1089 histograms().ExpectBucketCount("OfflinePages.DownloadSavedPageDuplicateCount", | |
1090 2, 1); | |
1091 histograms().ExpectBucketCount("OfflinePages.DownloadSavedPageDuplicateCount", | |
1092 1, 1); | |
1093 histograms().ExpectTotalCount( | |
1094 "OfflinePages.DownloadSavedPageTimeSinceDuplicateSaved", 1); | |
1095 histograms().ExpectTotalCount( | |
1096 "OfflinePages.DownloadDeletedPageDuplicateCount", 0); | |
1097 | |
1098 // void DeletePage(int64_t offline_id, const DeletePageCallback& callback) { | |
1099 const std::vector<int64_t> ids = | |
1100 GetOfflineIdsForClientId(kTestUserRequestedClientId); | |
1101 ASSERT_EQ(2U, ids.size()); | |
1102 | |
1103 DeletePage(ids[0], base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, | |
1104 AsWeakPtr())); | |
1105 PumpLoop(); | |
1106 histograms().ExpectUniqueSample( | |
1107 "OfflinePages.DownloadDeletedPageDuplicateCount", 2, 1); | |
1108 DeletePage(ids[1], base::Bind(&OfflinePageModelImplTest::OnDeletePageDone, | |
1109 AsWeakPtr())); | |
1110 PumpLoop(); | |
1111 // No change when we delete the last page. | |
1112 histograms().ExpectTotalCount( | |
1113 "OfflinePages.DownloadDeletedPageDuplicateCount", 2); | |
1114 histograms().ExpectBucketCount( | |
1115 "OfflinePages.DownloadDeletedPageDuplicateCount", 1, 1); | |
1116 histograms().ExpectBucketCount( | |
1117 "OfflinePages.DownloadDeletedPageDuplicateCount", 2, 1); | |
1118 } | |
1119 | |
1120 TEST_F(OfflinePageModelImplTest, GetPagesByClientIds) { | |
1121 // We will save 2 pages. | |
1122 std::pair<SavePageResult, int64_t> saved_pages[3]; | |
1123 saved_pages[0] = SavePage(kTestUrl, kTestClientId1); | |
1124 saved_pages[1] = SavePage(kTestUrl2, kTestClientId2); | |
1125 | |
1126 for (const auto& save_result : saved_pages) { | |
1127 ASSERT_EQ(OfflinePageModel::SavePageResult::SUCCESS, | |
1128 std::get<0>(save_result)); | |
1129 } | |
1130 | |
1131 std::vector<ClientId> client_ids = {kTestClientId2}; | |
1132 std::vector<OfflinePageItem> offline_pages = GetPagesByClientIds(client_ids); | |
1133 EXPECT_EQ(1U, offline_pages.size()); | |
1134 | |
1135 const OfflinePageItem& item = offline_pages[0]; | |
1136 EXPECT_EQ(kTestClientId2.name_space, item.client_id.name_space); | |
1137 EXPECT_EQ(kTestClientId2.id, item.client_id.id); | |
1138 EXPECT_EQ(kTestUrl2, item.url); | |
1139 } | |
1140 | |
1141 TEST_F(OfflinePageModelImplTest, DeletePagesByClientIds) { | |
1142 // We will save 3 pages. | |
1143 std::pair<SavePageResult, int64_t> saved_pages[3]; | |
1144 saved_pages[0] = SavePage(kTestUrl, kTestClientId1); | |
1145 saved_pages[1] = SavePage(kTestUrl2, kTestClientId2); | |
1146 saved_pages[2] = SavePage(kTestUrl3, kTestClientId3); | |
1147 | |
1148 for (const auto& save_result : saved_pages) { | |
1149 ASSERT_EQ(OfflinePageModel::SavePageResult::SUCCESS, | |
1150 std::get<0>(save_result)); | |
1151 } | |
1152 | |
1153 std::vector<ClientId> client_ids = {kTestClientId1, kTestClientId2}; | |
1154 DeletePagesByClientIds(client_ids); | |
1155 std::vector<OfflinePageItem> offline_pages = GetAllPages(); | |
1156 ASSERT_EQ(1U, offline_pages.size()); | |
1157 | |
1158 const OfflinePageItem& item = offline_pages[0]; | |
1159 EXPECT_EQ(kTestClientId3.name_space, item.client_id.name_space); | |
1160 EXPECT_EQ(kTestClientId3.id, item.client_id.id); | |
1161 EXPECT_EQ(kTestUrl3, item.url); | |
1162 } | |
1163 | |
1164 TEST_F(OfflinePageModelImplTest, CustomTabsNamespace) { | |
1165 SavePage(kTestUrl, ClientId(kCCTNamespace, "123")); | |
1166 std::string histogram_name = "OfflinePages.SavePageResult."; | |
1167 histogram_name += kCCTNamespace; | |
1168 | |
1169 histograms().ExpectUniqueSample(histogram_name, | |
1170 static_cast<int>(SavePageResult::SUCCESS), 1); | |
1171 } | |
1172 | |
1173 TEST_F(OfflinePageModelImplTest, DownloadNamespace) { | |
1174 SavePage(kTestUrl, ClientId(kDownloadNamespace, "123")); | |
1175 std::string histogram_name = "OfflinePages.SavePageResult."; | |
1176 histogram_name += kDownloadNamespace; | |
1177 | |
1178 histograms().ExpectUniqueSample(histogram_name, | |
1179 static_cast<int>(SavePageResult::SUCCESS), 1); | |
1180 } | |
1181 | |
1182 TEST_F(OfflinePageModelImplTest, NewTabPageNamespace) { | |
1183 SavePage(kTestUrl, ClientId(kNTPSuggestionsNamespace, "123")); | |
1184 std::string histogram_name = "OfflinePages.SavePageResult."; | |
1185 histogram_name += kNTPSuggestionsNamespace; | |
1186 | |
1187 histograms().ExpectUniqueSample(histogram_name, | |
1188 static_cast<int>(SavePageResult::SUCCESS), 1); | |
1189 } | |
1190 | |
1191 TEST_F(OfflinePageModelImplTest, StoreResetSuccessful) { | |
1192 GetStore()->set_test_scenario( | |
1193 OfflinePageTestStore::TestScenario::LOAD_FAILED_RESET_SUCCESS); | |
1194 ResetModel(); | |
1195 | |
1196 const std::vector<OfflinePageItem>& offline_pages = GetAllPages(); | |
1197 | |
1198 EXPECT_TRUE(model()->is_loaded()); | |
1199 EXPECT_EQ(StoreState::LOADED, GetStore()->state()); | |
1200 EXPECT_EQ(0UL, offline_pages.size()); | |
1201 | |
1202 std::pair<SavePageResult, int64_t> result = | |
1203 SavePage(kTestUrl, ClientId(kDownloadNamespace, "123")); | |
1204 | |
1205 EXPECT_EQ(SavePageResult::SUCCESS, result.first); | |
1206 } | |
1207 | |
1208 TEST_F(OfflinePageModelImplTest, StoreResetFailed) { | |
1209 GetStore()->set_test_scenario( | |
1210 OfflinePageTestStore::TestScenario::LOAD_FAILED_RESET_FAILED); | |
1211 ResetModel(); | |
1212 | |
1213 const std::vector<OfflinePageItem>& offline_pages = GetAllPages(); | |
1214 | |
1215 EXPECT_TRUE(model()->is_loaded()); | |
1216 EXPECT_EQ(StoreState::FAILED_RESET, GetStore()->state()); | |
1217 EXPECT_EQ(0UL, offline_pages.size()); | |
1218 | |
1219 ResetResults(); | |
1220 std::pair<SavePageResult, int64_t> result = | |
1221 SavePage(kTestUrl, ClientId(kDownloadNamespace, "123")); | |
1222 | |
1223 EXPECT_EQ(SavePageResult::STORE_FAILURE, result.first); | |
1224 } | |
1225 | |
1226 TEST_F(OfflinePageModelImplTest, GetPagesMatchingQuery) { | |
1227 std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver( | |
1228 kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED)); | |
1229 SavePageWithArchiverAsync(kTestUrl, kTestClientId1, kTestUrl2, | |
1230 std::move(archiver)); | |
1231 PumpLoop(); | |
1232 | |
1233 std::vector<ClientId> client_ids{kTestClientId1}; | |
1234 OfflinePageModelQueryBuilder builder; | |
1235 builder.SetClientIds(OfflinePageModelQuery::Requirement::INCLUDE_MATCHING, | |
1236 client_ids); | |
1237 | |
1238 MultipleOfflinePageItemResult offline_pages; | |
1239 model()->GetPagesMatchingQuery( | |
1240 builder.Build(model()->GetPolicyController()), | |
1241 base::Bind(&OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult, | |
1242 AsWeakPtr(), base::Unretained(&offline_pages))); | |
1243 PumpLoop(); | |
1244 | |
1245 ASSERT_EQ(1UL, offline_pages.size()); | |
1246 EXPECT_EQ(kTestUrl, offline_pages[0].url); | |
1247 EXPECT_EQ(kTestClientId1.id, offline_pages[0].client_id.id); | |
1248 EXPECT_EQ(kTestClientId1.name_space, offline_pages[0].client_id.name_space); | |
1249 EXPECT_EQ(last_archiver_path(), offline_pages[0].file_path); | |
1250 EXPECT_EQ(kTestFileSize, offline_pages[0].file_size); | |
1251 EXPECT_EQ(0, offline_pages[0].access_count); | |
1252 EXPECT_EQ(0, offline_pages[0].flags); | |
1253 EXPECT_EQ(kTestTitle, offline_pages[0].title); | |
1254 EXPECT_EQ(kTestUrl2, offline_pages[0].original_url); | |
1255 } | |
1256 | |
1257 TEST(CommandLineFlagsTest, OfflineBookmarks) { | |
1258 // Disabled by default. | |
1259 EXPECT_FALSE(offline_pages::IsOfflineBookmarksEnabled()); | |
1260 | |
1261 // Check if feature is correctly enabled by command-line flag. | |
1262 base::test::ScopedFeatureList scoped_feature_list; | |
1263 scoped_feature_list.InitAndEnableFeature(kOfflineBookmarksFeature); | |
1264 EXPECT_TRUE(offline_pages::IsOfflineBookmarksEnabled()); | |
1265 } | |
1266 | |
1267 TEST(CommandLineFlagsTest, OffliningRecentPages) { | |
1268 // Enable offline bookmarks feature first. | |
1269 // TODO(dimich): once offline pages are enabled by default, remove this. | |
1270 std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list( | |
1271 new base::test::ScopedFeatureList); | |
1272 scoped_feature_list->InitAndEnableFeature(kOfflineBookmarksFeature); | |
1273 | |
1274 // This feature is still disabled by default. | |
1275 EXPECT_FALSE(offline_pages::IsOffliningRecentPagesEnabled()); | |
1276 | |
1277 // Check if feature is correctly enabled by command-line flag. | |
1278 scoped_feature_list.reset(new base::test::ScopedFeatureList); | |
1279 scoped_feature_list->InitFromCommandLine( | |
1280 std::string(kOfflineBookmarksFeature.name) + "," + | |
1281 kOffliningRecentPagesFeature.name, | |
1282 ""); | |
1283 EXPECT_TRUE(offline_pages::IsOffliningRecentPagesEnabled()); | |
1284 } | |
1285 | |
1286 TEST(CommandLineFlagsTest, OfflinePagesSharing) { | |
1287 // Enable offline bookmarks feature first. | |
1288 // TODO(dimich): once offline pages are enabled by default, remove this. | |
1289 std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list( | |
1290 new base::test::ScopedFeatureList); | |
1291 scoped_feature_list->InitAndEnableFeature(kOfflineBookmarksFeature); | |
1292 | |
1293 // This feature is still disabled by default. | |
1294 EXPECT_FALSE(offline_pages::IsOfflinePagesSharingEnabled()); | |
1295 | |
1296 // Check if feature is correctly enabled by command-line flag. | |
1297 scoped_feature_list.reset(new base::test::ScopedFeatureList); | |
1298 scoped_feature_list->InitFromCommandLine( | |
1299 std::string(kOfflineBookmarksFeature.name) + "," + | |
1300 kOfflinePagesSharingFeature.name, | |
1301 ""); | |
1302 EXPECT_TRUE(offline_pages::IsOfflinePagesSharingEnabled()); | |
1303 } | |
1304 | |
1305 TEST(CommandLineFlagsTest, OfflinePagesSvelteConcurrentLoading) { | |
1306 // This feature is disabled by default. | |
1307 EXPECT_FALSE(offline_pages::IsOfflinePagesSvelteConcurrentLoadingEnabled()); | |
1308 | |
1309 // Check if feature is correctly enabled by command-line flag. | |
1310 base::test::ScopedFeatureList scoped_feature_list; | |
1311 scoped_feature_list.InitAndEnableFeature( | |
1312 kOfflinePagesSvelteConcurrentLoadingFeature); | |
1313 EXPECT_TRUE(offline_pages::IsOfflinePagesSvelteConcurrentLoadingEnabled()); | |
1314 } | |
1315 | |
1316 } // namespace offline_pages | |
OLD | NEW |