popup_blocker_tab_helper_unittest.cc 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. #include "components/blocked_content/popup_blocker_tab_helper.h"
  5. #include "base/memory/raw_ptr.h"
  6. #include "base/scoped_observation.h"
  7. #include "base/test/scoped_feature_list.h"
  8. #include "components/blocked_content/popup_navigation_delegate.h"
  9. #include "components/blocked_content/safe_browsing_triggered_popup_blocker.h"
  10. #include "components/blocked_content/test/test_popup_navigation_delegate.h"
  11. #include "components/blocked_content/url_list_manager.h"
  12. #include "components/content_settings/browser/page_specific_content_settings.h"
  13. #include "components/content_settings/browser/test_page_specific_content_settings_delegate.h"
  14. #include "components/content_settings/core/browser/host_content_settings_map.h"
  15. #include "components/sync_preferences/testing_pref_service_syncable.h"
  16. #include "content/public/test/mock_navigation_handle.h"
  17. #include "content/public/test/test_renderer_host.h"
  18. #include "testing/gmock/include/gmock/gmock.h"
  19. #include "third_party/blink/public/mojom/window_features/window_features.mojom.h"
  20. #include "ui/base/window_open_disposition.h"
  21. namespace blocked_content {
  22. namespace {
  23. using testing::Pair;
  24. using testing::UnorderedElementsAre;
  25. constexpr char kUrl1[] = "http://example1.test";
  26. constexpr char kUrl2[] = "http://example2.test";
  27. // Observer which allows retrieving a map of all the blocked URLs.
  28. class BlockedUrlListObserver : public UrlListManager::Observer {
  29. public:
  30. explicit BlockedUrlListObserver(PopupBlockerTabHelper* helper) {
  31. observation_.Observe(helper->manager());
  32. }
  33. // UrlListManager::Observer:
  34. void BlockedUrlAdded(int32_t id, const GURL& url) override {
  35. blocked_urls_.insert({id, url});
  36. }
  37. const std::map<int32_t, GURL>& blocked_urls() const { return blocked_urls_; }
  38. private:
  39. std::map<int32_t, GURL> blocked_urls_;
  40. base::ScopedObservation<UrlListManager, UrlListManager::Observer>
  41. observation_{this};
  42. };
  43. } // namespace
  44. class PopupBlockerTabHelperTest : public content::RenderViewHostTestHarness {
  45. public:
  46. PopupBlockerTabHelperTest() {
  47. // Make sure the SafeBrowsingTriggeredPopupBlocker is not created.
  48. // This needs to be done as early as possible to avoid tsan data races
  49. // caused by other threads trying to access the feature list.
  50. feature_list_.InitAndDisableFeature(kAbusiveExperienceEnforce);
  51. }
  52. ~PopupBlockerTabHelperTest() override { settings_map_->ShutdownOnUIThread(); }
  53. // content::RenderViewHostTestHarness:
  54. void SetUp() override {
  55. content::RenderViewHostTestHarness::SetUp();
  56. HostContentSettingsMap::RegisterProfilePrefs(pref_service_.registry());
  57. settings_map_ = base::MakeRefCounted<HostContentSettingsMap>(
  58. &pref_service_, false /* is_off_the_record */,
  59. false /* store_last_modified */, false /* restore_session*/);
  60. content_settings::PageSpecificContentSettings::CreateForWebContents(
  61. web_contents(),
  62. std::make_unique<
  63. content_settings::TestPageSpecificContentSettingsDelegate>(
  64. /*prefs=*/nullptr, settings_map_.get()));
  65. PopupBlockerTabHelper::CreateForWebContents(web_contents());
  66. helper_ = PopupBlockerTabHelper::FromWebContents(web_contents());
  67. }
  68. PopupBlockerTabHelper* helper() { return helper_; }
  69. private:
  70. base::test::ScopedFeatureList feature_list_;
  71. raw_ptr<PopupBlockerTabHelper> helper_ = nullptr;
  72. sync_preferences::TestingPrefServiceSyncable pref_service_;
  73. scoped_refptr<HostContentSettingsMap> settings_map_;
  74. };
  75. TEST_F(PopupBlockerTabHelperTest, BlocksAndShowsPopup) {
  76. BlockedUrlListObserver observer(helper());
  77. TestPopupNavigationDelegate::ResultHolder result;
  78. blink::mojom::WindowFeatures window_features;
  79. window_features.has_x = true;
  80. helper()->AddBlockedPopup(
  81. std::make_unique<TestPopupNavigationDelegate>(GURL(kUrl1), &result),
  82. window_features, PopupBlockType::kNoGesture);
  83. EXPECT_EQ(result.total_popups_blocked_on_page, 1);
  84. EXPECT_FALSE(result.did_navigate);
  85. EXPECT_THAT(observer.blocked_urls(),
  86. UnorderedElementsAre(Pair(0, GURL(kUrl1))));
  87. helper()->ShowBlockedPopup(0, WindowOpenDisposition::NEW_FOREGROUND_TAB);
  88. EXPECT_TRUE(result.did_navigate);
  89. EXPECT_TRUE(result.navigation_window_features.has_x);
  90. EXPECT_EQ(result.navigation_disposition,
  91. WindowOpenDisposition::NEW_FOREGROUND_TAB);
  92. }
  93. TEST_F(PopupBlockerTabHelperTest, MultiplePopups) {
  94. BlockedUrlListObserver observer(helper());
  95. TestPopupNavigationDelegate::ResultHolder result1;
  96. helper()->AddBlockedPopup(
  97. std::make_unique<TestPopupNavigationDelegate>(GURL(kUrl1), &result1),
  98. blink::mojom::WindowFeatures(), PopupBlockType::kNoGesture);
  99. EXPECT_EQ(result1.total_popups_blocked_on_page, 1);
  100. EXPECT_THAT(observer.blocked_urls(),
  101. UnorderedElementsAre(Pair(0, GURL(kUrl1))));
  102. EXPECT_EQ(helper()->GetBlockedPopupsCount(), 1u);
  103. TestPopupNavigationDelegate::ResultHolder result2;
  104. helper()->AddBlockedPopup(
  105. std::make_unique<TestPopupNavigationDelegate>(GURL(kUrl2), &result2),
  106. blink::mojom::WindowFeatures(), PopupBlockType::kNoGesture);
  107. EXPECT_EQ(result2.total_popups_blocked_on_page, 2);
  108. EXPECT_THAT(observer.blocked_urls(),
  109. UnorderedElementsAre(Pair(0, GURL(kUrl1)), Pair(1, GURL(kUrl2))));
  110. EXPECT_EQ(helper()->GetBlockedPopupsCount(), 2u);
  111. helper()->ShowBlockedPopup(1, WindowOpenDisposition::NEW_FOREGROUND_TAB);
  112. EXPECT_EQ(helper()->GetBlockedPopupsCount(), 1u);
  113. EXPECT_TRUE(result2.did_navigate);
  114. EXPECT_EQ(result2.navigation_disposition,
  115. WindowOpenDisposition::NEW_FOREGROUND_TAB);
  116. EXPECT_FALSE(result1.did_navigate);
  117. helper()->ShowBlockedPopup(0, WindowOpenDisposition::CURRENT_TAB);
  118. EXPECT_EQ(helper()->GetBlockedPopupsCount(), 0u);
  119. EXPECT_TRUE(result1.did_navigate);
  120. EXPECT_FALSE(result1.navigation_disposition.has_value());
  121. }
  122. TEST_F(PopupBlockerTabHelperTest, DoesNotShowPopupWithInvalidID) {
  123. TestPopupNavigationDelegate::ResultHolder result;
  124. helper()->AddBlockedPopup(
  125. std::make_unique<TestPopupNavigationDelegate>(GURL(kUrl1), &result),
  126. blink::mojom::WindowFeatures(), PopupBlockType::kNoGesture);
  127. EXPECT_EQ(helper()->GetBlockedPopupsCount(), 1u);
  128. // Invalid ID should not do anything.
  129. helper()->ShowBlockedPopup(1, WindowOpenDisposition::NEW_FOREGROUND_TAB);
  130. EXPECT_EQ(helper()->GetBlockedPopupsCount(), 1u);
  131. EXPECT_FALSE(result.did_navigate);
  132. helper()->ShowBlockedPopup(0, WindowOpenDisposition::NEW_FOREGROUND_TAB);
  133. EXPECT_EQ(helper()->GetBlockedPopupsCount(), 0u);
  134. EXPECT_TRUE(result.did_navigate);
  135. }
  136. TEST_F(PopupBlockerTabHelperTest, SetsContentSettingsPopupState) {
  137. auto* content_settings =
  138. content_settings::PageSpecificContentSettings::GetForFrame(
  139. web_contents()->GetPrimaryMainFrame());
  140. EXPECT_FALSE(content_settings->IsContentBlocked(ContentSettingsType::POPUPS));
  141. TestPopupNavigationDelegate::ResultHolder result;
  142. helper()->AddBlockedPopup(
  143. std::make_unique<TestPopupNavigationDelegate>(GURL(kUrl1), &result),
  144. blink::mojom::WindowFeatures(), PopupBlockType::kNoGesture);
  145. EXPECT_TRUE(content_settings->IsContentBlocked(ContentSettingsType::POPUPS));
  146. helper()->AddBlockedPopup(
  147. std::make_unique<TestPopupNavigationDelegate>(GURL(kUrl2), &result),
  148. blink::mojom::WindowFeatures(), PopupBlockType::kNoGesture);
  149. EXPECT_TRUE(content_settings->IsContentBlocked(ContentSettingsType::POPUPS));
  150. helper()->ShowBlockedPopup(0, WindowOpenDisposition::NEW_FOREGROUND_TAB);
  151. EXPECT_TRUE(content_settings->IsContentBlocked(ContentSettingsType::POPUPS));
  152. helper()->ShowBlockedPopup(1, WindowOpenDisposition::NEW_FOREGROUND_TAB);
  153. EXPECT_FALSE(content_settings->IsContentBlocked(ContentSettingsType::POPUPS));
  154. }
  155. TEST_F(PopupBlockerTabHelperTest, ClearsContentSettingsPopupStateOnNavigation) {
  156. TestPopupNavigationDelegate::ResultHolder result;
  157. helper()->AddBlockedPopup(
  158. std::make_unique<TestPopupNavigationDelegate>(GURL(kUrl1), &result),
  159. blink::mojom::WindowFeatures(), PopupBlockType::kNoGesture);
  160. EXPECT_TRUE(content_settings::PageSpecificContentSettings::GetForFrame(
  161. web_contents()->GetPrimaryMainFrame())
  162. ->IsContentBlocked(ContentSettingsType::POPUPS));
  163. NavigateAndCommit(GURL(kUrl2));
  164. EXPECT_FALSE(content_settings::PageSpecificContentSettings::GetForFrame(
  165. web_contents()->GetPrimaryMainFrame())
  166. ->IsContentBlocked(ContentSettingsType::POPUPS));
  167. }
  168. TEST_F(PopupBlockerTabHelperTest,
  169. NavigatingNonPrimaryDoesntClearsContentSettings) {
  170. TestPopupNavigationDelegate::ResultHolder result;
  171. helper()->AddBlockedPopup(
  172. std::make_unique<TestPopupNavigationDelegate>(GURL(kUrl1), &result),
  173. blink::mojom::WindowFeatures(), PopupBlockType::kNoGesture);
  174. EXPECT_TRUE(content_settings::PageSpecificContentSettings::GetForFrame(
  175. web_contents()->GetPrimaryMainFrame())
  176. ->IsContentBlocked(ContentSettingsType::POPUPS));
  177. // Navigating a non-primary main frame shoudn't clear the popups.
  178. content::MockNavigationHandle handle(GURL(kUrl2),
  179. web_contents()->GetPrimaryMainFrame());
  180. handle.set_has_committed(true);
  181. handle.set_is_in_primary_main_frame(false);
  182. helper()->DidFinishNavigation(&handle);
  183. EXPECT_TRUE(content_settings::PageSpecificContentSettings::GetForFrame(
  184. web_contents()->GetPrimaryMainFrame())
  185. ->IsContentBlocked(ContentSettingsType::POPUPS));
  186. // Navigating the primary main frame should clear the popups.
  187. handle.set_is_in_primary_main_frame(true);
  188. helper()->DidFinishNavigation(&handle);
  189. EXPECT_FALSE(content_settings::PageSpecificContentSettings::GetForFrame(
  190. web_contents()->GetPrimaryMainFrame())
  191. ->IsContentBlocked(ContentSettingsType::POPUPS));
  192. }
  193. } // namespace blocked_content