summaryrefslogtreecommitdiff
path: root/chromium/content/browser/conversions/conversion_host_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/conversions/conversion_host_unittest.cc')
-rw-r--r--chromium/content/browser/conversions/conversion_host_unittest.cc246
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