blob: 9626aac39466cc3b6a5209853612c60d197c6709 [file] [log] [blame]
[email protected]3d831992013-07-04 01:13:291// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chrome_content_browser_client.h"
6
msramek1f4746d2016-08-19 21:37:077#include <list>
bmcquade5d2d9cf32015-06-19 17:42:288#include <map>
msramek1f4746d2016-08-19 21:37:079#include <memory>
bmcquade5d2d9cf32015-06-19 17:42:2810
msramek1f4746d2016-08-19 21:37:0711#include "base/bind.h"
[email protected]30335fdf02014-02-26 19:51:2712#include "base/command_line.h"
avie4d7b6f2015-12-26 00:59:1813#include "base/macros.h"
msramek1f4746d2016-08-19 21:37:0714#include "base/memory/ptr_util.h"
15#include "base/message_loop/message_loop.h"
[email protected]10a9bf92013-11-13 23:34:4816#include "base/metrics/field_trial.h"
msramek1f4746d2016-08-19 21:37:0717#include "base/strings/stringprintf.h"
mpearson3c6d7af2015-05-13 23:59:5318#include "base/strings/utf_string_conversions.h"
avie4d7b6f2015-12-26 00:59:1819#include "build/build_config.h"
msramek1f4746d2016-08-19 21:37:0720#include "chrome/browser/browsing_data/browsing_data_filter_builder.h"
21#include "chrome/browser/browsing_data/browsing_data_helper.h"
22#include "chrome/browser/browsing_data/browsing_data_remover.h"
23#include "chrome/browser/browsing_data/browsing_data_remover_factory.h"
24#include "chrome/browser/browsing_data/origin_filter_builder.h"
25#include "chrome/browser/browsing_data/registrable_domain_filter_builder.h"
[email protected]10a9bf92013-11-13 23:34:4826#include "chrome/browser/search_engines/template_url_service_factory.h"
msramek1f4746d2016-08-19 21:37:0727#include "chrome/test/base/testing_profile.h"
timvolodinea47291a2015-01-23 14:04:4328#include "components/content_settings/core/browser/host_content_settings_map.h"
[email protected]bf5c532d2014-07-05 00:29:5329#include "components/search_engines/template_url_service.h"
[email protected]10a9bf92013-11-13 23:34:4830#include "components/variations/entropy_provider.h"
bmcquade5d2d9cf32015-06-19 17:42:2831#include "components/variations/variations_associated_data.h"
sdefresne9fb67692015-08-03 18:48:2232#include "components/version_info/version_info.h"
[email protected]10a9bf92013-11-13 23:34:4833#include "content/public/browser/navigation_controller.h"
34#include "content/public/browser/navigation_entry.h"
35#include "content/public/browser/web_contents.h"
[email protected]30335fdf02014-02-26 19:51:2736#include "content/public/common/content_switches.h"
bmcquade5d2d9cf32015-06-19 17:42:2837#include "content/public/test/test_browser_thread_bundle.h"
msramek1f4746d2016-08-19 21:37:0738#include "testing/gmock/include/gmock/gmock.h"
[email protected]3d831992013-07-04 01:13:2939#include "testing/gtest/include/gtest/gtest.h"
[email protected]5f5ef802013-07-04 16:11:1340#include "url/gurl.h"
[email protected]3d831992013-07-04 01:13:2941
jam1c5a91492016-02-24 20:47:5342#if !defined(OS_ANDROID)
thestigf80564462015-09-29 23:12:0843#include "chrome/browser/ui/browser.h"
44#include "chrome/browser/ui/tabs/tab_strip_model.h"
bengre8a146f2016-03-10 01:20:2245#include "chrome/common/pref_names.h"
thestigf80564462015-09-29 23:12:0846#include "chrome/test/base/browser_with_test_window_test.h"
47#include "chrome/test/base/search_test_utils.h"
48#endif
49
msramek1f4746d2016-08-19 21:37:0750using testing::_;
mlamourieb40d552015-02-05 00:57:0851using ChromeContentBrowserClientTest = testing::Test;
[email protected]3d831992013-07-04 01:13:2952
[email protected]3d831992013-07-04 01:13:2953TEST_F(ChromeContentBrowserClientTest, ShouldAssignSiteForURL) {
54 ChromeContentBrowserClient client;
55 EXPECT_FALSE(client.ShouldAssignSiteForURL(GURL("chrome-native://test")));
56 EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("http://www.google.com")));
57 EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("https://www.google.com")));
58}
59
jam1c5a91492016-02-24 20:47:5360// BrowserWithTestWindowTest doesn't work on Android.
61#if !defined(OS_ANDROID)
mlamourieb40d552015-02-05 00:57:0862
peterbbcccc12015-02-11 22:23:3363using ChromeContentBrowserClientWindowTest = BrowserWithTestWindowTest;
64
65static void DidOpenURLForWindowTest(content::WebContents** target_contents,
66 content::WebContents* opened_contents) {
67 DCHECK(target_contents);
68
69 *target_contents = opened_contents;
70}
71
bengre8a146f2016-03-10 01:20:2272TEST_F(ChromeContentBrowserClientWindowTest, IsDataSaverEnabled) {
73 ChromeContentBrowserClient client;
74 content::BrowserContext* context = browser()->profile();
75 EXPECT_FALSE(client.IsDataSaverEnabled(context));
76 browser()->profile()->GetPrefs()->SetBoolean(prefs::kDataSaverEnabled, true);
77 EXPECT_TRUE(client.IsDataSaverEnabled(context));
78}
79
mlamourieb40d552015-02-05 00:57:0880// This test opens two URLs using ContentBrowserClient::OpenURL. It expects the
81// URLs to be opened in new tabs and activated, changing the active tabs after
82// each call and increasing the tab count by 2.
83TEST_F(ChromeContentBrowserClientWindowTest, OpenURL) {
84 ChromeContentBrowserClient client;
85
86 int previous_count = browser()->tab_strip_model()->count();
87
88 GURL urls[] = { GURL("https://www.google.com"),
89 GURL("https://www.chromium.org") };
90
91 for (const GURL& url : urls) {
nick3b04f322016-08-31 19:29:1992 content::OpenURLParams params(url, content::Referrer(),
93 WindowOpenDisposition::NEW_FOREGROUND_TAB,
94 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false);
peterbbcccc12015-02-11 22:23:3395 // TODO(peter): We should have more in-depth browser tests for the window
96 // opening functionality, which also covers Android. This test can currently
97 // only be ran on platforms where OpenURL is implemented synchronously.
98 // See https://crbug.com/457667.
99 content::WebContents* web_contents = nullptr;
100 client.OpenURL(browser()->profile(),
101 params,
102 base::Bind(&DidOpenURLForWindowTest, &web_contents));
103
104 EXPECT_TRUE(web_contents);
mlamourieb40d552015-02-05 00:57:08105
106 content::WebContents* active_contents = browser()->tab_strip_model()->
107 GetActiveWebContents();
peterbbcccc12015-02-11 22:23:33108 EXPECT_EQ(web_contents, active_contents);
mlamourieb40d552015-02-05 00:57:08109 EXPECT_EQ(url, active_contents->GetVisibleURL());
110 }
111
112 EXPECT_EQ(previous_count + 2, browser()->tab_strip_model()->count());
113}
114
jam1c5a91492016-02-24 20:47:53115#endif // !defined(OS_ANDROID)
mlamourieb40d552015-02-05 00:57:08116
brettwa68ea2b2015-02-01 02:54:07117#if defined(ENABLE_WEBRTC)
118
[email protected]30335fdf02014-02-26 19:51:27119// NOTE: Any updates to the expectations in these tests should also be done in
120// the browser test WebRtcDisableEncryptionFlagBrowserTest.
121class DisableWebRtcEncryptionFlagTest : public testing::Test {
122 public:
123 DisableWebRtcEncryptionFlagTest()
avi3ef9ec9e2014-12-22 22:50:17124 : from_command_line_(base::CommandLine::NO_PROGRAM),
125 to_command_line_(base::CommandLine::NO_PROGRAM) {}
[email protected]30335fdf02014-02-26 19:51:27126
127 protected:
dchenge1bc7982014-10-30 00:32:40128 void SetUp() override {
[email protected]30335fdf02014-02-26 19:51:27129 from_command_line_.AppendSwitch(switches::kDisableWebRtcEncryption);
130 }
131
sdefresne6e883e42015-07-30 08:05:54132 void MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel channel) {
[email protected]30335fdf02014-02-26 19:51:27133 ChromeContentBrowserClient::MaybeCopyDisableWebRtcEncryptionSwitch(
134 &to_command_line_,
135 from_command_line_,
136 channel);
137 }
138
avi3ef9ec9e2014-12-22 22:50:17139 base::CommandLine from_command_line_;
140 base::CommandLine to_command_line_;
[email protected]30335fdf02014-02-26 19:51:27141
thestigf80564462015-09-29 23:12:08142 private:
[email protected]30335fdf02014-02-26 19:51:27143 DISALLOW_COPY_AND_ASSIGN(DisableWebRtcEncryptionFlagTest);
144};
145
146TEST_F(DisableWebRtcEncryptionFlagTest, UnknownChannel) {
sdefresne6e883e42015-07-30 08:05:54147 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::UNKNOWN);
[email protected]30335fdf02014-02-26 19:51:27148 EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
149}
150
151TEST_F(DisableWebRtcEncryptionFlagTest, CanaryChannel) {
sdefresne6e883e42015-07-30 08:05:54152 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::CANARY);
[email protected]30335fdf02014-02-26 19:51:27153 EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
154}
155
156TEST_F(DisableWebRtcEncryptionFlagTest, DevChannel) {
sdefresne6e883e42015-07-30 08:05:54157 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::DEV);
[email protected]30335fdf02014-02-26 19:51:27158 EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
159}
160
161TEST_F(DisableWebRtcEncryptionFlagTest, BetaChannel) {
sdefresne6e883e42015-07-30 08:05:54162 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::BETA);
[email protected]30335fdf02014-02-26 19:51:27163#if defined(OS_ANDROID)
164 EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
165#else
166 EXPECT_FALSE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
167#endif
168}
169
170TEST_F(DisableWebRtcEncryptionFlagTest, StableChannel) {
sdefresne6e883e42015-07-30 08:05:54171 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::STABLE);
[email protected]30335fdf02014-02-26 19:51:27172 EXPECT_FALSE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
173}
174
brettwa68ea2b2015-02-01 02:54:07175#endif // ENABLE_WEBRTC
176
bmcquade5d2d9cf32015-06-19 17:42:28177class BlinkSettingsFieldTrialTest : public testing::Test {
178 public:
bmcquade9dd54cc2015-06-22 16:56:52179 static const char kParserFieldTrialName[];
180 static const char kIFrameFieldTrialName[];
pmeenan9ac669682015-08-17 14:57:03181 static const char kFakeGroupName[];
182 static const char kDefaultGroupName[];
bmcquade9dd54cc2015-06-22 16:56:52183
bmcquade5d2d9cf32015-06-19 17:42:28184 BlinkSettingsFieldTrialTest()
185 : trial_list_(NULL),
186 command_line_(base::CommandLine::NO_PROGRAM) {}
187
188 void SetUp() override {
189 command_line_.AppendSwitchASCII(
190 switches::kProcessType, switches::kRendererProcess);
191 }
192
193 void TearDown() override {
194 variations::testing::ClearAllVariationParams();
195 }
196
pmeenan9ac669682015-08-17 14:57:03197 void CreateFieldTrial(const char* trial_name, const char* group_name) {
198 base::FieldTrialList::CreateFieldTrial(trial_name, group_name);
bmcquade5d2d9cf32015-06-19 17:42:28199 }
200
bmcquade9dd54cc2015-06-22 16:56:52201 void CreateFieldTrialWithParams(
202 const char* trial_name,
pmeenan9ac669682015-08-17 14:57:03203 const char* group_name,
bmcquade9dd54cc2015-06-22 16:56:52204 const char* key1, const char* value1,
205 const char* key2, const char* value2) {
bmcquade5d2d9cf32015-06-19 17:42:28206 std::map<std::string, std::string> params;
bmcquade9dd54cc2015-06-22 16:56:52207 params.insert(std::make_pair(key1, value1));
208 params.insert(std::make_pair(key2, value2));
pmeenan9ac669682015-08-17 14:57:03209 CreateFieldTrial(trial_name, kFakeGroupName);
210 variations::AssociateVariationParams(trial_name, kFakeGroupName, params);
bmcquade5d2d9cf32015-06-19 17:42:28211 }
212
213 void AppendContentBrowserClientSwitches() {
214 client_.AppendExtraCommandLineSwitches(&command_line_, kFakeChildProcessId);
215 }
216
217 const base::CommandLine& command_line() const {
218 return command_line_;
219 }
220
221 void AppendBlinkSettingsSwitch(const char* value) {
222 command_line_.AppendSwitchASCII(switches::kBlinkSettings, value);
223 }
224
225 private:
226 static const int kFakeChildProcessId = 1;
bmcquade5d2d9cf32015-06-19 17:42:28227
228 ChromeContentBrowserClient client_;
229 base::FieldTrialList trial_list_;
230 base::CommandLine command_line_;
231
232 content::TestBrowserThreadBundle thread_bundle_;
233};
234
bmcquade9dd54cc2015-06-22 16:56:52235const char BlinkSettingsFieldTrialTest::kParserFieldTrialName[] =
bmcquade5d2d9cf32015-06-19 17:42:28236 "BackgroundHtmlParserTokenLimits";
bmcquade9dd54cc2015-06-22 16:56:52237const char BlinkSettingsFieldTrialTest::kIFrameFieldTrialName[] =
238 "LowPriorityIFrames";
pmeenan9ac669682015-08-17 14:57:03239const char BlinkSettingsFieldTrialTest::kFakeGroupName[] = "FakeGroup";
240const char BlinkSettingsFieldTrialTest::kDefaultGroupName[] = "Default";
bmcquade5d2d9cf32015-06-19 17:42:28241
242TEST_F(BlinkSettingsFieldTrialTest, NoFieldTrial) {
243 AppendContentBrowserClientSwitches();
244 EXPECT_FALSE(command_line().HasSwitch(switches::kBlinkSettings));
245}
246
247TEST_F(BlinkSettingsFieldTrialTest, FieldTrialWithoutParams) {
pmeenan9ac669682015-08-17 14:57:03248 CreateFieldTrial(kParserFieldTrialName, kFakeGroupName);
bmcquade5d2d9cf32015-06-19 17:42:28249 AppendContentBrowserClientSwitches();
250 EXPECT_FALSE(command_line().HasSwitch(switches::kBlinkSettings));
251}
252
253TEST_F(BlinkSettingsFieldTrialTest, BlinkSettingsSwitchAlreadySpecified) {
254 AppendBlinkSettingsSwitch("foo");
pmeenan9ac669682015-08-17 14:57:03255 CreateFieldTrialWithParams(kParserFieldTrialName, kFakeGroupName,
bmcquade9dd54cc2015-06-22 16:56:52256 "key1", "value1", "key2", "value2");
bmcquade5d2d9cf32015-06-19 17:42:28257 AppendContentBrowserClientSwitches();
258 EXPECT_TRUE(command_line().HasSwitch(switches::kBlinkSettings));
259 EXPECT_EQ("foo",
260 command_line().GetSwitchValueASCII(switches::kBlinkSettings));
261}
262
263TEST_F(BlinkSettingsFieldTrialTest, FieldTrialEnabled) {
pmeenan9ac669682015-08-17 14:57:03264 CreateFieldTrialWithParams(kParserFieldTrialName, kFakeGroupName,
bmcquade9dd54cc2015-06-22 16:56:52265 "key1", "value1", "key2", "value2");
bmcquade5d2d9cf32015-06-19 17:42:28266 AppendContentBrowserClientSwitches();
267 EXPECT_TRUE(command_line().HasSwitch(switches::kBlinkSettings));
268 EXPECT_EQ("key1=value1,key2=value2",
269 command_line().GetSwitchValueASCII(switches::kBlinkSettings));
270}
271
bmcquade9dd54cc2015-06-22 16:56:52272TEST_F(BlinkSettingsFieldTrialTest, MultipleFieldTrialsEnabled) {
pmeenan9ac669682015-08-17 14:57:03273 CreateFieldTrialWithParams(kParserFieldTrialName, kFakeGroupName,
bmcquade9dd54cc2015-06-22 16:56:52274 "key1", "value1", "key2", "value2");
pmeenan9ac669682015-08-17 14:57:03275 CreateFieldTrialWithParams(kIFrameFieldTrialName, kFakeGroupName,
bmcquade9dd54cc2015-06-22 16:56:52276 "keyA", "valueA", "keyB", "valueB");
277 AppendContentBrowserClientSwitches();
278 EXPECT_TRUE(command_line().HasSwitch(switches::kBlinkSettings));
279 EXPECT_EQ("key1=value1,key2=value2,keyA=valueA,keyB=valueB",
280 command_line().GetSwitchValueASCII(switches::kBlinkSettings));
281}
282
283TEST_F(BlinkSettingsFieldTrialTest, MultipleFieldTrialsDuplicateKeys) {
pmeenan9ac669682015-08-17 14:57:03284 CreateFieldTrialWithParams(kParserFieldTrialName, kFakeGroupName,
bmcquade9dd54cc2015-06-22 16:56:52285 "key1", "value1", "key2", "value2");
pmeenan9ac669682015-08-17 14:57:03286 CreateFieldTrialWithParams(kIFrameFieldTrialName, kFakeGroupName,
bmcquade9dd54cc2015-06-22 16:56:52287 "key2", "duplicate", "key3", "value3");
288 AppendContentBrowserClientSwitches();
289 EXPECT_TRUE(command_line().HasSwitch(switches::kBlinkSettings));
290 EXPECT_EQ("key1=value1,key2=value2,key2=duplicate,key3=value3",
291 command_line().GetSwitchValueASCII(switches::kBlinkSettings));
292}
293
jam1c5a91492016-02-24 20:47:53294#if !defined(OS_ANDROID)
[email protected]10a9bf92013-11-13 23:34:48295namespace content {
296
297class InstantNTPURLRewriteTest : public BrowserWithTestWindowTest {
298 protected:
dchenge1bc7982014-10-30 00:32:40299 void SetUp() override {
[email protected]10a9bf92013-11-13 23:34:48300 BrowserWithTestWindowTest::SetUp();
301 field_trial_list_.reset(new base::FieldTrialList(
302 new metrics::SHA1EntropyProvider("42")));
303 }
304
305 void InstallTemplateURLWithNewTabPage(GURL new_tab_page_url) {
306 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
307 profile(), &TemplateURLServiceFactory::BuildInstanceFor);
308 TemplateURLService* template_url_service =
309 TemplateURLServiceFactory::GetForProfile(browser()->profile());
thestigf80564462015-09-29 23:12:08310 search_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
[email protected]10a9bf92013-11-13 23:34:48311
312 TemplateURLData data;
mpearson3c6d7af2015-05-13 23:59:53313 data.SetShortName(base::ASCIIToUTF16("foo.com"));
[email protected]10a9bf92013-11-13 23:34:48314 data.SetURL("http://foo.com/url?bar={searchTerms}");
315 data.new_tab_url = new_tab_page_url.spec();
avi8a64b715b2016-09-02 17:30:04316 TemplateURL* template_url =
317 template_url_service->Add(base::MakeUnique<TemplateURL>(data));
[email protected]f1cb5582014-04-25 07:35:26318 template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
[email protected]10a9bf92013-11-13 23:34:48319 }
320
dcheng4af48582016-04-19 00:29:35321 std::unique_ptr<base::FieldTrialList> field_trial_list_;
[email protected]10a9bf92013-11-13 23:34:48322};
323
324TEST_F(InstantNTPURLRewriteTest, UberURLHandler_InstantExtendedNewTabPage) {
325 const GURL url_original("chrome://newtab");
326 const GURL url_rewritten("https://www.example.com/newtab");
327 InstallTemplateURLWithNewTabPage(url_rewritten);
328 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended",
329 "Group1 use_cacheable_ntp:1"));
330
331 AddTab(browser(), GURL("chrome://blank"));
332 NavigateAndCommitActiveTab(url_original);
333
334 NavigationEntry* entry = browser()->tab_strip_model()->
335 GetActiveWebContents()->GetController().GetLastCommittedEntry();
336 ASSERT_TRUE(entry != NULL);
337 EXPECT_EQ(url_rewritten, entry->GetURL());
338 EXPECT_EQ(url_original, entry->GetVirtualURL());
339}
340
341} // namespace content
jam1c5a91492016-02-24 20:47:53342#endif // !defined(OS_ANDROID)
msramek1f4746d2016-08-19 21:37:07343
344namespace {
345
346// A BrowsingDataRemover that only records calls.
347class MockBrowsingDataRemover : public BrowsingDataRemover {
348 public:
349 explicit MockBrowsingDataRemover(content::BrowserContext* context)
350 : BrowsingDataRemover(context) {}
351
352 ~MockBrowsingDataRemover() override {
353 DCHECK(!expected_calls_.size())
354 << "Expectations were set but not verified.";
355 }
356
357 void RemoveInternal(const TimeRange& time_range,
358 int remove_mask,
359 int origin_type_mask,
360 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
361 BrowsingDataRemover::Observer* observer) override {
362 actual_calls_.emplace_back(time_range, remove_mask, origin_type_mask,
363 std::move(filter_builder), UNKNOWN);
364
365 // |observer| is not recorded in |actual_calls_| to be compared with
366 // expectations, because it's created internally in ClearSiteData() and
367 // it's unknown to this. However, it is tested implicitly, because we use
368 // it for the completion callback, so an incorrect |observer| will fail
369 // the test by waiting for the callback forever.
370 DCHECK(observer);
371 observer->OnBrowsingDataRemoverDone();
372 }
373
374 void ExpectCall(
375 const TimeRange& time_range,
376 int remove_mask,
377 int origin_type_mask,
378 std::unique_ptr<RegistrableDomainFilterBuilder> filter_builder) {
379 expected_calls_.emplace_back(time_range, remove_mask, origin_type_mask,
380 std::move(filter_builder),
381 REGISTRABLE_DOMAIN_FILTER_BUILDER);
382 }
383
384 void ExpectCall(const TimeRange& time_range,
385 int remove_mask,
386 int origin_type_mask,
387 std::unique_ptr<OriginFilterBuilder> filter_builder) {
388 expected_calls_.emplace_back(time_range, remove_mask, origin_type_mask,
389 std::move(filter_builder),
390 ORIGIN_FILTER_BUILDER);
391 }
392
393 void ExpectCallDontCareAboutFilterBuilder(const TimeRange& time_range,
394 int remove_mask,
395 int origin_type_mask) {
396 expected_calls_.emplace_back(time_range, remove_mask, origin_type_mask,
397 std::unique_ptr<BrowsingDataFilterBuilder>(),
398 DONT_CARE);
399 }
400
401 void VerifyAndClearExpectations() {
402 EXPECT_EQ(expected_calls_, actual_calls_);
403 expected_calls_.clear();
404 actual_calls_.clear();
405 }
406
407 private:
408 // Used to further specify the type and intention behind the passed
409 // std::unique_ptr<BrowsingDataFilterBuilder>. This is needed for comparison
410 // between the expected and actual call parameters.
411 enum FilterBuilderType {
412 REGISTRABLE_DOMAIN_FILTER_BUILDER, // RegistrableDomainFilterBuilder
413 ORIGIN_FILTER_BUILDER, // OriginFilterBuilder
414 UNKNOWN, // can't static_cast<>
415 DONT_CARE // don't have to compare for equality
416 };
417
418 class CallParameters {
419 public:
420 CallParameters(const TimeRange& time_range,
421 int remove_mask,
422 int origin_type_mask,
423 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
424 FilterBuilderType type)
425 : time_range_(time_range),
426 remove_mask_(remove_mask),
427 origin_type_mask_(origin_type_mask),
428 filter_builder_(std::move(filter_builder)),
429 type_(type) {}
430 ~CallParameters() {}
431
432 bool operator==(const CallParameters& other) const {
433 const CallParameters& a = *this;
434 const CallParameters& b = other;
435
436 if (!(a.time_range_ == b.time_range_) ||
437 a.remove_mask_ != b.remove_mask_ ||
438 a.origin_type_mask_ != b.origin_type_mask_) {
439 return false;
440 }
441
442 if (a.type_ == DONT_CARE || b.type_ == DONT_CARE)
443 return true;
444 if (a.type_ == UNKNOWN && b.type_ == UNKNOWN)
445 return false;
446 if (a.type_ != UNKNOWN && b.type_ != UNKNOWN && a.type_ != b.type_)
447 return false;
448
449 FilterBuilderType resolved_type =
450 (a.type_ != UNKNOWN) ? a.type_ : b.type_;
451
452 DCHECK(resolved_type == ORIGIN_FILTER_BUILDER ||
453 resolved_type == REGISTRABLE_DOMAIN_FILTER_BUILDER);
454
455 if (resolved_type == ORIGIN_FILTER_BUILDER) {
456 return *static_cast<OriginFilterBuilder*>(a.filter_builder_.get()) ==
457 *static_cast<OriginFilterBuilder*>(b.filter_builder_.get());
458 } else if (resolved_type == REGISTRABLE_DOMAIN_FILTER_BUILDER) {
459 return *static_cast<RegistrableDomainFilterBuilder*>(
460 a.filter_builder_.get()) ==
461 *static_cast<RegistrableDomainFilterBuilder*>(
462 b.filter_builder_.get());
463 }
464
465 NOTREACHED();
466 return false;
467 }
468
469 private:
470 TimeRange time_range_;
471 int remove_mask_;
472 int origin_type_mask_;
473 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_;
474 FilterBuilderType type_;
475 };
476
477 std::list<CallParameters> actual_calls_;
478 std::list<CallParameters> expected_calls_;
479};
480
481// Tests for ChromeContentBrowserClient::ClearSiteData().
482class ChromeContentBrowserClientClearSiteDataTest : public testing::Test {
483 public:
484 void SetUp() override {
485 BrowsingDataRemoverFactory::GetInstance()->SetTestingFactoryAndUse(
486 &profile_, &ChromeContentBrowserClientClearSiteDataTest::GetRemover);
487 }
488
489 content::BrowserContext* profile() { return &profile_; }
490
491 MockBrowsingDataRemover* remover() {
492 return static_cast<MockBrowsingDataRemover*>(
493 BrowsingDataRemoverFactory::GetForBrowserContext(&profile_));
494 }
495
496 void SetClearingFinished(bool finished) { finished_ = finished; }
497
498 bool IsClearingFinished() { return finished_; }
499
500 private:
501 static std::unique_ptr<KeyedService> GetRemover(
502 content::BrowserContext* context) {
503 return base::WrapUnique(new MockBrowsingDataRemover(context));
504 }
505
506 base::MessageLoop loop_;
507 TestingProfile profile_;
508 bool finished_;
509};
510
511// Tests that the parameters to ClearBrowsingData() are translated to
512// the correct BrowsingDataRemover::RemoveInternal() operation. The fourth
513// parameter, |filter_builder|, is tested in detail in the RegistrableDomains
514// test below.
515TEST_F(ChromeContentBrowserClientClearSiteDataTest, Parameters) {
516 ChromeContentBrowserClient client;
517
518 struct TestCase {
519 bool cookies;
520 bool storage;
521 bool cache;
522 int mask;
523 } test_cases[] = {
524 {false, false, false, 0},
525 {true, false, false, BrowsingDataRemover::REMOVE_COOKIES |
526 BrowsingDataRemover::REMOVE_CHANNEL_IDS |
527 BrowsingDataRemover::REMOVE_PLUGIN_DATA},
528 {false, true, false, BrowsingDataRemover::REMOVE_SITE_DATA &
529 ~BrowsingDataRemover::REMOVE_COOKIES &
530 ~BrowsingDataRemover::REMOVE_CHANNEL_IDS &
531 ~BrowsingDataRemover::REMOVE_PLUGIN_DATA},
532 {false, false, true, BrowsingDataRemover::REMOVE_CACHE},
533 {true, true, false, BrowsingDataRemover::REMOVE_SITE_DATA},
534 {true, false, true, BrowsingDataRemover::REMOVE_COOKIES |
535 BrowsingDataRemover::REMOVE_CHANNEL_IDS |
536 BrowsingDataRemover::REMOVE_PLUGIN_DATA |
537 BrowsingDataRemover::REMOVE_CACHE},
538 {false, true, true, BrowsingDataRemover::REMOVE_CACHE |
539 (BrowsingDataRemover::REMOVE_SITE_DATA &
540 ~BrowsingDataRemover::REMOVE_COOKIES &
541 ~BrowsingDataRemover::REMOVE_CHANNEL_IDS &
542 ~BrowsingDataRemover::REMOVE_PLUGIN_DATA)},
543 {true, true, true, BrowsingDataRemover::REMOVE_SITE_DATA |
544 BrowsingDataRemover::REMOVE_CACHE},
545 };
546
547 for (unsigned int i = 0; i < arraysize(test_cases); ++i) {
548 SCOPED_TRACE(base::StringPrintf("Test case %d", i));
549 const TestCase& test_case = test_cases[i];
550
551 // We always delete data for all time and all origin types.
552 BrowsingDataRemover::TimeRange all_time(base::Time(), base::Time::Max());
553 BrowsingDataHelper::OriginTypeMask all_origin_types =
554 BrowsingDataHelper::ALL;
555
556 // Some data are deleted for the origin and some for the registrable domain.
557 // Depending on the chosen datatypes, this might result into one or two
558 // calls. In the latter case, the removal mask will be split into two
559 // parts - one for the origin deletion and one for the registrable domain.
560 const int domain_scoped_types = BrowsingDataRemover::REMOVE_COOKIES |
561 BrowsingDataRemover::REMOVE_CHANNEL_IDS |
562 BrowsingDataRemover::REMOVE_PLUGIN_DATA;
563 int registrable_domain_deletion_mask = test_case.mask & domain_scoped_types;
564 int origin_deletion_mask = test_case.mask & ~domain_scoped_types;
565
566 if (registrable_domain_deletion_mask) {
567 remover()->ExpectCallDontCareAboutFilterBuilder(
568 all_time, registrable_domain_deletion_mask, all_origin_types);
569 }
570
571 if (origin_deletion_mask) {
572 remover()->ExpectCallDontCareAboutFilterBuilder(
573 all_time, origin_deletion_mask, all_origin_types);
574 }
575
576 SetClearingFinished(false);
577 client.ClearSiteData(
578 profile(), url::Origin(GURL("https://www.example.com")),
579 test_case.cookies, test_case.storage, test_case.cache,
580 base::Bind(
581 &ChromeContentBrowserClientClearSiteDataTest::SetClearingFinished,
582 base::Unretained(this), true));
583 EXPECT_TRUE(IsClearingFinished());
584
585 remover()->VerifyAndClearExpectations();
586 }
587}
588
589// Tests that ClearBrowsingData() called for an origin deletes cookies in the
590// scope of the registrable domain corresponding to that origin, while cache
591// is deleted for that exact origin.
592TEST_F(ChromeContentBrowserClientClearSiteDataTest, RegistrableDomains) {
593 ChromeContentBrowserClient client;
594
595 struct TestCase {
596 const char* origin; // origin on which ClearSiteData() is called.
597 const char* domain; // domain on which cookies will be deleted.
598 } test_cases[] = {
599 // TLD has no embedded dot.
600 {"https://example.com", "example.com"},
601 {"https://www.example.com", "example.com"},
602 {"https://www.fourth.third.second.com", "second.com"},
603
604 // TLD has one embedded dot.
605 {"https://www.example.co.uk", "example.co.uk"},
606 {"https://example.co.uk", "example.co.uk"},
607
608 // TLD has more embedded dots.
609 {"https://www.website.sp.nom.br", "website.sp.nom.br"},
610
611 // IP addresses.
612 {"http://127.0.0.1", "127.0.0.1"},
613 {"http://192.168.0.1", "192.168.0.1"},
614 {"http://192.168.0.1", "192.168.0.1"},
615
616 // Internal hostnames.
617 {"http://localhost", "localhost"},
618 {"http://fileserver", "fileserver"},
619
620 // These are not subdomains of internal hostnames, but subdomain of
621 // unknown TLDs.
622 {"http://subdomain.localhost", "subdomain.localhost"},
623 {"http://www.subdomain.localhost", "subdomain.localhost"},
624 {"http://documents.fileserver", "documents.fileserver"},
625
626 // Scheme and port don't matter.
627 {"http://example.com", "example.com"},
628 {"http://example.com:8080", "example.com"},
629 {"https://example.com:4433", "example.com"},
630 };
631
632 for (const TestCase& test_case : test_cases) {
633 SCOPED_TRACE(test_case.origin);
634
635 std::unique_ptr<RegistrableDomainFilterBuilder>
636 registrable_domain_filter_builder(new RegistrableDomainFilterBuilder(
637 BrowsingDataFilterBuilder::WHITELIST));
638 registrable_domain_filter_builder->AddRegisterableDomain(test_case.domain);
639
640 remover()->ExpectCall(
641 BrowsingDataRemover::Period(browsing_data::TimePeriod::ALL_TIME),
642 BrowsingDataRemover::REMOVE_COOKIES |
643 BrowsingDataRemover::REMOVE_CHANNEL_IDS |
644 BrowsingDataRemover::REMOVE_PLUGIN_DATA,
645 BrowsingDataHelper::ALL, std::move(registrable_domain_filter_builder));
646
647 std::unique_ptr<OriginFilterBuilder> origin_filter_builder(
648 new OriginFilterBuilder(BrowsingDataFilterBuilder::WHITELIST));
649 origin_filter_builder->AddOrigin(url::Origin(GURL(test_case.origin)));
650
651 remover()->ExpectCall(
652 BrowsingDataRemover::Period(browsing_data::TimePeriod::ALL_TIME),
653 BrowsingDataRemover::REMOVE_CACHE, BrowsingDataHelper::ALL,
654 std::move(origin_filter_builder));
655
656 SetClearingFinished(false);
657 client.ClearSiteData(
658 profile(), url::Origin(GURL(test_case.origin)), true /* cookies */,
659 false /* storage */, true /* cache */,
660 base::Bind(
661 &ChromeContentBrowserClientClearSiteDataTest::SetClearingFinished,
662 base::Unretained(this), true));
663 EXPECT_TRUE(IsClearingFinished());
664
665 remover()->VerifyAndClearExpectations();
666 }
667}
668
669// Tests that we always wait for all scheduled BrowsingDataRemover tasks and
670// that BrowsingDataRemoverObserver never leaks.
671TEST_F(ChromeContentBrowserClientClearSiteDataTest, Tasks) {
672 ChromeContentBrowserClient client;
673 url::Origin origin(GURL("https://www.example.com"));
674
675 // No removal tasks.
676 SetClearingFinished(false);
677 client.ClearSiteData(
678 profile(), origin, false /* cookies */, false /* storage */,
679 false /* cache */,
680 base::Bind(
681 &ChromeContentBrowserClientClearSiteDataTest::SetClearingFinished,
682 base::Unretained(this), true));
683 EXPECT_TRUE(IsClearingFinished());
684
685 // One removal task: deleting cookies with a domain filter.
686 SetClearingFinished(false);
687 client.ClearSiteData(
688 profile(), origin, true /* cookies */, false /* storage */,
689 false /* cache */,
690 base::Bind(
691 &ChromeContentBrowserClientClearSiteDataTest::SetClearingFinished,
692 base::Unretained(this), true));
693 EXPECT_TRUE(IsClearingFinished());
694
695 // One removal task: deleting cache with a domain filter.
696 SetClearingFinished(false);
697 client.ClearSiteData(
698 profile(), origin, false /* cookies */, false /* storage */,
699 true /* cache */,
700 base::Bind(
701 &ChromeContentBrowserClientClearSiteDataTest::SetClearingFinished,
702 base::Unretained(this), true));
703 EXPECT_TRUE(IsClearingFinished());
704
705 // Two removal tasks, with domain and origin filters respectively.
706 SetClearingFinished(false);
707 client.ClearSiteData(
708 profile(), origin, true /* cookies */, false /* storage */,
709 true /* cache */,
710 base::Bind(
711 &ChromeContentBrowserClientClearSiteDataTest::SetClearingFinished,
712 base::Unretained(this), true));
713 EXPECT_TRUE(IsClearingFinished());
714}
715
716} // namespace