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

Side by Side Diff: chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc

Issue 2016313003: Adds unit tests for Offliner SavePage implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Renamed Fake* to Stub* and added files to proper build target Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/threading/thread_task_runner_handle.h" 11 #include "base/threading/thread_task_runner_handle.h"
12 #include "chrome/browser/android/offline_pages/prerendering_loader.h" 12 #include "chrome/browser/android/offline_pages/prerendering_loader.h"
13 #include "chrome/test/base/testing_profile.h"
13 #include "components/offline_pages/background/offliner.h" 14 #include "components/offline_pages/background/offliner.h"
14 #include "components/offline_pages/background/save_page_request.h" 15 #include "components/offline_pages/background/save_page_request.h"
16 #include "components/offline_pages/stub_offline_page_model.h"
15 #include "content/public/test/test_browser_thread_bundle.h" 17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "content/public/test/web_contents_tester.h"
16 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
17 20
18 namespace offline_pages { 21 namespace offline_pages {
19 22
20 namespace { 23 namespace {
21 const int64_t kRequestId = 7; 24 const int64_t kRequestId = 7;
22 const GURL kHttpUrl("http://tunafish.com"); 25 const GURL kHttpUrl("http://tunafish.com");
26 const GURL kFileUrl("file://sailfish.png");
23 const ClientId kClientId("AsyncLoading", "88"); 27 const ClientId kClientId("AsyncLoading", "88");
24 28
25 // Mock Loader for testing the Offliner calls. 29 // Mock Loader for testing the Offliner calls.
26 class MockPrerenderingLoader : public PrerenderingLoader { 30 class MockPrerenderingLoader : public PrerenderingLoader {
27 public: 31 public:
28 explicit MockPrerenderingLoader(content::BrowserContext* browser_context) 32 explicit MockPrerenderingLoader(content::BrowserContext* browser_context)
29 : PrerenderingLoader(browser_context), 33 : PrerenderingLoader(browser_context),
34 can_prerender_(true),
30 mock_loading_(false), 35 mock_loading_(false),
31 mock_loaded_(false) {} 36 mock_loaded_(false) {}
32 ~MockPrerenderingLoader() override {} 37 ~MockPrerenderingLoader() override {}
33 38
34 bool LoadPage(const GURL& url, const LoadPageCallback& callback) override { 39 bool LoadPage(const GURL& url, const LoadPageCallback& callback) override {
35 mock_loading_ = true; 40 mock_loading_ = true;
36 load_page_callback_ = callback; 41 load_page_callback_ = callback;
37 return mock_loading_; 42 return mock_loading_;
38 } 43 }
39 44
40 void StopLoading() override { 45 void StopLoading() override {
41 mock_loading_ = false; 46 mock_loading_ = false;
42 mock_loaded_ = false; 47 mock_loaded_ = false;
43 } 48 }
49
50 bool CanPrerender() override { return can_prerender_; }
44 bool IsIdle() override { return !mock_loading_ && !mock_loaded_; } 51 bool IsIdle() override { return !mock_loading_ && !mock_loaded_; }
45 bool IsLoaded() override { return mock_loaded_; } 52 bool IsLoaded() override { return mock_loaded_; }
46 53
47 void CallbackForLoadFailed() { 54 void CompleteLoadingAsFailed() {
48 DCHECK(mock_loading_); 55 DCHECK(mock_loading_);
49 mock_loading_ = false; 56 mock_loading_ = false;
50 mock_loaded_ = false; 57 mock_loaded_ = false;
51 base::ThreadTaskRunnerHandle::Get()->PostTask( 58 base::ThreadTaskRunnerHandle::Get()->PostTask(
52 FROM_HERE, 59 FROM_HERE,
53 base::Bind(load_page_callback_, Offliner::RequestStatus::FAILED, 60 base::Bind(load_page_callback_, Offliner::RequestStatus::FAILED,
54 nullptr /* web_contents */)); 61 nullptr /* web_contents */));
55 } 62 }
56 63
57 bool mock_loading() const { return mock_loading_; } 64 void CompleteLoadingAsLoaded() {
58 bool mock_loaded() const { return mock_loaded_; } 65 DCHECK(mock_loading_);
66 mock_loading_ = false;
67 mock_loaded_ = true;
68 base::ThreadTaskRunnerHandle::Get()->PostTask(
69 FROM_HERE,
70 base::Bind(load_page_callback_, Offliner::RequestStatus::LOADED,
71 content::WebContentsTester::CreateTestWebContents(
72 new TestingProfile(), NULL)));
73 }
74
75 void CompleteLoadingAsCanceled() {
76 DCHECK(!IsIdle());
77 mock_loading_ = false;
78 mock_loaded_ = false;
79 base::ThreadTaskRunnerHandle::Get()->PostTask(
80 FROM_HERE,
81 base::Bind(load_page_callback_, Offliner::RequestStatus::CANCELED,
82 nullptr /* web_contents */));
83 }
84
85 void DisablePrerendering() { can_prerender_ = false; }
59 const LoadPageCallback& load_page_callback() { return load_page_callback_; } 86 const LoadPageCallback& load_page_callback() { return load_page_callback_; }
60 87
61 private: 88 private:
89 bool can_prerender_;
62 bool mock_loading_; 90 bool mock_loading_;
63 bool mock_loaded_; 91 bool mock_loaded_;
64 LoadPageCallback load_page_callback_; 92 LoadPageCallback load_page_callback_;
65 93
66 DISALLOW_COPY_AND_ASSIGN(MockPrerenderingLoader); 94 DISALLOW_COPY_AND_ASSIGN(MockPrerenderingLoader);
67 }; 95 };
68 96
97 // Mock OfflinePageModel for testing the SavePage calls.
98 class MockOfflinePageModel : public StubOfflinePageModel {
99 public:
100 MockOfflinePageModel() : mock_saving_(false) {}
101 ~MockOfflinePageModel() override {}
102
103 void SavePage(const GURL& url,
104 const ClientId& client_id,
105 std::unique_ptr<OfflinePageArchiver> archiver,
106 const SavePageCallback& callback) override {
107 mock_saving_ = true;
108 save_page_callback_ = callback;
109 }
110
111 void CompleteSavingAsArchiveCreationFailed() {
112 DCHECK(mock_saving_);
113 mock_saving_ = false;
114 base::ThreadTaskRunnerHandle::Get()->PostTask(
115 FROM_HERE, base::Bind(save_page_callback_,
116 SavePageResult::ARCHIVE_CREATION_FAILED, 0));
117 }
118
119 void CompleteSavingAsSuccess() {
120 DCHECK(mock_saving_);
121 mock_saving_ = false;
122 base::ThreadTaskRunnerHandle::Get()->PostTask(
123 FROM_HERE,
124 base::Bind(save_page_callback_, SavePageResult::SUCCESS, 123456));
125 }
126
127 bool mock_saving() const { return mock_saving_; }
128
129 private:
130 bool mock_saving_;
131 SavePageCallback save_page_callback_;
132
133 DISALLOW_COPY_AND_ASSIGN(MockOfflinePageModel);
134 };
135
69 void PumpLoop() { 136 void PumpLoop() {
70 base::RunLoop().RunUntilIdle(); 137 base::RunLoop().RunUntilIdle();
71 } 138 }
72 139
73 } // namespace 140 } // namespace
74 141
75 class PrerenderingOfflinerTest : public testing::Test { 142 class PrerenderingOfflinerTest : public testing::Test {
76 public: 143 public:
77 PrerenderingOfflinerTest(); 144 PrerenderingOfflinerTest();
78 ~PrerenderingOfflinerTest() override; 145 ~PrerenderingOfflinerTest() override;
79 146
80 void SetUp() override; 147 void SetUp() override;
81 148
82 PrerenderingOffliner* offliner() const { return offliner_.get(); } 149 PrerenderingOffliner* offliner() const { return offliner_.get(); }
83 Offliner::CompletionCallback const callback() { 150 Offliner::CompletionCallback const callback() {
84 return base::Bind(&PrerenderingOfflinerTest::OnCompletion, 151 return base::Bind(&PrerenderingOfflinerTest::OnCompletion,
85 base::Unretained(this)); 152 base::Unretained(this));
86 } 153 }
87 154
88 bool loading() const { return loader_->mock_loading(); } 155 bool SaveInProgress() const { return model_->mock_saving(); }
89 bool loaded() const { return loader_->mock_loaded(); }
90 MockPrerenderingLoader* loader() { return loader_; } 156 MockPrerenderingLoader* loader() { return loader_; }
91 bool callback_called() { return callback_called_; } 157 MockOfflinePageModel* model() { return model_; }
158 bool completion_callback_called() { return completion_callback_called_; }
92 Offliner::RequestStatus request_status() { return request_status_; } 159 Offliner::RequestStatus request_status() { return request_status_; }
93 160
94 private: 161 private:
95 void OnCompletion(const SavePageRequest& request, 162 void OnCompletion(const SavePageRequest& request,
96 Offliner::RequestStatus status); 163 Offliner::RequestStatus status);
97 164
98 content::TestBrowserThreadBundle thread_bundle_; 165 content::TestBrowserThreadBundle thread_bundle_;
99 std::unique_ptr<PrerenderingOffliner> offliner_; 166 std::unique_ptr<PrerenderingOffliner> offliner_;
100 // Not owned. 167 // Not owned.
101 MockPrerenderingLoader* loader_; 168 MockPrerenderingLoader* loader_;
102 bool callback_called_; 169 MockOfflinePageModel* model_;
170 bool completion_callback_called_;
103 Offliner::RequestStatus request_status_; 171 Offliner::RequestStatus request_status_;
104 172
105 DISALLOW_COPY_AND_ASSIGN(PrerenderingOfflinerTest); 173 DISALLOW_COPY_AND_ASSIGN(PrerenderingOfflinerTest);
106 }; 174 };
107 175
108 PrerenderingOfflinerTest::PrerenderingOfflinerTest() 176 PrerenderingOfflinerTest::PrerenderingOfflinerTest()
109 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 177 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
110 callback_called_(false), 178 completion_callback_called_(false),
111 request_status_(Offliner::RequestStatus::UNKNOWN) {} 179 request_status_(Offliner::RequestStatus::UNKNOWN) {}
112 180
113 PrerenderingOfflinerTest::~PrerenderingOfflinerTest() {} 181 PrerenderingOfflinerTest::~PrerenderingOfflinerTest() {}
114 182
115 void PrerenderingOfflinerTest::SetUp() { 183 void PrerenderingOfflinerTest::SetUp() {
116 offliner_.reset(new PrerenderingOffliner(nullptr, nullptr, nullptr)); 184 model_ = new MockOfflinePageModel();
185 offliner_.reset(new PrerenderingOffliner(nullptr, nullptr, model_));
117 std::unique_ptr<MockPrerenderingLoader> mock_loader( 186 std::unique_ptr<MockPrerenderingLoader> mock_loader(
118 new MockPrerenderingLoader(nullptr)); 187 new MockPrerenderingLoader(nullptr));
119 loader_ = mock_loader.get(); 188 loader_ = mock_loader.get();
120 offliner_->SetLoaderForTesting(std::move(mock_loader)); 189 offliner_->SetLoaderForTesting(std::move(mock_loader));
121 } 190 }
122 191
123 void PrerenderingOfflinerTest::OnCompletion(const SavePageRequest& request, 192 void PrerenderingOfflinerTest::OnCompletion(const SavePageRequest& request,
124 Offliner::RequestStatus status) { 193 Offliner::RequestStatus status) {
125 DCHECK(!callback_called_); // Only expect single callback per request. 194 DCHECK(!completion_callback_called_); // Expect single callback per request.
126 callback_called_ = true; 195 completion_callback_called_ = true;
127 request_status_ = status; 196 request_status_ = status;
128 } 197 }
129 198
199 TEST_F(PrerenderingOfflinerTest, LoadAndSaveBadUrl) {
200 base::Time creation_time = base::Time::Now();
201 SavePageRequest request(kRequestId, kFileUrl, kClientId, creation_time);
202 EXPECT_FALSE(offliner()->LoadAndSave(request, callback()));
203 EXPECT_TRUE(loader()->IsIdle());
204 }
205
206 TEST_F(PrerenderingOfflinerTest, LoadAndSavePrerenderingDisabled) {
207 base::Time creation_time = base::Time::Now();
208 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
209 loader()->DisablePrerendering();
210 EXPECT_FALSE(offliner()->LoadAndSave(request, callback()));
211 EXPECT_TRUE(loader()->IsIdle());
212 }
213
130 TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadStartedButFails) { 214 TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadStartedButFails) {
131 base::Time creation_time = base::Time::Now(); 215 base::Time creation_time = base::Time::Now();
132 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time); 216 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
133 EXPECT_TRUE(offliner()->LoadAndSave(request, callback())); 217 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
134 EXPECT_TRUE(loading()); 218 EXPECT_FALSE(loader()->IsIdle());
135 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status()); 219 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
136 220
137 loader()->CallbackForLoadFailed(); 221 loader()->CompleteLoadingAsFailed();
138 PumpLoop(); 222 PumpLoop();
139 EXPECT_TRUE(callback_called()); 223 EXPECT_TRUE(completion_callback_called());
140 EXPECT_EQ(Offliner::RequestStatus::FAILED, request_status()); 224 EXPECT_EQ(Offliner::RequestStatus::FAILED, request_status());
141 EXPECT_FALSE(loading()); 225 EXPECT_TRUE(loader()->IsIdle());
142 EXPECT_FALSE(loaded()); 226 EXPECT_FALSE(SaveInProgress());
143 } 227 }
144 228
145 TEST_F(PrerenderingOfflinerTest, CancelWhenLoading) { 229 TEST_F(PrerenderingOfflinerTest, CancelWhenLoading) {
146 base::Time creation_time = base::Time::Now(); 230 base::Time creation_time = base::Time::Now();
147 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time); 231 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
148 EXPECT_TRUE(offliner()->LoadAndSave(request, callback())); 232 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
149 EXPECT_TRUE(loading()); 233 EXPECT_FALSE(loader()->IsIdle());
150 234
151 offliner()->Cancel(); 235 offliner()->Cancel();
152 EXPECT_FALSE(loading()); 236 EXPECT_TRUE(loader()->IsIdle());
237 }
238
239 TEST_F(PrerenderingOfflinerTest, CancelWhenLoaded) {
240 base::Time creation_time = base::Time::Now();
241 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
242 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
243 EXPECT_FALSE(loader()->IsIdle());
244 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
245
246 loader()->CompleteLoadingAsLoaded();
247 PumpLoop();
248 EXPECT_FALSE(completion_callback_called());
249 EXPECT_TRUE(loader()->IsLoaded());
250 EXPECT_TRUE(SaveInProgress());
251
252 offliner()->Cancel();
253 PumpLoop();
254 EXPECT_FALSE(completion_callback_called());
255 EXPECT_FALSE(loader()->IsLoaded());
256 // Note: save still in progress since it does not support canceling.
257 EXPECT_TRUE(SaveInProgress());
258
259 // Subsequent save callback causes no harm (no crash and no callback).
260 model()->CompleteSavingAsArchiveCreationFailed();
261 PumpLoop();
262 EXPECT_FALSE(completion_callback_called());
263 EXPECT_TRUE(loader()->IsIdle());
264 EXPECT_FALSE(SaveInProgress());
265 }
266
267 TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadedButSaveFails) {
268 base::Time creation_time = base::Time::Now();
269 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
270 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
271 EXPECT_FALSE(loader()->IsIdle());
272 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
273
274 loader()->CompleteLoadingAsLoaded();
275 PumpLoop();
276 EXPECT_FALSE(completion_callback_called());
277 EXPECT_TRUE(loader()->IsLoaded());
278 EXPECT_TRUE(SaveInProgress());
279
280 model()->CompleteSavingAsArchiveCreationFailed();
281 PumpLoop();
282 EXPECT_TRUE(completion_callback_called());
283 EXPECT_EQ(Offliner::RequestStatus::FAILED_SAVE, request_status());
284 EXPECT_FALSE(loader()->IsLoaded());
285 EXPECT_FALSE(SaveInProgress());
286 }
287
288 TEST_F(PrerenderingOfflinerTest, LoadAndSaveSuccessful) {
289 base::Time creation_time = base::Time::Now();
290 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
291 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
292 EXPECT_FALSE(loader()->IsIdle());
293 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
294
295 loader()->CompleteLoadingAsLoaded();
296 PumpLoop();
297 EXPECT_FALSE(completion_callback_called());
298 EXPECT_TRUE(loader()->IsLoaded());
299 EXPECT_TRUE(SaveInProgress());
300
301 model()->CompleteSavingAsSuccess();
302 PumpLoop();
303 EXPECT_TRUE(completion_callback_called());
304 EXPECT_EQ(Offliner::RequestStatus::SAVED, request_status());
305 EXPECT_FALSE(loader()->IsLoaded());
306 EXPECT_FALSE(SaveInProgress());
307 }
308
309 TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadedButThenCanceledFromLoader) {
310 base::Time creation_time = base::Time::Now();
311 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
312 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
313 EXPECT_FALSE(loader()->IsIdle());
314 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
315
316 loader()->CompleteLoadingAsLoaded();
317 PumpLoop();
318 EXPECT_FALSE(completion_callback_called());
319 EXPECT_TRUE(loader()->IsLoaded());
320 EXPECT_TRUE(SaveInProgress());
321
322 loader()->CompleteLoadingAsCanceled();
323 PumpLoop();
324 EXPECT_TRUE(completion_callback_called());
325 EXPECT_EQ(Offliner::RequestStatus::CANCELED, request_status());
326 EXPECT_FALSE(loader()->IsLoaded());
327 // Note: save still in progress since it does not support canceling.
328 EXPECT_TRUE(SaveInProgress());
153 } 329 }
154 330
155 } // namespace offline_pages 331 } // namespace offline_pages
OLDNEW
« no previous file with comments | « chrome/browser/android/offline_pages/prerendering_offliner.cc ('k') | components/offline_pages.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698