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

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: 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
« no previous file with comments | « chrome/browser/android/offline_pages/prerendering_offliner.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
15 #include "content/public/test/test_browser_thread_bundle.h" 16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "content/public/test/web_contents_tester.h"
16 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
17 19
18 namespace offline_pages { 20 namespace offline_pages {
19 21
20 namespace { 22 namespace {
21 const int64_t kRequestId = 7; 23 const int64_t kRequestId = 7;
22 const GURL kHttpUrl("http://tunafish.com"); 24 const GURL kHttpUrl("http://tunafish.com");
25 const GURL kFileUrl("file://sailfish.png");
23 const ClientId kClientId("AsyncLoading", "88"); 26 const ClientId kClientId("AsyncLoading", "88");
24 27
25 // Mock Loader for testing the Offliner calls. 28 // Mock Loader for testing the Offliner calls.
26 class MockPrerenderingLoader : public PrerenderingLoader { 29 class MockPrerenderingLoader : public PrerenderingLoader {
27 public: 30 public:
28 explicit MockPrerenderingLoader(content::BrowserContext* browser_context) 31 explicit MockPrerenderingLoader(content::BrowserContext* browser_context)
29 : PrerenderingLoader(browser_context), 32 : PrerenderingLoader(browser_context),
33 can_prerender_(true),
30 mock_loading_(false), 34 mock_loading_(false),
31 mock_loaded_(false) {} 35 mock_loaded_(false) {}
32 ~MockPrerenderingLoader() override {} 36 ~MockPrerenderingLoader() override {}
33 37
34 bool LoadPage(const GURL& url, const LoadPageCallback& callback) override { 38 bool LoadPage(const GURL& url, const LoadPageCallback& callback) override {
35 mock_loading_ = true; 39 mock_loading_ = true;
36 load_page_callback_ = callback; 40 load_page_callback_ = callback;
37 return mock_loading_; 41 return mock_loading_;
38 } 42 }
39 43
40 void StopLoading() override { 44 void StopLoading() override {
41 mock_loading_ = false; 45 mock_loading_ = false;
42 mock_loaded_ = false; 46 mock_loaded_ = false;
43 } 47 }
48
49 bool CanPrerender() override { return can_prerender_; }
44 bool IsIdle() override { return !mock_loading_ && !mock_loaded_; } 50 bool IsIdle() override { return !mock_loading_ && !mock_loaded_; }
45 bool IsLoaded() override { return mock_loaded_; } 51 bool IsLoaded() override { return mock_loaded_; }
46 52
47 void CallbackForLoadFailed() { 53 void CallbackForLoadFailed() {
48 DCHECK(mock_loading_); 54 DCHECK(mock_loading_);
49 mock_loading_ = false; 55 mock_loading_ = false;
50 mock_loaded_ = false; 56 mock_loaded_ = false;
51 base::ThreadTaskRunnerHandle::Get()->PostTask( 57 base::ThreadTaskRunnerHandle::Get()->PostTask(
52 FROM_HERE, 58 FROM_HERE,
53 base::Bind(load_page_callback_, Offliner::RequestStatus::FAILED, 59 base::Bind(load_page_callback_, Offliner::RequestStatus::FAILED,
54 nullptr /* web_contents */)); 60 nullptr /* web_contents */));
55 } 61 }
56 62
63 void CallbackForLoaded() {
64 DCHECK(mock_loading_);
65 mock_loading_ = false;
fgorski 2016/05/27 18:43:11 Just a consideration: * Might mock_loading_ and mo
dougarnett 2016/05/27 20:39:18 True - was hoping two bools might be simpler to se
66 mock_loaded_ = true;
67 base::ThreadTaskRunnerHandle::Get()->PostTask(
68 FROM_HERE,
69 base::Bind(load_page_callback_, Offliner::RequestStatus::LOADED,
70 content::WebContentsTester::CreateTestWebContents(
71 new TestingProfile(), NULL)));
72 }
73
74 void CallbackForLoadCanceledAfterLoaded() {
75 DCHECK(mock_loaded_);
76 mock_loading_ = false;
77 mock_loaded_ = false;
78 base::ThreadTaskRunnerHandle::Get()->PostTask(
79 FROM_HERE,
80 base::Bind(load_page_callback_, Offliner::RequestStatus::CANCELED,
81 nullptr /* web_contents */));
82 }
83
84 void DisablePrerendering() { can_prerender_ = false; }
57 bool mock_loading() const { return mock_loading_; } 85 bool mock_loading() const { return mock_loading_; }
58 bool mock_loaded() const { return mock_loaded_; } 86 bool mock_loaded() const { return mock_loaded_; }
59 const LoadPageCallback& load_page_callback() { return load_page_callback_; } 87 const LoadPageCallback& load_page_callback() { return load_page_callback_; }
60 88
61 private: 89 private:
90 bool can_prerender_;
62 bool mock_loading_; 91 bool mock_loading_;
63 bool mock_loaded_; 92 bool mock_loaded_;
64 LoadPageCallback load_page_callback_; 93 LoadPageCallback load_page_callback_;
65 94
66 DISALLOW_COPY_AND_ASSIGN(MockPrerenderingLoader); 95 DISALLOW_COPY_AND_ASSIGN(MockPrerenderingLoader);
67 }; 96 };
68 97
98 // TODO(dougarnett): Remove this subclass once OfflinePageModel is split out
Pete Williamson 2016/05/27 18:32:09 I'd prefer to delay checking in this changelist un
dougarnett 2016/05/27 20:39:18 I do too - hopefully that review can land soon. I'
Pete Williamson 2016/05/27 21:06:46 OK. Still waiting for this one.
dougarnett 2016/06/01 17:51:10 Done.
99 // as an interface that can be mocked (so can mock SavePage() call with it).
100 class TestPrerenderingOffliner : public PrerenderingOffliner {
101 public:
102 TestPrerenderingOffliner()
103 : PrerenderingOffliner(nullptr, nullptr, nullptr), mock_saving_(false) {}
104
105 ~TestPrerenderingOffliner() override {}
106
107 void CallbackForSaveFailed() {
108 DCHECK(mock_saving_);
109 mock_saving_ = false;
110 base::ThreadTaskRunnerHandle::Get()->PostTask(
111 FROM_HERE, base::Bind(save_page_callback_,
112 SavePageResult::ARCHIVE_CREATION_FAILED, 0));
113 }
114
115 void CallbackForSaved() {
fgorski 2016/05/27 18:43:11 Can you consider this to be mirror for the method
dougarnett 2016/05/27 20:39:18 Went with the later Complete* naming suggested bel
116 DCHECK(mock_saving_);
117 mock_saving_ = false;
118 base::ThreadTaskRunnerHandle::Get()->PostTask(
119 FROM_HERE,
120 base::Bind(save_page_callback_, SavePageResult::SUCCESS, 123456));
121 }
122
123 bool mock_saving() { return mock_saving_; }
fgorski 2016/05/27 18:43:11 I believe this method can be const.
dougarnett 2016/05/27 20:39:18 Done.
124
125 protected:
126 void SavePage(const GURL& url,
127 const ClientId& client_id,
128 std::unique_ptr<OfflinePageArchiver> archiver,
129 const SavePageCallback& callback) override {
130 mock_saving_ = true;
131 save_page_callback_ = callback;
132 }
133
134 private:
135 bool mock_saving_;
136 SavePageCallback save_page_callback_;
137 };
138
69 void PumpLoop() { 139 void PumpLoop() {
70 base::RunLoop().RunUntilIdle(); 140 base::RunLoop().RunUntilIdle();
71 } 141 }
72 142
73 } // namespace 143 } // namespace
74 144
75 class PrerenderingOfflinerTest : public testing::Test { 145 class PrerenderingOfflinerTest : public testing::Test {
76 public: 146 public:
77 PrerenderingOfflinerTest(); 147 PrerenderingOfflinerTest();
78 ~PrerenderingOfflinerTest() override; 148 ~PrerenderingOfflinerTest() override;
79 149
80 void SetUp() override; 150 void SetUp() override;
81 151
82 PrerenderingOffliner* offliner() const { return offliner_.get(); } 152 TestPrerenderingOffliner* offliner() const { return offliner_.get(); }
83 Offliner::CompletionCallback const callback() { 153 Offliner::CompletionCallback const callback() {
84 return base::Bind(&PrerenderingOfflinerTest::OnCompletion, 154 return base::Bind(&PrerenderingOfflinerTest::OnCompletion,
85 base::Unretained(this)); 155 base::Unretained(this));
86 } 156 }
87 157
88 bool loading() const { return loader_->mock_loading(); } 158 bool loading() const { return loader_->mock_loading(); }
89 bool loaded() const { return loader_->mock_loaded(); } 159 bool loaded() const { return loader_->mock_loaded(); }
160 bool saving() const { return offliner_->mock_saving(); }
90 MockPrerenderingLoader* loader() { return loader_; } 161 MockPrerenderingLoader* loader() { return loader_; }
91 bool callback_called() { return callback_called_; } 162 bool callback_called() { return callback_called_; }
92 Offliner::RequestStatus request_status() { return request_status_; } 163 Offliner::RequestStatus request_status() { return request_status_; }
93 164
94 private: 165 private:
95 void OnCompletion(const SavePageRequest& request, 166 void OnCompletion(const SavePageRequest& request,
96 Offliner::RequestStatus status); 167 Offliner::RequestStatus status);
97 168
98 content::TestBrowserThreadBundle thread_bundle_; 169 content::TestBrowserThreadBundle thread_bundle_;
99 std::unique_ptr<PrerenderingOffliner> offliner_; 170 std::unique_ptr<TestPrerenderingOffliner> offliner_;
100 // Not owned. 171 // Not owned.
101 MockPrerenderingLoader* loader_; 172 MockPrerenderingLoader* loader_;
102 bool callback_called_; 173 bool callback_called_;
103 Offliner::RequestStatus request_status_; 174 Offliner::RequestStatus request_status_;
104 175
105 DISALLOW_COPY_AND_ASSIGN(PrerenderingOfflinerTest); 176 DISALLOW_COPY_AND_ASSIGN(PrerenderingOfflinerTest);
106 }; 177 };
107 178
108 PrerenderingOfflinerTest::PrerenderingOfflinerTest() 179 PrerenderingOfflinerTest::PrerenderingOfflinerTest()
109 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 180 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
110 callback_called_(false), 181 callback_called_(false),
111 request_status_(Offliner::RequestStatus::UNKNOWN) {} 182 request_status_(Offliner::RequestStatus::UNKNOWN) {}
112 183
113 PrerenderingOfflinerTest::~PrerenderingOfflinerTest() {} 184 PrerenderingOfflinerTest::~PrerenderingOfflinerTest() {}
114 185
115 void PrerenderingOfflinerTest::SetUp() { 186 void PrerenderingOfflinerTest::SetUp() {
116 offliner_.reset(new PrerenderingOffliner(nullptr, nullptr, nullptr)); 187 offliner_.reset(new TestPrerenderingOffliner());
117 std::unique_ptr<MockPrerenderingLoader> mock_loader( 188 std::unique_ptr<MockPrerenderingLoader> mock_loader(
118 new MockPrerenderingLoader(nullptr)); 189 new MockPrerenderingLoader(nullptr));
119 loader_ = mock_loader.get(); 190 loader_ = mock_loader.get();
120 offliner_->SetLoaderForTesting(std::move(mock_loader)); 191 offliner_->SetLoaderForTesting(std::move(mock_loader));
121 } 192 }
122 193
123 void PrerenderingOfflinerTest::OnCompletion(const SavePageRequest& request, 194 void PrerenderingOfflinerTest::OnCompletion(const SavePageRequest& request,
124 Offliner::RequestStatus status) { 195 Offliner::RequestStatus status) {
125 DCHECK(!callback_called_); // Only expect single callback per request. 196 DCHECK(!callback_called_); // Only expect single callback per request.
126 callback_called_ = true; 197 callback_called_ = true;
127 request_status_ = status; 198 request_status_ = status;
128 } 199 }
129 200
201 TEST_F(PrerenderingOfflinerTest, LoadAndSaveBadUrl) {
202 base::Time creation_time = base::Time::Now();
203 SavePageRequest request(kRequestId, kFileUrl, kClientId, creation_time);
204 EXPECT_FALSE(offliner()->LoadAndSave(request, callback()));
205 EXPECT_FALSE(loading());
206 }
207
208 TEST_F(PrerenderingOfflinerTest, LoadAndSavePrerenderingDisabled) {
209 base::Time creation_time = base::Time::Now();
210 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
211 loader()->DisablePrerendering();
212 EXPECT_FALSE(offliner()->LoadAndSave(request, callback()));
213 EXPECT_FALSE(loading());
Pete Williamson 2016/05/27 18:32:09 Which loading() function is being called here, the
dougarnett 2016/05/27 20:39:18 Reworked to use IsIdle() and IsLoaded() methods on
Pete Williamson 2016/05/27 21:06:46 Acknowledged.
214 }
215
130 TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadStartedButFails) { 216 TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadStartedButFails) {
131 base::Time creation_time = base::Time::Now(); 217 base::Time creation_time = base::Time::Now();
132 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time); 218 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
133 EXPECT_TRUE(offliner()->LoadAndSave(request, callback())); 219 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
134 EXPECT_TRUE(loading()); 220 EXPECT_TRUE(loading());
135 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status()); 221 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
136 222
137 loader()->CallbackForLoadFailed(); 223 loader()->CallbackForLoadFailed();
138 PumpLoop(); 224 PumpLoop();
139 EXPECT_TRUE(callback_called()); 225 EXPECT_TRUE(callback_called());
140 EXPECT_EQ(Offliner::RequestStatus::FAILED, request_status()); 226 EXPECT_EQ(Offliner::RequestStatus::FAILED, request_status());
141 EXPECT_FALSE(loading()); 227 EXPECT_FALSE(loading());
142 EXPECT_FALSE(loaded()); 228 EXPECT_FALSE(loaded());
229 EXPECT_FALSE(saving());
143 } 230 }
144 231
145 TEST_F(PrerenderingOfflinerTest, CancelWhenLoading) { 232 TEST_F(PrerenderingOfflinerTest, CancelWhenLoading) {
146 base::Time creation_time = base::Time::Now(); 233 base::Time creation_time = base::Time::Now();
147 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time); 234 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
148 EXPECT_TRUE(offliner()->LoadAndSave(request, callback())); 235 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
149 EXPECT_TRUE(loading()); 236 EXPECT_TRUE(loading());
150 237
151 offliner()->Cancel(); 238 offliner()->Cancel();
152 EXPECT_FALSE(loading()); 239 EXPECT_FALSE(loading());
153 } 240 }
154 241
242 TEST_F(PrerenderingOfflinerTest, CancelWhenLoaded) {
243 base::Time creation_time = base::Time::Now();
244 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
245 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
246 EXPECT_TRUE(loading());
247 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
248
249 loader()->CallbackForLoaded();
fgorski 2016/05/27 18:43:11 I am thinking whether there is a better name here.
dougarnett 2016/05/27 20:39:18 Done - trying new naming scheme
250 PumpLoop();
251 EXPECT_FALSE(callback_called());
Pete Williamson 2016/05/27 18:32:09 I'm a bit confused that callback_called() is retur
dougarnett 2016/05/27 20:39:18 changed to completion_callback_called()
Pete Williamson 2016/05/27 21:06:46 Acknowledged.
252 EXPECT_TRUE(loaded());
253 EXPECT_TRUE(saving());
254
255 offliner()->Cancel();
256 PumpLoop();
257 EXPECT_FALSE(callback_called());
258 EXPECT_FALSE(loaded());
259 EXPECT_TRUE(saving());
fgorski 2016/05/27 18:43:11 Could you add a comment and explain why saving is
dougarnett 2016/05/27 20:39:18 Done.
260
261 // Subsequent save callback causes no harm (no crash and no callback).
262 offliner()->CallbackForSaveFailed();
263 PumpLoop();
264 EXPECT_FALSE(callback_called());
265 EXPECT_FALSE(loaded());
266 EXPECT_FALSE(saving());
267 }
268
269 TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadedButSaveFails) {
270 base::Time creation_time = base::Time::Now();
271 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
272 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
273 EXPECT_TRUE(loading());
274 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
275
276 loader()->CallbackForLoaded();
277 PumpLoop();
278 EXPECT_FALSE(callback_called());
279 EXPECT_TRUE(loaded());
280 EXPECT_TRUE(saving());
281
282 offliner()->CallbackForSaveFailed();
283 PumpLoop();
284 EXPECT_TRUE(callback_called());
285 EXPECT_EQ(Offliner::RequestStatus::FAILED_SAVE, request_status());
286 EXPECT_FALSE(loaded());
287 EXPECT_FALSE(saving());
288 }
289
290 TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadedAndSaved) {
fgorski 2016/05/27 18:43:11 How about: LoadAndSaveSuccessful
dougarnett 2016/05/27 20:39:18 Done.
291 base::Time creation_time = base::Time::Now();
292 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
293 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
294 EXPECT_TRUE(loading());
295 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
296
297 loader()->CallbackForLoaded();
298 PumpLoop();
299 EXPECT_FALSE(callback_called());
300 EXPECT_TRUE(loaded());
301 EXPECT_TRUE(saving());
302
303 offliner()->CallbackForSaved();
304 PumpLoop();
305 EXPECT_TRUE(callback_called());
306 EXPECT_EQ(Offliner::RequestStatus::SAVED, request_status());
307 EXPECT_FALSE(loaded());
308 EXPECT_FALSE(saving());
309 }
310
311 TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadedButThenCanceledFromLoader) {
312 base::Time creation_time = base::Time::Now();
313 SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
314 EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
315 EXPECT_TRUE(loading());
316 EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
317
318 loader()->CallbackForLoaded();
319 PumpLoop();
320 EXPECT_FALSE(callback_called());
321 EXPECT_TRUE(loaded());
322 EXPECT_TRUE(saving());
323
324 loader()->CallbackForLoadCanceledAfterLoaded();
325 PumpLoop();
326 EXPECT_TRUE(callback_called());
327 EXPECT_EQ(Offliner::RequestStatus::CANCELED, request_status());
328 EXPECT_FALSE(loaded());
fgorski 2016/05/27 18:43:11 Is there an assertion related to saving missing he
dougarnett 2016/05/27 20:39:18 Done.
329 }
330
155 } // namespace offline_pages 331 } // namespace offline_pages
OLDNEW
« no previous file with comments | « chrome/browser/android/offline_pages/prerendering_offliner.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698