1 // Copyright 2020 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/ui/extensions/settings_overridden_params_providers.h"
6 
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/extension_service_test_base.h"
10 #include "chrome/browser/extensions/extension_web_ui.h"
11 #include "chrome/browser/extensions/extension_web_ui_override_registrar.h"
12 #include "chrome/browser/search_engines/template_url_service_factory.h"
13 #include "chrome/common/webui_url_constants.h"
14 #include "chrome/test/base/search_test_utils.h"
15 #include "components/search_engines/template_url_service.h"
16 #include "extensions/common/extension_builder.h"
17 #include "extensions/common/value_builder.h"
18 
19 class SettingsOverriddenParamsProvidersUnitTest
20     : public extensions::ExtensionServiceTestBase {
21  public:
SetUp()22   void SetUp() override {
23     extensions::ExtensionServiceTestBase::SetUp();
24     InitializeEmptyExtensionService();
25 
26     // The NtpOverriddenDialogController rellies on ExtensionWebUI; ensure one
27     // exists.
28     extensions::ExtensionWebUIOverrideRegistrar::GetFactoryInstance()
29         ->SetTestingFactoryAndUse(
30             profile(), base::Bind([](content::BrowserContext* context)
31                                       -> std::unique_ptr<KeyedService> {
32               return std::make_unique<
33                   extensions::ExtensionWebUIOverrideRegistrar>(context);
34             }));
35     auto* template_url_service = static_cast<TemplateURLService*>(
36         TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
37             profile(),
38             base::BindRepeating(&TemplateURLServiceFactory::BuildInstanceFor)));
39     search_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
40   }
41 
42   // Adds a new extension that overrides the NTP.
AddExtensionControllingNewTab(const char * name="ntp override")43   const extensions::Extension* AddExtensionControllingNewTab(
44       const char* name = "ntp override") {
45     std::unique_ptr<base::Value> chrome_url_overrides =
46         extensions::DictionaryBuilder().Set("newtab", "newtab.html").Build();
47     scoped_refptr<const extensions::Extension> extension =
48         extensions::ExtensionBuilder(name)
49             .SetLocation(extensions::Manifest::INTERNAL)
50             .SetManifestKey("chrome_url_overrides",
51                             std::move(chrome_url_overrides))
52             .Build();
53 
54     service()->AddExtension(extension.get());
55     EXPECT_EQ(extension, ExtensionWebUI::GetExtensionControllingURL(
56                              GURL(chrome::kChromeUINewTabURL), profile()));
57 
58     return extension.get();
59   }
60 };
61 
TEST_F(SettingsOverriddenParamsProvidersUnitTest,GetExtensionControllingNewTab)62 TEST_F(SettingsOverriddenParamsProvidersUnitTest,
63        GetExtensionControllingNewTab) {
64   // With no extensions installed, there should be no controlling extension.
65   EXPECT_EQ(base::nullopt,
66             settings_overridden_params::GetNtpOverriddenParams(profile()));
67 
68   // Install an extension, but not one that overrides the NTP. There should
69   // still be no controlling extension.
70   scoped_refptr<const extensions::Extension> regular_extension =
71       extensions::ExtensionBuilder("regular").Build();
72   service()->AddExtension(regular_extension.get());
73   EXPECT_EQ(base::nullopt,
74             settings_overridden_params::GetNtpOverriddenParams(profile()));
75 
76   // Finally, install an extension that overrides the NTP. It should be the
77   // controlling extension.
78   const extensions::Extension* ntp_extension = AddExtensionControllingNewTab();
79   base::Optional<ExtensionSettingsOverriddenDialog::Params> params =
80       settings_overridden_params::GetNtpOverriddenParams(profile());
81   ASSERT_TRUE(params);
82   EXPECT_EQ(ntp_extension->id(), params->controlling_extension_id);
83 
84   // In this case, disabling the extension would go back to the default NTP, so
85   // a specific message should show.
86   EXPECT_EQ("Change back to Google?", base::UTF16ToUTF8(params->dialog_title));
87 }
88 
TEST_F(SettingsOverriddenParamsProvidersUnitTest,DialogStringsWhenMultipleNtpOverrides_MultipleExtensions)89 TEST_F(SettingsOverriddenParamsProvidersUnitTest,
90        DialogStringsWhenMultipleNtpOverrides_MultipleExtensions) {
91   const extensions::Extension* extension1 =
92       AddExtensionControllingNewTab("uno");
93   const extensions::Extension* extension2 =
94       AddExtensionControllingNewTab("dos");
95   EXPECT_NE(extension1->id(), extension2->id());
96 
97   // When there are multiple extensions that could override the NTP, we should
98   // show a generic dialog (rather than prompting to go back to the default
99   // NTP), because the other extension would just take over.
100   base::Optional<ExtensionSettingsOverriddenDialog::Params> params =
101       settings_overridden_params::GetNtpOverriddenParams(profile());
102   ASSERT_TRUE(params);
103   EXPECT_EQ(extension2->id(), params->controlling_extension_id);
104   EXPECT_EQ("Did you mean to change this page?",
105             base::UTF16ToUTF8(params->dialog_title));
106 }
107