blob: e8b086f8459764647787d57eb44395e2a790b1c6 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/contextual_cueing/contextual_cueing_page_data.h"
#include "base/test/test_future.h"
#include "chrome/browser/contextual_cueing/contextual_cueing_enums.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/web_contents_tester.h"
namespace contextual_cueing {
class ContextualCueingPageDataTest : public ChromeRenderViewHostTestHarness {
public:
void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp();
web_contents_ = CreateTestWebContents();
}
void TearDown() override {
web_contents_.reset();
ChromeRenderViewHostTestHarness::TearDown();
}
void InvokePdfPageCountReceived(size_t page_count) {
auto* page_data =
ContextualCueingPageData::GetForPage(web_contents_->GetPrimaryPage());
page_data->OnPdfPageCountReceived(
pdf::mojom::PdfListener::GetPdfBytesStatus::kSuccess, {}, page_count);
}
protected:
std::unique_ptr<content::WebContents> web_contents_;
};
TEST_F(ContextualCueingPageDataTest, Basic) {
base::test::TestFuture<
base::expected<std::string, contextual_cueing::NudgeDecision>>
future;
optimization_guide::proto::GlicContextualCueingMetadata metadata;
auto* config = metadata.add_cueing_configurations();
config->set_cue_label("basic label");
ContextualCueingPageData::CreateForPage(web_contents_->GetPrimaryPage(),
std::move(metadata),
future.GetCallback());
ASSERT_TRUE(future.Wait());
EXPECT_EQ("basic label", future.Get().value());
}
TEST_F(ContextualCueingPageDataTest, EarlyDestruction) {
base::test::TestFuture<
base::expected<std::string, contextual_cueing::NudgeDecision>>
future;
optimization_guide::proto::GlicContextualCueingMetadata metadata;
auto* config = metadata.add_cueing_configurations();
config->set_cue_label("basic label");
// Use a page content condition to prevent the callback from being invoked
// immediately.
auto* condition = config->add_conditions();
condition->set_signal(
optimization_guide::proto::ContextualCueingClientSignal::
CONTEXTUAL_CUEING_CLIENT_SIGNAL_CONTENT_LENGTH_WORD_COUNT);
condition->set_cueing_operator(
optimization_guide::proto::ContextualCueingOperator::
CONTEXTUAL_CUEING_OPERATOR_GREATER_THAN_OR_EQUAL_TO);
condition->set_int64_threshold(1000);
ContextualCueingPageData::CreateForPage(web_contents_->GetPrimaryPage(),
std::move(metadata),
future.GetCallback());
ContextualCueingPageData::DeleteForPage(web_contents_->GetPrimaryPage());
ASSERT_TRUE(future.Wait());
EXPECT_EQ(NudgeDecision::kNudgeDecisionInterrupted, future.Get().error());
}
TEST_F(ContextualCueingPageDataTest, NonPdfPageFails) {
base::test::TestFuture<
base::expected<std::string, contextual_cueing::NudgeDecision>>
future;
optimization_guide::proto::GlicContextualCueingMetadata metadata;
auto* config = metadata.add_cueing_configurations();
config->set_cue_label("basic label");
auto* pdf_condition = config->add_conditions();
pdf_condition->set_cueing_operator(
optimization_guide::proto::ContextualCueingOperator::
CONTEXTUAL_CUEING_OPERATOR_GREATER_THAN_OR_EQUAL_TO);
pdf_condition->set_int64_threshold(2);
ContextualCueingPageData::CreateForPage(web_contents_->GetPrimaryPage(),
std::move(metadata),
future.GetCallback());
ASSERT_TRUE(future.Wait());
EXPECT_EQ(future.Get().error(),
contextual_cueing::NudgeDecision::kClientConditionsUnmet);
}
TEST_F(ContextualCueingPageDataTest, PdfPageCountFails) {
content::WebContentsTester::For(web_contents_.get())
->SetMainFrameMimeType(pdf::kPDFMimeType);
base::test::TestFuture<
base::expected<std::string, contextual_cueing::NudgeDecision>>
future;
optimization_guide::proto::GlicContextualCueingMetadata metadata;
auto* config = metadata.add_cueing_configurations();
config->set_cue_label("pdf label");
auto* pdf_condition = config->add_conditions();
pdf_condition->set_signal(optimization_guide::proto::
CONTEXTUAL_CUEING_CLIENT_SIGNAL_PDF_PAGE_COUNT);
pdf_condition->set_cueing_operator(
optimization_guide::proto::ContextualCueingOperator::
CONTEXTUAL_CUEING_OPERATOR_GREATER_THAN_OR_EQUAL_TO);
pdf_condition->set_int64_threshold(2);
ContextualCueingPageData::CreateForPage(web_contents_->GetPrimaryPage(),
std::move(metadata),
future.GetCallback());
InvokePdfPageCountReceived(1);
ASSERT_TRUE(future.Wait());
EXPECT_EQ(future.Get().error(),
contextual_cueing::NudgeDecision::kClientConditionsUnmet);
}
TEST_F(ContextualCueingPageDataTest, PdfPageCountPasses) {
content::WebContentsTester::For(web_contents_.get())
->SetMainFrameMimeType(pdf::kPDFMimeType);
base::test::TestFuture<
base::expected<std::string, contextual_cueing::NudgeDecision>>
future;
optimization_guide::proto::GlicContextualCueingMetadata metadata;
auto* config = metadata.add_cueing_configurations();
config->set_cue_label("pdf label");
auto* pdf_condition = config->add_conditions();
pdf_condition->set_signal(optimization_guide::proto::
CONTEXTUAL_CUEING_CLIENT_SIGNAL_PDF_PAGE_COUNT);
pdf_condition->set_cueing_operator(
optimization_guide::proto::ContextualCueingOperator::
CONTEXTUAL_CUEING_OPERATOR_GREATER_THAN_OR_EQUAL_TO);
pdf_condition->set_int64_threshold(2);
ContextualCueingPageData::CreateForPage(web_contents_->GetPrimaryPage(),
std::move(metadata),
future.GetCallback());
InvokePdfPageCountReceived(4);
ASSERT_TRUE(future.Wait());
EXPECT_EQ("pdf label", future.Get().value());
}
TEST_F(ContextualCueingPageDataTest, BasicAndPdfPageCountCondition) {
content::WebContentsTester::For(web_contents_.get())
->SetMainFrameMimeType(pdf::kPDFMimeType);
base::test::TestFuture<
base::expected<std::string, contextual_cueing::NudgeDecision>>
future;
optimization_guide::proto::GlicContextualCueingMetadata metadata;
auto* config = metadata.add_cueing_configurations();
config->set_cue_label("pdf label");
auto* pdf_condition = config->add_conditions();
pdf_condition->set_signal(optimization_guide::proto::
CONTEXTUAL_CUEING_CLIENT_SIGNAL_PDF_PAGE_COUNT);
pdf_condition->set_cueing_operator(
optimization_guide::proto::ContextualCueingOperator::
CONTEXTUAL_CUEING_OPERATOR_GREATER_THAN_OR_EQUAL_TO);
pdf_condition->set_int64_threshold(2);
// Second basic condition should get picked.
config = metadata.add_cueing_configurations();
config->set_cue_label("basic label");
ContextualCueingPageData::CreateForPage(web_contents_->GetPrimaryPage(),
std::move(metadata),
future.GetCallback());
ASSERT_TRUE(future.Wait());
EXPECT_EQ("basic label", future.Get().value());
}
} // namespace contextual_cueing