OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/android/offline_pages/prerendering_offliner.h" | 5 #include "chrome/browser/android/offline_pages/prerendering_offliner.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
11 #include "base/sys_info.h" | 11 #include "base/sys_info.h" |
| 12 #include "base/test/scoped_feature_list.h" |
12 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
13 #include "chrome/browser/android/offline_pages/prerendering_loader.h" | 14 #include "chrome/browser/android/offline_pages/prerendering_loader.h" |
14 #include "chrome/browser/net/prediction_options.h" | 15 #include "chrome/browser/net/prediction_options.h" |
15 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
16 #include "chrome/test/base/testing_profile.h" | 17 #include "chrome/test/base/testing_profile.h" |
17 #include "components/content_settings/core/common/pref_names.h" | 18 #include "components/content_settings/core/common/pref_names.h" |
18 #include "components/offline_pages/core/background/offliner.h" | 19 #include "components/offline_pages/core/background/offliner.h" |
19 #include "components/offline_pages/core/background/offliner_policy.h" | 20 #include "components/offline_pages/core/background/offliner_policy.h" |
20 #include "components/offline_pages/core/background/save_page_request.h" | 21 #include "components/offline_pages/core/background/save_page_request.h" |
| 22 #include "components/offline_pages/core/offline_page_feature.h" |
21 #include "components/offline_pages/core/stub_offline_page_model.h" | 23 #include "components/offline_pages/core/stub_offline_page_model.h" |
22 #include "components/prefs/pref_service.h" | 24 #include "components/prefs/pref_service.h" |
| 25 #include "content/public/browser/mhtml_extra_parts.h" |
23 #include "content/public/test/test_browser_thread_bundle.h" | 26 #include "content/public/test/test_browser_thread_bundle.h" |
24 #include "content/public/test/web_contents_tester.h" | 27 #include "content/public/test/web_contents_tester.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
26 | 29 |
27 namespace offline_pages { | 30 namespace offline_pages { |
28 | 31 |
29 namespace { | 32 namespace { |
30 const int64_t kRequestId = 7; | 33 const int64_t kRequestId = 7; |
31 const GURL kHttpUrl("http://tunafish.com"); | 34 const GURL kHttpUrl("http://tunafish.com"); |
32 const GURL kFileUrl("file://sailfish.png"); | 35 const GURL kFileUrl("file://sailfish.png"); |
33 const ClientId kClientId("AsyncLoading", "88"); | 36 const ClientId kClientId("AsyncLoading", "88"); |
34 const bool kUserRequested = true; | 37 const bool kUserRequested = true; |
35 | 38 |
36 // Mock Loader for testing the Offliner calls. | 39 // Mock Loader for testing the Offliner calls. |
37 class MockPrerenderingLoader : public PrerenderingLoader { | 40 class MockPrerenderingLoader : public PrerenderingLoader { |
38 public: | 41 public: |
39 explicit MockPrerenderingLoader(content::BrowserContext* browser_context) | 42 explicit MockPrerenderingLoader(content::BrowserContext* browser_context) |
40 : PrerenderingLoader(browser_context), | 43 : PrerenderingLoader(browser_context), |
41 can_prerender_(true), | 44 can_prerender_(true), |
42 mock_loading_(false), | 45 mock_loading_(false), |
43 mock_loaded_(false), | 46 mock_loaded_(false), |
44 mock_is_lowbar_met_(false), | 47 mock_is_lowbar_met_(false), |
45 start_snapshot_called_(false) {} | 48 start_snapshot_called_(false) {} |
46 ~MockPrerenderingLoader() override {} | 49 ~MockPrerenderingLoader() override { delete web_contents_; } |
47 | 50 |
48 bool LoadPage(const GURL& url, | 51 bool LoadPage(const GURL& url, |
49 const LoadPageCallback& load_done_callback, | 52 const LoadPageCallback& load_done_callback, |
50 const ProgressCallback& progress_callback) override { | 53 const ProgressCallback& progress_callback) override { |
51 mock_loading_ = can_prerender_; | 54 mock_loading_ = can_prerender_; |
52 load_page_callback_ = load_done_callback; | 55 load_page_callback_ = load_done_callback; |
53 progress_callback_ = progress_callback; | 56 progress_callback_ = progress_callback; |
54 return mock_loading_; | 57 return mock_loading_; |
55 } | 58 } |
56 | 59 |
(...skipping 15 matching lines...) Expand all Loading... |
72 base::ThreadTaskRunnerHandle::Get()->PostTask( | 75 base::ThreadTaskRunnerHandle::Get()->PostTask( |
73 FROM_HERE, | 76 FROM_HERE, |
74 base::Bind(load_page_callback_, Offliner::RequestStatus::LOADING_FAILED, | 77 base::Bind(load_page_callback_, Offliner::RequestStatus::LOADING_FAILED, |
75 nullptr /* web_contents */)); | 78 nullptr /* web_contents */)); |
76 } | 79 } |
77 | 80 |
78 void CompleteLoadingAsLoaded() { | 81 void CompleteLoadingAsLoaded() { |
79 DCHECK(mock_loading_); | 82 DCHECK(mock_loading_); |
80 mock_loading_ = false; | 83 mock_loading_ = false; |
81 mock_loaded_ = true; | 84 mock_loaded_ = true; |
| 85 web_contents_ = content::WebContentsTester::CreateTestWebContents( |
| 86 new TestingProfile(), NULL); |
82 base::ThreadTaskRunnerHandle::Get()->PostTask( | 87 base::ThreadTaskRunnerHandle::Get()->PostTask( |
83 FROM_HERE, | 88 FROM_HERE, base::Bind(load_page_callback_, |
84 base::Bind(load_page_callback_, Offliner::RequestStatus::LOADED, | 89 Offliner::RequestStatus::LOADED, web_contents_)); |
85 content::WebContentsTester::CreateTestWebContents( | |
86 new TestingProfile(), NULL))); | |
87 } | 90 } |
88 | 91 |
89 void CompleteLoadingAsCanceled() { | 92 void CompleteLoadingAsCanceled() { |
90 DCHECK(!IsIdle()); | 93 DCHECK(!IsIdle()); |
91 mock_loading_ = false; | 94 mock_loading_ = false; |
92 mock_loaded_ = false; | 95 mock_loaded_ = false; |
93 base::ThreadTaskRunnerHandle::Get()->PostTask( | 96 base::ThreadTaskRunnerHandle::Get()->PostTask( |
94 FROM_HERE, base::Bind(load_page_callback_, | 97 FROM_HERE, base::Bind(load_page_callback_, |
95 Offliner::RequestStatus::LOADING_CANCELED, | 98 Offliner::RequestStatus::LOADING_CANCELED, |
96 nullptr /* web_contents */)); | 99 nullptr /* web_contents */)); |
97 } | 100 } |
98 | 101 |
99 void DisablePrerendering() { can_prerender_ = false; } | 102 void DisablePrerendering() { can_prerender_ = false; } |
100 const LoadPageCallback& load_page_callback() { return load_page_callback_; } | 103 const LoadPageCallback& load_page_callback() { return load_page_callback_; } |
101 void set_is_lowbar_met(bool is_lowbar_met) { | 104 void set_is_lowbar_met(bool is_lowbar_met) { |
102 mock_is_lowbar_met_ = is_lowbar_met; | 105 mock_is_lowbar_met_ = is_lowbar_met; |
103 } | 106 } |
104 bool start_snapshot_called() { return start_snapshot_called_; } | 107 bool start_snapshot_called() { return start_snapshot_called_; } |
105 | 108 |
| 109 content::WebContents* web_contents() { return web_contents_; } |
| 110 |
106 private: | 111 private: |
107 bool can_prerender_; | 112 bool can_prerender_; |
108 bool mock_loading_; | 113 bool mock_loading_; |
109 bool mock_loaded_; | 114 bool mock_loaded_; |
110 bool mock_is_lowbar_met_; | 115 bool mock_is_lowbar_met_; |
111 bool start_snapshot_called_; | 116 bool start_snapshot_called_; |
112 LoadPageCallback load_page_callback_; | 117 LoadPageCallback load_page_callback_; |
113 ProgressCallback progress_callback_; | 118 ProgressCallback progress_callback_; |
| 119 content::WebContents* web_contents_; |
114 | 120 |
115 DISALLOW_COPY_AND_ASSIGN(MockPrerenderingLoader); | 121 DISALLOW_COPY_AND_ASSIGN(MockPrerenderingLoader); |
116 }; | 122 }; |
117 | 123 |
118 // Mock OfflinePageModel for testing the SavePage calls. | 124 // Mock OfflinePageModel for testing the SavePage calls. |
119 class MockOfflinePageModel : public StubOfflinePageModel { | 125 class MockOfflinePageModel : public StubOfflinePageModel { |
120 public: | 126 public: |
121 MockOfflinePageModel() : mock_saving_(false) {} | 127 MockOfflinePageModel() : mock_saving_(false) {} |
122 ~MockOfflinePageModel() override {} | 128 ~MockOfflinePageModel() override {} |
123 | 129 |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 base::Time creation_time = base::Time::Now(); | 524 base::Time creation_time = base::Time::Now(); |
519 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time, | 525 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time, |
520 kUserRequested); | 526 kUserRequested); |
521 EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), | 527 EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), |
522 progress_callback())); | 528 progress_callback())); |
523 loader()->set_is_lowbar_met(true); | 529 loader()->set_is_lowbar_met(true); |
524 EXPECT_FALSE(offliner()->HandleTimeout(request)); | 530 EXPECT_FALSE(offliner()->HandleTimeout(request)); |
525 EXPECT_FALSE(loader()->start_snapshot_called()); | 531 EXPECT_FALSE(loader()->start_snapshot_called()); |
526 } | 532 } |
527 | 533 |
| 534 TEST_F(PrerenderingOfflinerTest, SignalCollectionDisabled) { |
| 535 // Ensure feature flag for Signal collection is off, |
| 536 EXPECT_FALSE(offline_pages::IsOfflinePagesLoadSignalCollectingEnabled()); |
| 537 |
| 538 base::Time creation_time = base::Time::Now(); |
| 539 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time, |
| 540 kUserRequested); |
| 541 EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), |
| 542 progress_callback())); |
| 543 EXPECT_FALSE(loader()->IsIdle()); |
| 544 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status()); |
| 545 |
| 546 loader()->CompleteLoadingAsLoaded(); |
| 547 PumpLoop(); |
| 548 |
| 549 model()->CompleteSavingAsSuccess(); |
| 550 PumpLoop(); |
| 551 EXPECT_EQ(Offliner::RequestStatus::SAVED, request_status()); |
| 552 |
| 553 // No extra parts should be added if the flag is off. |
| 554 content::MHTMLExtraParts* extra_parts = |
| 555 content::MHTMLExtraParts::FromWebContents(loader()->web_contents()); |
| 556 EXPECT_EQ(extra_parts->size(), 0); |
| 557 } |
| 558 |
| 559 TEST_F(PrerenderingOfflinerTest, SignalCollectionEnabled) { |
| 560 // Ensure feature flag for signal collection is on. |
| 561 base::test::ScopedFeatureList scoped_feature_list; |
| 562 scoped_feature_list.InitAndEnableFeature( |
| 563 kOfflinePagesLoadSignalCollectingFeature); |
| 564 EXPECT_TRUE(IsOfflinePagesLoadSignalCollectingEnabled()); |
| 565 |
| 566 base::Time creation_time = base::Time::Now(); |
| 567 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time, |
| 568 kUserRequested); |
| 569 EXPECT_TRUE(offliner()->LoadAndSave(request, completion_callback(), |
| 570 progress_callback())); |
| 571 EXPECT_FALSE(loader()->IsIdle()); |
| 572 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status()); |
| 573 |
| 574 loader()->CompleteLoadingAsLoaded(); |
| 575 PumpLoop(); |
| 576 |
| 577 model()->CompleteSavingAsSuccess(); |
| 578 PumpLoop(); |
| 579 EXPECT_EQ(Offliner::RequestStatus::SAVED, request_status()); |
| 580 |
| 581 // One extra part should be added if the flag is on. |
| 582 content::MHTMLExtraParts* extra_parts = |
| 583 content::MHTMLExtraParts::FromWebContents(loader()->web_contents()); |
| 584 EXPECT_EQ(extra_parts->size(), 1); |
| 585 } |
| 586 |
528 } // namespace offline_pages | 587 } // namespace offline_pages |
OLD | NEW |