| Index: chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc
|
| diff --git a/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc b/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc
|
| index 45267eddc5a7e63e4424ffb594d9047ae4ddf0f0..eef086b15126e5ab7b1c4fca8515074fb65088b6 100644
|
| --- a/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc
|
| +++ b/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc
|
| @@ -10,9 +10,12 @@
|
| #include "base/run_loop.h"
|
| #include "base/threading/thread_task_runner_handle.h"
|
| #include "chrome/browser/android/offline_pages/prerendering_loader.h"
|
| +#include "chrome/test/base/testing_profile.h"
|
| #include "components/offline_pages/background/offliner.h"
|
| #include "components/offline_pages/background/save_page_request.h"
|
| +#include "components/offline_pages/stub_offline_page_model.h"
|
| #include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "content/public/test/web_contents_tester.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace offline_pages {
|
| @@ -20,6 +23,7 @@ namespace offline_pages {
|
| namespace {
|
| const int64_t kRequestId = 7;
|
| const GURL kHttpUrl("http://tunafish.com");
|
| +const GURL kFileUrl("file://sailfish.png");
|
| const ClientId kClientId("AsyncLoading", "88");
|
|
|
| // Mock Loader for testing the Offliner calls.
|
| @@ -27,6 +31,7 @@ class MockPrerenderingLoader : public PrerenderingLoader {
|
| public:
|
| explicit MockPrerenderingLoader(content::BrowserContext* browser_context)
|
| : PrerenderingLoader(browser_context),
|
| + can_prerender_(true),
|
| mock_loading_(false),
|
| mock_loaded_(false) {}
|
| ~MockPrerenderingLoader() override {}
|
| @@ -41,10 +46,12 @@ class MockPrerenderingLoader : public PrerenderingLoader {
|
| mock_loading_ = false;
|
| mock_loaded_ = false;
|
| }
|
| +
|
| + bool CanPrerender() override { return can_prerender_; }
|
| bool IsIdle() override { return !mock_loading_ && !mock_loaded_; }
|
| bool IsLoaded() override { return mock_loaded_; }
|
|
|
| - void CallbackForLoadFailed() {
|
| + void CompleteLoadingAsFailed() {
|
| DCHECK(mock_loading_);
|
| mock_loading_ = false;
|
| mock_loaded_ = false;
|
| @@ -54,11 +61,32 @@ class MockPrerenderingLoader : public PrerenderingLoader {
|
| nullptr /* web_contents */));
|
| }
|
|
|
| - bool mock_loading() const { return mock_loading_; }
|
| - bool mock_loaded() const { return mock_loaded_; }
|
| + void CompleteLoadingAsLoaded() {
|
| + DCHECK(mock_loading_);
|
| + mock_loading_ = false;
|
| + mock_loaded_ = true;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(load_page_callback_, Offliner::RequestStatus::LOADED,
|
| + content::WebContentsTester::CreateTestWebContents(
|
| + new TestingProfile(), NULL)));
|
| + }
|
| +
|
| + void CompleteLoadingAsCanceled() {
|
| + DCHECK(!IsIdle());
|
| + mock_loading_ = false;
|
| + mock_loaded_ = false;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(load_page_callback_, Offliner::RequestStatus::CANCELED,
|
| + nullptr /* web_contents */));
|
| + }
|
| +
|
| + void DisablePrerendering() { can_prerender_ = false; }
|
| const LoadPageCallback& load_page_callback() { return load_page_callback_; }
|
|
|
| private:
|
| + bool can_prerender_;
|
| bool mock_loading_;
|
| bool mock_loaded_;
|
| LoadPageCallback load_page_callback_;
|
| @@ -66,6 +94,45 @@ class MockPrerenderingLoader : public PrerenderingLoader {
|
| DISALLOW_COPY_AND_ASSIGN(MockPrerenderingLoader);
|
| };
|
|
|
| +// Mock OfflinePageModel for testing the SavePage calls.
|
| +class MockOfflinePageModel : public StubOfflinePageModel {
|
| + public:
|
| + MockOfflinePageModel() : mock_saving_(false) {}
|
| + ~MockOfflinePageModel() override {}
|
| +
|
| + void SavePage(const GURL& url,
|
| + const ClientId& client_id,
|
| + std::unique_ptr<OfflinePageArchiver> archiver,
|
| + const SavePageCallback& callback) override {
|
| + mock_saving_ = true;
|
| + save_page_callback_ = callback;
|
| + }
|
| +
|
| + void CompleteSavingAsArchiveCreationFailed() {
|
| + DCHECK(mock_saving_);
|
| + mock_saving_ = false;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::Bind(save_page_callback_,
|
| + SavePageResult::ARCHIVE_CREATION_FAILED, 0));
|
| + }
|
| +
|
| + void CompleteSavingAsSuccess() {
|
| + DCHECK(mock_saving_);
|
| + mock_saving_ = false;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(save_page_callback_, SavePageResult::SUCCESS, 123456));
|
| + }
|
| +
|
| + bool mock_saving() const { return mock_saving_; }
|
| +
|
| + private:
|
| + bool mock_saving_;
|
| + SavePageCallback save_page_callback_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MockOfflinePageModel);
|
| +};
|
| +
|
| void PumpLoop() {
|
| base::RunLoop().RunUntilIdle();
|
| }
|
| @@ -85,10 +152,10 @@ class PrerenderingOfflinerTest : public testing::Test {
|
| base::Unretained(this));
|
| }
|
|
|
| - bool loading() const { return loader_->mock_loading(); }
|
| - bool loaded() const { return loader_->mock_loaded(); }
|
| + bool SaveInProgress() const { return model_->mock_saving(); }
|
| MockPrerenderingLoader* loader() { return loader_; }
|
| - bool callback_called() { return callback_called_; }
|
| + MockOfflinePageModel* model() { return model_; }
|
| + bool completion_callback_called() { return completion_callback_called_; }
|
| Offliner::RequestStatus request_status() { return request_status_; }
|
|
|
| private:
|
| @@ -99,7 +166,8 @@ class PrerenderingOfflinerTest : public testing::Test {
|
| std::unique_ptr<PrerenderingOffliner> offliner_;
|
| // Not owned.
|
| MockPrerenderingLoader* loader_;
|
| - bool callback_called_;
|
| + MockOfflinePageModel* model_;
|
| + bool completion_callback_called_;
|
| Offliner::RequestStatus request_status_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(PrerenderingOfflinerTest);
|
| @@ -107,13 +175,14 @@ class PrerenderingOfflinerTest : public testing::Test {
|
|
|
| PrerenderingOfflinerTest::PrerenderingOfflinerTest()
|
| : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
|
| - callback_called_(false),
|
| + completion_callback_called_(false),
|
| request_status_(Offliner::RequestStatus::UNKNOWN) {}
|
|
|
| PrerenderingOfflinerTest::~PrerenderingOfflinerTest() {}
|
|
|
| void PrerenderingOfflinerTest::SetUp() {
|
| - offliner_.reset(new PrerenderingOffliner(nullptr, nullptr, nullptr));
|
| + model_ = new MockOfflinePageModel();
|
| + offliner_.reset(new PrerenderingOffliner(nullptr, nullptr, model_));
|
| std::unique_ptr<MockPrerenderingLoader> mock_loader(
|
| new MockPrerenderingLoader(nullptr));
|
| loader_ = mock_loader.get();
|
| @@ -122,34 +191,141 @@ void PrerenderingOfflinerTest::SetUp() {
|
|
|
| void PrerenderingOfflinerTest::OnCompletion(const SavePageRequest& request,
|
| Offliner::RequestStatus status) {
|
| - DCHECK(!callback_called_); // Only expect single callback per request.
|
| - callback_called_ = true;
|
| + DCHECK(!completion_callback_called_); // Expect single callback per request.
|
| + completion_callback_called_ = true;
|
| request_status_ = status;
|
| }
|
|
|
| +TEST_F(PrerenderingOfflinerTest, LoadAndSaveBadUrl) {
|
| + base::Time creation_time = base::Time::Now();
|
| + SavePageRequest request(kRequestId, kFileUrl, kClientId, creation_time);
|
| + EXPECT_FALSE(offliner()->LoadAndSave(request, callback()));
|
| + EXPECT_TRUE(loader()->IsIdle());
|
| +}
|
| +
|
| +TEST_F(PrerenderingOfflinerTest, LoadAndSavePrerenderingDisabled) {
|
| + base::Time creation_time = base::Time::Now();
|
| + SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
|
| + loader()->DisablePrerendering();
|
| + EXPECT_FALSE(offliner()->LoadAndSave(request, callback()));
|
| + EXPECT_TRUE(loader()->IsIdle());
|
| +}
|
| +
|
| TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadStartedButFails) {
|
| base::Time creation_time = base::Time::Now();
|
| SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
|
| EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
|
| - EXPECT_TRUE(loading());
|
| + EXPECT_FALSE(loader()->IsIdle());
|
| EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
|
|
|
| - loader()->CallbackForLoadFailed();
|
| + loader()->CompleteLoadingAsFailed();
|
| PumpLoop();
|
| - EXPECT_TRUE(callback_called());
|
| + EXPECT_TRUE(completion_callback_called());
|
| EXPECT_EQ(Offliner::RequestStatus::FAILED, request_status());
|
| - EXPECT_FALSE(loading());
|
| - EXPECT_FALSE(loaded());
|
| + EXPECT_TRUE(loader()->IsIdle());
|
| + EXPECT_FALSE(SaveInProgress());
|
| }
|
|
|
| TEST_F(PrerenderingOfflinerTest, CancelWhenLoading) {
|
| base::Time creation_time = base::Time::Now();
|
| SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
|
| EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
|
| - EXPECT_TRUE(loading());
|
| + EXPECT_FALSE(loader()->IsIdle());
|
| +
|
| + offliner()->Cancel();
|
| + EXPECT_TRUE(loader()->IsIdle());
|
| +}
|
| +
|
| +TEST_F(PrerenderingOfflinerTest, CancelWhenLoaded) {
|
| + base::Time creation_time = base::Time::Now();
|
| + SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
|
| + EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
|
| + EXPECT_FALSE(loader()->IsIdle());
|
| + EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
|
| +
|
| + loader()->CompleteLoadingAsLoaded();
|
| + PumpLoop();
|
| + EXPECT_FALSE(completion_callback_called());
|
| + EXPECT_TRUE(loader()->IsLoaded());
|
| + EXPECT_TRUE(SaveInProgress());
|
|
|
| offliner()->Cancel();
|
| - EXPECT_FALSE(loading());
|
| + PumpLoop();
|
| + EXPECT_FALSE(completion_callback_called());
|
| + EXPECT_FALSE(loader()->IsLoaded());
|
| + // Note: save still in progress since it does not support canceling.
|
| + EXPECT_TRUE(SaveInProgress());
|
| +
|
| + // Subsequent save callback causes no harm (no crash and no callback).
|
| + model()->CompleteSavingAsArchiveCreationFailed();
|
| + PumpLoop();
|
| + EXPECT_FALSE(completion_callback_called());
|
| + EXPECT_TRUE(loader()->IsIdle());
|
| + EXPECT_FALSE(SaveInProgress());
|
| +}
|
| +
|
| +TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadedButSaveFails) {
|
| + base::Time creation_time = base::Time::Now();
|
| + SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
|
| + EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
|
| + EXPECT_FALSE(loader()->IsIdle());
|
| + EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
|
| +
|
| + loader()->CompleteLoadingAsLoaded();
|
| + PumpLoop();
|
| + EXPECT_FALSE(completion_callback_called());
|
| + EXPECT_TRUE(loader()->IsLoaded());
|
| + EXPECT_TRUE(SaveInProgress());
|
| +
|
| + model()->CompleteSavingAsArchiveCreationFailed();
|
| + PumpLoop();
|
| + EXPECT_TRUE(completion_callback_called());
|
| + EXPECT_EQ(Offliner::RequestStatus::FAILED_SAVE, request_status());
|
| + EXPECT_FALSE(loader()->IsLoaded());
|
| + EXPECT_FALSE(SaveInProgress());
|
| +}
|
| +
|
| +TEST_F(PrerenderingOfflinerTest, LoadAndSaveSuccessful) {
|
| + base::Time creation_time = base::Time::Now();
|
| + SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
|
| + EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
|
| + EXPECT_FALSE(loader()->IsIdle());
|
| + EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
|
| +
|
| + loader()->CompleteLoadingAsLoaded();
|
| + PumpLoop();
|
| + EXPECT_FALSE(completion_callback_called());
|
| + EXPECT_TRUE(loader()->IsLoaded());
|
| + EXPECT_TRUE(SaveInProgress());
|
| +
|
| + model()->CompleteSavingAsSuccess();
|
| + PumpLoop();
|
| + EXPECT_TRUE(completion_callback_called());
|
| + EXPECT_EQ(Offliner::RequestStatus::SAVED, request_status());
|
| + EXPECT_FALSE(loader()->IsLoaded());
|
| + EXPECT_FALSE(SaveInProgress());
|
| +}
|
| +
|
| +TEST_F(PrerenderingOfflinerTest, LoadAndSaveLoadedButThenCanceledFromLoader) {
|
| + base::Time creation_time = base::Time::Now();
|
| + SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time);
|
| + EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
|
| + EXPECT_FALSE(loader()->IsIdle());
|
| + EXPECT_EQ(Offliner::RequestStatus::UNKNOWN, request_status());
|
| +
|
| + loader()->CompleteLoadingAsLoaded();
|
| + PumpLoop();
|
| + EXPECT_FALSE(completion_callback_called());
|
| + EXPECT_TRUE(loader()->IsLoaded());
|
| + EXPECT_TRUE(SaveInProgress());
|
| +
|
| + loader()->CompleteLoadingAsCanceled();
|
| + PumpLoop();
|
| + EXPECT_TRUE(completion_callback_called());
|
| + EXPECT_EQ(Offliner::RequestStatus::CANCELED, request_status());
|
| + EXPECT_FALSE(loader()->IsLoaded());
|
| + // Note: save still in progress since it does not support canceling.
|
| + EXPECT_TRUE(SaveInProgress());
|
| }
|
|
|
| } // namespace offline_pages
|
|
|