910e62b5创建于 1月15日历史提交
// Copyright 2024 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/commerce/browser_utils.h"

#include <memory>

#include "chrome/browser/commerce/shopping_service_factory.h"
#include "chrome/test/base/testing_profile.h"
#include "components/commerce/core/commerce_constants.h"
#include "components/commerce/core/commerce_feature_list.h"
#include "components/commerce/core/feature_utils.h"
#include "components/commerce/core/mock_account_checker.h"
#include "components/commerce/core/mock_shopping_service.h"
#include "components/commerce/core/test_utils.h"
#include "components/prefs/testing_pref_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gtest/include/gtest/gtest.h"

using content::WebContents;

class CommerceBrowserUtilsTest : public testing::Test {
 public:
  CommerceBrowserUtilsTest()
      : account_checker_(std::make_unique<commerce::MockAccountChecker>()),
        prefs_(std::make_unique<TestingPrefServiceSimple>()) {}
  void SetUp() override {
    commerce::MockAccountChecker::RegisterCommercePrefs(prefs_->registry());
    account_checker_->SetPrefs(prefs_.get());
    TestingProfile::Builder profile_builder;
    profile_builder.AddTestingFactory(
        commerce::ShoppingServiceFactory::GetInstance(),
        base::BindRepeating([](content::BrowserContext* context) {
          return commerce::MockShoppingService::Build();
        }));
    profile_ = profile_builder.Build();
    auto* shopping_service = static_cast<commerce::MockShoppingService*>(
        commerce::ShoppingServiceFactory::GetForBrowserContext(profile_.get()));
    shopping_service->SetAccountChecker(account_checker_.get());
    // By default, the account checker and prefs are set up to enable product
    // specifications.
    commerce::EnableProductSpecificationsDataFetch(account_checker_.get(),
                                                   prefs_.get());
  }

 protected:
  const std::string kHttpsUrl = "https://example.com/";
  const std::string kHttpUrl = "http://example.com/";
  const std::string kChromeUrl = "chrome://example/";

  TestingProfile* profile() { return profile_.get(); }
  std::unique_ptr<WebContents> CreateWebContentsAndCommitFakeUrl(
      std::string url) {
    auto web_contents =
        content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
    content::WebContentsTester::For(web_contents.get())
        ->NavigateAndCommit(GURL(url));
    return web_contents;
  }

  base::test::ScopedFeatureList scoped_feature_list_;
  std::unique_ptr<commerce::MockAccountChecker> account_checker_;

 private:
  content::BrowserTaskEnvironment task_environment_;
  std::unique_ptr<TestingProfile> profile_;
  content::RenderViewHostTestEnabler render_view_host_test_enabler_;
  std::unique_ptr<TestingPrefServiceSimple> prefs_;
};

TEST_F(CommerceBrowserUtilsTest, TestIsWebContentsListEligibleForProductSpecs) {
  auto https_web_contents_1 = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);
  auto https_web_contents_2 = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);

  std::vector<WebContents*> web_contents_list{https_web_contents_1.get(),
                                              https_web_contents_2.get()};

  ASSERT_TRUE(
      commerce::IsWebContentsListEligibleForProductSpecs(web_contents_list));
}

TEST_F(CommerceBrowserUtilsTest, IsProductSpecsMultiSelectMenuEnabled) {
  scoped_feature_list_.InitWithFeatures({commerce::kProductSpecifications}, {});
  ASSERT_TRUE(
      commerce::CanFetchProductSpecificationsData(account_checker_.get()));

  auto web_contents = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);
  ASSERT_TRUE(commerce::IsProductSpecsMultiSelectMenuEnabled(
      profile(), web_contents.get()));

  // Navigate to a chrome:// url.
  content::WebContentsTester::For(web_contents.get())
      ->NavigateAndCommit(GURL(kChromeUrl));
  ASSERT_FALSE(commerce::IsProductSpecsMultiSelectMenuEnabled(
      profile(), web_contents.get()));
}

TEST_F(CommerceBrowserUtilsTest,
       IsProductSpecsMultiSelectMenuEnabled_HttpOrigin) {
  scoped_feature_list_.InitWithFeatures({commerce::kProductSpecifications}, {});
  ASSERT_TRUE(
      commerce::CanFetchProductSpecificationsData(account_checker_.get()));
  auto http_web_contents = CreateWebContentsAndCommitFakeUrl(kHttpUrl);
  ASSERT_TRUE(commerce::IsProductSpecsMultiSelectMenuEnabled(
      profile(), http_web_contents.get()));
}

TEST_F(CommerceBrowserUtilsTest,
       IsProductSpecsMultiSelectMenuEnabled_FeatureDisabled) {
  scoped_feature_list_.InitWithFeatures({}, {commerce::kProductSpecifications});
  ASSERT_FALSE(
      commerce::CanFetchProductSpecificationsData(account_checker_.get()));
  auto https_web_contents = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);
  ASSERT_FALSE(commerce::IsProductSpecsMultiSelectMenuEnabled(
      profile(), https_web_contents.get()));
}

TEST_F(CommerceBrowserUtilsTest,
       IsProductSpecsMultiSelectMenuEnabled_FeatureCannotFetch) {
  scoped_feature_list_.InitWithFeatures({commerce::kProductSpecifications}, {});
  // Update account checker to disable product specifications data fetch.
  account_checker_->SetIsSubjectToParentalControls(true);
  ASSERT_FALSE(
      commerce::CanFetchProductSpecificationsData(account_checker_.get()));

  auto https_web_contents = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);
  ASSERT_FALSE(commerce::IsProductSpecsMultiSelectMenuEnabled(
      profile(), https_web_contents.get()));
}

TEST_F(CommerceBrowserUtilsTest,
       IsProductSpecsMultiSelectMenuEnabled_NoIneligibleWebContents) {
  scoped_feature_list_.InitWithFeatures({commerce::kProductSpecifications}, {});
  ASSERT_TRUE(
      commerce::CanFetchProductSpecificationsData(account_checker_.get()));
  auto chrome_web_contents = CreateWebContentsAndCommitFakeUrl(kChromeUrl);
  ASSERT_FALSE(commerce::IsProductSpecsMultiSelectMenuEnabled(
      profile(), chrome_web_contents.get()));
}

TEST_F(CommerceBrowserUtilsTest,
       IsProductSpecsMultiSelectMenuEnabled_NoOffTheRecord) {
  scoped_feature_list_.InitWithFeatures({commerce::kProductSpecifications}, {});
  ASSERT_TRUE(
      commerce::CanFetchProductSpecificationsData(account_checker_.get()));
  auto https_web_contents = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);

  // Incognito profile
  TestingProfile::Builder profile_builder;
  auto* incognito_profile = profile_builder.BuildIncognito(profile());
  ASSERT_FALSE(commerce::IsProductSpecsMultiSelectMenuEnabled(
      incognito_profile, https_web_contents.get()));

  // OffTheRecord profile
  auto* otr_profile = profile()->GetOffTheRecordProfile(
      Profile::OTRProfileID::CreateUniqueForTesting(), true);
  ASSERT_FALSE(commerce::IsProductSpecsMultiSelectMenuEnabled(
      otr_profile, https_web_contents.get()));
}

TEST_F(CommerceBrowserUtilsTest,
       IsProductSpecsMultiSelectMenuEnabled_NoGuestSession) {
  scoped_feature_list_.InitWithFeatures({commerce::kProductSpecifications}, {});
  ASSERT_TRUE(
      commerce::CanFetchProductSpecificationsData(account_checker_.get()));

  TestingProfile::Builder profile_builder;
  auto guest_session = profile_builder.SetGuestSession().Build();

  auto https_web_contents = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);
  ASSERT_FALSE(commerce::IsProductSpecsMultiSelectMenuEnabled(
      guest_session.get(), https_web_contents.get()));
}

TEST_F(CommerceBrowserUtilsTest, IsWebContentsListEligibleForProductSpecs) {
  auto http_web_contents = CreateWebContentsAndCommitFakeUrl(kHttpUrl);
  auto https_web_contents_1 = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);
  auto https_web_contents_2 = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);

  std::vector<WebContents*> web_contents_list{http_web_contents.get(),
                                              https_web_contents_1.get(),
                                              https_web_contents_2.get()};
  ASSERT_TRUE(
      commerce::IsWebContentsListEligibleForProductSpecs(web_contents_list));
}

TEST_F(CommerceBrowserUtilsTest,
       IsWebContentsListEligibleForProductSpecs_NotEnoughUrls) {
  auto chrome_web_contents_1 = CreateWebContentsAndCommitFakeUrl(kChromeUrl);
  auto chrome_web_contents_2 = CreateWebContentsAndCommitFakeUrl(kChromeUrl);
  auto https_web_contents = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);

  std::vector<WebContents*> web_contents_list{chrome_web_contents_1.get(),
                                              chrome_web_contents_2.get(),
                                              https_web_contents.get()};
  ASSERT_FALSE(
      commerce::IsWebContentsListEligibleForProductSpecs(web_contents_list));
}

TEST_F(CommerceBrowserUtilsTest, GetListOfProductSpecsEligibleUrls) {
  auto chrome_web_contents_1 = CreateWebContentsAndCommitFakeUrl(kChromeUrl);
  auto chrome_web_contents_2 = CreateWebContentsAndCommitFakeUrl(kChromeUrl);
  auto https_web_contents = CreateWebContentsAndCommitFakeUrl(kHttpsUrl);

  std::vector<WebContents*> web_contents_list{chrome_web_contents_1.get(),
                                              chrome_web_contents_2.get(),
                                              https_web_contents.get()};

  auto eligible_urls =
      commerce::GetListOfProductSpecsEligibleUrls(web_contents_list);
  ASSERT_EQ(1U, eligible_urls.size());
}