diff options
Diffstat (limited to 'chromium/content/browser/conversions/conversion_host_unittest.cc')
-rw-r--r-- | chromium/content/browser/conversions/conversion_host_unittest.cc | 246 |
1 files changed, 239 insertions, 7 deletions
diff --git a/chromium/content/browser/conversions/conversion_host_unittest.cc b/chromium/content/browser/conversions/conversion_host_unittest.cc index 255587e9365..2769ef893d8 100644 --- a/chromium/content/browser/conversions/conversion_host_unittest.cc +++ b/chromium/content/browser/conversions/conversion_host_unittest.cc @@ -6,31 +6,51 @@ #include <memory> +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "content/browser/conversions/conversion_manager.h" +#include "content/browser/conversions/conversion_test_utils.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/common/content_features.h" #include "content/public/test/test_renderer_host.h" #include "content/test/fake_mojo_message_dispatch_context.h" +#include "content/test/navigation_simulator_impl.h" #include "content/test/test_render_frame_host.h" #include "content/test/test_web_contents.h" #include "mojo/public/cpp/test_support/test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/conversions/conversions.mojom.h" #include "url/gurl.h" #include "url/origin.h" namespace content { +namespace { + +const char kConversionUrl[] = "https://b.com"; + +Impression CreateValidImpression() { + Impression result; + result.conversion_destination = url::Origin::Create(GURL(kConversionUrl)); + result.reporting_origin = url::Origin::Create(GURL("https://c.com")); + result.impression_data = 1UL; + return result; +} + +} // namespace + class ConversionHostTest : public RenderViewHostTestHarness { public: - ConversionHostTest() { - feature_list_.InitAndEnableFeature(features::kConversionMeasurement); - } + ConversionHostTest() = default; void SetUp() override { RenderViewHostTestHarness::SetUp(); static_cast<WebContentsImpl*>(web_contents()) ->RemoveReceiverSetForTesting(blink::mojom::ConversionHost::Name_); - conversion_host_ = std::make_unique<ConversionHost>(web_contents()); + + conversion_host_ = ConversionHost::CreateForTesting( + web_contents(), std::make_unique<TestManagerProvider>(&test_manager_)); contents()->GetMainFrame()->InitializeRenderFrameIfNeeded(); } @@ -40,8 +60,10 @@ class ConversionHostTest : public RenderViewHostTestHarness { ConversionHost* conversion_host() { return conversion_host_.get(); } + protected: + TestConversionManager test_manager_; + private: - base::test::ScopedFeatureList feature_list_; std::unique_ptr<ConversionHost> conversion_host_; }; @@ -64,6 +86,7 @@ TEST_F(ConversionHostTest, ConversionInSubframe_BadMessage) { conversion_host()->RegisterConversion(std::move(conversion)); EXPECT_EQ("blink.mojom.ConversionHost can only be used by the main frame.", bad_message_observer.WaitForBadMessage()); + EXPECT_EQ(0u, test_manager_.num_conversions()); } TEST_F(ConversionHostTest, ConversionOnInsecurePage_BadMessage) { @@ -83,6 +106,7 @@ TEST_F(ConversionHostTest, ConversionOnInsecurePage_BadMessage) { "blink.mojom.ConversionHost can only be used in secure contexts with a " "secure conversion registration origin.", bad_message_observer.WaitForBadMessage()); + EXPECT_EQ(0u, test_manager_.num_conversions()); } TEST_F(ConversionHostTest, ConversionWithInsecureReportingOrigin_BadMessage) { @@ -101,14 +125,15 @@ TEST_F(ConversionHostTest, ConversionWithInsecureReportingOrigin_BadMessage) { "blink.mojom.ConversionHost can only be used in secure contexts with a " "secure conversion registration origin.", bad_message_observer.WaitForBadMessage()); + EXPECT_EQ(0u, test_manager_.num_conversions()); } TEST_F(ConversionHostTest, ValidConversion_NoBadMessage) { - // Create a page with an insecure origin. + // Create a page with a secure origin. contents()->NavigateAndCommit(GURL("https://www.example.com")); conversion_host()->SetCurrentTargetFrameForTesting(main_rfh()); - // Create a fake dispatch context to trigger a bad message in. + // Create a fake dispatch context to listen for bad messages. FakeMojoMessageDispatchContext fake_dispatch_context; mojo::test::BadMessageObserver bad_message_observer; @@ -121,6 +146,213 @@ TEST_F(ConversionHostTest, ValidConversion_NoBadMessage) { // triggered. base::RunLoop().RunUntilIdle(); EXPECT_FALSE(bad_message_observer.got_bad_message()); + EXPECT_EQ(1u, test_manager_.num_conversions()); +} + +TEST_F(ConversionHostTest, PerPageConversionMetrics) { + base::HistogramTester histograms; + + contents()->NavigateAndCommit(GURL("https://www.example.com")); + + // Initial document should not log metrics. + histograms.ExpectTotalCount("Conversions.RegisteredConversionsPerPage", 0); + + conversion_host()->SetCurrentTargetFrameForTesting(main_rfh()); + blink::mojom::ConversionPtr conversion = blink::mojom::Conversion::New(); + conversion->reporting_origin = + url::Origin::Create(GURL("https://secure.com")); + + for (size_t i = 0u; i < 8u; i++) { + conversion_host()->RegisterConversion(conversion->Clone()); + EXPECT_EQ(1u, test_manager_.num_conversions()); + test_manager_.Reset(); + } + + // Same document navs should not reset the counter. + contents()->NavigateAndCommit(GURL("https://www.example.com#hash")); + histograms.ExpectTotalCount("Conversions.RegisteredConversionsPerPage", 0); + + // Re-navigating should reset the counter. + contents()->NavigateAndCommit(GURL("https://www.example-next.com")); + histograms.ExpectUniqueSample("Conversions.RegisteredConversionsPerPage", 8, + 1); +} + +TEST_F(ConversionHostTest, NoManager_NoPerPageConversionMetrics) { + // Replace the ConversionHost on the WebContents with one that is backed by a + // null ConversionManager. + static_cast<WebContentsImpl*>(web_contents()) + ->RemoveReceiverSetForTesting(blink::mojom::ConversionHost::Name_); + auto conversion_host = ConversionHost::CreateForTesting( + web_contents(), std::make_unique<TestManagerProvider>(nullptr)); + contents()->NavigateAndCommit(GURL("https://www.example.com")); + + base::HistogramTester histograms; + conversion_host->SetCurrentTargetFrameForTesting(main_rfh()); + blink::mojom::ConversionPtr conversion = blink::mojom::Conversion::New(); + conversion->reporting_origin = + url::Origin::Create(GURL("https://secure.com")); + conversion_host->RegisterConversion(std::move(conversion)); + + // Navigate again to trigger histogram code. + contents()->NavigateAndCommit(GURL("https://www.example-next.com")); + histograms.ExpectBucketCount("Conversions.RegisteredConversionsPerPage", 1, + 0); +} + +TEST_F(ConversionHostTest, NavigationWithNoImpression_Ignored) { + contents()->NavigateAndCommit(GURL("https://secure_impression.com")); + NavigationSimulatorImpl::NavigateAndCommitFromDocument(GURL(kConversionUrl), + main_rfh()); + + EXPECT_EQ(0u, test_manager_.num_impressions()); +} + +TEST_F(ConversionHostTest, ValidImpression_ForwardedToManager) { + contents()->NavigateAndCommit(GURL("https://secure_impression.com")); + auto navigation = NavigationSimulatorImpl::CreateRendererInitiated( + GURL(kConversionUrl), main_rfh()); + navigation->SetInitiatorFrame(main_rfh()); + navigation->set_impression(CreateValidImpression()); + navigation->Commit(); + + EXPECT_EQ(1u, test_manager_.num_impressions()); +} + +TEST_F(ConversionHostTest, ImpressionWithNoManagerAvilable_NoCrash) { + // Replace the ConversionHost on the WebContents with one that is backed by a + // null ConversionManager. + static_cast<WebContentsImpl*>(web_contents()) + ->RemoveReceiverSetForTesting(blink::mojom::ConversionHost::Name_); + auto conversion_host = ConversionHost::CreateForTesting( + web_contents(), std::make_unique<TestManagerProvider>(nullptr)); + + auto navigation = NavigationSimulatorImpl::CreateRendererInitiated( + GURL(kConversionUrl), main_rfh()); + navigation->SetInitiatorFrame(main_rfh()); + navigation->set_impression(CreateValidImpression()); + navigation->Commit(); +} + +TEST_F(ConversionHostTest, ImpressionInSubframe_Ignored) { + contents()->NavigateAndCommit(GURL("https://secure_impression.com")); + + // Create a subframe and use it as a target for the conversion registration + // mojo. + content::RenderFrameHostTester* rfh_tester = + content::RenderFrameHostTester::For(main_rfh()); + content::RenderFrameHost* subframe = rfh_tester->AppendChild("subframe"); + + auto navigation = NavigationSimulatorImpl::CreateRendererInitiated( + GURL(kConversionUrl), subframe); + navigation->SetInitiatorFrame(main_rfh()); + navigation->set_impression(CreateValidImpression()); + navigation->Commit(); + + EXPECT_EQ(0u, test_manager_.num_impressions()); +} + +// Test that if we cannot access the initiator frame of the navigation, we +// ignore the associated impression. +TEST_F(ConversionHostTest, ImpressionNavigationWithDeadInitiator_Ignored) { + contents()->NavigateAndCommit(GURL("https://secure_impression.com")); + + auto navigation = NavigationSimulatorImpl::CreateRendererInitiated( + GURL(kConversionUrl), main_rfh()); + navigation->set_impression(CreateValidImpression()); + navigation->Commit(); + + EXPECT_EQ(0u, test_manager_.num_impressions()); +} + +TEST_F(ConversionHostTest, ImpressionNavigationCommitsToErrorPage_Ignored) { + contents()->NavigateAndCommit(GURL("https://secure_impression.com")); + + auto navigation = NavigationSimulatorImpl::CreateRendererInitiated( + GURL(kConversionUrl), main_rfh()); + navigation->SetInitiatorFrame(main_rfh()); + navigation->set_impression(CreateValidImpression()); + navigation->Fail(net::ERR_FAILED); + navigation->CommitErrorPage(); + + EXPECT_EQ(0u, test_manager_.num_impressions()); +} + +TEST_F(ConversionHostTest, ImpressionNavigationAborts_Ignored) { + contents()->NavigateAndCommit(GURL("https://secure_impression.com")); + + auto navigation = NavigationSimulatorImpl::CreateRendererInitiated( + GURL(kConversionUrl), main_rfh()); + navigation->SetInitiatorFrame(main_rfh()); + navigation->set_impression(CreateValidImpression()); + navigation->AbortCommit(); + + EXPECT_EQ(0u, test_manager_.num_impressions()); +} + +TEST_F(ConversionHostTest, + CommittedOriginDiffersFromConversionDesintation_Ignored) { + contents()->NavigateAndCommit(GURL("https://secure_impression.com")); + + auto navigation = NavigationSimulatorImpl::CreateRendererInitiated( + GURL("https://different.com"), main_rfh()); + navigation->SetInitiatorFrame(main_rfh()); + navigation->set_impression(CreateValidImpression()); + navigation->Commit(); + + EXPECT_EQ(0u, test_manager_.num_impressions()); +} + +TEST_F(ConversionHostTest, + ImpressionNavigation_OriginTrustworthyChecksPerformed) { + const char kLocalHost[] = "http://localhost"; + + struct { + std::string impression_origin; + std::string conversion_origin; + std::string reporting_origin; + bool impression_expected; + } kTestCases[] = { + {kLocalHost /* impression_origin */, kLocalHost /* conversion_origin */, + kLocalHost /* reporting_origin */, true /* impression_expected */}, + {"http://127.0.0.1" /* impression_origin */, + "http://127.0.0.1" /* conversion_origin */, + "http://127.0.0.1" /* reporting_origin */, + true /* impression_expected */}, + {kLocalHost /* impression_origin */, kLocalHost /* conversion_origin */, + "http://insecure.com" /* reporting_origin */, + false /* impression_expected */}, + {kLocalHost /* impression_origin */, + "http://insecure.com" /* conversion_origin */, + kLocalHost /* reporting_origin */, false /* impression_expected */}, + {"http://insecure.com" /* impression_origin */, + kLocalHost /* conversion_origin */, kLocalHost /* reporting_origin */, + false /* impression_expected */}, + {"https://secure.com" /* impression_origin */, + "https://secure.com" /* conversion_origin */, + "https://secure.com" /* reporting_origin */, + true /* impression_expected */}, + }; + + for (const auto& test_case : kTestCases) { + contents()->NavigateAndCommit(GURL(test_case.impression_origin)); + auto navigation = NavigationSimulatorImpl::CreateRendererInitiated( + GURL(test_case.conversion_origin), main_rfh()); + + Impression impression; + impression.conversion_destination = + url::Origin::Create(GURL(test_case.conversion_origin)); + impression.reporting_origin = + url::Origin::Create(GURL(test_case.reporting_origin)); + navigation->set_impression(impression); + navigation->SetInitiatorFrame(main_rfh()); + navigation->Commit(); + + EXPECT_EQ(test_case.impression_expected, test_manager_.num_impressions()) + << "For test case: " << test_case.impression_origin << " | " + << test_case.conversion_origin << " | " << test_case.reporting_origin; + test_manager_.Reset(); + } } } // namespace content |