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

Unified Diff: chrome/browser/android/offline_pages/offline_page_request_job_unittest.cc

Issue 2245733004: Serve offline page for online URL on disconnected or bad networks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix junit test Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/offline_pages/offline_page_request_job_unittest.cc
diff --git a/chrome/browser/android/offline_pages/offline_page_request_job_unittest.cc b/chrome/browser/android/offline_pages/offline_page_request_job_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6d34d5962763479ef1e0e90e57b34d29d24c4285
--- /dev/null
+++ b/chrome/browser/android/offline_pages/offline_page_request_job_unittest.cc
@@ -0,0 +1,673 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/offline_pages/offline_page_request_job.h"
+
+#include "base/callback.h"
+#include "base/feature_list.h"
+#include "base/files/file_path.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/metrics/field_trial.h"
+#include "base/path_service.h"
+#include "base/run_loop.h"
+#include "base/test/histogram_tester.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "chrome/browser/android/offline_pages/offline_page_model_factory.h"
+#include "chrome/browser/android/offline_pages/offline_page_request_interceptor.h"
+#include "chrome/browser/android/offline_pages/offline_page_tab_helper.h"
+#include "chrome/browser/android/offline_pages/test_offline_page_model_builder.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "components/offline_pages/client_namespace_constants.h"
+#include "components/offline_pages/offline_page_model.h"
+#include "components/previews/previews_experiments.h"
+#include "components/variations/variations_associated_data.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/resource_type.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/nqe/network_quality_estimator.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_intercepting_job_factory.h"
+#include "net/url_request/url_request_job_factory_impl.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace offline_pages {
+
+namespace {
+
+const GURL kTestUrl("http://test.org/page1");
+const GURL kTestUrl2("http://test.org/page2");
+const ClientId kTestClientId = ClientId(kBookmarkNamespace, "1234");
+const int kTestFileSize = 444;
+const int kTabId = 1;
+const int kBufSize = 1024;
+const char kAggregatedRequestResultHistogram[] =
+ "OfflinePages.AggregatedRequestResult";
+
+class OfflinePageRequestJobTestDelegate :
+ public OfflinePageRequestJob::Delegate {
+ public:
+ OfflinePageRequestJobTestDelegate(content::WebContents* web_content,
+ int tab_id)
+ : web_content_(web_content),
+ tab_id_(tab_id) {}
+
+ content::ResourceRequestInfo::WebContentsGetter
+ GetWebContentsGetter(net::URLRequest* request) const override {
+ return base::Bind(&OfflinePageRequestJobTestDelegate::GetWebContents,
+ web_content_);
+ }
+
+ OfflinePageRequestJob::Delegate::TabIdGetter GetTabIdGetter() const override {
+ return base::Bind(&OfflinePageRequestJobTestDelegate::GetTabId,
+ tab_id_);
+ }
+
+ private:
+ static content::WebContents* GetWebContents(
+ content::WebContents* web_content) {
+ return web_content;
+ }
+
+ static bool GetTabId(
+ int tab_id_value, content::WebContents* web_content, int* tab_id) {
+ *tab_id = tab_id_value;
+ return true;
+ }
+
+ content::WebContents* web_content_;
+ int tab_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(OfflinePageRequestJobTestDelegate);
+};
+
+class TestURLRequestDelegate : public net::URLRequest::Delegate {
+ public:
+ typedef base::Callback<void(int)> ReadCompletedCallback;
+
+ explicit TestURLRequestDelegate(const ReadCompletedCallback& callback)
+ : read_completed_callback_(callback),
+ buffer_(new net::IOBuffer(kBufSize)) {}
+
+ void OnResponseStarted(net::URLRequest* request) override {
+ if (!request->status().is_success()) {
+ read_completed_callback_.Run(0);
+ return;
+ }
+ int bytes_read = 0;
+ request->Read(buffer_.get(), kBufSize, &bytes_read);
+ }
+
+ void OnReadCompleted(net::URLRequest* request, int bytes_read) override {
+ if (!read_completed_callback_.is_null())
+ read_completed_callback_.Run(bytes_read);
+ }
+
+ private:
+ ReadCompletedCallback read_completed_callback_;
+ scoped_refptr<net::IOBuffer> buffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestURLRequestDelegate);
+};
+
+class TestURLRequestInterceptingJobFactory
+ : public net::URLRequestInterceptingJobFactory {
+ public:
+ TestURLRequestInterceptingJobFactory(
+ std::unique_ptr<net::URLRequestJobFactory> job_factory,
+ std::unique_ptr<net::URLRequestInterceptor> interceptor,
+ content::WebContents* web_contents)
+ : net::URLRequestInterceptingJobFactory(
+ std::move(job_factory), std::move(interceptor)),
+ web_contents_(web_contents) {}
+ ~TestURLRequestInterceptingJobFactory() override {}
+
+ net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
+ const std::string& scheme,
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ net::URLRequestJob* job = net::URLRequestInterceptingJobFactory::
+ MaybeCreateJobWithProtocolHandler(scheme, request, network_delegate);
+ if (job) {
+ static_cast<OfflinePageRequestJob*>(job)->SetDelegateForTesting(
+ base::MakeUnique<OfflinePageRequestJobTestDelegate>(
+ web_contents_, kTabId));
+ }
+ return job;
+ }
+
+ private:
+ content::WebContents* web_contents_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestURLRequestInterceptingJobFactory);
+};
+
+class TestNetworkChangeNotifier : public net::NetworkChangeNotifier {
+ public:
+ TestNetworkChangeNotifier() : online_(true) {}
+ ~TestNetworkChangeNotifier() override {}
+
+ net::NetworkChangeNotifier::ConnectionType GetCurrentConnectionType()
+ const override {
+ return online_ ? net::NetworkChangeNotifier::CONNECTION_UNKNOWN
+ : net::NetworkChangeNotifier::CONNECTION_NONE;
+ }
+
+ void set_online(bool online) { online_ = online; }
+
+ private:
+ bool online_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestNetworkChangeNotifier);
+};
+
+class TestNetworkQualityEstimator : public net::NetworkQualityEstimator {
+ public:
+ explicit TestNetworkQualityEstimator(
+ const std::map<std::string, std::string>& variation_params)
+ : NetworkQualityEstimator(
+ std::unique_ptr<net::ExternalEstimateProvider>(),
+ variation_params),
+ effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {}
+ ~TestNetworkQualityEstimator() override {}
+
+ net::EffectiveConnectionType GetEffectiveConnectionType() const override {
+ return effective_connection_type_;
+ }
+
+ void set_effective_connection_type(
+ net::EffectiveConnectionType effective_connection_type) {
+ effective_connection_type_ = effective_connection_type;
+ }
+
+ private:
+ net::EffectiveConnectionType effective_connection_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator);
+};
+
+class ScopedEnableProbihibitivelySlowNetwork {
+ public:
+ explicit ScopedEnableProbihibitivelySlowNetwork(
+ net::URLRequestContext* url_request_context)
+ : field_trial_list_(nullptr),
+ url_request_context_(url_request_context) {
+ previews::EnableOfflinePreviewsForTesting();
+
+ test_network_quality_estimator_ =
+ base::MakeUnique<TestNetworkQualityEstimator>
+ (network_quality_estimator_params_);
+ test_network_quality_estimator_->set_effective_connection_type(
+ net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
+ url_request_context_->set_network_quality_estimator(
+ test_network_quality_estimator_.get());
+ }
+
+ ~ScopedEnableProbihibitivelySlowNetwork() {
+ url_request_context_->set_network_quality_estimator(nullptr);
+ variations::testing::ClearAllVariationParams();
+ }
+
+ private:
+ base::FieldTrialList field_trial_list_;
+ std::map<std::string, std::string> network_quality_estimator_params_;
+ std::unique_ptr<TestNetworkQualityEstimator> test_network_quality_estimator_;
+ net::URLRequestContext* url_request_context_;
+};
+
+class TestOfflinePageArchiver : public OfflinePageArchiver {
+ public:
+ TestOfflinePageArchiver(const GURL& url,
+ const base::FilePath& archive_file_path)
+ : url_(url),
+ archive_file_path_(archive_file_path) {}
+ ~TestOfflinePageArchiver() override {}
+
+ void CreateArchive(const base::FilePath& archives_dir,
+ int64_t archive_id,
+ const CreateArchiveCallback& callback) override {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(callback, this, ArchiverResult::SUCCESSFULLY_CREATED,
+ url_, archive_file_path_, base::string16(), kTestFileSize));
+ }
+
+ private:
+ const GURL url_;
+ const base::FilePath archive_file_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestOfflinePageArchiver);
+};
+
+} // namespace
+
+class OfflinePageRequestJobTest : public testing::Test {
+ public:
+ OfflinePageRequestJobTest();
+ ~OfflinePageRequestJobTest() override {}
+
+ void SetUp() override;
+
+ void SimulateHasNetworkConnectivity(bool has_connectivity);
+ void RunUntilIdle();
+
+ void InterceptRequest(const GURL& url,
+ const std::string& method,
+ const std::string& extra_header_name,
+ const std::string& extra_header_value,
+ content::ResourceType resource_type);
+
+ void ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult result);
+
+ net::TestURLRequestContext* url_request_context() {
+ return test_url_request_context_.get();
+ }
+ Profile* profile() { return profile_; }
+ OfflinePageTabHelper* offline_page_tab_helper() const {
+ return offline_page_tab_helper_;
+ }
+ int64_t offline_id() const { return offline_id_; }
+ int bytes_read() const { return bytes_read_; }
+
+ private:
+ void OnSavePageDone(SavePageResult result, int64_t offline_id);
+ std::unique_ptr<net::URLRequest> CreateRequest(
+ const GURL& url,
+ const std::string& method,
+ content::ResourceType resource_type);
+ void ReadCompleted(int bytes_read);
+
+ // Runs on IO thread.
+ void InterceptRequestOnIO(const GURL& url,
+ const std::string& method,
+ const std::string& extra_header_name,
+ const std::string& extra_header_value,
+ content::ResourceType resource_type,
+ void* profile_id);
+ void ReadCompletedOnIO(int bytes_read);
+
+ content::TestBrowserThreadBundle thread_bundle_;
+ std::unique_ptr<TestNetworkChangeNotifier> network_change_notifier_;
+ std::unique_ptr<net::TestURLRequestContext> test_url_request_context_;
+ net::URLRequestJobFactoryImpl url_request_job_factory_;
+ std::unique_ptr<net::URLRequestInterceptingJobFactory>
+ intercepting_job_factory_;
+ std::unique_ptr<TestURLRequestDelegate> url_request_delegate_;
+ net::TestNetworkDelegate network_delegate_;
+ TestingProfileManager profile_manager_;
+ TestingProfile* profile_;
+ std::unique_ptr<content::WebContents> web_contents_;
+ base::HistogramTester histogram_tester_;
+ OfflinePageTabHelper* offline_page_tab_helper_; // Not owned.
+ std::unique_ptr<net::URLRequest> request_;
+ int64_t offline_id_;
+ int bytes_read_;
+
+ DISALLOW_COPY_AND_ASSIGN(OfflinePageRequestJobTest);
+};
+
+OfflinePageRequestJobTest::OfflinePageRequestJobTest()
+ : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+ network_change_notifier_(new TestNetworkChangeNotifier()),
+ profile_manager_(TestingBrowserProcess::GetGlobal()),
+ offline_id_(-1),
+ bytes_read_(0) {
+}
+
+void OfflinePageRequestJobTest::SetUp() {
+ // Create a test profile.
+ ASSERT_TRUE(profile_manager_.SetUp());
+ profile_ = profile_manager_.CreateTestingProfile("Profile 1");
+
+ // Create a test web contents.
+ web_contents_.reset(content::WebContents::Create(
+ content::WebContents::CreateParams(profile_)));
+ OfflinePageTabHelper::CreateForWebContents(web_contents_.get());
+ offline_page_tab_helper_ =
+ OfflinePageTabHelper::FromWebContents(web_contents_.get());
+
+ // Set up the factory for testing.
+ OfflinePageModelFactory::GetInstance()->SetTestingFactoryAndUse(
+ profile(), BuildTestOfflinePageModel);
+ RunUntilIdle();
+
+ // Use a test archive file.
+ base::FilePath archive_file_path;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &archive_file_path));
+ archive_file_path =
+ archive_file_path.AppendASCII("offline_pages").AppendASCII("test.mhtml");
+ std::unique_ptr<TestOfflinePageArchiver> archiver(
+ new TestOfflinePageArchiver(kTestUrl, archive_file_path));
+
+ // Save an offline page.
+ OfflinePageModel* model =
+ OfflinePageModelFactory::GetForBrowserContext(profile());
+ model->SavePage(
+ kTestUrl, kTestClientId, 0, std::move(archiver),
+ base::Bind(&OfflinePageRequestJobTest::OnSavePageDone,
+ base::Unretained(this)));
+ RunUntilIdle();
+
+ // Create a context with delayed initialization.
+ test_url_request_context_.reset(new net::TestURLRequestContext(true));
+
+ // Install the interceptor.
+ std::unique_ptr<net::URLRequestInterceptor> interceptor(
+ new OfflinePageRequestInterceptor(profile_));
+ std::unique_ptr<net::URLRequestJobFactoryImpl> job_factory_impl(
+ new net::URLRequestJobFactoryImpl());
+ intercepting_job_factory_.reset(new TestURLRequestInterceptingJobFactory(
+ std::move(job_factory_impl),
+ std::move(interceptor),
+ web_contents_.get()));
+
+ test_url_request_context_->set_job_factory(intercepting_job_factory_.get());
+ test_url_request_context_->Init();
+}
+
+void OfflinePageRequestJobTest::SimulateHasNetworkConnectivity(
+ bool online) {
+ network_change_notifier_->set_online(online);
+}
+
+void OfflinePageRequestJobTest::RunUntilIdle() {
+ base::RunLoop().RunUntilIdle();
+}
+
+std::unique_ptr<net::URLRequest> OfflinePageRequestJobTest::CreateRequest(
+ const GURL& url,
+ const std::string& method,
+ content::ResourceType resource_type) {
+ url_request_delegate_ = base::MakeUnique<TestURLRequestDelegate>(
+ base::Bind(&OfflinePageRequestJobTest::ReadCompletedOnIO,
+ base::Unretained(this)));
+
+ std::unique_ptr<net::URLRequest> request =
+ url_request_context()->CreateRequest(
+ url, net::DEFAULT_PRIORITY, url_request_delegate_.get());
+ request->set_method(method);
+
+ content::ResourceRequestInfo::AllocateForTesting(
+ request.get(),
+ resource_type,
+ nullptr,
+ 1, /* render_process_id */
+ -1, /* render_view_id */
+ 1, /* render_frame_id */
+ true, /* is_main_frame */
+ false, /* parent_is_main_frame */
+ true, /* allow_download */
+ true, /* is_async */
+ false /* is_using_lofi */);
+
+ return request;
+}
+
+void OfflinePageRequestJobTest::ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult result) {
+ histogram_tester_.ExpectUniqueSample(
+ kAggregatedRequestResultHistogram, static_cast<int>(result), 1);
+}
+
+void OfflinePageRequestJobTest::OnSavePageDone(SavePageResult result,
+ int64_t offline_id) {
+ ASSERT_EQ(SavePageResult::SUCCESS, result);
+ offline_id_ = offline_id;
+}
+
+void OfflinePageRequestJobTest::InterceptRequestOnIO(
+ const GURL& url,
+ const std::string& method,
+ const std::string& extra_header_name,
+ const std::string& extra_header_value,
+ content::ResourceType resource_type,
+ void* profile_id) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ request_ = CreateRequest(url, method, resource_type);
+ if (!extra_header_name.empty()) {
+ request_->SetExtraRequestHeaderByName(
+ extra_header_name, extra_header_value, true);
+ }
+ request_->Start();
+}
+
+void OfflinePageRequestJobTest::InterceptRequest(
+ const GURL& url,
+ const std::string& method,
+ const std::string& extra_header_name,
+ const std::string& extra_header_value,
+ content::ResourceType resource_type) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&OfflinePageRequestJobTest::InterceptRequestOnIO,
+ base::Unretained(this), url, method, extra_header_name,
+ extra_header_value, resource_type, profile()));
+}
+
+void OfflinePageRequestJobTest::ReadCompletedOnIO(int bytes_read) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::Bind(&OfflinePageRequestJobTest::ReadCompleted,
+ base::Unretained(this), bytes_read));
+}
+
+void OfflinePageRequestJobTest::ReadCompleted(int bytes_read) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ bytes_read_ = bytes_read;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
+}
+
+TEST_F(OfflinePageRequestJobTest, FailedToCreateRequestJob) {
+ SimulateHasNetworkConnectivity(false);
+
+ // Must be http/https URL.
+ InterceptRequest(GURL("ftp://host/doc"), "GET", "", "",
+ content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+
+ InterceptRequest(GURL("file:///path/doc"), "GET", "", "",
+ content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+
+ // Must be GET method.
+ InterceptRequest(
+ kTestUrl, "POST", "", "", content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+
+ InterceptRequest(
+ kTestUrl, "HEAD", "", "", content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+
+ // Must be main resource.
+ InterceptRequest(
+ kTestUrl, "POST", "", "", content::RESOURCE_TYPE_SUB_FRAME);
+ base::RunLoop().Run();
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+
+ InterceptRequest(
+ kTestUrl, "POST", "", "", content::RESOURCE_TYPE_IMAGE);
+ base::RunLoop().Run();
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+}
+
+TEST_F(OfflinePageRequestJobTest, LoadOfflinePageOnDisconnectedNetwork) {
+ SimulateHasNetworkConnectivity(false);
+
+ InterceptRequest(kTestUrl, "GET", "", "", content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+
+ EXPECT_EQ(kTestFileSize, bytes_read());
+ ASSERT_TRUE(offline_page_tab_helper()->offline_page());
+ EXPECT_EQ(offline_id(),
+ offline_page_tab_helper()->offline_page()->offline_id);
+ ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult::
+ SHOW_OFFLINE_ON_DISCONNECTED_NETWORK);
+}
+
+TEST_F(OfflinePageRequestJobTest, PageNotFoundOnDisconnectedNetwork) {
+ SimulateHasNetworkConnectivity(false);
+
+ InterceptRequest(kTestUrl2, "GET", "", "", content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+ ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult::
+ PAGE_NOT_FOUND_ON_DISCONNECTED_NETWORK);
+}
+
+TEST_F(OfflinePageRequestJobTest, LoadOfflinePageOnProhibitivelySlowNetwork) {
+ SimulateHasNetworkConnectivity(true);
+
+ ScopedEnableProbihibitivelySlowNetwork scoped(url_request_context());
+
+ InterceptRequest(kTestUrl, "GET", "", "", content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+
+ EXPECT_EQ(kTestFileSize, bytes_read());
+ ASSERT_TRUE(offline_page_tab_helper()->offline_page());
+ EXPECT_EQ(offline_id(),
+ offline_page_tab_helper()->offline_page()->offline_id);
+ ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult::
+ SHOW_OFFLINE_ON_PROHIBITIVELY_SLOW_NETWORK);
+}
+
+TEST_F(OfflinePageRequestJobTest, PageNotFoundOnProhibitivelySlowNetwork) {
+ SimulateHasNetworkConnectivity(true);
+
+ ScopedEnableProbihibitivelySlowNetwork scoped(url_request_context());
+
+ InterceptRequest(kTestUrl2, "GET", "", "", content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+ ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult::
+ PAGE_NOT_FOUND_ON_PROHIBITIVELY_SLOW_NETWORK);
+}
+
+TEST_F(OfflinePageRequestJobTest, LoadOfflinePageOnFlakyNetwork) {
+ SimulateHasNetworkConnectivity(true);
+
+ // When custom offline header exists and contains "reason=error", it means
+ // that net error is hit in last request due to flaky network.
+ InterceptRequest(
+ kTestUrl,
+ "GET",
+ kLoadingOfflinePageHeader,
+ std::string(kLoadingOfflinePageReason) + kLoadingOfflinePageDueToNetError,
+ content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+
+ EXPECT_EQ(kTestFileSize, bytes_read());
+ ASSERT_TRUE(offline_page_tab_helper()->offline_page());
+ EXPECT_EQ(offline_id(),
+ offline_page_tab_helper()->offline_page()->offline_id);
+ ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult::
+ SHOW_OFFLINE_ON_FLAKY_NETWORK);
+}
+
+TEST_F(OfflinePageRequestJobTest, PageNotFoundOnFlakyNetwork) {
+ SimulateHasNetworkConnectivity(true);
+
+ // When custom offline header exists and contains "reason=error", it means
+ // that net error is hit in last request due to flaky network.
+ InterceptRequest(
+ kTestUrl2,
+ "GET",
+ kLoadingOfflinePageHeader,
+ std::string(kLoadingOfflinePageReason) + kLoadingOfflinePageDueToNetError,
+ content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+ ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult::
+ PAGE_NOT_FOUND_ON_FLAKY_NETWORK);
+}
+
+TEST_F(OfflinePageRequestJobTest, ForceLoadOfflinePageOnConnectedNetwork) {
+ SimulateHasNetworkConnectivity(true);
+
+ // When custom offline header exists and contains value other than
+ // "reason=error", it means that offline page is forced to load.
+ InterceptRequest(
+ kTestUrl,
+ "GET",
+ kLoadingOfflinePageHeader,
+ std::string(kLoadingOfflinePageReason) + "download",
+ content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+
+ EXPECT_EQ(kTestFileSize, bytes_read());
+ ASSERT_TRUE(offline_page_tab_helper()->offline_page());
+ EXPECT_EQ(offline_id(),
+ offline_page_tab_helper()->offline_page()->offline_id);
+ ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult::
+ SHOW_OFFLINE_ON_CONNECTED_NETWORK);
+}
+
+TEST_F(OfflinePageRequestJobTest, PageNotFoundOnConnectedNetwork) {
+ SimulateHasNetworkConnectivity(true);
+
+ // When custom offline header exists and contains value other than
+ // "reason=error", it means that offline page is forced to load.
+ InterceptRequest(
+ kTestUrl2,
+ "GET",
+ kLoadingOfflinePageHeader,
+ std::string(kLoadingOfflinePageReason) + "download",
+ content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+ ExpectAggregatedRequestResultHistogram(
+ OfflinePageRequestJob::AggregatedRequestResult::
+ PAGE_NOT_FOUND_ON_CONNECTED_NETWORK);
+}
+
+TEST_F(OfflinePageRequestJobTest, DoNotLoadOfflinePageOnConnectedNetwork) {
+ SimulateHasNetworkConnectivity(true);
+
+ InterceptRequest(kTestUrl, "GET", "", "", content::RESOURCE_TYPE_MAIN_FRAME);
+ base::RunLoop().Run();
+
+ EXPECT_EQ(0, bytes_read());
+ EXPECT_FALSE(offline_page_tab_helper()->offline_page());
+}
+
+} // namespace offline_pages

Powered by Google App Engine
This is Rietveld 408576698