Chromium Code Reviews| Index: chrome/browser/loader/delay_navigation_throttle_unittest.cc | 
| diff --git a/chrome/browser/loader/delay_navigation_throttle_unittest.cc b/chrome/browser/loader/delay_navigation_throttle_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..2bf20f41ff80b8bf7fc8f612018db2395a4f36ef | 
| --- /dev/null | 
| +++ b/chrome/browser/loader/delay_navigation_throttle_unittest.cc | 
| @@ -0,0 +1,163 @@ | 
| +// Copyright 2017 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/loader/delay_navigation_throttle.h" | 
| + | 
| +#include "base/memory/ptr_util.h" | 
| +#include "base/run_loop.h" | 
| +#include "base/test/scoped_feature_list.h" | 
| +#include "base/test/scoped_mock_time_message_loop_task_runner.h" | 
| +#include "base/test/test_mock_time_task_runner.h" | 
| +#include "chrome/test/base/chrome_render_view_host_test_harness.h" | 
| +#include "components/variations/variations_associated_data.h" | 
| +#include "content/public/browser/navigation_handle.h" | 
| +#include "net/http/http_util.h" | 
| + | 
| +class ScopedDelayNavigationFeatureParams { | 
| 
 
Charlie Harrison
2017/03/22 15:30:12
optional: Since this is a fairly simple feature, a
 
Bryan McQuade
2017/03/22 20:50:54
Sure, I ported to a parameterized harness. I kept
 
 | 
| + public: | 
| + ScopedDelayNavigationFeatureParams( | 
| + base::FeatureList::OverrideState feature_state, | 
| + const std::map<std::string, std::string>& variation_params) { | 
| + static const char kTestFieldTrialName[] = "TestTrial"; | 
| + static const char kTestExperimentGroupName[] = "TestGroup"; | 
| + | 
| + EXPECT_TRUE(variations::AssociateVariationParams( | 
| + kTestFieldTrialName, kTestExperimentGroupName, variation_params)); | 
| + | 
| + base::FieldTrial* field_trial = base::FieldTrialList::CreateFieldTrial( | 
| + kTestFieldTrialName, kTestExperimentGroupName); | 
| + | 
| + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); | 
| + feature_list->RegisterFieldTrialOverride(kDelayNavigationFeature.name, | 
| + feature_state, field_trial); | 
| + | 
| + // Since we are adding a scoped feature list after browser start, copy over | 
| + // the existing feature list to prevent inconsistency. | 
| + base::FeatureList* existing_feature_list = base::FeatureList::GetInstance(); | 
| + if (existing_feature_list) { | 
| + std::string enabled_features; | 
| + std::string disabled_features; | 
| + base::FeatureList::GetInstance()->GetFeatureOverrides(&enabled_features, | 
| + &disabled_features); | 
| + feature_list->InitializeFromCommandLine(enabled_features, | 
| + disabled_features); | 
| + } | 
| + | 
| + scoped_feature_list_.InitWithFeatureList(std::move(feature_list)); | 
| + } | 
| + | 
| + ~ScopedDelayNavigationFeatureParams() { | 
| + variations::testing::ClearAllVariationParams(); | 
| + } | 
| + | 
| + private: | 
| + base::test::ScopedFeatureList scoped_feature_list_; | 
| + | 
| + DISALLOW_COPY_AND_ASSIGN(ScopedDelayNavigationFeatureParams); | 
| +}; | 
| + | 
| +class DelayNavigationThrottleTest : public ChromeRenderViewHostTestHarness {}; | 
| + | 
| +TEST_F(DelayNavigationThrottleTest, BasicDelay) { | 
| + const char kBasicResponseHeaders[] = "HTTP/1.1 200 OK"; | 
| + base::TimeDelta navigation_delay = base::TimeDelta::FromSeconds(1); | 
| + GURL url("http://www.example.com/"); | 
| + | 
| + scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner( | 
| + new base::TestMockTimeTaskRunner()); | 
| + std::unique_ptr<content::NavigationHandle> test_handle = | 
| + content::NavigationHandle::CreateNavigationHandleForTesting(url, | 
| + main_rfh()); | 
| + test_handle->RegisterThrottleForTesting( | 
| + base::MakeUnique<DelayNavigationThrottle>( | 
| + test_handle.get(), mock_time_task_runner, navigation_delay)); | 
| + | 
| + EXPECT_FALSE(mock_time_task_runner->HasPendingTask()); | 
| + EXPECT_EQ(content::NavigationThrottle::DEFER, | 
| + test_handle->CallWillStartRequestForTesting( | 
| + false /* is_post */, content::Referrer(), | 
| + false /* has_user_gesture */, ui::PAGE_TRANSITION_LINK, | 
| + false /* is_external_protocol */)); | 
| + | 
| + // There may be other throttles that DEFER and post async tasks to the UI | 
| + // thread. Allow them to run to completion, so our throttle is guaranteed to | 
| + // have a chance to run. | 
| + base::RunLoop().RunUntilIdle(); | 
| + | 
| + EXPECT_TRUE(mock_time_task_runner->HasPendingTask()); | 
| + EXPECT_FALSE(test_handle->HasCommitted()); | 
| + | 
| + mock_time_task_runner->FastForwardBy(navigation_delay); | 
| + EXPECT_FALSE(mock_time_task_runner->HasPendingTask()); | 
| + | 
| + // Run any remaining async tasks, to make sure all other deferred throttles | 
| + // can complete. | 
| + base::RunLoop().RunUntilIdle(); | 
| + | 
| + // Verify that the WillSendRequest portion of the navigation has completed, | 
| + // and NavigationHandle::WillProcessResponse and the commit portion of the | 
| + // navigation lifetime can now be invoked. | 
| + EXPECT_EQ(content::NavigationThrottle::PROCEED, | 
| + test_handle->CallWillProcessResponseForTesting( | 
| + main_rfh(), | 
| + net::HttpUtil::AssembleRawHeaders( | 
| + kBasicResponseHeaders, strlen(kBasicResponseHeaders)))); | 
| + test_handle->CallDidCommitNavigationForTesting(url); | 
| + EXPECT_TRUE(test_handle->HasCommitted()); | 
| +} | 
| + | 
| +TEST_F(DelayNavigationThrottleTest, NoThrottleWhenFeatureDisabled) { | 
| + base::FieldTrialList field_trial_list(nullptr /* entropy_provider */); | 
| + ScopedDelayNavigationFeatureParams params( | 
| + base::FeatureList::OVERRIDE_DISABLE_FEATURE, | 
| + std::map<std::string, std::string>()); | 
| + GURL url("http://www.example.com/"); | 
| + std::unique_ptr<content::NavigationHandle> test_handle = | 
| + content::NavigationHandle::CreateNavigationHandleForTesting(url, | 
| + main_rfh()); | 
| + EXPECT_EQ(nullptr, | 
| + DelayNavigationThrottle::MaybeCreateThrottleFor(test_handle.get())); | 
| +} | 
| + | 
| +TEST_F(DelayNavigationThrottleTest, CreateThrottleWhenFeatureEnabled) { | 
| + base::FieldTrialList field_trial_list(nullptr /* entropy_provider */); | 
| + ScopedDelayNavigationFeatureParams params( | 
| + base::FeatureList::OVERRIDE_ENABLE_FEATURE, | 
| + {{DelayNavigationThrottle::kParamDelayNavigationDurationMillis, "10"}, | 
| + {DelayNavigationThrottle::kParamDelayNavigationProbability, "1"}}); | 
| + GURL url("http://www.example.com/"); | 
| + std::unique_ptr<content::NavigationHandle> test_handle = | 
| + content::NavigationHandle::CreateNavigationHandleForTesting(url, | 
| + main_rfh()); | 
| + EXPECT_NE(nullptr, | 
| + DelayNavigationThrottle::MaybeCreateThrottleFor(test_handle.get())); | 
| +} | 
| + | 
| +TEST_F(DelayNavigationThrottleTest, NoThrottleForNonHttpOrHttpsURL) { | 
| + base::FieldTrialList field_trial_list(nullptr /* entropy_provider */); | 
| + ScopedDelayNavigationFeatureParams params( | 
| + base::FeatureList::OVERRIDE_ENABLE_FEATURE, | 
| + {{DelayNavigationThrottle::kParamDelayNavigationDurationMillis, "10"}, | 
| + {DelayNavigationThrottle::kParamDelayNavigationProbability, "1"}}); | 
| + GURL url("chrome://version"); | 
| + std::unique_ptr<content::NavigationHandle> test_handle = | 
| + content::NavigationHandle::CreateNavigationHandleForTesting(url, | 
| + main_rfh()); | 
| + EXPECT_EQ(nullptr, | 
| + DelayNavigationThrottle::MaybeCreateThrottleFor(test_handle.get())); | 
| +} | 
| + | 
| +TEST_F(DelayNavigationThrottleTest, NoThrottleWhenProbabilityZero) { | 
| + base::FieldTrialList field_trial_list(nullptr /* entropy_provider */); | 
| + ScopedDelayNavigationFeatureParams params( | 
| + base::FeatureList::OVERRIDE_ENABLE_FEATURE, | 
| + {{DelayNavigationThrottle::kParamDelayNavigationDurationMillis, "10"}, | 
| + {DelayNavigationThrottle::kParamDelayNavigationProbability, "0"}}); | 
| + GURL url("http://www.example.com/"); | 
| + std::unique_ptr<content::NavigationHandle> test_handle = | 
| + content::NavigationHandle::CreateNavigationHandleForTesting(url, | 
| + main_rfh()); | 
| + EXPECT_EQ(nullptr, | 
| + DelayNavigationThrottle::MaybeCreateThrottleFor(test_handle.get())); | 
| +} |