diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc | 230 |
1 files changed, 218 insertions, 12 deletions
diff --git a/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc b/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc index d7de5d47bfc..68ca2035ba3 100644 --- a/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc +++ b/chromium/third_party/blink/renderer/core/frame/ad_tracker_test.cc @@ -4,12 +4,15 @@ #include "third_party/blink/renderer/core/frame/ad_tracker.h" +#include <memory> + #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" - -#include <memory> +#include "third_party/blink/renderer/core/testing/sim/sim_request.h" +#include "third_party/blink/renderer/core/testing/sim/sim_test.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" namespace blink { @@ -18,18 +21,54 @@ namespace { class TestAdTracker : public AdTracker { public: explicit TestAdTracker(LocalFrame* frame) : AdTracker(frame) {} - void SetScriptAtTopOfStack(String url) { script_at_top_ = url; } + void SetScriptAtTopOfStack(const String& url) { script_at_top_ = url; } + void SetExecutionContext(ExecutionContext* execution_context) { + execution_context_ = execution_context; + } + + void SetAdSuffix(const String& ad_suffix) { ad_suffix_ = ad_suffix; } ~TestAdTracker() override {} + void Trace(Visitor* visitor) override { + visitor->Trace(execution_context_); + AdTracker::Trace(visitor); + } + protected: - // Returns "" by default unless SetScriptAtTopOfStack is called with - // something else. String ScriptAtTopOfStack(ExecutionContext* execution_context) override { + if (script_at_top_.IsEmpty()) + return AdTracker::ScriptAtTopOfStack(execution_context); + return script_at_top_; } + ExecutionContext* GetCurrentExecutionContext() override { + if (!execution_context_) + return AdTracker::GetCurrentExecutionContext(); + + return execution_context_; + } + + void WillSendRequest(ExecutionContext* execution_context, + unsigned long identifier, + DocumentLoader* document_loader, + ResourceRequest& resource_request, + const ResourceResponse& redirect_response, + const FetchInitiatorInfo& fetch_initiator_info, + Resource::Type resource_type) override { + if (!ad_suffix_.IsEmpty() && + resource_request.Url().GetString().EndsWith(ad_suffix_)) { + resource_request.SetIsAdResource(); + } + AdTracker::WillSendRequest(execution_context, identifier, document_loader, + resource_request, redirect_response, + fetch_initiator_info, resource_type); + } + private: String script_at_top_; + Member<ExecutionContext> execution_context_; + String ad_suffix_; }; } // namespace @@ -43,15 +82,16 @@ class AdTrackerTest : public testing::Test { } void WillExecuteScript(const String& script_url) { - ad_tracker_->WillExecuteScript(script_url); + ad_tracker_->WillExecuteScript(&page_holder_->GetDocument(), + String(script_url)); } bool AnyExecutingScriptsTaggedAsAdResource() { - return ad_tracker_->IsAdScriptInStack(&page_holder_->GetDocument()); + return ad_tracker_->IsAdScriptInStack(); } - void AppendToKnownAdScripts(const KURL& url) { - ad_tracker_->AppendToKnownAdScripts(url); + void AppendToKnownAdScripts(const String& url) { + ad_tracker_->AppendToKnownAdScripts(page_holder_->GetDocument(), url); } Persistent<TestAdTracker> ad_tracker_; @@ -62,6 +102,7 @@ void AdTrackerTest::SetUp() { page_holder_ = DummyPageHolder::Create(IntSize(800, 600)); page_holder_->GetDocument().SetURL(KURL("https://example.com/foo")); ad_tracker_ = new TestAdTracker(GetFrame()); + ad_tracker_->SetExecutionContext(&page_holder_->GetDocument()); } void AdTrackerTest::TearDown() { @@ -69,7 +110,7 @@ void AdTrackerTest::TearDown() { } TEST_F(AdTrackerTest, AnyExecutingScriptsTaggedAsAdResource) { - KURL ad_script_url("https://example.com/bar.js"); + String ad_script_url("https://example.com/bar.js"); AppendToKnownAdScripts(ad_script_url); WillExecuteScript("https://example.com/foo.js"); @@ -86,7 +127,7 @@ TEST_F(AdTrackerTest, AnyExecutingScriptsTaggedAsAdResource_False) { } TEST_F(AdTrackerTest, TopOfStackIncluded) { - KURL ad_script_url("https://example.com/ad.js"); + String ad_script_url("https://example.com/ad.js"); AppendToKnownAdScripts(ad_script_url); WillExecuteScript("https://example.com/foo.js"); @@ -105,11 +146,176 @@ TEST_F(AdTrackerTest, TopOfStackIncluded) { ad_tracker_->SetScriptAtTopOfStack(""); EXPECT_FALSE(AnyExecutingScriptsTaggedAsAdResource()); - ad_tracker_->SetScriptAtTopOfStack(WTF::String()); + ad_tracker_->SetScriptAtTopOfStack(String()); EXPECT_FALSE(AnyExecutingScriptsTaggedAsAdResource()); WillExecuteScript(ad_script_url); EXPECT_TRUE(AnyExecutingScriptsTaggedAsAdResource()); } +class AdTrackerSimTest : public SimTest { + protected: + void SetUp() override { + SimTest::SetUp(); + main_resource_ = std::make_unique<SimRequest>( + "https://example.com/test.html", "text/html"); + + LoadURL("https://example.com/test.html"); + main_resource_->Start(); + ad_tracker_ = new TestAdTracker(GetDocument().GetFrame()); + GetDocument().GetFrame()->SetAdTrackerForTesting(ad_tracker_); + } + + void TearDown() override { + ad_tracker_->Shutdown(); + SimTest::TearDown(); + } + + bool IsKnownAdScript(ExecutionContext* execution_context, const String& url) { + return ad_tracker_->IsKnownAdScript(execution_context, url); + } + + std::unique_ptr<SimRequest> main_resource_; + Persistent<TestAdTracker> ad_tracker_; +}; + +// Resources loaded by ad script are tagged as ads. +TEST_F(AdTrackerSimTest, ResourceLoadedWhileExecutingAdScript) { + SimRequest ad_resource("https://example.com/ad_script.js", "text/javascript"); + SimRequest vanilla_script("https://example.com/vanilla_script.js", + "text/javascript"); + + ad_tracker_->SetAdSuffix("ad_script.js"); + + main_resource_->Complete("<body></body><script src=ad_script.js></script>"); + + ad_resource.Complete(R"SCRIPT( + script = document.createElement("script"); + script.src = "vanilla_script.js"; + document.body.appendChild(script); + )SCRIPT"); + vanilla_script.Complete(""); + + EXPECT_TRUE(IsKnownAdScript(&GetDocument(), + String("https://example.com/ad_script.js"))); + EXPECT_TRUE(IsKnownAdScript(&GetDocument(), + String("https://example.com/vanilla_script.js"))); +} + +// A script tagged as an ad in one frame shouldn't cause it to be considered +// an ad when executed in another frame. +TEST_F(AdTrackerSimTest, Contexts) { + // Load a page that loads library.js. It also creates an iframe that also + // loads library.js (where it gets tagged as an ad). Even though library.js + // gets tagged as an ad script in the subframe, that shouldn't cause it to + // be treated as an ad in the main frame. + SimRequest iframe_resource("https://example.com/iframe.html", "text/html"); + SimRequest library_resource("https://example.com/library.js", + "text/javascript"); + + main_resource_->Complete(R"HTML( + <script src=library.js></script> + <iframe src=iframe.html></iframe> + )HTML"); + + // Complete the main frame's library.js. + library_resource.Complete(""); + + // The library script is loaded for a second time, this time in the + // subframe. Mark it as an ad. + SimRequest library_resource_for_subframe("https://example.com/library.js", + "text/javascript"); + ad_tracker_->SetAdSuffix("library.js"); + + iframe_resource.Complete(R"HTML( + <script src="library.js"></script> + )HTML"); + library_resource_for_subframe.Complete(""); + + // Verify that library.js is an ad script in the subframe's context but not + // in the main frame's context. + Frame* subframe = GetDocument().GetFrame()->Tree().FirstChild(); + ASSERT_TRUE(subframe->IsLocalFrame()); + LocalFrame* local_subframe = ToLocalFrame(subframe); + EXPECT_TRUE(IsKnownAdScript(local_subframe->GetDocument(), + String("https://example.com/library.js"))); + + EXPECT_FALSE(IsKnownAdScript(&GetDocument(), + String("https://example.com/library.js"))); +} + +TEST_F(AdTrackerSimTest, SameOriginSubframeFromAdScript) { + SimRequest ad_resource("https://example.com/ad_script.js", "text/javascript"); + SimRequest iframe_resource("https://example.com/iframe.html", "text/html"); + ad_tracker_->SetAdSuffix("ad_script.js"); + + main_resource_->Complete(R"HTML( + <body></body><script src=ad_script.js></script> + )HTML"); + ad_resource.Complete(R"SCRIPT( + var iframe = document.createElement("iframe"); + iframe.src = "iframe.html"; + document.body.appendChild(iframe); + )SCRIPT"); + + iframe_resource.Complete("iframe data"); + + Frame* subframe = GetDocument().GetFrame()->Tree().FirstChild(); + ASSERT_TRUE(subframe->IsLocalFrame()); + LocalFrame* local_subframe = ToLocalFrame(subframe); + EXPECT_TRUE(local_subframe->IsAdSubframe()); +} + +TEST_F(AdTrackerSimTest, SameOriginDocWrittenSubframeFromAdScript) { + SimRequest ad_resource("https://example.com/ad_script.js", "text/javascript"); + ad_tracker_->SetAdSuffix("ad_script.js"); + + main_resource_->Complete(R"HTML( + <body></body><script src=ad_script.js></script> + )HTML"); + ad_resource.Complete(R"SCRIPT( + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + var iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write("iframe data"); + iframeDocument.close(); + )SCRIPT"); + + Frame* subframe = GetDocument().GetFrame()->Tree().FirstChild(); + ASSERT_TRUE(subframe->IsLocalFrame()); + LocalFrame* local_subframe = ToLocalFrame(subframe); + EXPECT_TRUE(local_subframe->IsAdSubframe()); +} + +class AdTrackerDisabledSimTest : public SimTest { + protected: + void SetUp() override { + RuntimeEnabledFeatures::SetAdTaggingEnabled(false); + + SimTest::SetUp(); + main_resource_ = std::make_unique<SimRequest>( + "https://example.com/test.html", "text/html"); + + LoadURL("https://example.com/test.html"); + main_resource_->Start(); + } + + void TearDown() override { SimTest::TearDown(); } + + std::unique_ptr<SimRequest> main_resource_; +}; + +TEST_F(AdTrackerDisabledSimTest, ResourceLoadedWhenAdTaggingDisabled) { + SimRequest iframe_resource("https://example.com/iframe.html", "text/html"); + + main_resource_->Complete(R"HTML( + <iframe src=https://example.com/iframe.html></iframe> + )HTML"); + + iframe_resource.Complete("<body></body>"); + + EXPECT_FALSE(GetDocument().GetFrame()->IsAdSubframe()); +} + } // namespace blink |