blob: dd997a75e7e4f4334ccc516fd79158b2724588c8 [file] [log] [blame]
// Copyright 2012 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/extensions/event_router_forwarder.h"
#include <utility>
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/thread_test_helper.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/common/extension_id.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace extensions {
namespace {
const events::HistogramValue kHistogramValue = events::FOR_TEST;
const char kEventName[] = "event_name";
class MockEventRouterForwarder : public EventRouterForwarder {
public:
MOCK_METHOD3(CallEventRouter,
void(Profile*, events::HistogramValue, const std::string&));
void CallEventRouter(Profile* profile,
events::HistogramValue histogram_value,
const std::string& event_name,
base::Value::List args) override {
CallEventRouter(profile, histogram_value, event_name);
}
protected:
~MockEventRouterForwarder() override = default;
};
static void BroadcastEventToRenderers(
EventRouterForwarder* event_router,
events::HistogramValue histogram_value,
const std::string& event_name,
bool dispatch_to_off_the_record_profiles) {
event_router->BroadcastEventToRenderers(histogram_value, event_name,
base::Value::List(),
dispatch_to_off_the_record_profiles);
}
} // namespace
class EventRouterForwarderTest : public testing::Test {
protected:
EventRouterForwarderTest()
: task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD),
profile_manager_(TestingBrowserProcess::GetGlobal()) {
}
void SetUp() override {
ASSERT_TRUE(profile_manager_.SetUp());
// Inject a BrowserProcess with a ProfileManager.
profile1_ = profile_manager_.CreateTestingProfile("one");
profile2_ = profile_manager_.CreateTestingProfile("two");
}
content::BrowserTaskEnvironment task_environment_;
TestingProfileManager profile_manager_;
// Profiles are weak pointers, owned by ProfileManager in |browser_process_|.
raw_ptr<TestingProfile> profile1_;
raw_ptr<TestingProfile> profile2_;
};
TEST_F(EventRouterForwarderTest, BroadcastRendererUI) {
scoped_refptr<MockEventRouterForwarder> event_router(
new MockEventRouterForwarder);
GURL url;
EXPECT_CALL(*event_router,
CallEventRouter(profile1_.get(), kHistogramValue, kEventName));
EXPECT_CALL(*event_router,
CallEventRouter(profile2_.get(), kHistogramValue, kEventName));
BroadcastEventToRenderers(event_router.get(), kHistogramValue, kEventName,
false);
}
TEST_F(EventRouterForwarderTest, BroadcastRendererUIIncognito) {
scoped_refptr<MockEventRouterForwarder> event_router(
new MockEventRouterForwarder);
using ::testing::_;
GURL url;
Profile* incognito =
profile1_->GetPrimaryOTRProfile(/*create_if_needed=*/true);
EXPECT_CALL(*event_router,
CallEventRouter(profile1_.get(), kHistogramValue, kEventName));
EXPECT_CALL(*event_router, CallEventRouter(incognito, _, _)).Times(0);
EXPECT_CALL(*event_router,
CallEventRouter(profile2_.get(), kHistogramValue, kEventName));
BroadcastEventToRenderers(event_router.get(), kHistogramValue, kEventName,
false);
}
TEST_F(EventRouterForwarderTest,
BroadcastRendererUIIncognitoWithDispatchToOffTheRecordProfiles) {
scoped_refptr<MockEventRouterForwarder> event_router(
new MockEventRouterForwarder);
using ::testing::_;
GURL url;
Profile* incognito1 =
profile1_->GetPrimaryOTRProfile(/*create_if_needed=*/true);
Profile* incognito2 =
profile2_->GetPrimaryOTRProfile(/*create_if_needed=*/true);
EXPECT_CALL(*event_router,
CallEventRouter(profile1_.get(), kHistogramValue, kEventName));
EXPECT_CALL(*event_router, CallEventRouter(incognito1, _, _));
EXPECT_CALL(*event_router,
CallEventRouter(profile2_.get(), kHistogramValue, kEventName));
EXPECT_CALL(*event_router, CallEventRouter(incognito2, _, _));
BroadcastEventToRenderers(event_router.get(), kHistogramValue, kEventName,
true);
}
// This is the canonical test for passing control flow from the IO thread
// to the UI thread. Repeating this for all public functions of
// EventRouterForwarder would not increase coverage.
TEST_F(EventRouterForwarderTest, BroadcastRendererIO) {
scoped_refptr<MockEventRouterForwarder> event_router(
new MockEventRouterForwarder);
GURL url;
EXPECT_CALL(*event_router,
CallEventRouter(profile1_.get(), kHistogramValue, kEventName));
EXPECT_CALL(*event_router,
CallEventRouter(profile2_.get(), kHistogramValue, kEventName));
content::GetIOThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(&BroadcastEventToRenderers,
base::Unretained(event_router.get()),
kHistogramValue, kEventName, false));
// Wait for IO thread's message loop to be processed
scoped_refptr<base::ThreadTestHelper> helper(
new base::ThreadTestHelper(content::GetIOThreadTaskRunner({}).get()));
ASSERT_TRUE(helper->Run());
base::RunLoop().RunUntilIdle();
}
} // namespace extensions