| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/views/extensions/extensions_toolbar_controls.h" |
| |
| #include "base/strings/strcat.h" |
| #include "base/test/metrics/user_action_tester.h" |
| #include "chrome/browser/extensions/extension_action_runner.h" |
| #include "chrome/browser/extensions/extension_context_menu_model.h" |
| #include "chrome/browser/extensions/site_permissions_helper.h" |
| #include "chrome/browser/extensions/tab_helper.h" |
| #include "chrome/browser/ui/views/extensions/extensions_request_access_button.h" |
| #include "chrome/browser/ui/views/extensions/extensions_toolbar_button.h" |
| #include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h" |
| #include "chrome/browser/ui/views/extensions/extensions_toolbar_unittest.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "extensions/browser/permissions_manager.h" |
| #include "extensions/common/extension_features.h" |
| #include "extensions/test/permissions_manager_waiter.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "url/origin.h" |
| |
| namespace { |
| |
| // TODO(crbug.com/1452171): Same as permission's ChipController. Pull out to a |
| // shared location. |
| base::TimeDelta kConfirmationDisplayDuration = base::Seconds(4); |
| |
| } // namespace |
| |
| class ExtensionsToolbarControlsUnitTest : public ExtensionsToolbarUnitTest { |
| public: |
| ExtensionsToolbarControlsUnitTest(); |
| ~ExtensionsToolbarControlsUnitTest() override = default; |
| ExtensionsToolbarControlsUnitTest(const ExtensionsToolbarControlsUnitTest&) = |
| delete; |
| const ExtensionsToolbarControlsUnitTest& operator=( |
| const ExtensionsToolbarControlsUnitTest&) = delete; |
| |
| // Navigates to `url`. |
| void NavigateAndCommit(const GURL& URL); |
| |
| ExtensionsRequestAccessButton* request_access_button(); |
| ExtensionsToolbarButton* extensions_button(); |
| |
| // Returns whether the request access button is visible or not. |
| bool IsRequestAccessButtonVisible(); |
| |
| // ExtensionsToolbarUnitTest: |
| void SetUp() override; |
| |
| private: |
| base::test::ScopedFeatureList scoped_feature_list_; |
| raw_ptr<content::WebContentsTester, DanglingUntriaged> web_contents_tester_; |
| }; |
| |
| ExtensionsToolbarControlsUnitTest::ExtensionsToolbarControlsUnitTest() |
| : ExtensionsToolbarUnitTest( |
| base::test::TaskEnvironment::TimeSource::MOCK_TIME) { |
| scoped_feature_list_.InitAndEnableFeature( |
| extensions_features::kExtensionsMenuAccessControl); |
| } |
| |
| void ExtensionsToolbarControlsUnitTest::NavigateAndCommit(const GURL& url) { |
| web_contents_tester_->NavigateAndCommit(url); |
| WaitForAnimation(); |
| } |
| |
| ExtensionsRequestAccessButton* |
| ExtensionsToolbarControlsUnitTest::request_access_button() { |
| return extensions_container() |
| ->GetExtensionsToolbarControls() |
| ->request_access_button(); |
| } |
| |
| ExtensionsToolbarButton* |
| ExtensionsToolbarControlsUnitTest::extensions_button() { |
| return extensions_container()->GetExtensionsButton(); |
| } |
| |
| bool ExtensionsToolbarControlsUnitTest::IsRequestAccessButtonVisible() { |
| return request_access_button()->GetVisible(); |
| } |
| |
| void ExtensionsToolbarControlsUnitTest::SetUp() { |
| ExtensionsToolbarUnitTest::SetUp(); |
| web_contents_tester_ = AddWebContentsAndGetTester(); |
| } |
| |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| ExtensionsButton_SitePermissionsUpdates) { |
| // Install an extension that requests host permissions. |
| auto extension = |
| InstallExtensionWithHostPermissions("Extension", {"<all_urls>"}); |
| |
| const GURL url("http://www.url.com"); |
| auto url_origin = url::Origin::Create(url); |
| NavigateAndCommit(url); |
| |
| auto* manager = extensions::PermissionsManager::Get(profile()); |
| { |
| // Extensions button has "all extensions blocked" icon type when it's |
| // an user restricted site. |
| extensions::PermissionsManagerWaiter manager_waiter(manager); |
| manager->AddUserRestrictedSite(url_origin); |
| manager_waiter.WaitForUserPermissionsSettingsChange(); |
| WaitForAnimation(); |
| EXPECT_EQ(extensions_button()->state(), |
| ExtensionsToolbarButton::State::kAllExtensionsBlocked); |
| } |
| |
| { |
| // Extensions button has "any extension has access" icon type when it's not |
| // an user restricted site and 1+ extensions have |
| // site access granted. Note that by default extensions have granted access. |
| extensions::PermissionsManagerWaiter manager_waiter(manager); |
| manager->RemoveUserRestrictedSite(url_origin); |
| manager_waiter.WaitForUserPermissionsSettingsChange(); |
| WaitForAnimation(); |
| EXPECT_EQ(extensions_button()->state(), |
| ExtensionsToolbarButton::State::kAnyExtensionHasAccess); |
| } |
| |
| { |
| // Extension button has "default" icon type when it's not an user restricted |
| // site and no extensions have site access granted. |
| // To achieve this, we withhold host permissions in the only extension |
| // installed. |
| WithholdHostPermissions(extension.get()); |
| WaitForAnimation(); |
| EXPECT_EQ(extensions_button()->state(), |
| ExtensionsToolbarButton::State::kDefault); |
| } |
| } |
| |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| ExtensionsButton_ChromeRestrictedSite) { |
| InstallExtensionWithHostPermissions("Extension", {"<all_urls>"}); |
| |
| const GURL restricted_url("chrome://extensions"); |
| NavigateAndCommit(restricted_url); |
| |
| // Extensions button has "all extensions blocked" icon type for chrome |
| // restricted sites. |
| EXPECT_EQ(extensions_button()->state(), |
| ExtensionsToolbarButton::State::kAllExtensionsBlocked); |
| } |
| |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| RequestAccessButtonVisibility_NavigationBetweenPages) { |
| const GURL url_a("http://www.a.com"); |
| const GURL url_b("http://www.b.com"); |
| |
| // Add an extension that only requests access to a specific url, and withhold |
| // site access. |
| auto extension_a = |
| InstallExtensionWithHostPermissions("Extension A", {url_a.spec()}); |
| WithholdHostPermissions(extension_a.get()); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| |
| // Navigate to an url the extension requests access to. |
| NavigateAndCommit(url_a); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_EQ( |
| request_access_button()->GetText(), |
| l10n_util::GetStringFUTF16Int(IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON, 1)); |
| |
| // Navigate to an url the extension does not request access to. |
| NavigateAndCommit(url_b); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| } |
| |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| RequestAccessButtonVisibility_ContextMenuChangesHostPermissions) { |
| const GURL url_a("http://www.a.com"); |
| const GURL url_b("http://www.b.com"); |
| |
| // Add an extension with all urls host permissions. Since we haven't navigated |
| // to an url yet, the extension should not request access. |
| auto extension = |
| InstallExtensionWithHostPermissions("Extension AllUrls", {"<all_urls>"}); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| |
| // Navigate to an url the extension should have access to as part of |
| // <all_urls>, since permissions are granted by default. |
| NavigateAndCommit(url_a); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| |
| extensions::ExtensionContextMenuModel context_menu( |
| extension.get(), browser(), /*is_pinned=*/true, /*delegate=*/nullptr, |
| /*can_show_icon_in_toolbar=*/true, |
| extensions::ExtensionContextMenuModel::ContextMenuSource::kToolbarAction); |
| |
| // Changing the context menu may trigger the reload page bubble. Accept it so |
| // permissions are updated. |
| extensions::ExtensionActionRunner* runner = |
| extensions::ExtensionActionRunner::GetForWebContents( |
| browser()->tab_strip_model()->GetActiveWebContents()); |
| runner->accept_bubble_for_testing(true); |
| |
| auto* manager = extensions::PermissionsManager::Get(profile()); |
| // Change the extension to run only on click using the context |
| // menu. The extension should request access to the current site. |
| { |
| extensions::PermissionsManagerWaiter waiter(manager); |
| context_menu.ExecuteCommand( |
| extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_CLICK, 0); |
| waiter.WaitForExtensionPermissionsUpdate(); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_EQ( |
| request_access_button()->GetText(), |
| l10n_util::GetStringFUTF16Int(IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON, 1)); |
| } |
| |
| // Change the extension to run only on site using the context |
| // menu. The extension should not request access to the current site. |
| { |
| extensions::PermissionsManagerWaiter waiter(manager); |
| context_menu.ExecuteCommand( |
| extensions::ExtensionContextMenuModel::PAGE_ACCESS_RUN_ON_SITE, 0); |
| waiter.WaitForExtensionPermissionsUpdate(); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| } |
| } |
| |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| RequestAccessButtonVisibility_MultipleExtensions) { |
| const GURL url_a("http://www.a.com"); |
| const GURL url_b("http://www.b.com"); |
| |
| // Navigate to a.com and since there are no extensions installed yet, no |
| // extension is requesting access to the current site. |
| NavigateAndCommit(url_a); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| |
| // Add an extension that doesn't request host permissions. |
| InstallExtension("no_permissions"); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| |
| // Add an extension that only requests access to a.com, and |
| // withhold host permissions. |
| auto extension = |
| InstallExtensionWithHostPermissions("Extension", {url_a.spec()}); |
| WithholdHostPermissions(extension.get()); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_EQ( |
| request_access_button()->GetText(), |
| l10n_util::GetStringFUTF16Int(IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON, 1)); |
| std::u16string tooltip = base::UTF8ToUTF16( |
| base::StrCat({"Click to allow on a.com:\n", extension->name()})); |
| EXPECT_EQ(request_access_button()->GetTooltipText(gfx::Point()), tooltip); |
| |
| // Add an extension with all urls host permissions, and withhold host |
| // permissions. |
| auto extension_all_urls = |
| InstallExtensionWithHostPermissions("Extension AllUrls", {"<all_urls>"}); |
| WithholdHostPermissions(extension_all_urls.get()); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_EQ( |
| request_access_button()->GetText(), |
| l10n_util::GetStringFUTF16Int(IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON, 2)); |
| tooltip = base::UTF8ToUTF16( |
| base::StrCat({"Click to allow on a.com:\n", extension->name(), "\n", |
| extension_all_urls->name()})); |
| EXPECT_EQ(request_access_button()->GetTooltipText(gfx::Point()), tooltip); |
| |
| // Navigate to a different url. Only "all_urls" should request access. |
| NavigateAndCommit(url_b); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_EQ( |
| request_access_button()->GetText(), |
| l10n_util::GetStringFUTF16Int(IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON, 1)); |
| tooltip = base::UTF8ToUTF16( |
| base::StrCat({"Click to allow on b.com:\n", extension_all_urls->name()})); |
| EXPECT_EQ(request_access_button()->GetTooltipText(gfx::Point()), tooltip); |
| |
| // Remove the only extension that requests access to the current site. |
| UninstallExtension(extension_all_urls->id()); |
| LayoutContainerIfNecessary(); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| } |
| |
| // Tests that extensions with activeTab and requested url with withheld access |
| // are taken into account for the request access button visibility, but not the |
| // ones with just activeTab. |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| RequestAccessButtonVisibility_ActiveTabExtensions) { |
| const GURL requested_url("http://www.requested-url.com"); |
| |
| InstallExtensionWithPermissions("Extension A", {"activeTab"}); |
| auto extension = InstallExtensionWithHostPermissions( |
| "Extension B", {requested_url.spec(), "activeTab"}); |
| WithholdHostPermissions(extension.get()); |
| |
| NavigateAndCommit(requested_url); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_THAT(request_access_button()->GetExtensionIdsForTesting(), |
| testing::ElementsAre(extension->id())); |
| |
| NavigateAndCommit(GURL("http://www.non-requested-url.com")); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| } |
| |
| // Test that request access button is visible based on the user site setting |
| // selected. |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| RequestAccessButtonVisibility_UserSiteSetting) { |
| const GURL url("http://www.url.com"); |
| auto url_origin = url::Origin::Create(url); |
| |
| // Install an extension and withhold permissions so request access button can |
| // be visible. |
| auto extension = |
| InstallExtensionWithHostPermissions("Extension", {"<all_urls>"}); |
| WithholdHostPermissions(extension.get()); |
| |
| NavigateAndCommit(url); |
| |
| // A site has "customize by extensions" site setting by default, |
| ASSERT_EQ( |
| GetUserSiteSetting(url), |
| extensions::PermissionsManager::UserSiteSetting::kCustomizeByExtension); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| |
| auto* manager = extensions::PermissionsManager::Get(profile()); |
| |
| { |
| // Request access button is not visible in restricted sites. |
| extensions::PermissionsManagerWaiter manager_waiter(manager); |
| manager->AddUserRestrictedSite(url_origin); |
| manager_waiter.WaitForUserPermissionsSettingsChange(); |
| WaitForAnimation(); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| } |
| |
| { |
| // Request acesss button is visible if site is not restricted, |
| // and at least one extension is requesting access. |
| extensions::PermissionsManagerWaiter manager_waiter(manager); |
| manager->RemoveUserRestrictedSite(url_origin); |
| manager_waiter.WaitForUserPermissionsSettingsChange(); |
| WaitForAnimation(); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| } |
| } |
| |
| // Tests that an extension requesting site access but not allowed in |
| // the button is not shown in the request access button. |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| RequestAccessButtonVisibility_ExtensionsNotAllowedInButton) { |
| // Add two extensions that request access to all urls, and withhold their |
| // site access. |
| auto extension_a = |
| InstallExtensionWithHostPermissions("Extension A", {"<all_urls>"}); |
| auto extension_b = |
| InstallExtensionWithHostPermissions("Extension B", {"<all_urls>"}); |
| WithholdHostPermissions(extension_a.get()); |
| WithholdHostPermissions(extension_b.get()); |
| |
| // By default, both extensions should be allowed in the request |
| // access button. However, request access button is not visible because we |
| // haven't navigated to a site yet. |
| extensions::SitePermissionsHelper permissions_helper(browser()->profile()); |
| EXPECT_TRUE( |
| permissions_helper.ShowAccessRequestsInToolbar(extension_a->id())); |
| EXPECT_TRUE( |
| permissions_helper.ShowAccessRequestsInToolbar(extension_b->id())); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| |
| // Navigate to an url that both extensions requests access to. |
| const GURL url("http://www.example.com"); |
| NavigateAndCommit(url); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_EQ( |
| request_access_button()->GetText(), |
| l10n_util::GetStringFUTF16Int(IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON, 2)); |
| |
| // Disallow extension A in the request access button. Verify only extension A |
| // is visible in the button. |
| permissions_helper.SetShowAccessRequestsInToolbar(extension_a->id(), false); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_EQ( |
| request_access_button()->GetText(), |
| l10n_util::GetStringFUTF16Int(IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON, 1)); |
| |
| // Disallow extension B in the request access button. Verify button is not |
| // visible anymore. |
| permissions_helper.SetShowAccessRequestsInToolbar(extension_b->id(), false); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| } |
| |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| RequestAccessButtonVisibility_ExtensionDismissedRequests) { |
| // Add two extensions that request access to all urls, and withhold their |
| // site access. |
| auto extension_a = |
| InstallExtensionWithHostPermissions("Extension A", {"<all_urls>"}); |
| auto extension_b = |
| InstallExtensionWithHostPermissions("Extension B", {"<all_urls>"}); |
| WithholdHostPermissions(extension_a.get()); |
| WithholdHostPermissions(extension_b.get()); |
| |
| // By default, both extensions should be allowed in the request |
| // access button. However, request access button is not visible because we |
| // haven't navigated to a site yet. |
| extensions::SitePermissionsHelper permissions_helper(browser()->profile()); |
| EXPECT_TRUE( |
| permissions_helper.ShowAccessRequestsInToolbar(extension_a->id())); |
| EXPECT_TRUE( |
| permissions_helper.ShowAccessRequestsInToolbar(extension_b->id())); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| |
| // Navigate to an url that both extensions requests access to. |
| const GURL url("http://www.example.com"); |
| NavigateAndCommit(url); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_EQ( |
| request_access_button()->GetText(), |
| l10n_util::GetStringFUTF16Int(IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON, 2)); |
| |
| // Dismiss extension A's requests. Verify only extension B is visible in the |
| // button. |
| extensions::TabHelper* tab_helper = extensions::TabHelper::FromWebContents( |
| browser()->tab_strip_model()->GetActiveWebContents()); |
| tab_helper->DismissExtensionRequests(extension_a->id()); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| EXPECT_EQ( |
| request_access_button()->GetText(), |
| l10n_util::GetStringFUTF16Int(IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON, 1)); |
| |
| // Dismiss extension B's requests. Verify button is not visible anymore. |
| tab_helper->DismissExtensionRequests(extension_b->id()); |
| EXPECT_FALSE(IsRequestAccessButtonVisible()); |
| } |
| |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| RequestAccessButton_OnPressedExecuteAction) { |
| auto extension = |
| InstallExtensionWithHostPermissions("Extension", {"<all_urls>"}); |
| WithholdHostPermissions(extension.get()); |
| |
| const GURL url("http://www.example.com"); |
| NavigateAndCommit(url); |
| LayoutContainerIfNecessary(); |
| |
| constexpr char kActivatedUserAction[] = |
| "Extensions.Toolbar.ExtensionsActivatedFromRequestAccessButton"; |
| base::UserActionTester user_action_tester; |
| auto* permissions = extensions::PermissionsManager::Get(profile()); |
| |
| // Request access button is visible because the extension is requesting |
| // access. |
| ASSERT_TRUE(request_access_button()->GetVisible()); |
| EXPECT_EQ(user_action_tester.GetActionCount(kActivatedUserAction), 0); |
| EXPECT_EQ(permissions->GetUserSiteAccess(*extension, url), |
| extensions::PermissionsManager::UserSiteAccess::kOnClick); |
| |
| // Extension menu button has default state since extensions are not blocked, |
| // and there is no extension with access to the site. |
| EXPECT_EQ(extensions_button()->state(), |
| ExtensionsToolbarButton::State::kDefault); |
| |
| ClickButton(request_access_button()); |
| WaitForAnimation(); |
| LayoutContainerIfNecessary(); |
| |
| // Verify extension was executed and extensions menu button has "any |
| // extension has access" state. Extension's site access should have not |
| // changed, since clicking the button grants one time access. |
| EXPECT_EQ(user_action_tester.GetActionCount(kActivatedUserAction), 1); |
| EXPECT_EQ(extensions_button()->state(), |
| ExtensionsToolbarButton::State::kAnyExtensionHasAccess); |
| EXPECT_EQ(permissions->GetUserSiteAccess(*extension, url), |
| extensions::PermissionsManager::UserSiteAccess::kOnClick); |
| |
| // Verify confirmation message appears on the request access button. |
| EXPECT_TRUE(request_access_button()->GetVisible()); |
| EXPECT_EQ(request_access_button()->GetText(), |
| l10n_util::GetStringUTF16( |
| IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON_DISMISSED_TEXT)); |
| |
| // Force the confirmation to be collapsed. |
| task_environment()->AdvanceClock(kConfirmationDisplayDuration); |
| base::RunLoop().RunUntilIdle(); |
| |
| // Verify the request access button is hidden. |
| ASSERT_FALSE(request_access_button()->GetVisible()); |
| } |
| |
| // Tests that if an update comes in between the request access button is clicked |
| // and the confirmation is collapsed, the button is updated afterwards with the |
| // correct information. |
| TEST_F(ExtensionsToolbarControlsUnitTest, |
| RequestAccessButton_UpdateInBetweenClickAndConfirmationCollapse) { |
| auto extension_A = |
| InstallExtensionWithHostPermissions("Extension A", {"<all_urls>"}); |
| auto extension_B = |
| InstallExtensionWithHostPermissions("Extension B", {"<all_urls>"}); |
| auto extension_C = |
| InstallExtensionWithHostPermissions("Extension C", {"<all_urls>"}); |
| WithholdHostPermissions(extension_A.get()); |
| WithholdHostPermissions(extension_B.get()); |
| |
| const GURL url("http://www.example.com"); |
| NavigateAndCommit(url); |
| LayoutContainerIfNecessary(); |
| |
| // Request access button is visible because extension A and B are requesting |
| // access. |
| EXPECT_TRUE(request_access_button()->GetVisible()); |
| EXPECT_THAT(request_access_button()->GetExtensionIdsForTesting(), |
| testing::ElementsAre(extension_A->id(), extension_B->id())); |
| |
| ClickButton(request_access_button()); |
| WaitForAnimation(); |
| LayoutContainerIfNecessary(); |
| |
| // Verify confirmation message appears on the request access button after |
| // clicking on it |
| EXPECT_TRUE(request_access_button()->GetVisible()); |
| EXPECT_EQ(request_access_button()->GetText(), |
| l10n_util::GetStringUTF16( |
| IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON_DISMISSED_TEXT)); |
| |
| // Update a different extension before the confirmation is collapsed. |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| UpdateUserSiteAccess( |
| *extension_C, web_contents, |
| extensions::PermissionsManager::UserSiteAccess::kOnClick); |
| |
| // Confirmation is still showing since collapse time hasn't elapsed. |
| EXPECT_TRUE(request_access_button()->GetVisible()); |
| EXPECT_EQ(request_access_button()->GetText(), |
| l10n_util::GetStringUTF16( |
| IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON_DISMISSED_TEXT)); |
| |
| // Force the confirmation to be collapsed. |
| task_environment()->AdvanceClock(kConfirmationDisplayDuration); |
| base::RunLoop().RunUntilIdle(); |
| |
| // Verify the request access button is visible since extension C is now |
| // requesting access. |
| EXPECT_TRUE(request_access_button()->GetVisible()); |
| EXPECT_THAT(request_access_button()->GetExtensionIdsForTesting(), |
| testing::ElementsAre(extension_C->id())); |
| } |
| |
| class ExtensionsToolbarControlsWithPermittedSitesUnitTest |
| : public ExtensionsToolbarControlsUnitTest { |
| public: |
| ExtensionsToolbarControlsWithPermittedSitesUnitTest() { |
| std::vector<base::test::FeatureRef> enabled_features = { |
| extensions_features::kExtensionsMenuAccessControl, |
| extensions_features::kExtensionsMenuAccessControlWithPermittedSites}; |
| std::vector<base::test::FeatureRef> disabled_features; |
| feature_list_.InitWithFeatures(enabled_features, disabled_features); |
| } |
| ExtensionsToolbarControlsWithPermittedSitesUnitTest( |
| const ExtensionsToolbarControlsWithPermittedSitesUnitTest&) = delete; |
| const ExtensionsToolbarControlsWithPermittedSitesUnitTest& operator=( |
| const ExtensionsToolbarControlsWithPermittedSitesUnitTest&) = delete; |
| ~ExtensionsToolbarControlsWithPermittedSitesUnitTest() override = default; |
| |
| private: |
| base::test::ScopedFeatureList feature_list_; |
| }; |
| |
| // Test that request access button is visible based on the user site setting |
| // selected. |
| TEST_F(ExtensionsToolbarControlsWithPermittedSitesUnitTest, |
| RequestAccessButtonVisibilityOnPermittedSites) { |
| const GURL url("http://www.url.com"); |
| auto url_origin = url::Origin::Create(url); |
| |
| // Install an extension and withhold permissions so request access button can |
| // be visible. |
| auto extension = |
| InstallExtensionWithHostPermissions("Extension", {"<all_urls>"}); |
| WithholdHostPermissions(extension.get()); |
| |
| NavigateAndCommit(url); |
| |
| // A site has "customize by extensions" site setting by default, |
| ASSERT_EQ( |
| GetUserSiteSetting(url), |
| extensions::PermissionsManager::UserSiteSetting::kCustomizeByExtension); |
| EXPECT_TRUE(IsRequestAccessButtonVisible()); |
| |
| // Request access button is not visible in permitted sites. |
| auto* manager = extensions::PermissionsManager::Get(profile()); |
| extensions::PermissionsManagerWaiter waiter(manager); |
| manager->AddUserPermittedSite(url_origin); |
| waiter.WaitForUserPermissionsSettingsChange(); |
| WaitForAnimation(); |
| |
| // Request access button visibility is the same for other site settings, which |
| // is already tested, regardless of whether permitted sites are supported or |
| // not. |
| } |