// Copyright 2024 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/ash/growth/show_nudge_action_performer.h"
#include <memory>
#include <optional>
#include "base/json/json_reader.h"
#include "base/run_loop.h"
#include "base/scoped_observation.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/ash/growth/campaigns_manager_client_impl.h"
#include "chrome/browser/ash/growth/metrics.h"
#include "chrome/browser/ash/growth/mock_ui_performer_observer.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
constexpr char kNudgePayloadTemplate[] = R"(
{
"clearEvents": ["event"],
"title": "title",
"%s": "text"
}
)";
} // namespace
class ShowNudgeActionPerformerTest : public testing::Test {
public:
ShowNudgeActionPerformerTest()
: profile_manager_(std::make_unique<TestingProfileManager>(
TestingBrowserProcess::GetGlobal())) {}
ShowNudgeActionPerformerTest(const ShowNudgeActionPerformerTest&) = delete;
ShowNudgeActionPerformerTest& operator=(const ShowNudgeActionPerformerTest&) =
delete;
~ShowNudgeActionPerformerTest() override = default;
void SetUp() override {
ASSERT_TRUE(profile_manager_->SetUp());
action_ = std::make_unique<ShowNudgeActionPerformer>();
scoped_observation_.Observe(action_.get());
}
void TearDown() override {
scoped_observation_.Reset();
profile_manager_->DeleteAllTestingProfiles();
}
ShowNudgeActionPerformer& action() { return *action_; }
void RunActionPerformerCallback(
growth::ActionResult result,
std::optional<growth::ActionResultReason> reason) {
if (result == growth::ActionResult::kSuccess) {
std::move(action_success_closure_).Run();
} else {
std::move(action_failed_closure_).Run();
}
}
bool VerifyActionResult(bool success) {
if (success) {
action_success_run_loop_.Run();
} else {
action_failed_run_loop_.Run();
}
return true;
}
protected:
MockUiPerformerObserver mock_observer_;
private:
content::BrowserTaskEnvironment task_environment_;
base::RunLoop action_success_run_loop_;
base::RunLoop action_failed_run_loop_;
base::OnceClosure action_success_closure_ =
action_success_run_loop_.QuitClosure();
base::OnceClosure action_failed_closure_ =
action_failed_run_loop_.QuitClosure();
std::unique_ptr<ShowNudgeActionPerformer> action_;
base::ScopedObservation<UiActionPerformer, UiActionPerformer::Observer>
scoped_observation_{&mock_observer_};
CampaignsManagerClientImpl client_;
std::unique_ptr<TestingProfileManager> profile_manager_;
};
TEST_F(ShowNudgeActionPerformerTest, TestValidPayloadParams) {
const auto validPayloadParam =
base::StringPrintf(kNudgePayloadTemplate, "body");
auto value = base::JSONReader::Read(validPayloadParam);
ASSERT_TRUE(value.has_value());
action().Run(
/*campaign_id=*/1, /*group_id=*/std::nullopt, &value->GetDict(),
base::BindOnce(&ShowNudgeActionPerformerTest::RunActionPerformerCallback,
base::Unretained(this)));
EXPECT_TRUE(VerifyActionResult(/*success=*/true));
}
TEST_F(ShowNudgeActionPerformerTest, TestInvalidPayloadParams) {
auto* const inValidOpenUrlParam = "{}";
auto value = base::JSONReader::Read(inValidOpenUrlParam);
ASSERT_TRUE(value.has_value());
action().Run(
/*campaign_id=*/1, /*group_id=*/std::nullopt, &value->GetDict(),
base::BindOnce(&ShowNudgeActionPerformerTest::RunActionPerformerCallback,
base::Unretained(this)));
EXPECT_TRUE(VerifyActionResult(/*success=*/false));
}
TEST_F(ShowNudgeActionPerformerTest, TestInvalidPayloadBody) {
auto const inValidOpenUrlParam =
base::StringPrintf(kNudgePayloadTemplate, "Body");
auto value = base::JSONReader::Read(inValidOpenUrlParam);
ASSERT_TRUE(value.has_value());
action().Run(
/*campaign_id=*/1, /*group_id=*/std::nullopt, &value->GetDict(),
base::BindOnce(&ShowNudgeActionPerformerTest::RunActionPerformerCallback,
base::Unretained(this)));
EXPECT_TRUE(VerifyActionResult(/*success=*/false));
}
TEST_F(ShowNudgeActionPerformerTest, ShouldCallOnReadyToLogImpression) {
const auto validPayloadParam =
base::StringPrintf(kNudgePayloadTemplate, "body");
auto value = base::JSONReader::Read(validPayloadParam);
ASSERT_TRUE(value.has_value());
int campaign_id = 100;
EXPECT_CALL(
mock_observer_,
OnReadyToLogImpression(testing::Eq(campaign_id),
/*group_id=*/testing::_,
/*should_log_cros_events=*/testing::Eq(false)))
.Times(1);
action().Run(
campaign_id, /*group_id=*/std::nullopt, &value->GetDict(),
base::BindOnce(&ShowNudgeActionPerformerTest::RunActionPerformerCallback,
base::Unretained(this)));
EXPECT_TRUE(VerifyActionResult(/*success=*/true));
}