[M85 Dev][EFL] Fix errors to generate ninja files
[platform/framework/web/chromium-efl.git] / chrome / browser / chrome_content_browser_client_unittest.cc
1 // 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
7 #include <list>
8 #include <map>
9 #include <memory>
10
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/macros.h"
14 #include "base/metrics/field_trial.h"
15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/test/gtest_util.h"
19 #include "base/test/scoped_command_line.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "build/build_config.h"
22 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
23 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
24 #include "chrome/browser/search_engines/template_url_service_factory.h"
25 #include "chrome/common/webui_url_constants.h"
26 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
27 #include "chrome/test/base/testing_profile.h"
28 #include "components/browsing_data/content/browsing_data_helper.h"
29 #include "components/captive_portal/core/buildflags.h"
30 #include "components/content_settings/core/browser/host_content_settings_map.h"
31 #include "components/search_engines/template_url_service.h"
32 #include "components/variations/variations_associated_data.h"
33 #include "components/version_info/version_info.h"
34 #include "content/public/browser/browsing_data_filter_builder.h"
35 #include "content/public/browser/browsing_data_remover.h"
36 #include "content/public/browser/navigation_controller.h"
37 #include "content/public/browser/navigation_entry.h"
38 #include "content/public/browser/site_instance.h"
39 #include "content/public/browser/storage_partition.h"
40 #include "content/public/browser/web_contents.h"
41 #include "content/public/common/content_switches.h"
42 #include "content/public/common/user_agent.h"
43 #include "content/public/test/browser_task_environment.h"
44 #include "content/public/test/mock_render_process_host.h"
45 #include "media/media_buildflags.h"
46 #include "testing/gmock/include/gmock/gmock.h"
47 #include "testing/gtest/include/gtest/gtest.h"
48 #include "third_party/blink/public/common/features.h"
49 #include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
50 #include "url/gurl.h"
51
52 #if defined(USE_X11) || defined(USE_OZONE)
53 #include <sys/utsname.h>
54 #endif
55
56 #if !defined(OS_ANDROID)
57 #include "chrome/browser/ui/browser.h"
58 #include "chrome/browser/ui/tabs/tab_strip_model.h"
59 #include "chrome/common/pref_names.h"
60 #include "chrome/test/base/browser_with_test_window_test.h"
61 #include "chrome/test/base/search_test_utils.h"
62 #include "ui/base/page_transition_types.h"
63 #else
64 #include "base/system/sys_info.h"
65 #endif
66
67 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
68 #include "components/captive_portal/content/captive_portal_tab_helper.h"
69 #endif
70
71 #if defined(OS_CHROMEOS)
72 #include "chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h"
73 #include "chrome/test/base/scoped_testing_local_state.h"
74 #include "chrome/test/base/testing_browser_process.h"
75 #include "components/policy/core/common/policy_pref_names.h"
76 #endif  // defined(OS_CHROMEOS)
77
78 using content::BrowsingDataFilterBuilder;
79 using testing::_;
80 using ChromeContentBrowserClientTest = testing::Test;
81
82 namespace {
83
84 void CheckUserAgentStringOrdering(bool mobile_device) {
85   std::vector<std::string> pieces;
86
87   // Check if the pieces of the user agent string come in the correct order.
88   ChromeContentBrowserClient content_browser_client;
89   std::string buffer = content_browser_client.GetUserAgent();
90
91   pieces = base::SplitStringUsingSubstr(
92       buffer, "Mozilla/5.0 (", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
93   ASSERT_EQ(2u, pieces.size());
94   buffer = pieces[1];
95   EXPECT_EQ("", pieces[0]);
96
97   pieces = base::SplitStringUsingSubstr(
98       buffer, ") AppleWebKit/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
99   ASSERT_EQ(2u, pieces.size());
100   buffer = pieces[1];
101   std::string os_str = pieces[0];
102
103   pieces =
104       base::SplitStringUsingSubstr(buffer, " (KHTML, like Gecko) ",
105                                    base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
106   ASSERT_EQ(2u, pieces.size());
107   buffer = pieces[1];
108   std::string webkit_version_str = pieces[0];
109
110   pieces = base::SplitStringUsingSubstr(
111       buffer, " Safari/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
112   ASSERT_EQ(2u, pieces.size());
113   std::string product_str = pieces[0];
114   std::string safari_version_str = pieces[1];
115
116   EXPECT_FALSE(os_str.empty());
117
118   pieces = base::SplitStringUsingSubstr(os_str, "; ", base::KEEP_WHITESPACE,
119                                         base::SPLIT_WANT_ALL);
120 #if defined(OS_WIN)
121   // Windows NT 10.0; Win64; x64
122   // Windows NT 10.0; WOW64
123   // Windows NT 10.0
124   std::string os_and_version = pieces[0];
125   for (unsigned int i = 1; i < pieces.size(); ++i) {
126     bool equals = ((pieces[i] == "WOW64") || (pieces[i] == "Win64") ||
127                    pieces[i] == "x64");
128     ASSERT_TRUE(equals);
129   }
130   pieces = base::SplitStringUsingSubstr(pieces[0], " ", base::KEEP_WHITESPACE,
131                                         base::SPLIT_WANT_ALL);
132   ASSERT_EQ(3u, pieces.size());
133   ASSERT_EQ("Windows", pieces[0]);
134   ASSERT_EQ("NT", pieces[1]);
135   double version;
136   ASSERT_TRUE(base::StringToDouble(pieces[2], &version));
137   ASSERT_LE(4.0, version);
138   ASSERT_GT(11.0, version);
139 #elif defined(OS_MACOSX)
140   // Macintosh; Intel Mac OS X 10_15_4
141   ASSERT_EQ(2u, pieces.size());
142   ASSERT_EQ("Macintosh", pieces[0]);
143   pieces = base::SplitStringUsingSubstr(pieces[1], " ", base::KEEP_WHITESPACE,
144                                         base::SPLIT_WANT_ALL);
145   ASSERT_EQ(5u, pieces.size());
146   ASSERT_EQ("Intel", pieces[0]);
147   ASSERT_EQ("Mac", pieces[1]);
148   ASSERT_EQ("OS", pieces[2]);
149   ASSERT_EQ("X", pieces[3]);
150   pieces = base::SplitStringUsingSubstr(pieces[4], "_", base::KEEP_WHITESPACE,
151                                         base::SPLIT_WANT_ALL);
152   ASSERT_EQ("10", pieces[0]);
153   int value;
154   ASSERT_TRUE(base::StringToInt(pieces[1], &value));
155   ASSERT_LE(0, value);
156   ASSERT_TRUE(base::StringToInt(pieces[2], &value));
157   ASSERT_LE(0, value);
158 #elif defined(USE_X11) || defined(USE_OZONE)
159   // X11; Linux x86_64
160   // X11; CrOS armv7l 4537.56.0
161   struct utsname unixinfo;
162   uname(&unixinfo);
163   std::string machine = unixinfo.machine;
164   if (strcmp(unixinfo.machine, "x86_64") == 0 &&
165       sizeof(void*) == sizeof(int32_t)) {
166     machine = "i686 (x86_64)";
167   }
168   ASSERT_EQ(2u, pieces.size());
169   ASSERT_EQ("X11", pieces[0]);
170   pieces = base::SplitStringUsingSubstr(pieces[1], " ", base::KEEP_WHITESPACE,
171                                         base::SPLIT_WANT_ALL);
172 #if defined(OS_CHROMEOS)
173   // X11; CrOS armv7l 4537.56.0
174   //      ^^
175   ASSERT_EQ(3u, pieces.size());
176   ASSERT_EQ("CrOS", pieces[0]);
177   ASSERT_EQ(machine, pieces[1]);
178   pieces = base::SplitStringUsingSubstr(pieces[2], ".", base::KEEP_WHITESPACE,
179                                         base::SPLIT_WANT_ALL);
180   for (unsigned int i = 1; i < pieces.size(); ++i) {
181     int value;
182     ASSERT_TRUE(base::StringToInt(pieces[i], &value));
183   }
184 #else
185   // X11; Linux x86_64
186   //      ^^
187   ASSERT_EQ(2u, pieces.size());
188   // This may not be Linux in all cases in the wild, but it is on the bots.
189   ASSERT_EQ("Linux", pieces[0]);
190   ASSERT_EQ(machine, pieces[1]);
191 #endif
192 #elif defined(OS_ANDROID)
193   // Linux; Android 7.1.1; Samsung Chromebook 3
194   ASSERT_GE(3u, pieces.size());
195   ASSERT_EQ("Linux", pieces[0]);
196   std::string model;
197   if (pieces.size() > 2)
198     model = pieces[2];
199
200   pieces = base::SplitStringUsingSubstr(pieces[1], " ", base::KEEP_WHITESPACE,
201                                         base::SPLIT_WANT_ALL);
202   ASSERT_EQ(2u, pieces.size());
203   ASSERT_EQ("Android", pieces[0]);
204   pieces = base::SplitStringUsingSubstr(pieces[1], ".", base::KEEP_WHITESPACE,
205                                         base::SPLIT_WANT_ALL);
206   for (unsigned int i = 1; i < pieces.size(); ++i) {
207     int value;
208     ASSERT_TRUE(base::StringToInt(pieces[i], &value));
209   }
210
211   if (!model.empty()) {
212     if (base::SysInfo::GetAndroidBuildCodename() == "REL")
213       ASSERT_EQ(base::SysInfo::HardwareModelName(), model);
214     else
215       ASSERT_EQ("", model);
216   }
217 #elif defined(OS_FUCHSIA)
218   // X11; Fuchsia
219   ASSERT_EQ(2u, pieces.size());
220   ASSERT_EQ("X11", pieces[0]);
221   ASSERT_EQ("Fuchsia", pieces[1]);
222 #endif
223
224   // Check that the version numbers match.
225   EXPECT_FALSE(webkit_version_str.empty());
226   EXPECT_FALSE(safari_version_str.empty());
227   EXPECT_EQ(webkit_version_str, safari_version_str);
228
229   EXPECT_TRUE(
230       base::StartsWith(product_str, "Chrome/", base::CompareCase::SENSITIVE));
231   if (mobile_device) {
232     // "Mobile" gets tacked on to the end for mobile devices, like phones.
233     EXPECT_TRUE(
234         base::EndsWith(product_str, " Mobile", base::CompareCase::SENSITIVE));
235   }
236 }
237
238 }  // namespace
239
240 TEST_F(ChromeContentBrowserClientTest, ShouldAssignSiteForURL) {
241   ChromeContentBrowserClient client;
242   EXPECT_FALSE(client.ShouldAssignSiteForURL(GURL("chrome-native://test")));
243   EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("http://www.google.com")));
244   EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("https://www.google.com")));
245 }
246
247 // BrowserWithTestWindowTest doesn't work on Android.
248 #if !defined(OS_ANDROID)
249
250 using ChromeContentBrowserClientWindowTest = BrowserWithTestWindowTest;
251
252 static void DidOpenURLForWindowTest(content::WebContents** target_contents,
253                                     content::WebContents* opened_contents) {
254   DCHECK(target_contents);
255
256   *target_contents = opened_contents;
257 }
258
259 // This test opens two URLs using ContentBrowserClient::OpenURL. It expects the
260 // URLs to be opened in new tabs and activated, changing the active tabs after
261 // each call and increasing the tab count by 2.
262 TEST_F(ChromeContentBrowserClientWindowTest, OpenURL) {
263   ChromeContentBrowserClient client;
264
265   int previous_count = browser()->tab_strip_model()->count();
266
267   GURL urls[] = { GURL("https://www.google.com"),
268                   GURL("https://www.chromium.org") };
269
270   for (const GURL& url : urls) {
271     content::OpenURLParams params(url, content::Referrer(),
272                                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
273                                   ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false);
274     // TODO(peter): We should have more in-depth browser tests for the window
275     // opening functionality, which also covers Android. This test can currently
276     // only be ran on platforms where OpenURL is implemented synchronously.
277     // See https://crbug.com/457667.
278     content::WebContents* web_contents = nullptr;
279     scoped_refptr<content::SiteInstance> site_instance =
280         content::SiteInstance::Create(browser()->profile());
281     client.OpenURL(site_instance.get(), params,
282                    base::BindOnce(&DidOpenURLForWindowTest, &web_contents));
283
284     EXPECT_TRUE(web_contents);
285
286     content::WebContents* active_contents = browser()->tab_strip_model()->
287         GetActiveWebContents();
288     EXPECT_EQ(web_contents, active_contents);
289     EXPECT_EQ(url, active_contents->GetVisibleURL());
290   }
291
292   EXPECT_EQ(previous_count + 2, browser()->tab_strip_model()->count());
293 }
294
295 // TODO(crbug.com/566091): Remove the need for ShouldStayInParentProcessForNTP()
296 //    and associated test.
297 TEST_F(ChromeContentBrowserClientWindowTest, ShouldStayInParentProcessForNTP) {
298   ChromeContentBrowserClient client;
299   scoped_refptr<content::SiteInstance> site_instance =
300       content::SiteInstance::CreateForURL(
301           browser()->profile(),
302           GURL("chrome-search://local-ntp/local-ntp.html"));
303   EXPECT_TRUE(client.ShouldStayInParentProcessForNTP(
304       GURL("chrome-search://local-ntp/local-ntp.html"), site_instance.get()));
305
306   site_instance = content::SiteInstance::CreateForURL(
307       browser()->profile(), GURL("chrome://new-tab-page"));
308   // chrome://new-tab-page is an NTP replacing local-ntp and supports OOPIFs.
309   // ShouldStayInParentProcessForNTP() should only return true for NTPs hosted
310   // under the chrome-search: scheme.
311   EXPECT_FALSE(client.ShouldStayInParentProcessForNTP(
312       GURL("chrome://new-tab-page"), site_instance.get()));
313 }
314
315 TEST_F(ChromeContentBrowserClientWindowTest, OverrideNavigationParams) {
316   ChromeContentBrowserClient client;
317   ui::PageTransition transition;
318   bool is_renderer_initiated;
319   content::Referrer referrer = content::Referrer();
320   base::Optional<url::Origin> initiator_origin = base::nullopt;
321
322   scoped_refptr<content::SiteInstance> site_instance =
323       content::SiteInstance::CreateForURL(
324           browser()->profile(),
325           GURL("chrome-search://local-ntp/local-ntp.html"));
326   transition = ui::PAGE_TRANSITION_LINK;
327   is_renderer_initiated = true;
328   // The origin is a placeholder to test that |initiator_origin| is set to
329   // base::nullopt and is not meant to represent what would happen in practice.
330   initiator_origin = url::Origin::Create(GURL("https://www.example.com"));
331   client.OverrideNavigationParams(site_instance.get(), &transition,
332                                   &is_renderer_initiated, &referrer,
333                                   &initiator_origin);
334   EXPECT_TRUE(ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_AUTO_BOOKMARK,
335                                            transition));
336   EXPECT_FALSE(is_renderer_initiated);
337   EXPECT_EQ(base::nullopt, initiator_origin);
338
339   site_instance = content::SiteInstance::CreateForURL(
340       browser()->profile(), GURL("chrome://new-tab-page"));
341   transition = ui::PAGE_TRANSITION_LINK;
342   is_renderer_initiated = true;
343   initiator_origin = url::Origin::Create(GURL("https://www.example.com"));
344   client.OverrideNavigationParams(site_instance.get(), &transition,
345                                   &is_renderer_initiated, &referrer,
346                                   &initiator_origin);
347   EXPECT_TRUE(ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_AUTO_BOOKMARK,
348                                            transition));
349   EXPECT_FALSE(is_renderer_initiated);
350   EXPECT_EQ(base::nullopt, initiator_origin);
351
352   // No change for transitions that are not PAGE_TRANSITION_LINK.
353   site_instance = content::SiteInstance::CreateForURL(
354       browser()->profile(), GURL("chrome://new-tab-page"));
355   transition = ui::PAGE_TRANSITION_TYPED;
356   client.OverrideNavigationParams(site_instance.get(), &transition,
357                                   &is_renderer_initiated, &referrer,
358                                   &initiator_origin);
359   EXPECT_TRUE(
360       ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_TYPED, transition));
361
362   // No change for transitions on a non-NTP page.
363   site_instance = content::SiteInstance::CreateForURL(
364       browser()->profile(), GURL("https://www.example.com"));
365   transition = ui::PAGE_TRANSITION_LINK;
366   client.OverrideNavigationParams(site_instance.get(), &transition,
367                                   &is_renderer_initiated, &referrer,
368                                   &initiator_origin);
369   EXPECT_TRUE(
370       ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_LINK, transition));
371 }
372
373 #endif  // !defined(OS_ANDROID)
374
375 // NOTE: Any updates to the expectations in these tests should also be done in
376 // the browser test WebRtcDisableEncryptionFlagBrowserTest.
377 class DisableWebRtcEncryptionFlagTest : public testing::Test {
378  public:
379   DisableWebRtcEncryptionFlagTest()
380       : from_command_line_(base::CommandLine::NO_PROGRAM),
381         to_command_line_(base::CommandLine::NO_PROGRAM) {}
382
383  protected:
384   void SetUp() override {
385     from_command_line_.AppendSwitch(switches::kDisableWebRtcEncryption);
386   }
387
388   void MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel channel) {
389     ChromeContentBrowserClient::MaybeCopyDisableWebRtcEncryptionSwitch(
390         &to_command_line_,
391         from_command_line_,
392         channel);
393   }
394
395   base::CommandLine from_command_line_;
396   base::CommandLine to_command_line_;
397
398  private:
399   DISALLOW_COPY_AND_ASSIGN(DisableWebRtcEncryptionFlagTest);
400 };
401
402 TEST_F(DisableWebRtcEncryptionFlagTest, UnknownChannel) {
403   MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::UNKNOWN);
404   EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
405 }
406
407 TEST_F(DisableWebRtcEncryptionFlagTest, CanaryChannel) {
408   MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::CANARY);
409   EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
410 }
411
412 TEST_F(DisableWebRtcEncryptionFlagTest, DevChannel) {
413   MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::DEV);
414   EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
415 }
416
417 TEST_F(DisableWebRtcEncryptionFlagTest, BetaChannel) {
418   MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::BETA);
419 #if defined(OS_ANDROID)
420   EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
421 #else
422   EXPECT_FALSE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
423 #endif
424 }
425
426 TEST_F(DisableWebRtcEncryptionFlagTest, StableChannel) {
427   MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::STABLE);
428   EXPECT_FALSE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
429 }
430
431 class BlinkSettingsFieldTrialTest : public testing::Test {
432  public:
433   static const char kDisallowFetchFieldTrialName[];
434   static const char kFakeGroupName[];
435
436   BlinkSettingsFieldTrialTest()
437       : command_line_(base::CommandLine::NO_PROGRAM) {}
438
439   void SetUp() override {
440     command_line_.AppendSwitchASCII(
441         switches::kProcessType, switches::kRendererProcess);
442   }
443
444   void TearDown() override {
445     variations::testing::ClearAllVariationParams();
446   }
447
448   void CreateFieldTrial(const char* trial_name, const char* group_name) {
449     base::FieldTrialList::CreateFieldTrial(trial_name, group_name);
450   }
451
452   void CreateFieldTrialWithParams(
453       const char* trial_name,
454       const char* group_name,
455       const char* key1, const char* value1,
456       const char* key2, const char* value2) {
457     std::map<std::string, std::string> params;
458     params.insert(std::make_pair(key1, value1));
459     params.insert(std::make_pair(key2, value2));
460     CreateFieldTrial(trial_name, kFakeGroupName);
461     variations::AssociateVariationParams(trial_name, kFakeGroupName, params);
462   }
463
464   void AppendContentBrowserClientSwitches() {
465     client_.AppendExtraCommandLineSwitches(&command_line_, kFakeChildProcessId);
466   }
467
468   const base::CommandLine& command_line() const {
469     return command_line_;
470   }
471
472   void AppendBlinkSettingsSwitch(const char* value) {
473     command_line_.AppendSwitchASCII(switches::kBlinkSettings, value);
474   }
475
476  private:
477   static const int kFakeChildProcessId = 1;
478
479   ChromeContentBrowserClient client_;
480   base::CommandLine command_line_;
481
482   content::BrowserTaskEnvironment task_environment_;
483 };
484
485 const char BlinkSettingsFieldTrialTest::kDisallowFetchFieldTrialName[] =
486     "DisallowFetchForDocWrittenScriptsInMainFrame";
487 const char BlinkSettingsFieldTrialTest::kFakeGroupName[] = "FakeGroup";
488
489 TEST_F(BlinkSettingsFieldTrialTest, NoFieldTrial) {
490   AppendContentBrowserClientSwitches();
491   EXPECT_FALSE(command_line().HasSwitch(switches::kBlinkSettings));
492 }
493
494 TEST_F(BlinkSettingsFieldTrialTest, FieldTrialWithoutParams) {
495   CreateFieldTrial(kDisallowFetchFieldTrialName, kFakeGroupName);
496   AppendContentBrowserClientSwitches();
497   EXPECT_FALSE(command_line().HasSwitch(switches::kBlinkSettings));
498 }
499
500 TEST_F(BlinkSettingsFieldTrialTest, BlinkSettingsSwitchAlreadySpecified) {
501   AppendBlinkSettingsSwitch("foo");
502   CreateFieldTrialWithParams(kDisallowFetchFieldTrialName, kFakeGroupName,
503                              "key1", "value1", "key2", "value2");
504   AppendContentBrowserClientSwitches();
505   EXPECT_TRUE(command_line().HasSwitch(switches::kBlinkSettings));
506   EXPECT_EQ("foo",
507             command_line().GetSwitchValueASCII(switches::kBlinkSettings));
508 }
509
510 TEST_F(BlinkSettingsFieldTrialTest, FieldTrialEnabled) {
511   CreateFieldTrialWithParams(kDisallowFetchFieldTrialName, kFakeGroupName,
512                              "key1", "value1", "key2", "value2");
513   AppendContentBrowserClientSwitches();
514   EXPECT_TRUE(command_line().HasSwitch(switches::kBlinkSettings));
515   EXPECT_EQ("key1=value1,key2=value2",
516             command_line().GetSwitchValueASCII(switches::kBlinkSettings));
517 }
518
519 #if !defined(OS_ANDROID)
520 namespace content {
521
522 class InstantNTPURLRewriteTest : public BrowserWithTestWindowTest {
523  protected:
524   void InstallTemplateURLWithNewTabPage(GURL new_tab_page_url) {
525     TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
526         profile(),
527         base::BindRepeating(&TemplateURLServiceFactory::BuildInstanceFor));
528     TemplateURLService* template_url_service =
529         TemplateURLServiceFactory::GetForProfile(browser()->profile());
530     search_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
531
532     TemplateURLData data;
533     data.SetShortName(base::ASCIIToUTF16("foo.com"));
534     data.SetURL("http://foo.com/url?bar={searchTerms}");
535     data.new_tab_url = new_tab_page_url.spec();
536     TemplateURL* template_url =
537         template_url_service->Add(std::make_unique<TemplateURL>(data));
538     template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
539   }
540 };
541
542 TEST_F(InstantNTPURLRewriteTest, UberURLHandler_InstantExtendedNewTabPage) {
543   const GURL url_original(chrome::kChromeUINewTabURL);
544   const GURL url_rewritten("https://www.example.com/newtab");
545   InstallTemplateURLWithNewTabPage(url_rewritten);
546   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended",
547       "Group1 use_cacheable_ntp:1"));
548
549   AddTab(browser(), GURL(url::kAboutBlankURL));
550   NavigateAndCommitActiveTab(url_original);
551
552   NavigationEntry* entry = browser()->tab_strip_model()->
553       GetActiveWebContents()->GetController().GetLastCommittedEntry();
554   ASSERT_TRUE(entry != NULL);
555   EXPECT_EQ(url_rewritten, entry->GetURL());
556   EXPECT_EQ(url_original, entry->GetVirtualURL());
557 }
558
559 }  // namespace content
560 #endif  // !defined(OS_ANDROID)
561
562 class ChromeContentBrowserClientGetLoggingFileTest : public testing::Test {};
563
564 TEST_F(ChromeContentBrowserClientGetLoggingFileTest, GetLoggingFile) {
565   base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
566   ChromeContentBrowserClient client;
567   base::FilePath log_file_name;
568   EXPECT_FALSE(client.GetLoggingFileName(cmd_line).empty());
569 }
570
571 TEST_F(ChromeContentBrowserClientGetLoggingFileTest,
572        GetLoggingFileFromCommandLine) {
573   base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
574   cmd_line.AppendSwitchASCII(switches::kLogFile, "test_log.txt");
575   ChromeContentBrowserClient client;
576   base::FilePath log_file_name;
577   EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("test_log.txt")).value(),
578             client.GetLoggingFileName(cmd_line).value());
579 }
580
581 class TestChromeContentBrowserClient : public ChromeContentBrowserClient {
582  public:
583   using ChromeContentBrowserClient::HandleWebUI;
584   using ChromeContentBrowserClient::HandleWebUIReverse;
585 };
586
587 TEST(ChromeContentBrowserClientTest, HandleWebUI) {
588   TestChromeContentBrowserClient test_content_browser_client;
589   const GURL http_help("http://help/");
590   GURL should_not_redirect = http_help;
591   test_content_browser_client.HandleWebUI(&should_not_redirect, nullptr);
592   EXPECT_EQ(http_help, should_not_redirect);
593
594   const GURL chrome_help(chrome::kChromeUIHelpURL);
595   GURL should_redirect = chrome_help;
596   test_content_browser_client.HandleWebUI(&should_redirect, nullptr);
597   EXPECT_NE(chrome_help, should_redirect);
598 }
599
600 TEST(ChromeContentBrowserClientTest, HandleWebUIReverse) {
601   TestChromeContentBrowserClient test_content_browser_client;
602   GURL http_settings("http://settings/");
603   EXPECT_FALSE(
604       test_content_browser_client.HandleWebUIReverse(&http_settings, nullptr));
605   GURL chrome_settings(chrome::kChromeUISettingsURL);
606   EXPECT_TRUE(test_content_browser_client.HandleWebUIReverse(&chrome_settings,
607                                                              nullptr));
608 }
609
610 TEST(ChromeContentBrowserClientTest, UserAgentStringFrozen) {
611   base::test::ScopedFeatureList scoped_feature_list;
612   scoped_feature_list.InitAndEnableFeature(blink::features::kFreezeUserAgent);
613
614 #if defined(OS_ANDROID)
615   // Verify the correct user agent is returned when the UseMobileUserAgent
616   // command line flag is present.
617   const char* const kArguments[] = {"chrome"};
618   base::test::ScopedCommandLine scoped_command_line;
619   base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
620   command_line->InitFromArgv(1, kArguments);
621
622   // Verify the mobile user agent string is not returned when not using a mobile
623   // user agent.
624   ASSERT_FALSE(command_line->HasSwitch(switches::kUseMobileUserAgent));
625   {
626     ChromeContentBrowserClient content_browser_client;
627     std::string buffer = content_browser_client.GetUserAgent();
628     EXPECT_EQ(buffer, base::StringPrintf(
629                           content::frozen_user_agent_strings::kAndroid,
630                           version_info::GetMajorVersionNumber().c_str()));
631   }
632
633   // Verify the mobile user agent string is returned when using a mobile user
634   // agent.
635   command_line->AppendSwitch(switches::kUseMobileUserAgent);
636   ASSERT_TRUE(command_line->HasSwitch(switches::kUseMobileUserAgent));
637   {
638     ChromeContentBrowserClient content_browser_client;
639     std::string buffer = content_browser_client.GetUserAgent();
640     EXPECT_EQ(buffer, base::StringPrintf(
641                           content::frozen_user_agent_strings::kAndroidMobile,
642                           version_info::GetMajorVersionNumber().c_str()));
643   }
644 #else
645   {
646     ChromeContentBrowserClient content_browser_client;
647     std::string buffer = content_browser_client.GetUserAgent();
648     EXPECT_EQ(buffer, base::StringPrintf(
649                           content::frozen_user_agent_strings::kDesktop,
650                           version_info::GetMajorVersionNumber().c_str()));
651   }
652 #endif
653 }
654
655 TEST(ChromeContentBrowserClientTest, UserAgentStringOrdering) {
656 #if defined(OS_ANDROID)
657   const char* const kArguments[] = {"chrome"};
658   base::test::ScopedCommandLine scoped_command_line;
659   base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
660   command_line->InitFromArgv(1, kArguments);
661
662   // Do it for regular devices.
663   ASSERT_FALSE(command_line->HasSwitch(switches::kUseMobileUserAgent));
664   CheckUserAgentStringOrdering(false);
665
666   // Do it for mobile devices.
667   command_line->AppendSwitch(switches::kUseMobileUserAgent);
668   ASSERT_TRUE(command_line->HasSwitch(switches::kUseMobileUserAgent));
669   CheckUserAgentStringOrdering(true);
670 #else
671   CheckUserAgentStringOrdering(false);
672 #endif
673 }
674
675 TEST(ChromeContentBrowserClientTest, UserAgentMetadata) {
676   ChromeContentBrowserClient content_browser_client;
677   auto metadata = content_browser_client.GetUserAgentMetadata();
678
679   std::string major_version = version_info::GetMajorVersionNumber();
680
681   // According to spec, Sec-CH-UA should contain what project the browser is
682   // based on (i.e. Chromium in this case) as well as the actual product.
683   // In CHROMIUM_BRANDING builds this will check chromium twice. That should be
684   // ok though.
685
686   const blink::UserAgentBrandVersion chromium_brand_version = {"Chromium",
687                                                                major_version};
688   const blink::UserAgentBrandVersion product_brand_version = {
689       version_info::GetProductName(), version_info::GetMajorVersionNumber()};
690   bool contains_chromium_brand_version = false;
691   bool contains_product_brand_version = false;
692
693   for (const auto& brand_version : metadata.brand_version_list) {
694     if (brand_version == chromium_brand_version) {
695       contains_chromium_brand_version = true;
696     }
697     if (brand_version == product_brand_version) {
698       contains_product_brand_version = true;
699     }
700   }
701
702   EXPECT_TRUE(contains_chromium_brand_version);
703   EXPECT_TRUE(contains_product_brand_version);
704
705   EXPECT_EQ(metadata.full_version, version_info::GetVersionNumber());
706   EXPECT_EQ(metadata.platform_version,
707             content::GetOSVersion(content::IncludeAndroidBuildNumber::Exclude,
708                                   content::IncludeAndroidModel::Exclude));
709   // This makes sure no extra information is added to the platform version.
710   EXPECT_EQ(metadata.platform_version.find(";"), std::string::npos);
711   EXPECT_EQ(metadata.platform, version_info::GetOSType());
712   EXPECT_EQ(metadata.architecture, content::GetLowEntropyCpuArchitecture());
713   EXPECT_EQ(metadata.model, content::BuildModelInfo());
714 }
715
716 TEST(ChromeContentBrowserClientTest, GenerateBrandVersionList) {
717   blink::UserAgentMetadata metadata;
718
719   metadata.brand_version_list =
720       GenerateBrandVersionList(84, base::nullopt, "84");
721   std::string brand_list = metadata.SerializeBrandVersionList();
722   EXPECT_EQ(R"("\\Not\"A;Brand";v="99", "Chromium";v="84")", brand_list);
723
724   metadata.brand_version_list =
725       GenerateBrandVersionList(85, base::nullopt, "85");
726   std::string brand_list_diff = metadata.SerializeBrandVersionList();
727   // Make sure the lists are different for different seeds
728   EXPECT_EQ(R"("Chromium";v="85", "\\Not;A\"Brand";v="99")", brand_list_diff);
729   EXPECT_NE(brand_list, brand_list_diff);
730
731   metadata.brand_version_list =
732       GenerateBrandVersionList(84, "Totally A Brand", "84");
733   std::string brand_list_w_brand = metadata.SerializeBrandVersionList();
734   EXPECT_EQ(
735       R"("\\Not\"A;Brand";v="99", "Chromium";v="84", "Totally A Brand";v="84")",
736       brand_list_w_brand);
737
738   // Should DCHECK on negative numbers
739   EXPECT_DCHECK_DEATH(GenerateBrandVersionList(-1, base::nullopt, "99"));
740 }
741
742 TEST(ChromeContentBrowserClientTest, LowEntropyCpuArchitecture) {
743   std::string arch = content::GetLowEntropyCpuArchitecture();
744
745 #if (!defined(OS_POSIX) && !defined(OS_WIN)) || defined(OS_MACOSX) || \
746     defined(OS_ANDROID)
747   EXPECT_EQ("", arch);
748 #elif (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_WIN)
749   EXPECT_TRUE("arm" == arch || "x86" == arch);
750 #endif
751 }
752
753 #if defined(OS_CHROMEOS)
754 class ChromeContentSettingsRedirectTest
755     : public ChromeContentBrowserClientTest {
756  public:
757   ChromeContentSettingsRedirectTest()
758       : testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
759
760  protected:
761   content::BrowserTaskEnvironment task_environment_;
762   ScopedTestingLocalState testing_local_state_;
763   TestingProfile profile_;
764 };
765
766 TEST_F(ChromeContentSettingsRedirectTest, RedirectOSSettingsURL) {
767   TestChromeContentBrowserClient test_content_browser_client;
768   const GURL os_settings_url(chrome::kChromeUIOSSettingsURL);
769   GURL dest_url = os_settings_url;
770   test_content_browser_client.HandleWebUI(&dest_url, &profile_);
771   EXPECT_EQ(os_settings_url, dest_url);
772
773   base::Value list(base::Value::Type::LIST);
774   list.Append(policy::SystemFeature::OS_SETTINGS);
775   testing_local_state_.Get()->Set(
776       policy::policy_prefs::kSystemFeaturesDisableList, std::move(list));
777
778   dest_url = os_settings_url;
779   test_content_browser_client.HandleWebUI(&dest_url, &profile_);
780   EXPECT_EQ(GURL(chrome::kChromeUIAppDisabledURL), dest_url);
781
782   GURL os_settings_pwa_url =
783       GURL(chrome::kChromeUIOSSettingsURL).Resolve("pwa.html");
784   dest_url = os_settings_pwa_url;
785   test_content_browser_client.HandleWebUI(&dest_url, &profile_);
786   EXPECT_EQ(os_settings_pwa_url, dest_url);
787 }
788
789 TEST_F(ChromeContentSettingsRedirectTest, RedirectSettingsURL) {
790   TestChromeContentBrowserClient test_content_browser_client;
791   const GURL settings_url(chrome::kChromeUISettingsURL);
792   GURL dest_url = settings_url;
793   test_content_browser_client.HandleWebUI(&dest_url, &profile_);
794   EXPECT_EQ(settings_url, dest_url);
795
796   base::Value list(base::Value::Type::LIST);
797   list.Append(policy::SystemFeature::BROWSER_SETTINGS);
798   testing_local_state_.Get()->Set(
799       policy::policy_prefs::kSystemFeaturesDisableList, std::move(list));
800
801   dest_url = settings_url;
802   test_content_browser_client.HandleWebUI(&dest_url, &profile_);
803   EXPECT_EQ(GURL(chrome::kChromeUIAppDisabledURL), dest_url);
804 }
805 #endif  // defined(OS_CHROMEOS)
806
807 class CaptivePortalCheckProcessHost : public content::MockRenderProcessHost {
808  public:
809   explicit CaptivePortalCheckProcessHost(
810       content::BrowserContext* browser_context)
811       : MockRenderProcessHost(browser_context) {}
812
813   void CreateURLLoaderFactory(
814       mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
815       network::mojom::URLLoaderFactoryParamsPtr params) override {
816     *invoked_url_factory_ = true;
817     DCHECK_EQ(expected_disable_secure_dns_, params->disable_secure_dns);
818   }
819
820   void SetupForTracking(bool* invoked_url_factory,
821                         bool expected_disable_secure_dns) {
822     invoked_url_factory_ = invoked_url_factory;
823     expected_disable_secure_dns_ = expected_disable_secure_dns;
824   }
825
826  private:
827   bool* invoked_url_factory_ = nullptr;
828   bool expected_disable_secure_dns_ = false;
829
830   DISALLOW_COPY_AND_ASSIGN(CaptivePortalCheckProcessHost);
831 };
832
833 class CaptivePortalCheckRenderProcessHostFactory
834     : public content::RenderProcessHostFactory {
835  public:
836   CaptivePortalCheckRenderProcessHostFactory() = default;
837
838   content::RenderProcessHost* CreateRenderProcessHost(
839       content::BrowserContext* browser_context,
840       content::SiteInstance* site_instance) override {
841     rph_ = new CaptivePortalCheckProcessHost(browser_context);
842     return rph_;
843   }
844
845   void SetupForTracking(bool* invoked_url_factory,
846                         bool expected_disable_secure_dns) {
847     rph_->SetupForTracking(invoked_url_factory, expected_disable_secure_dns);
848   }
849
850  private:
851   CaptivePortalCheckProcessHost* rph_ = nullptr;
852
853   DISALLOW_COPY_AND_ASSIGN(CaptivePortalCheckRenderProcessHostFactory);
854 };
855
856 class ChromeContentBrowserClientCaptivePortalBrowserTest
857     : public ChromeRenderViewHostTestHarness {
858  public:
859  protected:
860   void SetUp() override {
861     SetRenderProcessHostFactory(&cp_rph_factory_);
862     ChromeRenderViewHostTestHarness::SetUp();
863   }
864
865   CaptivePortalCheckRenderProcessHostFactory cp_rph_factory_;
866 };
867
868 TEST_F(ChromeContentBrowserClientCaptivePortalBrowserTest,
869        NotCaptivePortalWindow) {
870   bool invoked_url_factory = false;
871   cp_rph_factory_.SetupForTracking(&invoked_url_factory,
872                                    false /* expected_disable_secure_dns */);
873   NavigateAndCommit(GURL("https://www.google.com"), ui::PAGE_TRANSITION_LINK);
874   EXPECT_TRUE(invoked_url_factory);
875 }
876
877 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
878 TEST_F(ChromeContentBrowserClientCaptivePortalBrowserTest,
879        CaptivePortalWindow) {
880   bool invoked_url_factory = false;
881   cp_rph_factory_.SetupForTracking(&invoked_url_factory,
882                                    true /* expected_disable_secure_dns */);
883   captive_portal::CaptivePortalTabHelper::CreateForWebContents(
884       web_contents(), CaptivePortalServiceFactory::GetForProfile(profile()),
885       base::Callback<void(void)>());
886   captive_portal::CaptivePortalTabHelper::FromWebContents(web_contents())
887       ->set_is_captive_portal_window();
888   NavigateAndCommit(GURL("https://www.google.com"), ui::PAGE_TRANSITION_LINK);
889   EXPECT_TRUE(invoked_url_factory);
890 }
891 #endif