chromium/components/blocked_content/android/popup_blocked_message_delegate_unittest.cc

// 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 "components/blocked_content/android/popup_blocked_message_delegate.h"

#include "base/android/jni_android.h"
#include "base/memory/raw_ptr.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "components/blocked_content/popup_blocker_tab_helper.h"
#include "components/blocked_content/safe_browsing_triggered_popup_blocker.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
#include "components/content_settings/browser/test_page_specific_content_settings_delegate.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/messages/android/mock_message_dispatcher_bridge.h"
#include "components/strings/grit/components_strings.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/test/test_renderer_host.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

namespace blocked_content {
namespace {
constexpr char kPageUrl[] = "http://example_page.test";
}  // namespace

class PopupBlockedMessageDelegateTest
    : public content::RenderViewHostTestHarness {
 public:
  PopupBlockedMessageDelegateTest() = default;
  ~PopupBlockedMessageDelegateTest() override;

  // content::RenderViewHostTestHarness:
  void SetUp() override;

  PopupBlockerTabHelper* helper() { return helper_; }

  HostContentSettingsMap* settings_map() { return settings_map_.get(); }

  bool EnqueueMessage(int num_pops,
                      base::OnceClosure on_accept_callback,
                      bool success);

  messages::MessageWrapper* GetMessageWrapper();
  void TriggerMessageDismissedCallback(messages::DismissReason dismiss_reason);
  void TriggerActionClick();

  PopupBlockedMessageDelegate* GetDelegate() {
    return popup_blocked_message_delegate_;
  }

 private:
  raw_ptr<PopupBlockerTabHelper> helper_ = nullptr;
  base::test::ScopedFeatureList feature_list_;
  sync_preferences::TestingPrefServiceSyncable pref_service_;
  scoped_refptr<HostContentSettingsMap> settings_map_;
  messages::MockMessageDispatcherBridge message_dispatcher_bridge_;
  raw_ptr<PopupBlockedMessageDelegate> popup_blocked_message_delegate_;
};

PopupBlockedMessageDelegateTest::~PopupBlockedMessageDelegateTest() {
  settings_map_->ShutdownOnUIThread();
}

void PopupBlockedMessageDelegateTest::SetUp() {
  content::RenderViewHostTestHarness::SetUp();

  // Make sure the SafeBrowsingTriggeredPopupBlocker is not created.
  feature_list_.InitAndDisableFeature(kAbusiveExperienceEnforce);

  HostContentSettingsMap::RegisterProfilePrefs(pref_service_.registry());
  settings_map_ = base::MakeRefCounted<HostContentSettingsMap>(
      &pref_service_, false /* is_off_the_record */,
      false /* store_last_modified */, false /* restore_session*/,
      false /* should_record_metrics */);
  content_settings::PageSpecificContentSettings::CreateForWebContents(
      web_contents(),
      std::make_unique<
          content_settings::TestPageSpecificContentSettingsDelegate>(
          /*prefs=*/nullptr, settings_map_.get()));

  PopupBlockerTabHelper::CreateForWebContents(web_contents());
  helper_ = PopupBlockerTabHelper::FromWebContents(web_contents());

  PopupBlockedMessageDelegate::CreateForWebContents(web_contents());
  popup_blocked_message_delegate_ =
      PopupBlockedMessageDelegate::FromWebContents(web_contents());
  NavigateAndCommit(GURL(kPageUrl));
  message_dispatcher_bridge_.SetMessagesEnabledForEmbedder(true);
  messages::MessageDispatcherBridge::SetInstanceForTesting(
      &message_dispatcher_bridge_);
}

messages::MessageWrapper* PopupBlockedMessageDelegateTest::GetMessageWrapper() {
  return popup_blocked_message_delegate_->message_for_testing();
}

bool PopupBlockedMessageDelegateTest::EnqueueMessage(
    int num_pops,
    base::OnceClosure on_accept_callback,
    bool success) {
  EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage)
      .WillOnce(testing::Return(success));
  return GetDelegate()->ShowMessage(num_pops, settings_map(),
                                    std::move(on_accept_callback));
}

void PopupBlockedMessageDelegateTest::TriggerActionClick() {
  GetMessageWrapper()->HandleActionClick(base::android::AttachCurrentThread());
}

void PopupBlockedMessageDelegateTest::TriggerMessageDismissedCallback(
    messages::DismissReason dismiss_reason) {
  GetMessageWrapper()->HandleDismissCallback(
      base::android::AttachCurrentThread(), static_cast<int>(dismiss_reason));
  EXPECT_EQ(nullptr, GetMessageWrapper());
}

// Tests that message properties (title, description, icon, button text) are
// set correctly.
TEST_F(PopupBlockedMessageDelegateTest, MessagePropertyValues) {
  int num_popups = 3;
  EnqueueMessage(num_popups, base::NullCallback(), true);
  EXPECT_EQ(l10n_util::GetPluralStringFUTF16(IDS_POPUPS_BLOCKED_INFOBAR_TEXT,
                                             num_popups),
            GetMessageWrapper()->GetTitle());
  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_POPUPS_BLOCKED_INFOBAR_BUTTON_SHOW),
            GetMessageWrapper()->GetPrimaryButtonText());

  // Should update title; #EnqueueMessage ensure message is enqueued only once.
  GetDelegate()->ShowMessage(num_popups + 1, settings_map(),
                             base::NullCallback());
  EXPECT_EQ(l10n_util::GetPluralStringFUTF16(IDS_POPUPS_BLOCKED_INFOBAR_TEXT,
                                             num_popups + 1),
            GetMessageWrapper()->GetTitle());
  TriggerMessageDismissedCallback(messages::DismissReason::UNKNOWN);
}

// Tests that title updated when another popup is blocked and a message
// is already on the screen.
TEST_F(PopupBlockedMessageDelegateTest, ShowsBlockedPopups) {
  bool on_accept_called = false;
  bool result =
      EnqueueMessage(1, base::BindLambdaForTesting([&on_accept_called] {
                       on_accept_called = true;
                     }),
                     true);
  EXPECT_TRUE(result);
  TriggerActionClick();
  EXPECT_TRUE(on_accept_called);
  TriggerMessageDismissedCallback(messages::DismissReason::UNKNOWN);
  EXPECT_EQ(settings_map()->GetContentSetting(GURL(kPageUrl), GURL(kPageUrl),
                                              ContentSettingsType::POPUPS),
            CONTENT_SETTING_ALLOW);
}

// Tests that title updated when another popup is blocked and a message
// is already on the screen.
TEST_F(PopupBlockedMessageDelegateTest, FailToShowMessage) {
  bool on_accept_called = false;
  bool result =
      EnqueueMessage(1, base::BindLambdaForTesting([&on_accept_called] {
                       on_accept_called = true;
                     }),
                     false);
  EXPECT_FALSE(result);
  EXPECT_FALSE(on_accept_called);
}

}  // namespace blocked_content