#include "chrome/browser/extensions/api/identity/web_auth_flow.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/time/time.h"
#include "chrome/browser/extensions/api/identity/web_auth_flow_info_bar_delegate.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/profiles/nuke_profile_directory_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_restore.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/test_navigation_observer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
class MockWebAuthFlowDelegate : public WebAuthFlow::Delegate {
public:
MOCK_METHOD(void, OnAuthFlowURLChange, (const GURL&), (override));
MOCK_METHOD(void, OnAuthFlowTitleChange, (const std::string&), (override));
MOCK_METHOD(void, OnAuthFlowFailure, (WebAuthFlow::Failure), (override));
};
class WebAuthFlowBrowserTest : public InProcessBrowserTest {
public:
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
ASSERT_TRUE(embedded_test_server()->Start());
ON_CALL(mock(), OnAuthFlowFailure(testing::_))
.WillByDefault(
[this](WebAuthFlow::Failure failure) { DeleteWebAuthFlow(); });
}
void DeleteWebAuthFlow() {
DCHECK(web_auth_flow_);
web_auth_flow_.release()->DetachDelegateAndDelete();
}
void TearDownOnMainThread() override {
timeout_task_runner_->RunUntilIdle();
if (web_auth_flow_) {
DeleteWebAuthFlow();
}
base::RunLoop().RunUntilIdle();
InProcessBrowserTest::TearDownOnMainThread();
}
void StartWebAuthFlow(
const GURL& url,
WebAuthFlow::Mode mode = WebAuthFlow::Mode::INTERACTIVE,
Profile* profile = nullptr,
WebAuthFlow::AbortOnLoad abort_on_load_for_non_interactive =
WebAuthFlow::AbortOnLoad::kYes,
std::optional<base::TimeDelta> timeout_for_non_interactive = std::nullopt,
std::optional<gfx::Rect> popup_bounds = std::nullopt) {
if (!profile)
profile = GetProfile();
web_auth_flow_ = std::make_unique<WebAuthFlow>(
&mock_web_auth_flow_delegate_, profile, url, mode,
true, abort_on_load_for_non_interactive,
timeout_for_non_interactive, popup_bounds);
timeout_task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
web_auth_flow_->SetClockForTesting(timeout_task_runner_->GetMockTickClock(),
timeout_task_runner_);
web_auth_flow_->Start();
}
WebAuthFlow* web_auth_flow() { return web_auth_flow_.get(); }
content::WebContents* web_contents() {
if (!web_auth_flow_) {
return nullptr;
}
return web_auth_flow_->web_contents();
}
MockWebAuthFlowDelegate& mock() { return mock_web_auth_flow_delegate_; }
scoped_refptr<base::TestMockTimeTaskRunner> timeout_task_runner() {
return timeout_task_runner_;
}
private:
std::unique_ptr<WebAuthFlow> web_auth_flow_;
MockWebAuthFlowDelegate mock_web_auth_flow_delegate_;
scoped_refptr<base::TestMockTimeTaskRunner> timeout_task_runner_;
};
class WebAuthFlowInBrowserTabParamBrowserTest : public WebAuthFlowBrowserTest {
public:
bool JsRedirectToUrl(const GURL& url) {
content::TestNavigationObserver redirect_observer(url);
redirect_observer.WatchExistingWebContents();
const std::string script =
base::StringPrintf("window.location.href = '%s'", url.spec().c_str());
bool result = content::ExecJs(web_contents(), script);
if (result) {
redirect_observer.Wait();
}
return result;
}
};
IN_PROC_BROWSER_TEST_F(WebAuthFlowInBrowserTabParamBrowserTest,
OnAuthFlowURLChangeCalled) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url);
navigation_observer.WaitForNavigationFinished();
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowInBrowserTabParamBrowserTest,
OnAuthFlowFailureChangeCalled) {
const GURL error_url = embedded_test_server()->GetURL("/error");
content::TestNavigationObserver navigation_observer(error_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowFailure(WebAuthFlow::LOAD_FAILED));
StartWebAuthFlow(error_url);
navigation_observer.WaitForNavigationFinished();
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowInBrowserTabParamBrowserTest,
OnAuthFlowFailureCalledInteractionRequired) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
EXPECT_CALL(mock(), OnAuthFlowFailure(WebAuthFlow::INTERACTION_REQUIRED));
StartWebAuthFlow(auth_url, WebAuthFlow::SILENT);
navigation_observer.Wait();
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowInBrowserTabParamBrowserTest,
OnAuthFlowInteractionRequiredWithTimeout) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
StartWebAuthFlow(auth_url, WebAuthFlow::SILENT, nullptr,
WebAuthFlow::AbortOnLoad::kNo,
base::Milliseconds(50));
navigation_observer.Wait();
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
timeout_task_runner()->FastForwardBy(base::Milliseconds(40));
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure(WebAuthFlow::INTERACTION_REQUIRED));
timeout_task_runner()->FastForwardBy(base::Milliseconds(20));
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowInBrowserTabParamBrowserTest,
OnAuthFlowInteractionRequiredWithDefaultTimeout) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
StartWebAuthFlow(auth_url, WebAuthFlow::SILENT, nullptr,
WebAuthFlow::AbortOnLoad::kNo);
navigation_observer.Wait();
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
timeout_task_runner()->FastForwardBy(base::Seconds(59));
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure(WebAuthFlow::INTERACTION_REQUIRED));
timeout_task_runner()->FastForwardBy(base::Seconds(2));
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowInBrowserTabParamBrowserTest,
OnAuthFlowPageLoadTimeout) {
const GURL auth_url = embedded_test_server()->GetURL("/hung-after-headers");
base::RunLoop run_loop;
ON_CALL(mock(), OnAuthFlowURLChange(testing::_))
.WillByDefault([&run_loop](const GURL& url) { run_loop.Quit(); });
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
StartWebAuthFlow(auth_url, WebAuthFlow::SILENT, nullptr,
WebAuthFlow::AbortOnLoad::kYes,
base::Milliseconds(50));
run_loop.Run();
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
timeout_task_runner()->FastForwardBy(base::Milliseconds(40));
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure(WebAuthFlow::TIMED_OUT));
timeout_task_runner()->FastForwardBy(base::Milliseconds(20));
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowInBrowserTabParamBrowserTest,
OnAuthFlowRedirectBeforeTimeout) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
StartWebAuthFlow(auth_url, WebAuthFlow::SILENT, nullptr,
WebAuthFlow::AbortOnLoad::kNo,
base::Milliseconds(50));
navigation_observer.Wait();
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
timeout_task_runner()->FastForwardBy(base::Milliseconds(40));
testing::Mock::VerifyAndClearExpectations(&mock());
const GURL redirect_url = embedded_test_server()->GetURL("/title2.html");
EXPECT_CALL(mock(), OnAuthFlowURLChange(redirect_url));
EXPECT_TRUE(JsRedirectToUrl(redirect_url));
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowInBrowserTabParamBrowserTest,
OnAuthFlowMultipleRedirects) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
StartWebAuthFlow(auth_url, WebAuthFlow::SILENT, nullptr,
WebAuthFlow::AbortOnLoad::kNo,
base::Milliseconds(50));
navigation_observer.Wait();
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
timeout_task_runner()->FastForwardBy(base::Milliseconds(10));
testing::Mock::VerifyAndClearExpectations(&mock());
const GURL redirect_url = embedded_test_server()->GetURL("/title2.html");
EXPECT_CALL(mock(), OnAuthFlowURLChange(redirect_url));
EXPECT_TRUE(JsRedirectToUrl(redirect_url));
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
timeout_task_runner()->FastForwardBy(base::Milliseconds(10));
testing::Mock::VerifyAndClearExpectations(&mock());
const GURL redirect_url2 = embedded_test_server()->GetURL("/title3.html");
EXPECT_CALL(mock(), OnAuthFlowURLChange(redirect_url2));
EXPECT_TRUE(JsRedirectToUrl(redirect_url2));
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
timeout_task_runner()->FastForwardBy(base::Milliseconds(10));
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowFailure(WebAuthFlow::INTERACTION_REQUIRED));
timeout_task_runner()->FastForwardBy(base::Milliseconds(30));
}
class WebAuthFlowFencedFrameTest
: public WebAuthFlowInBrowserTabParamBrowserTest {
public:
content::test::FencedFrameTestHelper& fenced_frame_test_helper() {
return fenced_frame_helper_;
}
private:
content::test::FencedFrameTestHelper fenced_frame_helper_;
};
IN_PROC_BROWSER_TEST_F(WebAuthFlowFencedFrameTest,
FencedFrameNavigationSuccess) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.set_wait_event(
content::TestNavigationObserver::WaitEvent::kLoadStopped);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url);
navigation_observer.Wait();
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url)).Times(0);
ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
web_contents()->GetPrimaryMainFrame(),
embedded_test_server()->GetURL("/fenced_frames/title1.html")));
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowFencedFrameTest,
FencedFrameNavigationFailure) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.set_wait_event(
content::TestNavigationObserver::WaitEvent::kLoadStopped);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url);
navigation_observer.Wait();
testing::Mock::VerifyAndClearExpectations(&mock());
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url)).Times(0);
EXPECT_CALL(mock(), OnAuthFlowFailure).Times(0);
ASSERT_TRUE(fenced_frame_test_helper().CreateFencedFrame(
web_contents()->GetPrimaryMainFrame(),
embedded_test_server()->GetURL("/error"), net::Error::ERR_FAILED));
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowBrowserTest,
InteractivePopupWindowCreatedWithAuthURL_ThenCloseTab) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::INTERACTIVE);
const char extension_name[] = "extension_name";
web_auth_flow()->SetShouldShowInfoBar(extension_name);
navigation_observer.Wait();
Browser* popup_browser = chrome::FindBrowserWithTab(web_contents());
EXPECT_EQ(popup_browser->type(), Browser::Type::TYPE_POPUP);
EXPECT_NE(browser(), popup_browser);
TabStripModel* tabs = popup_browser->tab_strip_model();
EXPECT_EQ(tabs->GetActiveWebContents()->GetLastCommittedURL(), auth_url);
base::WeakPtr<WebAuthFlowInfoBarDelegate> infobar_delegate =
web_auth_flow()->GetInfoBarDelegateForTesting();
EXPECT_TRUE(infobar_delegate);
EXPECT_EQ(
infobar_delegate->GetIdentifier(),
infobars::InfoBarDelegate::EXTENSIONS_WEB_AUTH_FLOW_INFOBAR_DELEGATE);
EXPECT_TRUE(infobar_delegate->GetMessageText().find(
base::UTF8ToUTF16(std::string(extension_name))));
EXPECT_CALL(mock(), OnAuthFlowFailure(WebAuthFlow::Failure::WINDOW_CLOSED));
tabs->CloseWebContentsAt(tabs->active_index(), 0);
}
IN_PROC_BROWSER_TEST_F(
WebAuthFlowBrowserTest,
InteractivePopupWindowCreatedWithAuthURL_NavigationInURLDoesNotBreakTheFlow) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::INTERACTIVE);
web_auth_flow()->SetShouldShowInfoBar("extension name");
navigation_observer.Wait();
testing::Mock::VerifyAndClearExpectations(&mock());
base::WeakPtr<WebAuthFlowInfoBarDelegate> auth_info_bar =
web_auth_flow()->GetInfoBarDelegateForTesting();
ASSERT_TRUE(auth_info_bar);
Browser* popup_browser = chrome::FindBrowserWithTab(web_contents());
EXPECT_EQ(popup_browser->type(), Browser::Type::TYPE_POPUP);
EXPECT_NE(browser(), popup_browser);
GURL new_url = embedded_test_server()->GetURL("/title2.html");
EXPECT_CALL(mock(), OnAuthFlowURLChange(new_url));
ASSERT_TRUE(content::NavigateToURL(web_contents(), new_url));
EXPECT_EQ(web_contents()->GetURL(), new_url);
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
content::DisableBackForwardCacheForTesting(
web_contents(), content::BackForwardCache::DisableForTestingReason::
TEST_REQUIRES_NO_CACHING);
ASSERT_TRUE(content::HistoryGoBack(web_contents()));
EXPECT_EQ(web_contents()->GetURL(), auth_url);
EXPECT_TRUE(popup_browser);
EXPECT_EQ(chrome::FindBrowserWithTab(web_contents()), popup_browser);
EXPECT_TRUE(auth_info_bar);
}
IN_PROC_BROWSER_TEST_F(
WebAuthFlowBrowserTest,
InteractiveNoBrowser_WebAuthCreatesBrowserWithPopupWindow) {
Profile* profile = GetProfile();
ScopedProfileKeepAlive profile_keep_alive(
profile, ProfileKeepAliveOrigin::kBackgroundMode);
ScopedKeepAlive keep_alive{KeepAliveOrigin::BROWSER,
KeepAliveRestartOption::DISABLED};
CloseBrowserSynchronously(browser());
ASSERT_FALSE(chrome::FindBrowserWithProfile(profile));
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::INTERACTIVE, profile);
navigation_observer.Wait();
Browser* new_browser = chrome::FindBrowserWithProfile(profile);
EXPECT_TRUE(new_browser);
EXPECT_EQ(new_browser->type(), Browser::Type::TYPE_POPUP);
EXPECT_EQ(new_browser->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL(),
auth_url);
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowBrowserTest,
InteractiveNoBrowser_NotActivatingSessionRestore) {
Profile* profile = GetProfile();
SessionStartupPref startup_pref(SessionStartupPref::LAST);
SessionStartupPref::SetStartupPref(profile, startup_pref);
ScopedProfileKeepAlive profile_keep_alive(
profile, ProfileKeepAliveOrigin::kBackgroundMode);
ScopedKeepAlive keep_alive{KeepAliveOrigin::BROWSER,
KeepAliveRestartOption::DISABLED};
CloseBrowserSynchronously(browser());
ASSERT_FALSE(chrome::FindBrowserWithProfile(profile));
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::INTERACTIVE, profile);
navigation_observer.Wait();
EXPECT_FALSE(SessionRestore::IsRestoring(profile));
EXPECT_EQ(chrome::FindAllBrowsersWithProfile(profile).size(), 1u);
Browser* new_browser = chrome::FindBrowserWithProfile(profile);
EXPECT_TRUE(new_browser);
EXPECT_EQ(new_browser->type(), Browser::Type::TYPE_POPUP);
EXPECT_EQ(new_browser->tab_strip_model()
->GetActiveWebContents()
->GetLastCommittedURL(),
auth_url);
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowBrowserTest, SilentNewTabNotCreated) {
TabStripModel* tabs = browser()->tab_strip_model();
int initial_tab_count = tabs->count();
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(),
OnAuthFlowFailure(WebAuthFlow::Failure::INTERACTION_REQUIRED));
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::SILENT);
navigation_observer.Wait();
EXPECT_EQ(tabs->count(), initial_tab_count);
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowBrowserTest,
InteractiveNewTabCreatedWithAuthURL_NoInfoBarByDefault) {
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::INTERACTIVE);
navigation_observer.Wait();
Browser* popup_browser = chrome::FindBrowserWithTab(web_contents());
TabStripModel* tabs = popup_browser->tab_strip_model();
EXPECT_NE(browser(), popup_browser);
EXPECT_EQ(tabs->GetActiveWebContents()->GetLastCommittedURL(), auth_url);
base::WeakPtr<WebAuthFlowInfoBarDelegate> infobar_delegate =
web_auth_flow()->GetInfoBarDelegateForTesting();
EXPECT_FALSE(infobar_delegate);
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowBrowserTest,
PopupWindowOpened_ThenCloseWindow) {
size_t initial_browser_count = chrome::GetTotalBrowserCount();
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::INTERACTIVE);
navigation_observer.Wait();
EXPECT_EQ(chrome::GetTotalBrowserCount(), initial_browser_count + 1);
Browser* popup_window_browser = chrome::FindBrowserWithTab(web_contents());
EXPECT_NE(popup_window_browser, browser());
TabStripModel* popup_tabs = popup_window_browser->tab_strip_model();
EXPECT_EQ(popup_tabs->count(), 1);
EXPECT_EQ(popup_tabs->GetActiveWebContents()->GetLastCommittedURL(),
auth_url);
EXPECT_CALL(mock(), OnAuthFlowFailure(WebAuthFlow::Failure::WINDOW_CLOSED));
CloseBrowserSynchronously(popup_window_browser);
}
IN_PROC_BROWSER_TEST_F(
WebAuthFlowBrowserTest,
Interactive_MarkedForDeletionProfileNotAllowedToCreatePopupWindow) {
MarkProfileDirectoryForDeletion(GetProfile()->GetPath());
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
EXPECT_CALL(mock(),
OnAuthFlowFailure(WebAuthFlow::Failure::CANNOT_CREATE_WINDOW));
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::INTERACTIVE);
navigation_observer.Wait();
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowBrowserTest, PopupWindowOpened_WithBounds) {
size_t initial_browser_count = chrome::GetTotalBrowserCount();
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
EXPECT_CALL(mock(), OnAuthFlowURLChange(auth_url));
const gfx::Rect test_bounds(35, 47, 400, 400);
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::INTERACTIVE, nullptr,
WebAuthFlow::AbortOnLoad::kYes, std::nullopt, test_bounds);
navigation_observer.Wait();
EXPECT_EQ(chrome::GetTotalBrowserCount(), initial_browser_count + 1);
Browser* popup_window_browser = chrome::FindBrowserWithTab(web_contents());
EXPECT_NE(popup_window_browser, browser());
gfx::Rect bounds = popup_window_browser->window()->GetBounds();
EXPECT_EQ(bounds.x(), test_bounds.x());
EXPECT_EQ(bounds.y(), test_bounds.y());
EXPECT_GE(bounds.width(), test_bounds.width());
EXPECT_GE(bounds.height(), test_bounds.height());
}
IN_PROC_BROWSER_TEST_F(WebAuthFlowBrowserTest,
WebContentsDestroyedBeforeProfileShutDown) {
ON_CALL(mock(), OnAuthFlowFailure)
.WillByDefault([](WebAuthFlow::Failure failure) {});
size_t initial_browser_count = chrome::GetTotalBrowserCount();
const GURL auth_url = embedded_test_server()->GetURL("/title1.html");
content::TestNavigationObserver navigation_observer(auth_url);
navigation_observer.StartWatchingNewWebContents();
StartWebAuthFlow(auth_url, WebAuthFlow::Mode::INTERACTIVE);
navigation_observer.Wait();
EXPECT_EQ(chrome::GetTotalBrowserCount(), initial_browser_count + 1);
Browser* popup = chrome::FindBrowserWithTab(web_contents());
static_cast<ProfileObserver*>(web_auth_flow())
->OnProfileWillBeDestroyed(GetProfile());
ui_test_utils::WaitForBrowserToClose(popup);
EXPECT_TRUE(web_auth_flow());
EXPECT_FALSE(web_auth_flow()->web_contents());
EXPECT_EQ(chrome::GetTotalBrowserCount(), initial_browser_count);
}
}