blob: eed4e5e961368f9bdc52af8adb264c326757d1ad [file] [log] [blame]
// 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/ui/webui/webui_embedding_context.h"
#include <memory>
#include "base/test/mock_callback.h"
#include "chrome/browser/ui/browser_window/test/mock_browser_window_interface.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_web_contents_factory.h"
namespace webui {
namespace {
class MockBrowserWindowInterfaceWithCloseListener
: public MockBrowserWindowInterface {
public:
~MockBrowserWindowInterfaceWithCloseListener() override {
browser_did_close_callback_list_.Notify(this);
}
// MockBrowserWindowInterface:
base::CallbackListSubscription RegisterBrowserDidClose(
BrowserDidCloseCallback callback) override {
return browser_did_close_callback_list_.Add(std::move(callback));
}
private:
using BrowserDidCloseCallbackList =
base::RepeatingCallbackList<void(BrowserWindowInterface*)>;
BrowserDidCloseCallbackList browser_did_close_callback_list_;
};
} // namespace
class WebUIEmbeddingContextTest : public testing::Test {
public:
content::WebContents* CreateWebContents() {
return web_contents_factory_.CreateWebContents(profile());
}
Profile* profile() { return &profile_; }
BrowserWindowInterface* browser() { return &browser_window_interface_; }
private:
content::BrowserTaskEnvironment task_environment_;
TestingProfile profile_;
content::TestWebContentsFactory web_contents_factory_;
MockBrowserWindowInterfaceWithCloseListener browser_window_interface_;
};
TEST_F(WebUIEmbeddingContextTest, SingleBrowserSingleHost) {
// Create a new host, assert the browser starts null.
content::WebContents* host_contents = CreateWebContents();
EXPECT_FALSE(GetBrowserWindowInterface(host_contents));
base::MockCallback<base::RepeatingClosure> browser_changed_callback;
base::CallbackListSubscription subscription =
RegisterBrowserWindowInterfaceChanged(host_contents,
browser_changed_callback.Get());
// Set the browser on the host.
EXPECT_CALL(browser_changed_callback, Run).Times(1);
SetBrowserWindowInterface(host_contents, browser());
EXPECT_EQ(browser(), GetBrowserWindowInterface(host_contents));
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback);
// Reset the host's browser.
EXPECT_CALL(browser_changed_callback, Run).Times(1);
SetBrowserWindowInterface(host_contents, nullptr);
EXPECT_FALSE(GetBrowserWindowInterface(host_contents));
}
TEST_F(WebUIEmbeddingContextTest, SingleBrowserMultipleHosts) {
// Create a two hosts, assert the browser starts null.
content::WebContents* host_contents_1 = CreateWebContents();
content::WebContents* host_contents_2 = CreateWebContents();
EXPECT_FALSE(GetBrowserWindowInterface(host_contents_1));
EXPECT_FALSE(GetBrowserWindowInterface(host_contents_2));
base::MockCallback<base::RepeatingClosure> browser_changed_callback_1;
base::MockCallback<base::RepeatingClosure> browser_changed_callback_2;
base::CallbackListSubscription subscription_1 =
RegisterBrowserWindowInterfaceChanged(host_contents_1,
browser_changed_callback_1.Get());
base::CallbackListSubscription subscription_2 =
RegisterBrowserWindowInterfaceChanged(host_contents_2,
browser_changed_callback_2.Get());
// Set the browser on the first host.
EXPECT_CALL(browser_changed_callback_1, Run).Times(1);
EXPECT_CALL(browser_changed_callback_2, Run).Times(0);
SetBrowserWindowInterface(host_contents_1, browser());
EXPECT_EQ(browser(), GetBrowserWindowInterface(host_contents_1));
EXPECT_FALSE(GetBrowserWindowInterface(host_contents_2));
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback_1);
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback_2);
// Set the browser on the second host.
EXPECT_CALL(browser_changed_callback_1, Run).Times(0);
EXPECT_CALL(browser_changed_callback_2, Run).Times(1);
SetBrowserWindowInterface(host_contents_2, browser());
EXPECT_EQ(browser(), GetBrowserWindowInterface(host_contents_1));
EXPECT_EQ(browser(), GetBrowserWindowInterface(host_contents_2));
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback_1);
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback_2);
// Reset the browser on the first host.
EXPECT_CALL(browser_changed_callback_1, Run).Times(1);
EXPECT_CALL(browser_changed_callback_2, Run).Times(0);
SetBrowserWindowInterface(host_contents_1, nullptr);
EXPECT_FALSE(GetBrowserWindowInterface(host_contents_1));
EXPECT_EQ(browser(), GetBrowserWindowInterface(host_contents_2));
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback_1);
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback_2);
// Reset the browser on the second host.
EXPECT_CALL(browser_changed_callback_1, Run).Times(0);
EXPECT_CALL(browser_changed_callback_2, Run).Times(1);
SetBrowserWindowInterface(host_contents_2, nullptr);
EXPECT_FALSE(GetBrowserWindowInterface(host_contents_1));
EXPECT_FALSE(GetBrowserWindowInterface(host_contents_2));
}
TEST_F(WebUIEmbeddingContextTest, MultipleBrowsersSingleHost) {
// Create a second browser.
MockBrowserWindowInterfaceWithCloseListener browser_2;
// Create a new host, assert the browser starts null.
content::WebContents* host_contents = CreateWebContents();
EXPECT_FALSE(GetBrowserWindowInterface(host_contents));
base::MockCallback<base::RepeatingClosure> browser_changed_callback;
base::CallbackListSubscription subscription =
RegisterBrowserWindowInterfaceChanged(host_contents,
browser_changed_callback.Get());
// Set the first browser on the host.
EXPECT_CALL(browser_changed_callback, Run).Times(1);
SetBrowserWindowInterface(host_contents, browser());
EXPECT_EQ(browser(), GetBrowserWindowInterface(host_contents));
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback);
// Set the second browser on the host.
EXPECT_CALL(browser_changed_callback, Run).Times(1);
SetBrowserWindowInterface(host_contents, &browser_2);
EXPECT_EQ(&browser_2, GetBrowserWindowInterface(host_contents));
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback);
// Reset the host's browser.
EXPECT_CALL(browser_changed_callback, Run).Times(1);
SetBrowserWindowInterface(host_contents, nullptr);
EXPECT_FALSE(GetBrowserWindowInterface(host_contents));
}
TEST_F(WebUIEmbeddingContextTest, SingleBrowserDestruction) {
// Create a new browser.
auto test_browser =
std::make_unique<MockBrowserWindowInterfaceWithCloseListener>();
// Create a new host, assert the browser starts null.
content::WebContents* host_contents = CreateWebContents();
EXPECT_FALSE(GetBrowserWindowInterface(host_contents));
base::MockCallback<base::RepeatingClosure> browser_changed_callback;
base::CallbackListSubscription subscription =
RegisterBrowserWindowInterfaceChanged(host_contents,
browser_changed_callback.Get());
// Set the test_browser on the host.
EXPECT_CALL(browser_changed_callback, Run).Times(1);
SetBrowserWindowInterface(host_contents, test_browser.get());
EXPECT_EQ(test_browser.get(), GetBrowserWindowInterface(host_contents));
testing::Mock::VerifyAndClearExpectations(&browser_changed_callback);
// Destroy the browser with the host still alive.
EXPECT_CALL(browser_changed_callback, Run).Times(1);
test_browser.reset();
EXPECT_FALSE(GetBrowserWindowInterface(host_contents));
}
} // namespace webui