| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/test/test_future.h" |
| #include "chrome/browser/apps/link_capturing/link_capturing_feature_test_support.h" |
| #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" |
| #include "chrome/browser/web_applications/test/web_app_test.h" |
| #include "chrome/browser/web_applications/web_app_command_scheduler.h" |
| #include "chrome/browser/web_applications/web_app_install_info.h" |
| #include "chrome/browser/web_applications/web_app_provider.h" |
| #include "chrome/browser/web_applications/web_app_registrar.h" |
| #include "chrome/common/chrome_features.h" |
| #include "components/webapps/common/web_app_id.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| namespace web_app { |
| namespace { |
| |
| class LinkCapturingJobTest : public WebAppTest, |
| public testing::WithParamInterface< |
| apps::test::LinkCapturingFeatureVersion> { |
| public: |
| const GURL kTestAppUrl = GURL("https://example.com/index.html"); |
| const GURL kTestOverlappingAppUrl = GURL("https://example.com/index2.html"); |
| const GURL kTestAppCapturablePage = GURL("https://example.com/page.html"); |
| |
| LinkCapturingJobTest() { |
| feature_list_.InitWithFeaturesAndParameters( |
| apps::test::GetFeaturesToEnableLinkCapturingUX(GetParam()), {}); |
| } |
| ~LinkCapturingJobTest() override = default; |
| |
| bool LinkCapturingEnabledByDefault() const { |
| return GetParam() == apps::test::LinkCapturingFeatureVersion::kV2DefaultOn; |
| } |
| |
| void SetUp() override { |
| WebAppTest::SetUp(); |
| test::AwaitStartWebAppProviderAndSubsystems(profile()); |
| } |
| |
| WebAppProvider* provider() { return WebAppProvider::GetForTest(profile()); } |
| |
| private: |
| base::test::ScopedFeatureList feature_list_; |
| }; |
| |
| TEST_P(LinkCapturingJobTest, SingleAppEnabled) { |
| webapps::AppId app_id = test::InstallWebApp( |
| profile(), WebAppInstallInfo::CreateWithStartUrlForTesting(kTestAppUrl)); |
| |
| // For LinkCapturingEnabledByDefault(), simply test the default & that |
| // enabling it doesn't change anything. |
| EXPECT_TRUE(provider()->registrar_unsafe().IsLinkCapturableByApp( |
| app_id, kTestAppCapturablePage)); |
| EXPECT_EQ(LinkCapturingEnabledByDefault(), |
| provider()->registrar_unsafe().CapturesLinksInScope(app_id)); |
| EXPECT_EQ( |
| LinkCapturingEnabledByDefault() ? std::optional(app_id) : std::nullopt, |
| provider()->registrar_unsafe().FindAppThatCapturesLinksInScope( |
| kTestAppCapturablePage)); |
| |
| base::test::TestFuture<void> preference_set; |
| provider()->scheduler().SetAppCapturesSupportedLinksDisableOverlapping( |
| app_id, /*set_to_preferred=*/true, preference_set.GetCallback()); |
| ASSERT_TRUE(preference_set.Wait()); |
| |
| EXPECT_EQ(provider() |
| ->registrar_unsafe() |
| .GetAppById(app_id) |
| ->user_link_capturing_preference(), |
| proto::NAVIGATION_CAPTURING_PREFERENCE_CAPTURE); |
| |
| EXPECT_TRUE(provider()->registrar_unsafe().IsLinkCapturableByApp( |
| app_id, kTestAppCapturablePage)); |
| EXPECT_TRUE(provider()->registrar_unsafe().CapturesLinksInScope(app_id)); |
| EXPECT_EQ(app_id, |
| provider()->registrar_unsafe().FindAppThatCapturesLinksInScope( |
| kTestAppCapturablePage)); |
| } |
| |
| TEST_P(LinkCapturingJobTest, SingleAppDisabled) { |
| webapps::AppId app_id = test::InstallWebApp( |
| profile(), WebAppInstallInfo::CreateWithStartUrlForTesting(kTestAppUrl)); |
| |
| base::test::TestFuture<void> preference_set; |
| provider()->scheduler().SetAppCapturesSupportedLinksDisableOverlapping( |
| app_id, /*set_to_preferred=*/false, preference_set.GetCallback()); |
| ASSERT_TRUE(preference_set.Wait()); |
| |
| EXPECT_EQ(provider() |
| ->registrar_unsafe() |
| .GetAppById(app_id) |
| ->user_link_capturing_preference(), |
| proto::NAVIGATION_CAPTURING_PREFERENCE_DO_NOT_CAPTURE); |
| EXPECT_TRUE(provider()->registrar_unsafe().IsLinkCapturableByApp( |
| app_id, kTestAppCapturablePage)); |
| EXPECT_FALSE(provider()->registrar_unsafe().CapturesLinksInScope(app_id)); |
| EXPECT_EQ(std::nullopt, |
| provider()->registrar_unsafe().FindAppThatCapturesLinksInScope( |
| kTestAppCapturablePage)); |
| } |
| |
| TEST_P(LinkCapturingJobTest, DisablesOtherApps) { |
| webapps::AppId app1_id = test::InstallWebApp( |
| profile(), WebAppInstallInfo::CreateWithStartUrlForTesting(kTestAppUrl)); |
| webapps::AppId app2_id = test::InstallWebApp( |
| profile(), |
| WebAppInstallInfo::CreateWithStartUrlForTesting(kTestOverlappingAppUrl)); |
| |
| { |
| base::test::TestFuture<void> preference_set; |
| provider()->scheduler().SetAppCapturesSupportedLinksDisableOverlapping( |
| app1_id, /*set_to_preferred=*/true, preference_set.GetCallback()); |
| ASSERT_TRUE(preference_set.Wait()); |
| } |
| |
| EXPECT_TRUE(provider()->registrar_unsafe().CapturesLinksInScope(app1_id)); |
| |
| // This should disable link capturing on the first app, and enable it on the |
| // second app. |
| { |
| base::test::TestFuture<void> preference_set; |
| provider()->scheduler().SetAppCapturesSupportedLinksDisableOverlapping( |
| app2_id, /*set_to_preferred=*/true, preference_set.GetCallback()); |
| ASSERT_TRUE(preference_set.Wait()); |
| } |
| |
| // The first app should have this disabled. |
| EXPECT_FALSE(provider()->registrar_unsafe().CapturesLinksInScope(app1_id)); |
| |
| // It should be set up on the second app. |
| EXPECT_TRUE(provider()->registrar_unsafe().CapturesLinksInScope(app2_id)); |
| EXPECT_EQ(app2_id, |
| provider()->registrar_unsafe().FindAppThatCapturesLinksInScope( |
| kTestAppCapturablePage)); |
| } |
| |
| TEST_P(LinkCapturingJobTest, DefaultOnChoosesFirstApp) { |
| if (!LinkCapturingEnabledByDefault()) { |
| GTEST_SKIP(); |
| } |
| webapps::AppId app1_id = test::InstallWebApp( |
| profile(), WebAppInstallInfo::CreateWithStartUrlForTesting(kTestAppUrl)); |
| webapps::AppId app2_id = test::InstallWebApp( |
| profile(), |
| WebAppInstallInfo::CreateWithStartUrlForTesting(kTestOverlappingAppUrl)); |
| |
| EXPECT_TRUE(provider()->registrar_unsafe().CapturesLinksInScope(app1_id)); |
| EXPECT_FALSE(provider()->registrar_unsafe().CapturesLinksInScope(app2_id)); |
| } |
| |
| TEST_P(LinkCapturingJobTest, ExplicitDisablingOverrideDefaultBehavior) { |
| webapps::AppId app1_id = test::InstallWebApp( |
| profile(), WebAppInstallInfo::CreateWithStartUrlForTesting(kTestAppUrl)); |
| webapps::AppId app2_id = test::InstallWebApp( |
| profile(), |
| WebAppInstallInfo::CreateWithStartUrlForTesting(kTestOverlappingAppUrl)); |
| |
| // Disabling the second should always cause it to be disabled, even in |
| // 'default on' scenario after the first app is uninstalled. |
| { |
| base::test::TestFuture<void> preference_set; |
| provider()->scheduler().SetAppCapturesSupportedLinksDisableOverlapping( |
| app2_id, /*set_to_preferred=*/false, preference_set.GetCallback()); |
| ASSERT_TRUE(preference_set.Wait()); |
| } |
| |
| EXPECT_FALSE(provider()->registrar_unsafe().CapturesLinksInScope(app2_id)); |
| |
| test::UninstallWebApp(profile(), app1_id); |
| |
| // The app remains disabled, if it we were "default on". |
| EXPECT_FALSE(provider()->registrar_unsafe().CapturesLinksInScope(app2_id)); |
| } |
| |
| TEST_P(LinkCapturingJobTest, UninstallOverlappingRevertsToDefault) { |
| webapps::AppId app1_id = test::InstallWebApp( |
| profile(), WebAppInstallInfo::CreateWithStartUrlForTesting(kTestAppUrl)); |
| webapps::AppId app2_id = test::InstallWebApp( |
| profile(), |
| WebAppInstallInfo::CreateWithStartUrlForTesting(kTestOverlappingAppUrl)); |
| |
| // Enable the first, which should explicitly disable the second. |
| { |
| base::test::TestFuture<void> preference_set; |
| provider()->scheduler().SetAppCapturesSupportedLinksDisableOverlapping( |
| app1_id, /*set_to_preferred=*/true, preference_set.GetCallback()); |
| ASSERT_TRUE(preference_set.Wait()); |
| } |
| |
| EXPECT_TRUE(provider()->registrar_unsafe().CapturesLinksInScope(app1_id)); |
| EXPECT_FALSE(provider()->registrar_unsafe().CapturesLinksInScope(app2_id)); |
| |
| // Uninstalling the first should make the second app revert to the default. |
| test::UninstallWebApp(profile(), app1_id); |
| |
| EXPECT_EQ(LinkCapturingEnabledByDefault(), |
| provider()->registrar_unsafe().CapturesLinksInScope(app2_id)); |
| } |
| |
| INSTANTIATE_TEST_SUITE_P( |
| , |
| LinkCapturingJobTest, |
| testing::Values(apps::test::LinkCapturingFeatureVersion::kV2DefaultOff, |
| apps::test::LinkCapturingFeatureVersion::kV2DefaultOn), |
| apps::test::LinkCapturingVersionToString); |
| |
| } // namespace |
| } // namespace web_app |