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