Skip to content

Commit

Permalink
Add Brave Ads status header to search.brave.com calls.
Browse files Browse the repository at this point in the history
  • Loading branch information
aseren committed Sep 22, 2022
1 parent 8ce3b9e commit fea0b18
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 1 deletion.
13 changes: 12 additions & 1 deletion browser/brave_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "base/json/json_reader.h"
#include "base/strings/strcat.h"
#include "base/system/sys_info.h"
#include "brave/browser/brave_ads/ads_service_factory.h"
#include "brave/browser/brave_ads/brave_ads_host.h"
#include "brave/browser/brave_browser_main_extra_parts.h"
#include "brave/browser/brave_browser_process.h"
Expand All @@ -34,6 +35,7 @@
#include "brave/browser/profiles/profile_util.h"
#include "brave/browser/skus/skus_service_factory.h"
#include "brave/components/binance/browser/buildflags/buildflags.h"
#include "brave/components/brave_ads/browser/ads_status_header_throttle.h"
#include "brave/components/brave_ads/common/features.h"
#include "brave/components/brave_federated/features.h"
#include "brave/components/brave_rewards/browser/rewards_protocol_handler.h"
Expand Down Expand Up @@ -770,12 +772,21 @@ BraveContentBrowserClient::CreateURLLoaderThrottles(
}
#endif // ENABLE_SPEEDREADER

// De-AMP
if (isMainFrame) {
// De-AMP
if (auto de_amp_throttle = de_amp::DeAmpThrottle::MaybeCreateThrottleFor(
base::ThreadTaskRunnerHandle::Get(), request, wc_getter)) {
result.push_back(std::move(de_amp_throttle));
}

brave_ads::AdsService* ads_service =
brave_ads::AdsServiceFactory::GetForProfile(
Profile::FromBrowserContext(browser_context));
if (auto ads_status_header_throttle =
brave_ads::AdsStatusHeaderThrottle::MaybeCreateThrottle(
ads_service, request)) {
result.push_back(std::move(ads_status_header_throttle));
}
}
}

Expand Down
37 changes: 37 additions & 0 deletions browser/brave_search/brave_search_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@

#include <memory>

#include "base/callback.h"
#include "base/containers/contains.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/thread_test_helper.h"
#include "bat/ads/pref_names.h"
#include "brave/components/brave_search/browser/brave_search_fallback_host.h"
#include "brave/components/brave_search/common/features.h"
#include "brave/components/constants/brave_paths.h"
Expand All @@ -20,6 +23,7 @@
#include "chrome/test/base/search_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/prefs/pref_service.h"
#include "components/search_engines/template_url_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/browser_test.h"
Expand All @@ -30,13 +34,17 @@
#include "net/test/embedded_test_server/http_response.h"

using extensions::ExtensionBrowserTest;
using RequestExpectationsCallback =
base::RepeatingCallback<void(const net::test_server::HttpRequest& request)>;

namespace {

const char kEmbeddedTestServerDirectory[] = "brave-search";
const char kAllowedDomain[] = "search.brave.com";
const char kAllowedDomainDev[] = "search-dev.brave.com";
const char kNotAllowedDomain[] = "brave.com";
const char kAdsStatusHeaderName[] = "X-Brave-Ads-Enabled";
const char kAdsStatusHeaderValue[] = "1";
const char kBackupSearchContent[] = "<html><body>results</body></html>";
const char kScriptDefaultAPIExists[] =
"window.domAutomationController.send("
Expand Down Expand Up @@ -119,6 +127,10 @@ class BraveSearchTest : public InProcessBrowserTest {

std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
const net::test_server::HttpRequest& request) {
if (request_expectations_callback_) {
request_expectations_callback_.Run(request);
}

GURL url = request.GetURL();
auto path = url.path_piece();

Expand All @@ -141,10 +153,15 @@ class BraveSearchTest : public InProcessBrowserTest {

net::EmbeddedTestServer* https_server() { return https_server_.get(); }

void SetRequestExpectationsCallback(RequestExpectationsCallback callback) {
request_expectations_callback_ = std::move(callback);
}

protected:
base::test::ScopedFeatureList feature_list_;

private:
RequestExpectationsCallback request_expectations_callback_;
content::ContentMockCertVerifier mock_cert_verifier_;
std::unique_ptr<net::EmbeddedTestServer> https_server_;
};
Expand Down Expand Up @@ -301,3 +318,23 @@ IN_PROC_BROWSER_TEST_F(BraveSearchTestDisabled, DefaultAPIInvisibleKnownHost) {
ExecuteScriptAndExtractBool(contents, kScriptDefaultAPIExists, &has_api));
EXPECT_FALSE(has_api);
}

IN_PROC_BROWSER_TEST_F(BraveSearchTest, AdsStatusHeader) {
SetRequestExpectationsCallback(
base::BindRepeating([](const net::test_server::HttpRequest& request) {
const GURL url = request.GetURL();
if (url.path_piece() == "/bravesearch.html") {
EXPECT_TRUE(base::Contains(request.headers, kAdsStatusHeaderName));
EXPECT_EQ(kAdsStatusHeaderValue,
request.headers.at(kAdsStatusHeaderName));
} else {
EXPECT_FALSE(base::Contains(request.headers, kAdsStatusHeaderName));
}
}));

PrefService* prefs = browser()->profile()->GetPrefs();
prefs->SetBoolean(ads::prefs::kEnabled, true);

GURL url = https_server()->GetURL(kAllowedDomain, "/bravesearch.html");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
}
3 changes: 3 additions & 0 deletions components/brave_ads/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ source_set("browser") {
"ads_service.cc",
"ads_service.h",
"ads_service_observer.h",
"ads_status_header_throttle.cc",
"ads_status_header_throttle.h",
"ads_storage_cleanup.cc",
"ads_storage_cleanup.h",
"component_updater/component_info.cc",
Expand Down Expand Up @@ -36,6 +38,7 @@ source_set("browser") {
"//components/prefs",
"//components/sessions",
"//sql",
"//third_party/blink/public/common",
"//url",
]

Expand Down
1 change: 1 addition & 0 deletions components/brave_ads/browser/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ include_rules = [
"+brave/components/constants",
"+content/public/browser",
"+services/network/public",
"+third_party/blink/public",
"+ui/base",
"+ui/message_center/public",
]
Expand Down
51 changes: 51 additions & 0 deletions components/brave_ads/browser/ads_status_header_throttle.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* Copyright 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "brave/components/brave_ads/browser/ads_status_header_throttle.h"

#include "brave/components/brave_ads/browser/ads_service.h"
#include "brave/components/brave_search/common/brave_search_utils.h"
#include "services/network/public/cpp/resource_request.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"

namespace {

constexpr char kAdsStatusHeader[] = "X-Brave-Ads-Enabled";
constexpr char kAdsEnabledStatusValue[] = "1";

} // namespace

namespace brave_ads {

// static
std::unique_ptr<blink::URLLoaderThrottle>
AdsStatusHeaderThrottle::MaybeCreateThrottle(
const AdsService* ads_service,
const network::ResourceRequest& request) {
DCHECK_EQ(request.resource_type,
static_cast<int>(blink::mojom::ResourceType::kMainFrame));
if (!ads_service || !ads_service->IsEnabled() ||
!request.is_outermost_main_frame ||
!brave_search::IsAllowedHost(request.url)) {
return nullptr;
}

return std::make_unique<AdsStatusHeaderThrottle>();
}

AdsStatusHeaderThrottle::AdsStatusHeaderThrottle() = default;

AdsStatusHeaderThrottle::~AdsStatusHeaderThrottle() = default;

void AdsStatusHeaderThrottle::WillStartRequest(
network::ResourceRequest* request,
bool* /* defer */) {
DCHECK(request);
DCHECK(brave_search::IsAllowedHost(request->url));

request->headers.SetHeader(kAdsStatusHeader, kAdsEnabledStatusValue);
}

} // namespace brave_ads
42 changes: 42 additions & 0 deletions components/brave_ads/browser/ads_status_header_throttle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* Copyright 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_COMPONENTS_BRAVE_ADS_BROWSER_ADS_STATUS_HEADER_THROTTLE_H_
#define BRAVE_COMPONENTS_BRAVE_ADS_BROWSER_ADS_STATUS_HEADER_THROTTLE_H_

#include <memory>

#include "third_party/blink/public/common/loader/url_loader_throttle.h"

namespace network {
struct ResourceRequest;
} // namespace network

namespace brave_ads {

class AdsService;

class AdsStatusHeaderThrottle : public blink::URLLoaderThrottle {
public:
static std::unique_ptr<blink::URLLoaderThrottle> MaybeCreateThrottle(
const AdsService* ads_service,
const network::ResourceRequest& request);

AdsStatusHeaderThrottle();
~AdsStatusHeaderThrottle() override;

AdsStatusHeaderThrottle(const AdsStatusHeaderThrottle&) = delete;
AdsStatusHeaderThrottle& operator=(const AdsStatusHeaderThrottle&) = delete;
AdsStatusHeaderThrottle(AdsStatusHeaderThrottle&&) = delete;
AdsStatusHeaderThrottle& operator=(AdsStatusHeaderThrottle&&) = delete;

// Implements blink::URLLoaderThrottle:
void WillStartRequest(network::ResourceRequest* request,
bool* defer) override;
};

} // namespace brave_ads

#endif // BRAVE_COMPONENTS_BRAVE_ADS_BROWSER_ADS_STATUS_HEADER_THROTTLE_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* Copyright (c) 2022 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <string>

#include "brave/components/brave_ads/browser/ads_service.h"
#include "brave/components/brave_ads/browser/ads_status_header_throttle.h"
#include "brave/components/brave_ads/browser/mock_ads_service.h"
#include "services/network/public/cpp/resource_request.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"

using ::testing::Return;

namespace {

constexpr char kAdsStatusHeader[] = "X-Brave-Ads-Enabled";
constexpr char kAdsEnabledStatusValue[] = "1";
constexpr char kAllowedURL[] = "https://search.brave.com/search";
constexpr char kNotAllowedURL[] = "https://brave.com/search";
constexpr char kTestingHeaderName[] = "TestingHeaderName";
constexpr char kTestingHeaderValue[] = "TestingHeaderValue";

} // namespace

namespace brave_ads {

class AdsStatusHeaderThrottleTest : public ::testing::Test {
public:
void SetUp() override {
ON_CALL(mock_ads_service_, IsEnabled()).WillByDefault(Return(true));
}

const AdsService* GetAdsService() const { return &mock_ads_service_; }

network::ResourceRequest BuildRequest() {
network::ResourceRequest request;
request.url = GURL(kAllowedURL);
request.is_outermost_main_frame = true;
request.headers.SetHeader("TestingHeaderName", "TestingHeaderValue");
return request;
}

private:
MockAdsService mock_ads_service_;
};

TEST_F(AdsStatusHeaderThrottleTest, AdsEnabledForAllowedHost) {
network::ResourceRequest request = BuildRequest();
auto throttle =
AdsStatusHeaderThrottle::MaybeCreateThrottle(GetAdsService(), request);
ASSERT_TRUE(throttle);
bool defer = false;
throttle->WillStartRequest(&request, &defer);
EXPECT_FALSE(defer);
std::string value;
EXPECT_TRUE(request.headers.GetHeader(kAdsStatusHeader, &value));
EXPECT_EQ(kAdsEnabledStatusValue, value);
EXPECT_TRUE(request.headers.GetHeader(kTestingHeaderName, &value));
EXPECT_EQ(kTestingHeaderValue, value);
}

TEST_F(AdsStatusHeaderThrottleTest, AdsDisabledForAllowedHost) {
network::ResourceRequest request = BuildRequest();
MockAdsService ads_service;
EXPECT_CALL(ads_service, IsEnabled()).WillOnce(Return(false));
auto throttle =
AdsStatusHeaderThrottle::MaybeCreateThrottle(&ads_service, request);
EXPECT_FALSE(throttle);
}

TEST_F(AdsStatusHeaderThrottleTest, IncognitoModeForAllowedHost) {
network::ResourceRequest request = BuildRequest();
auto throttle =
AdsStatusHeaderThrottle::MaybeCreateThrottle(nullptr, request);
EXPECT_FALSE(throttle);
}

TEST_F(AdsStatusHeaderThrottleTest, AdsEnabledForNotAllowedHost) {
network::ResourceRequest request = BuildRequest();
request.url = GURL(kNotAllowedURL);
auto throttle =
AdsStatusHeaderThrottle::MaybeCreateThrottle(GetAdsService(), request);
EXPECT_FALSE(throttle);
}

TEST_F(AdsStatusHeaderThrottleTest, NonOutermostMainFrameNavigation) {
network::ResourceRequest request = BuildRequest();
request.is_outermost_main_frame = false;
auto throttle =
AdsStatusHeaderThrottle::MaybeCreateThrottle(GetAdsService(), request);
EXPECT_FALSE(throttle);
}

} // namespace brave_ads
1 change: 1 addition & 0 deletions test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ test("brave_unit_tests") {
"//brave/chromium_src/services/network/public/cpp/cors/cors_unittest.cc",
"//brave/common/brave_content_client_unittest.cc",
"//brave/components/assist_ranker/ranker_model_loader_impl_unittest.cc",
"//brave/components/brave_ads/browser/ads_status_header_throttle_unittest.cc",
"//brave/components/brave_ads/common/search_result_ad_util_unittest.cc",
"//brave/components/brave_ads/content/browser/search_result_ad/search_result_ad_parsing_unittest.cc",
"//brave/components/brave_perf_predictor/browser/bandwidth_linreg_unittest.cc",
Expand Down

0 comments on commit fea0b18

Please sign in to comment.