blob: 47cff33bc507a69a95dd83f130c5758a52e4e070 [file] [log] [blame]
// Copyright 2020 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/device_api/managed_configuration_service.h"
#include <memory>
#include <string_view>
#include <tuple>
#include "base/check_deref.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.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/test/navigation_simulator.h"
#include "content/public/test/web_contents_tester.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "url/gurl.h"
namespace {
constexpr std::string_view kUrl = "https://example.com";
std::tuple<ManagedConfigurationServiceImpl*,
mojo::Remote<blink::mojom::ManagedConfigurationService>>
MaybeCreateService(content::WebContents* web_contents) {
mojo::Remote<blink::mojom::ManagedConfigurationService> remote;
content::NavigationSimulator::NavigateAndCommitFromBrowser(web_contents,
GURL(kUrl));
return std::make_tuple(ManagedConfigurationServiceImpl::Create(
web_contents->GetPrimaryMainFrame(),
remote.BindNewPipeAndPassReceiver()),
std::move(remote));
}
std::tuple<ManagedConfigurationServiceImpl&,
mojo::Remote<blink::mojom::ManagedConfigurationService>>
CreateService(content::WebContents* web_contents) {
auto [service, remote] = MaybeCreateService(web_contents);
return std::forward_as_tuple(CHECK_DEREF(service), std::move(remote));
}
// Observer that surfaces when `OnConfigurationChanged` is called.
class ChangeObserver : public blink::mojom::ManagedConfigurationObserver {
public:
ChangeObserver() = default;
ChangeObserver(const ChangeObserver&) = delete;
ChangeObserver& operator=(const ChangeObserver&) = delete;
~ChangeObserver() override = default;
// blink::mojom::ManagedConfigurationObserver overrides.
void OnConfigurationChanged() override { did_change_ = true; }
bool did_change() {
// Process pending messages that may be in flight.
receiver_.FlushForTesting();
return did_change_;
}
mojo::PendingRemote<blink::mojom::ManagedConfigurationObserver> bind() {
return receiver_.BindNewPipeAndPassRemote();
}
private:
bool did_change_ = false;
mojo::Receiver<blink::mojom::ManagedConfigurationObserver> receiver_{this};
};
} // namespace
using ManagedConfigurationServiceTest = ChromeRenderViewHostTestHarness;
TEST_F(ManagedConfigurationServiceTest,
ChangeNotificationWithoutObserversDoesNotCrash) {
auto [service, remote] = CreateService(web_contents());
service.OnManagedConfigurationChanged();
}
TEST_F(ManagedConfigurationServiceTest, NotifiesChangesToObserver) {
auto [service, remote] = CreateService(web_contents());
ChangeObserver observer;
service.SubscribeToManagedConfiguration(observer.bind());
EXPECT_FALSE(observer.did_change());
service.OnManagedConfigurationChanged();
EXPECT_TRUE(observer.did_change());
}
TEST_F(ManagedConfigurationServiceTest, SupportsOneObserverAtATime) {
auto [service, remote] = CreateService(web_contents());
{
ChangeObserver observer1;
service.SubscribeToManagedConfiguration(observer1.bind());
}
// `observer1` was destroyed above, flush so `service` gets the disconnect.
remote.FlushForTesting();
ChangeObserver observer2;
service.SubscribeToManagedConfiguration(observer2.bind());
EXPECT_FALSE(observer2.did_change());
service.OnManagedConfigurationChanged();
EXPECT_TRUE(observer2.did_change());
}
TEST_F(ManagedConfigurationServiceTest, IsBoundInNormalProfile) {
auto [service, remote] = MaybeCreateService(web_contents());
ASSERT_NE(service, nullptr);
remote.FlushForTesting();
ASSERT_TRUE(remote.is_connected());
}
TEST_F(ManagedConfigurationServiceTest, IsNotBoundInIncognito) {
std::unique_ptr<content::WebContents> incognito_web_contents =
content::WebContentsTester::CreateTestWebContents(
profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true), nullptr);
auto [service, remote] = MaybeCreateService(incognito_web_contents.get());
ASSERT_EQ(service, nullptr);
remote.FlushForTesting();
ASSERT_FALSE(remote.is_connected());
}
class ManagedConfigurationServiceGuestTest
: public ChromeRenderViewHostTestHarness {
public:
void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp();
ASSERT_TRUE(profile_manager_.SetUp());
}
void TearDown() override {
profile_manager_.DeleteAllTestingProfiles();
ChromeRenderViewHostTestHarness::TearDown();
}
TestingProfileManager& profile_manager() { return profile_manager_; }
private:
TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()};
};
TEST_F(ManagedConfigurationServiceGuestTest, IsNotBoundInGuestProfile) {
std::unique_ptr<content::WebContents> guest_web_contents =
content::WebContentsTester::CreateTestWebContents(
profile_manager().CreateGuestProfile()->GetPrimaryOTRProfile(
/*create_if_needed=*/true),
/*instance=*/nullptr);
auto [service, remote] = MaybeCreateService(guest_web_contents.get());
ASSERT_EQ(service, nullptr);
remote.FlushForTesting();
ASSERT_FALSE(remote.is_connected());
}