chromium/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_unittest.cc

// Copyright 2022 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/views/webid/fedcm_account_selection_view_desktop.h"

#include <memory>
#include <string>

#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/ui/views/chrome_constrained_window_views_client.h"
#include "chrome/browser/ui/views/webid/account_selection_bubble_view.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/views/chrome_views_test_base.h"
#include "components/constrained_window/constrained_window_views.h"
#include "content/public/browser/identity_request_dialog_controller.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/views/test/mock_input_event_activation_protector.h"
#include "url/gurl.h"

LoginState;
SignInMode;
TokenError;
DismissReason;

namespace {

constexpr char kTopFrameEtldPlusOne[] =;
constexpr char kIdpEtldPlusOne[] =;
constexpr char kConfigUrl[] =;
constexpr char kLoginUrl[] =;

constexpr char kAccountId1[] =;
constexpr char kAccountId2[] =;

// Mock AccountSelectionViewBase which tracks state.
class TestAccountSelectionView : public AccountSelectionViewBase {};

// Mock version of FedCmModalDialogView for injection during tests.
class MockFedCmModalDialogView : public FedCmModalDialogView {};

// Test FedCmAccountSelectionView which uses TestAccountSelectionView.
class TestFedCmAccountSelectionView : public FedCmAccountSelectionView {};

// Stub AccountSelectionView::Delegate.
class StubAccountSelectionViewDelegate : public AccountSelectionView::Delegate {};

}  // namespace

class FedCmAccountSelectionViewDesktopTest : public ChromeViewsTestBase {};

TEST_F(FedCmAccountSelectionViewDesktopTest, SingleAccountFlow) {}

TEST_F(FedCmAccountSelectionViewDesktopTest, MultipleAccountFlowReturning) {}

TEST_F(FedCmAccountSelectionViewDesktopTest, MultipleAccountFlowBack) {}

// Test transitioning from IdP sign-in status mismatch failure dialog to regular
// sign-in dialog.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusMismatchDialogToSigninFlow) {}

// Test transitioning from IdP sign-in status mismatch failure dialog to regular
// sign-in dialog while the dialog is hidden. This emulates a user signing
// into the IdP in a different tab.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusMismatchDialogToSigninFlowHidden) {}

TEST_F(FedCmAccountSelectionViewDesktopTest, AutoReauthnSingleAccountFlow) {}

namespace {

// AccountSelectionViewDelegate which deletes the FedCmAccountSelectionView in
// OnAccountSelected().
class ViewDeletingAccountSelectionViewDelegate
    : public StubAccountSelectionViewDelegate {};

}  // namespace

TEST_F(FedCmAccountSelectionViewDesktopTest, AccountSelectedDeletesView) {}

TEST_F(FedCmAccountSelectionViewDesktopTest, ClickProtection) {}

// Tests that when the auth re-authn dialog is closed, the relevant metric is
// recorded.
TEST_F(FedCmAccountSelectionViewDesktopTest, CloseAutoReauthnSheetMetric) {}

// Tests that when the mismatch dialog is closed through the close icon, the
// relevant metric is recorded.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       MismatchDialogDismissedByCloseIconMetric) {}

// Tests that when the mismatch dialog is closed through means other than the
// close icon, the relevant metric is recorded.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       MismatchDialogDismissedForOtherReasonsMetric) {}

// Tests that when FedCmAccountSelectionView is destroyed while the mismatch
// dialog is open, the relevant metric is recorded.
TEST_F(FedCmAccountSelectionViewDesktopTest, MismatchDialogDestroyedMetric) {}

// Tests that when the continue button on the mismatch dialog is clicked, the
// relevant metric is recorded.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       MismatchDialogContinueClickedMetric) {}

// Tests that when the continue button on the mismatch dialog is clicked and
// then FedCmAccountSelectionView is destroyed, we record only the metric for
// the continue button being clicked.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       MismatchDialogContinueClickedThenDestroyedMetric) {}

// Test transitioning from IdP sign-in status mismatch dialog to regular sign-in
// dialog. This emulates a user signing into the IdP in a pop-up window and the
// pop-up window closes PRIOR to the mismatch dialog being updated to a regular
// sign-in dialog.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusPopupClosedBeforeAccountsPopulated) {}

// Test transitioning from IdP sign-in status mismatch dialog to regular sign-in
// dialog. This emulates a user signing into the IdP in a pop-up window and the
// pop-up window closes AFTER the mismatch dialog has been updated to a regular
// sign-in dialog.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusPopupClosedAfterAccountsPopulated) {}

// Test that when user opens a pop-up window to complete the IDP sign-in flow,
// we record the appropriate metric when accounts are received but
// IdentityProvider.close() is not called.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusAccountsReceivedAndNoPopupClosedByIdpMetric) {}

// Test that when user opens a pop-up window to complete the IDP sign-in flow,
// we record the appropriate metric when accounts are not received but
// IdentityProvider.close() is called.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusAccountsNotReceivedAndPopupClosedByIdpMetric) {}

// Test that when user opens a pop-up window to complete the IDP sign-in flow,
// we record the appropriate metric when accounts are not received and
// IdentityProvider.close() is not called.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusAccountsNotReceivedAndNoPopupClosedByIdpMetric) {}

// Test closing the IdP sign-in pop-up window through IdentityProvider.close()
// should not close the widget.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusPopupClosedViaIdentityProviderClose) {}

// Test closing the IdP sign-in pop-up window through means other than
// IdentityProvider.close() should also close the widget.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusPopupClosedViaPopupDestroyed) {}

// Test that the mismatch dialog can be shown again after the pop-up window is
// closed.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusMismatchDialogReshown) {}

// Tests that RP context is properly set for the mismatch UI.
TEST_F(FedCmAccountSelectionViewDesktopTest, MismatchDialogWithRpContext) {}

// Tests the following
// 1. pop-up window is closed
// 2. visibility changes to hidden e.g. user navigates to different tab
// 3. Show() is invoked
// 4. widget should remain hidden
// 5. visibility changes to visible e.g. user navigates back to same tab
// 6. widget should now be visible
TEST_F(FedCmAccountSelectionViewDesktopTest,
       BubbleWidgetAfterPopupRemainsHiddenAfterAccountsFetched) {}

// Tests the following
// 1. pop-up window is closed
// 2. visibility changes to hidden e.g. user navigates to different tab
// 3. visibility changes to visible e.g. user navigates back to same tab
// 4. widget should remain hidden
// 5. Show() is invoked
// 6. widget should now be visible
TEST_F(FedCmAccountSelectionViewDesktopTest,
       BubbleWidgetAfterPopupRemainsHiddenBeforeAccountsFetched) {}

// Test transitioning from IdP sign-in status mismatch failure dialog to regular
// sign-in dialog where two accounts are logged in at once.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusMismatchMultiAccount) {}

// Test going from mismatch dialog to multiple accounts.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpMismatchToMultipleLoggedInAccounts) {}

// Test the use another account flow, resulting in the new account being shown
// after logging in.
TEST_F(FedCmAccountSelectionViewDesktopTest, UseAnotherAccount) {}

// Test the use another account flow when signing into the same account that the
// user started with.
TEST_F(FedCmAccountSelectionViewDesktopTest, UseAnotherAccountForSameAccount) {}

// Test the use another account flow, resulting in account chooser UI if it's a
// returning account.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       UseAnotherAccountForReturningAccount) {}

// Test the use another account flow in a modal, resulting in the new account
// being shown after logging in.
TEST_F(FedCmAccountSelectionViewDesktopTest, UseAnotherAccountModal) {}

// Test the use another account flow in a modal when signing into the same
// account that the user started with.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       UseAnotherAccountModalForSameAccount) {}

// Test the use another account flow in a modal, resulting in no account chooser
// UI if it's a returning account.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       UseAnotherAccountModalForReturningAccount) {}

// Test the logged-out LoginStatus flow in a modal, resulting in account
// chooser UI if it's a returning account.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       LoginStatusLoggedOutModalForReturningAccount) {}

// Test the logged-out LoginStatus flow in a modal, resulting in showing account
// chooser UI if it's a non-returning account.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       LoginStatusLoggedOutModalForNonReturningAccount) {}

// Test the browser trusted login state controls whether to skip the account
// chooser UI when in conflict with login state.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       BrowserTrustedLoginStateTakesPrecedenceOverLoginState) {}

// Test user triggering the use another account flow twice in a modal, without
// closing the pop-up from the first use another account flow.
TEST_F(FedCmAccountSelectionViewDesktopTest, UseAnotherAccountTwiceModal) {}

// Test user triggering the use another account flow twice in a modal, with
// closing the pop-up from the first use another account flow.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       UseAnotherAccountCloseThenReopenModal) {}

// Test user triggering the use another account flow then clicking on the cancel
// button in the modal without completing the use other account flow.
TEST_F(FedCmAccountSelectionViewDesktopTest, UseAnotherAccountThenCancel) {}

// Tests that the error dialog can be shown.
TEST_F(FedCmAccountSelectionViewDesktopTest, ErrorDialogShown) {}

// Tests that RP context is properly set for the error dialog.
TEST_F(FedCmAccountSelectionViewDesktopTest, ErrorDialogWithRpContext) {}

// Tests the flow for when the "got it" button on the error dialog is clicked.
TEST_F(FedCmAccountSelectionViewDesktopTest, ErrorDialogGotItClicked) {}

// Tests the flow for when the "more details" button on the error dialog is
// clicked.
TEST_F(FedCmAccountSelectionViewDesktopTest, ErrorDialogMoreDetailsClicked) {}

TEST_F(FedCmAccountSelectionViewDesktopTest, MultiIdpWithOneIdpMismatch) {}

TEST_F(FedCmAccountSelectionViewDesktopTest,
       MultiIdpWithSingleReturningAccount) {}

// Tests that closing the dialog when the single returning account UI is shown
// does not cause a crash.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       MultiIdpWithSingleReturningAccountClose) {}

// Tests that if a pop-up window is opened in button flow mode, closing the
// pop-up window triggers the dismiss callback.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       ButtonFlowPopupCloseTriggersDismissCallback) {}

TEST_F(FedCmAccountSelectionViewDesktopTest, MultiIdpMismatchAndShow) {}

// Tests that if a single account chooser is opened in button flow mode,
// selecting an account shows the request permission sheet. Then, confirming the
// account on the request permission sheet shows the verifying sheet.
TEST_F(FedCmAccountSelectionViewDesktopTest, SingleAccountFlowModal) {}

// Tests that if a multiple account chooser is opened in button flow mode,
// selecting an account shows the request permission sheet. Then, confirming the
// account on the request permission sheet shows the verifying sheet.
TEST_F(FedCmAccountSelectionViewDesktopTest, MultipleAccountFlowModal) {}

// Tests that if a single account chooser is opened in button flow mode,
// selecting a returning account shows the verifying sheet.
TEST_F(FedCmAccountSelectionViewDesktopTest, SingleAccountFlowReturningModal) {}

// Tests that if a multiple account chooser is opened in button flow mode,
// selecting a returning account shows the verifying sheet.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       MultipleAccountFlowReturningModal) {}

// Tests that if a single account chooser is opened in button flow mode,
// clicking the back button in the request permission dialog returns the user to
// the single account chooser.
TEST_F(FedCmAccountSelectionViewDesktopTest, SingleAccountFlowBackModal) {}

// Tests that if a multiple account chooser is opened in button flow mode,
// clicking the back button in the request permission dialog returns the user to
// the multiple account chooser.
TEST_F(FedCmAccountSelectionViewDesktopTest, MultipleAccountFlowBackModal) {}

// Tests that auto re-authn works in button mode.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       AutoReauthnSingleAccountFlowModal) {}

// Tests that the user can dismiss the loading modal.
TEST_F(FedCmAccountSelectionViewDesktopTest, DismissLoadingModal) {}

// Tests that the loading modal is not hidden when a pop-up window is displayed.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       ButtonFlowLoadingModalNotHiddenDuringLoginToIdP) {}

// Tests that opening an IDP sign-in pop-up during the loading modal, then
// closing the pop-up, does not crash. (This simulates the user triggering a
// button flow, then an IDP sign-in pop-up shows up because the user is logged
// out)
TEST_F(FedCmAccountSelectionViewDesktopTest,
       CloseIdpSigninPopupDuringLoadingState) {}

// Tests that opening a popup after a verifying sheet, then closing the popup,
// notifies the observer.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       UserClosingPopupAfterVerifyingSheetShouldNotify) {}

// Tests that opening a popup after a verifying sheet, then closing the popup
// programmatically, does not notify the observer.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       CodeClosingPopupAfterVerifyingSheetShouldNotNotify) {}

// Tests that if the dialog skips requesting permission, the verifying sheet is
// shown.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       SkipRequestPermissionShowsVerifying) {}

// Tests that if IDP supports add account, the correct sheet type is shown
// depending on the number of accounts and the rp mode.
TEST_F(FedCmAccountSelectionViewDesktopTest, SupportAddAccount) {}

// Tests that when adding accounts is supported, the back button is shown even
// if there is a single account after logging in.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       IdpSigninStatusMismatchToAccountChooserWithSupportAddAccount) {}

// Tests that the correct account chooser result metrics are recorded.
TEST_F(FedCmAccountSelectionViewDesktopTest, AccountChooserResultMetric) {}

// Tests that for button flows, going from an accounts dialog to an error dialog
// resets the account selection view. This is needed to switch from modal to
// bubble, since the error UI does not have a modal equivalent.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       AccountsToErrorButtonFlowResetsView) {}

// Tests that for button flows, going from a loading dialog to an accounts
// dialog does not reset the account selection view. This is important because
// the accounts dialog reuses the header from the loading dialog.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       LoadingToAccountsButtonFlowReusesView) {}

// Tests that resizing web contents would update the dialog visibility depending
// on whether the dialog can fit within the web contents.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       ResizeWebContentsChangesDialogVisibility) {}

// Tests that resizing web contents in different web contents visibility
// scenarios would update the dialog visibility correctly depending on whether
// the dialog can fit within the web contents or whether the web contents where
// the dialog is contained is visible.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       ResizeWebContentsWithWindowVisibilityChanges) {}

// Tests that changing visibility from hidden to visible, also updates the
// dialog position. This is needed in case the web contents was resized while
// hidden.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       VisibilityChangesUpdatesDialogPosition) {}

// Tests that the Lens overlay showing hides the dialog until the overlay is
// closed.
TEST_F(FedCmAccountSelectionViewDesktopTest, LensOverlayHidesDialog) {}

// Tests that the dialog does not open if the Lens overlay is already showing.
TEST_F(FedCmAccountSelectionViewDesktopTest, LensOverlaySuppressesDialog) {}

// Test that the fields API (request_permission=false) correctly hides the
// disclosure UI after logging in through the popup when logged out.
TEST_F(FedCmAccountSelectionViewDesktopTest,
       RequestPermissionFalseAndNewIdpDataDisclosureText) {}