// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/webid/request_service.h"

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/webid/disconnect_request.h"
#include "content/browser/webid/metrics.h"
#include "content/browser/webid/test/delegated_idp_network_request_manager.h"
#include "content/browser/webid/test/federated_auth_request_request_token_callback_helper.h"
#include "content/browser/webid/test/mock_api_permission_delegate.h"
#include "content/browser/webid/test/mock_auto_reauthn_permission_delegate.h"
#include "content/browser/webid/test/mock_identity_registry.h"
#include "content/browser/webid/test/mock_identity_request_dialog_controller.h"
#include "content/browser/webid/test/mock_idp_network_request_manager.h"
#include "content/browser/webid/test/mock_permission_delegate.h"
#include "content/browser/webid/webid_utils.h"
#include "content/common/content_navigation_policy.h"
#include "content/public/browser/login_metrics.h"
#include "content/public/browser/webid/identity_request_dialog_controller.h"
#include "content/public/common/content_features.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/fake_local_frame.h"
#include "content/test/test_render_frame_host.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "metrics.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/http/http_status_code.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/webid/login_status_account.h"
#include "third_party/blink/public/common/webid/login_status_options.h"
#include "ui/base/page_transition_types.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "url/gurl.h"
#include "url/origin.h"

using blink::mojom::FederatedAuthRequestResult;
using blink::mojom::RequestTokenStatus;
using ApiPermissionStatus =
    content::FederatedIdentityApiPermissionContextDelegate::PermissionStatus;
using AuthRequestCallbackHelper =
    content::FederatedAuthRequestRequestTokenCallbackHelper;
using DismissReason = content::IdentityRequestDialogController::DismissReason;
using FedCmEntry = ukm::builders::Blink_FedCm;
using FedCmIdpEntry = ukm::builders::Blink_FedCmIdp;
using FetchStatus = content::webid::FetchStatus;
using ParseStatus = content::webid::ParseStatus;
using TokenStatus = content::webid::RequestIdTokenStatus;
using LoginState = content::IdentityRequestAccount::LoginState;
using SignInMode = content::IdentityRequestAccount::SignInMode;
using SignInStateMatchStatus = content::webid::SignInStateMatchStatus;
using ErrorDialogType =
    content::webid::IdpNetworkRequestManager::FedCmErrorDialogType;
using TokenResponseType =
    content::webid::IdpNetworkRequestManager::FedCmTokenResponseType;
using ErrorUrlType =
    content::webid::IdpNetworkRequestManager::FedCmErrorUrlType;
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::NiceMock;
using ::testing::Optional;
using ::testing::Return;
using ::testing::StrictMock;

namespace content::webid {

namespace {

constexpr char kProviderUrlFull[] = "https://idp.example/fedcm.json";
constexpr char kRpUrl[] = "https://rp.example/";
constexpr char kRpOtherUrl[] = "https://rp.example/random/";
constexpr char kIdpUrl[] = "https://idp.example/";
constexpr char kAccountsEndpoint[] = "https://idp.example/accounts";
constexpr char kCrossOriginAccountsEndpoint[] = "https://idp2.example/accounts";
constexpr char kTokenEndpoint[] = "https://idp.example/token";
constexpr char kClientMetadataEndpoint[] =
    "https://idp.example/client_metadata";
constexpr char kMetricsEndpoint[] = "https://idp.example/metrics";
constexpr char kIdpBrandIconUrl[] = "https://idp.example/icon";
constexpr char kIdpLoginUrl[] = "https://idp.example/login_url";
constexpr char kIdpDisconnectUrl[] = "https://idp.example/disconnect";
constexpr char kPrivacyPolicyUrl[] = "https://rp.example/pp";
constexpr char kTermsOfServiceUrl[] = "https://rp.example/tos";
constexpr char kRpBrandIconUrl[] = "https://rp.example/icon";
constexpr char kClientId[] = "client_id_123";
constexpr char kNonce[] = "nonce123";
constexpr char kAccountEmailNicolas[] = "nicolas@email.com";
constexpr char kAccountEmailPeter[] = "peter@email.com";
constexpr char kAccountEmailZach[] = "zach@email.com";
constexpr char kAccountId[] = "1234";
constexpr char kAccountIdNicolas[] = "nico_id";
constexpr char kAccountIdPeter[] = "peter_id";
constexpr char kAccountIdZach[] = "zach_id";
constexpr char kAccountPicture[] = "https://idp.example/profilepic";
constexpr char kAccountPicture404[] = "https://idp.example/404";
constexpr int kAccountPictureSize = 10;
constexpr char kEmail[] = "ken@idp.example";
constexpr char kDomainHint[] = "domain@corp.com";
constexpr char kOtherDomainHint[] = "other_domain@corp.com";

// Values will be added here as token introspection is implemented.
constexpr char kToken[] = "[not a real token]";
constexpr char kEmptyToken[] = "";

constexpr char kFilterNoMatchMessage[] =
    "Accounts were received, but none matched the login hint, domain hint, "
    "and/or account labels provided.";

static const std::vector<std::string> kDomainHintVector = {kDomainHint};
static const std::vector<std::string> kLabelVector = {"label"};
static const std::vector<std::string> kLoginHints = {kAccountId, kEmail};
static const std::vector<std::string> kNicolasHints = {kAccountIdNicolas,
                                                       kAccountEmailNicolas};
static const std::vector<std::string> kPeterHints = {kAccountIdPeter,
                                                     kAccountEmailPeter};
static const std::vector<std::string> kTwoDomainHints = {kDomainHint,
                                                         kOtherDomainHint};
static const std::vector<std::string> kZachHints = {kAccountIdZach,
                                                    kAccountEmailZach};

static std::vector<IdentityRequestAccountPtr> kMultipleAccounts;
static std::vector<IdentityRequestAccountPtr>
    kMultipleAccountsWithHintsAndDomains;
static std::vector<IdentityRequestAccountPtr> kSingleAccount;
static std::vector<IdentityRequestAccountPtr> kSingleAccountWithDomainHint;
static std::vector<IdentityRequestAccountPtr> kSingleAccountWithHint;
static std::vector<IdentityRequestAccountPtr> kTwoAccounts;

static const std::set<std::string> kWellKnown{kProviderUrlFull};

struct IdentityProviderParameters {
  const char* provider;
  const char* client_id;
  const char* nonce;
  const char* login_hint;
  const char* domain_hint;
  std::optional<std::vector<std::string>> fields;
  const char* params_json;
  std::optional<std::string> type;
  bool from_idp_registration_api = false;
};

// Parameters for a call to RequestToken.
struct RequestParameters {
  std::vector<IdentityProviderParameters> identity_providers;
  blink::mojom::RpContext rp_context;
  blink::mojom::RpMode rp_mode;
};

// Expected return values from a call to RequestToken.
//
// DO NOT ADD NEW MEMBERS.
// Having a lot of members in RequestExpectations encourages bad test design.
// Specifically:
// - It encourages making the test harness more magic
// - It makes each test "test everything", making it really hard to determine
//   at a later date what the test was actually testing.

struct RequestExpectations {
  std::optional<RequestTokenStatus> return_status;
  FederatedAuthRequestResult devtools_issue_status;
  std::optional<std::string> standalone_console_message;
  std::optional<std::string> selected_idp_config_url;
  bool is_auto_selected{false};
};

// Mock configuration values for test.
struct MockClientIdConfiguration {
  FetchStatus fetch_status;
  std::string privacy_policy_url;
  std::string terms_of_service_url;
  std::string brand_icon_url;
};

struct MockWellKnown {
  std::set<std::string> provider_urls;
  FetchStatus fetch_status;
};

// Mock information returned from IdpNetworkRequestManager::FetchConfig().
struct MockConfig {
  FetchStatus fetch_status;
  std::string accounts_endpoint;
  std::string token_endpoint;
  std::string client_metadata_endpoint;
  std::string metrics_endpoint;
  std::string idp_login_url;
  std::string disconnect_endpoint;
  std::optional<SkColor> brand_background_color;
  std::optional<SkColor> brand_text_color;
  std::string requested_label;
  std::vector<std::string> types;
};

struct MockIdpInfo {
  MockWellKnown well_known;
  MockConfig config;
  MockClientIdConfiguration client_metadata;
  FetchStatus accounts_response;
  std::vector<IdentityRequestAccountPtr> accounts;
};

// Action on accounts dialog taken by TestDialogController. Does not indicate a
// test expectation.
enum class AccountsDialogAction {
  kNone,
  kClose,
  kSelectFirstAccount,
  kAddAccount,
};

// Action on IdP-sign-in-status-mismatch dialog taken by TestDialogController.
// Does not indicate a test expectation.
enum class IdpSigninStatusMismatchDialogAction {
  kNone,
  kClose,
  kClosePopup,
};

// Action on error dialog taken by TestDialogController.
// Does not indicate a test expectation.
enum class ErrorDialogAction {
  kNone,
  kClose,
  kSwipe,
  kGotIt,
  kMoreDetails,
};

// Action on loading dialog taken by TestDialogController.
// Does not indicate a test expectation.
enum class LoadingDialogAction {
  kNone,
  kClose,
};

struct MockConfiguration {
  const char* token;
  base::flat_map<std::string, MockIdpInfo> idp_info;
  FetchStatus token_response;
  bool delay_token_response;
  AccountsDialogAction accounts_dialog_action;
  IdpSigninStatusMismatchDialogAction idp_signin_status_mismatch_dialog_action;
  ErrorDialogAction error_dialog_action;
  LoadingDialogAction loading_dialog_action;
  std::optional<GURL> continue_on;
  MediationRequirement mediation_requirement = MediationRequirement::kOptional;
  std::optional<TokenError> token_error;
  TokenResponseType token_response_type = TokenResponseType::
      kTokenNotReceivedAndErrorNotReceivedAndContinueOnNotReceived;
  std::optional<ErrorDialogType> error_dialog_type;
  std::optional<ErrorUrlType> error_url_type;
  blink::mojom::RpMode rp_mode{blink::mojom::RpMode::kPassive};
  bool suppressed_by_segmentation_platform{false};
};

static const MockClientIdConfiguration kDefaultClientMetadata{
    {ParseStatus::kSuccess, net::HTTP_OK},
    kPrivacyPolicyUrl,
    kTermsOfServiceUrl,
    kRpBrandIconUrl};

static const IdentityProviderParameters kDefaultIdentityProviderRequestOptions{
    kProviderUrlFull, kClientId, kNonce, /*login_hint=*/"",
    /*domain_hint=*/""};

static const RequestParameters kDefaultRequestParameters{
    std::vector<IdentityProviderParameters>{
        kDefaultIdentityProviderRequestOptions},
    blink::mojom::RpContext::kSignIn, blink::mojom::RpMode::kPassive};

static MockIdpInfo kDefaultIdentityProviderInfo;
static MockIdpInfo kProviderTwoInfo;

static base::flat_map<std::string, MockIdpInfo> kSingleProviderInfo;

constexpr char kProviderTwoUrlFull[] = "https://idp2.example/fedcm.json";

static MockConfiguration kConfigurationValid;
static MockConfiguration kConfigurationMultiIdpValid;

static const RequestExpectations kExpectationSuccess{
    RequestTokenStatus::kSuccess, FederatedAuthRequestResult::kSuccess,
    /*standalone_console_message=*/std::nullopt, kProviderUrlFull};

static const RequestParameters kDefaultMultiIdpRequestParameters{
    std::vector<IdentityProviderParameters>{
        {kProviderUrlFull, kClientId, kNonce, /*login_hint=*/"",
         /*domain_hint=*/""},
        {kProviderTwoUrlFull, kClientId, kNonce, /*login_hint=*/"",
         /*domain_hint=*/""}},
    /*rp_context=*/blink::mojom::RpContext::kSignIn,
    /*rp_mode=*/blink::mojom::RpMode::kPassive};

url::Origin OriginFromString(const std::string& url_string) {
  return url::Origin::Create(GURL(url_string));
}

enum class FetchedEndpoint {
  CONFIG,
  CLIENT_METADATA,
  ACCOUNTS,
  TOKEN,
  WELL_KNOWN,
  PICTURE,
};

class TestIdpNetworkRequestManager : public MockIdpNetworkRequestManager {
 public:
  void SetTestConfig(const MockConfiguration& configuration) {
    config_ = configuration;
  }

  void RunDelayedCallbacks() {
    for (base::OnceClosure& delayed_callback : delayed_callbacks_) {
      std::move(delayed_callback).Run();
    }
    delayed_callbacks_.clear();
  }

  void FetchWellKnown(const GURL& provider,
                      FetchWellKnownCallback callback) override {
    ++num_fetched_[FetchedEndpoint::WELL_KNOWN];

    std::string provider_key = provider.spec();
    IdpNetworkRequestManager::WellKnown well_known;
    std::set<GURL> url_set(
        config_.idp_info[provider_key].well_known.provider_urls.begin(),
        config_.idp_info[provider_key].well_known.provider_urls.end());
    well_known.provider_urls = std::move(url_set);

    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(callback),
                       config_.idp_info[provider_key].well_known.fetch_status,
                       well_known));
  }

  void FetchConfig(const GURL& provider,
                   blink::mojom::RpMode rp_mode,
                   int idp_brand_icon_ideal_size,
                   int idp_brand_icon_minimum_size,
                   FetchConfigCallback callback) override {
    ++num_fetched_[FetchedEndpoint::CONFIG];

    std::string provider_key = provider.spec();
    const MockConfig& config = config_.idp_info[provider_key].config;
    IdpNetworkRequestManager::Endpoints endpoints;
    endpoints.token = GURL(config.token_endpoint);
    endpoints.accounts = GURL(config.accounts_endpoint);
    endpoints.client_metadata = GURL(config.client_metadata_endpoint);
    endpoints.metrics = GURL(config.metrics_endpoint);
    endpoints.disconnect = GURL(config.disconnect_endpoint);

    IdentityProviderMetadata idp_metadata;
    idp_metadata.config_url = provider;
    idp_metadata.idp_login_url = GURL(config.idp_login_url);
    idp_metadata.brand_background_color = config.brand_background_color;
    idp_metadata.brand_icon_url = GURL(kIdpBrandIconUrl);
    idp_metadata.brand_text_color = config.brand_text_color;
    idp_metadata.requested_label = config.requested_label;
    idp_metadata.types = config.types;
    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(callback),
                       config_.idp_info[provider_key].config.fetch_status,
                       endpoints, idp_metadata));
  }

  void FetchClientMetadata(const GURL& endpoint,
                           const std::string& client_id,
                           int rp_brand_icon_ideal_size,
                           int rp_brand_icon_minimum_size,
                           FetchClientMetadataCallback callback) override {
    ++num_fetched_[FetchedEndpoint::CLIENT_METADATA];

    // Find the info of the provider with the same client metadata endpoint.
    MockIdpInfo info;
    for (const auto& idp_info : config_.idp_info) {
      info = idp_info.second;
      if (GURL(info.config.client_metadata_endpoint) == endpoint) {
        break;
      }
    }

    IdpNetworkRequestManager::ClientMetadata client_metadata;
    client_metadata.privacy_policy_url =
        GURL(info.client_metadata.privacy_policy_url);
    client_metadata.terms_of_service_url =
        GURL(info.client_metadata.terms_of_service_url);
    client_metadata.brand_icon_url = GURL(info.client_metadata.brand_icon_url);
    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(callback), info.client_metadata.fetch_status,
                       client_metadata));
  }

  bool SendAccountsRequest(const url::Origin& idp_origin,
                           const GURL& accounts_url,
                           const std::string& client_id,
                           AccountsRequestCallback callback) override {
    ++num_fetched_[FetchedEndpoint::ACCOUNTS];

    // Find the info of the provider with the same accounts endpoint.
    MockIdpInfo info;
    for (const auto& idp_info : config_.idp_info) {
      info = idp_info.second;
      if (GURL(info.config.accounts_endpoint) == accounts_url) {
        break;
      }
    }

    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, base::BindOnce(std::move(callback), info.accounts_response,
                                  accounts_list_.empty() ? info.accounts
                                                         : accounts_list_));
    return true;
  }

  void SendTokenRequest(
      const GURL& token_url,
      const std::string& account,
      const std::string& url_encoded_post_data,
      bool idp_blidness,
      TokenRequestCallback callback,
      ContinueOnCallback on_continue,
      RecordErrorMetricsCallback record_error_metrics_callback) override {
    ++num_fetched_[FetchedEndpoint::TOKEN];

    base::OnceCallback bound_record_error_metrics_callback = base::BindOnce(
        std::move(record_error_metrics_callback), config_.token_response_type,
        config_.error_dialog_type, config_.error_url_type);
    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, std::move(bound_record_error_metrics_callback));

    if (config_.token_error) {
      TokenResult result;
      result.error = config_.token_error;

      base::OnceCallback bound_callback = base::BindOnce(
          std::move(callback), config_.token_response, std::move(result));
      if (config_.delay_token_response) {
        delayed_callbacks_.push_back(std::move(bound_callback));
      } else {
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, std::move(bound_callback));
      }
      return;
    }

    if (config_.continue_on) {
      base::OnceCallback bound_callback =
          base::BindOnce(std::move(on_continue), config_.token_response,
                         config_.continue_on.value());
      base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
          FROM_HERE, std::move(bound_callback));
      return;
    }

    std::string delivered_token =
        config_.token_response.parse_status == ParseStatus::kSuccess
            ? config_.token
            : std::string();
    TokenResult result;
    result.token = base::Value(delivered_token);
    base::OnceCallback bound_callback = base::BindOnce(
        std::move(callback), config_.token_response, std::move(result));
    if (config_.delay_token_response) {
      delayed_callbacks_.push_back(std::move(bound_callback));
    } else {
      base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
          FROM_HERE, std::move(bound_callback));
    }
  }

  void DownloadAndDecodeImage(const GURL& url,
                              ImageCallback callback) override {
    EXPECT_TRUE(url == GURL(kAccountPicture) ||
                url == GURL(kAccountPicture404) ||
                url == GURL(kRpBrandIconUrl) || url == GURL(kIdpBrandIconUrl))
        << url;
    ++num_fetched_[FetchedEndpoint::PICTURE];
    if (url == GURL(kAccountPicture404)) {
      std::move(callback).Run(gfx::Image());
    } else {
      std::move(callback).Run(gfx::test::CreateImage(kAccountPictureSize));
    }
  }

  std::map<FetchedEndpoint, size_t> num_fetched_;

  // If non-empty, the accounts endpoint will return this accounts list instead
  // of the accounts list in the `config_`.
  std::vector<IdentityRequestAccountPtr> accounts_list_;

 protected:
  MockConfiguration config_{kConfigurationValid};
  std::vector<base::OnceClosure> delayed_callbacks_;
};

// TestIdpNetworkRequestManager subclass which checks the values of the method
// params when executing an endpoint request.
class IdpNetworkRequestManagerParamChecker
    : public TestIdpNetworkRequestManager {
 public:
  void SetExpectations(const std::string& expected_client_id,
                       const std::string& expected_selected_account_id) {
    expected_client_id_ = expected_client_id;
    expected_selected_account_id_ = expected_selected_account_id;
  }

  void SetExpectedTokenPostData(
      const std::string& expected_url_encoded_post_data) {
    expected_url_encoded_post_data_ = expected_url_encoded_post_data;
  }

  void FetchClientMetadata(const GURL& endpoint,
                           const std::string& client_id,
                           int rp_brand_icon_ideal_size,
                           int rp_brand_icon_minimum_size,
                           FetchClientMetadataCallback callback) override {
    if (expected_client_id_) {
      EXPECT_EQ(expected_client_id_, client_id);
    }
    TestIdpNetworkRequestManager::FetchClientMetadata(
        endpoint, client_id, rp_brand_icon_ideal_size,
        rp_brand_icon_minimum_size, std::move(callback));
  }

  bool SendAccountsRequest(const url::Origin& idp_origin,
                           const GURL& accounts_url,
                           const std::string& client_id,
                           AccountsRequestCallback callback) override {
    if (expected_client_id_) {
      EXPECT_EQ(expected_client_id_, client_id);
    }
    return TestIdpNetworkRequestManager::SendAccountsRequest(
        idp_origin, accounts_url, client_id, std::move(callback));
  }

  void SendTokenRequest(
      const GURL& token_url,
      const std::string& account,
      const std::string& url_encoded_post_data,
      bool idp_blindness,
      TokenRequestCallback callback,
      ContinueOnCallback on_continue,
      RecordErrorMetricsCallback record_error_metrics_callback) override {
    if (expected_selected_account_id_) {
      EXPECT_EQ(expected_selected_account_id_, account);
    }
    if (expected_url_encoded_post_data_) {
      EXPECT_EQ(expected_url_encoded_post_data_, url_encoded_post_data);
    }
    TestIdpNetworkRequestManager::SendTokenRequest(
        token_url, account, url_encoded_post_data, idp_blindness,
        std::move(callback), std::move(on_continue),
        std::move(record_error_metrics_callback));
  }

 private:
  std::optional<std::string> expected_client_id_;
  std::optional<std::string> expected_selected_account_id_;
  std::optional<std::string> expected_url_encoded_post_data_;
};

class TestDialogController
    : public NiceMock<MockIdentityRequestDialogController> {
 public:
  struct State {
    // State related to ShowAccountsDialog().
    // The list of all accounts passed to the UI.
    std::vector<IdentityRequestAccountPtr> all_accounts_for_display;
    std::optional<IdentityRequestAccount::SignInMode> sign_in_mode;
    blink::mojom::RpContext rp_context;
    std::vector<IdentityRequestAccountPtr> new_accounts;
    // The last seen background/text color from IdP metadata.
    std::optional<SkColor> brand_background_color;
    std::optional<SkColor> brand_text_color;
    // State related to ShowFailureDialog().
    size_t num_show_idp_signin_status_mismatch_dialog_requests{0u};
    // State related to ShowErrorDialog().
    bool did_show_error_dialog{false};
    std::optional<TokenError> token_error;
    // State related to ShowLoadingDialog().
    bool did_show_loading_dialog{false};
    // List of IDP strings for which a mismatch is shown in a test.
    std::vector<std::string> displayed_mismatch_idps;
  };

  explicit TestDialogController(MockConfiguration config)
      : accounts_dialog_action_(config.accounts_dialog_action),
        idp_signin_status_mismatch_dialog_action_(
            config.idp_signin_status_mismatch_dialog_action),
        error_dialog_action_(config.error_dialog_action),
        loading_dialog_action_(config.loading_dialog_action),
        should_show_accounts_passive_dialog_(
            !config.suppressed_by_segmentation_platform) {}

  ~TestDialogController() override = default;
  TestDialogController(TestDialogController&) = delete;
  TestDialogController& operator=(TestDialogController&) = delete;

  void SetState(State* state) { state_ = state; }

  void SetIdpSigninStatusMismatchDialogAction(
      IdpSigninStatusMismatchDialogAction action) {
    idp_signin_status_mismatch_dialog_action_ = action;
  }

  void ShouldShowAccountsPassiveDialog(
      ShouldShowAccountsPassiveDialogCallback cb) override {
    std::move(cb).Run(should_show_accounts_passive_dialog_);
  }

  bool ShowAccountsDialog(
      content::RelyingPartyData rp_data,
      const std::vector<IdentityProviderDataPtr>& idp_list,
      const std::vector<IdentityRequestAccountPtr>& accounts,
      blink::mojom::RpMode rp_mode,
      const std::vector<IdentityRequestAccountPtr>& new_accounts,
      IdentityRequestDialogController::AccountSelectionCallback on_selected,
      IdentityRequestDialogController::LoginToIdPCallback on_add_account,
      IdentityRequestDialogController::DismissCallback dismiss_callback,
      IdentityRequestDialogController::AccountsDisplayedCallback
          accounts_displayed_callback) override {
    if (!state_) {
      return false;
    }
    state_->all_accounts_for_display.clear();

    // Auto reauthn should not call ShowAccountsDialog.
    state_->sign_in_mode = SignInMode::kExplicit;
    state_->rp_context = idp_list[0]->rp_context;

    state_->new_accounts = new_accounts;

    state_->all_accounts_for_display = accounts;
    for (const auto& idp_data : idp_list) {
      if (idp_data->has_login_status_mismatch) {
        state_->displayed_mismatch_idps.push_back(idp_data->idp_for_display);
      }
      EXPECT_FALSE(idp_data->idp_metadata.brand_decoded_icon.IsEmpty());
      state_->brand_background_color =
          idp_data->idp_metadata.brand_background_color;
      state_->brand_text_color = idp_data->idp_metadata.brand_text_color;
    }

    switch (accounts_dialog_action_) {
      case AccountsDialogAction::kSelectFirstAccount: {
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE,
            base::BindOnce(
                std::move(on_selected),
                accounts[0]->identity_provider->idp_metadata.config_url,
                accounts[0]->id,
                accounts[0]->idp_claimed_login_state.value_or(
                    accounts[0]->browser_trusted_login_state) ==
                    LoginState::kSignIn));
        break;
      }
      case AccountsDialogAction::kClose:
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(dismiss_callback),
                                      DismissReason::kCloseButton));
        break;
      case AccountsDialogAction::kAddAccount:
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(on_add_account),
                                      idp_list[0]->idp_metadata.config_url,
                                      idp_list[0]->idp_metadata.idp_login_url));
        // Set `accounts_dialog_action_` such that subsequent calls will select
        // the first account.
        accounts_dialog_action_ = AccountsDialogAction::kSelectFirstAccount;
        break;
      case AccountsDialogAction::kNone:
        break;
    }
    did_show_ui_ = true;
    return true;
  }

  bool ShowFailureDialog(
      const RelyingPartyData& rp_data,
      const std::string& idp_for_display,
      blink::mojom::RpContext rp_context,
      blink::mojom::RpMode rp_mode,
      const IdentityProviderMetadata& idp_metadata,
      IdentityRequestDialogController::DismissCallback dismiss_callback,
      IdentityRequestDialogController::LoginToIdPCallback
          identity_registry_callback) override {
    if (!state_) {
      return false;
    }

    state_->displayed_mismatch_idps.push_back(idp_for_display);
    ++state_->num_show_idp_signin_status_mismatch_dialog_requests;
    switch (idp_signin_status_mismatch_dialog_action_) {
      case IdpSigninStatusMismatchDialogAction::kClose:
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(dismiss_callback),
                                      DismissReason::kCloseButton));
        break;
      case IdpSigninStatusMismatchDialogAction::kClosePopup:
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE,
            base::BindOnce(std::move(dismiss_callback), DismissReason::kOther));
        break;
      case IdpSigninStatusMismatchDialogAction::kNone:
        break;
    }
    did_show_ui_ = true;
    return true;
  }

  bool ShowErrorDialog(
      const RelyingPartyData& rp_data,
      const std::string& idp_for_display,
      blink::mojom::RpContext rp_context,
      blink::mojom::RpMode rp_mode,
      const IdentityProviderMetadata& idp_metadata,
      const std::optional<TokenError>& error,
      IdentityRequestDialogController::DismissCallback dismiss_callback,
      IdentityRequestDialogController::MoreDetailsCallback
          more_details_callback) override {
    if (!state_) {
      return false;
    }

    state_->did_show_error_dialog = true;
    state_->token_error = error;
    switch (error_dialog_action_) {
      case ErrorDialogAction::kClose:
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(dismiss_callback),
                                      DismissReason::kCloseButton));
        break;
      case ErrorDialogAction::kSwipe:
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE,
            base::BindOnce(std::move(dismiss_callback), DismissReason::kSwipe));
        break;
      case ErrorDialogAction::kGotIt:
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(dismiss_callback),
                                      DismissReason::kGotItButton));
        break;
      case ErrorDialogAction::kMoreDetails:
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(more_details_callback)));
        break;
      case ErrorDialogAction::kNone:
        break;
    }
    did_show_ui_ = true;
    return true;
  }

  bool ShowLoadingDialog(const RelyingPartyData& rp_data,
                         const std::string& idp_for_display,
                         blink::mojom::RpContext rp_context,
                         blink::mojom::RpMode rp_mode,
                         IdentityRequestDialogController::DismissCallback
                             dismiss_callback) override {
    if (!state_) {
      return false;
    }

    state_->did_show_loading_dialog = true;
    switch (loading_dialog_action_) {
      case LoadingDialogAction::kClose:
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(dismiss_callback),
                                      DismissReason::kCloseButton));
        break;
      case LoadingDialogAction::kNone:
        break;
    }
    return true;
  }

  bool ShowVerifyingDialog(
      const content::RelyingPartyData& rp_data,
      const scoped_refptr<IdentityProviderData>& idp_data,
      const scoped_refptr<content::IdentityRequestAccount>& account,
      content::IdentityRequestAccount::SignInMode sign_in_mode,
      blink::mojom::RpMode rp_mode,
      IdentityRequestDialogController::AccountsDisplayedCallback
          accounts_displayed_callback) override {
    if (!state_) {
      return false;
    }

    state_->sign_in_mode = sign_in_mode;
    state_->all_accounts_for_display = {account};
    did_show_ui_ = true;
    return true;
  }

  bool DidShowUi() const override { return did_show_ui_; }

  base::WeakPtr<TestDialogController> AsWeakPtr() {
    return weak_ptr_factory_.GetWeakPtr();
  }

  AccountsDialogAction accounts_dialog_action_{AccountsDialogAction::kNone};

 private:
  IdpSigninStatusMismatchDialogAction idp_signin_status_mismatch_dialog_action_{
      IdpSigninStatusMismatchDialogAction::kNone};
  ErrorDialogAction error_dialog_action_{ErrorDialogAction::kNone};
  LoadingDialogAction loading_dialog_action_{LoadingDialogAction::kNone};
  bool did_show_ui_ = false;
  bool should_show_accounts_passive_dialog_;

  // Pointer so that the state can be queried after RequestService
  // destroys TestDialogController.
  raw_ptr<State> state_;
  base::WeakPtrFactory<TestDialogController> weak_ptr_factory_{this};
};

class TestApiPermissionDelegate : public MockApiPermissionDelegate {
 public:
  using PermissionOverride = std::pair<url::Origin, ApiPermissionStatus>;
  PermissionOverride permission_override_ =
      std::make_pair(url::Origin(), ApiPermissionStatus::GRANTED);
  std::optional<std::pair<size_t, PermissionOverride>>
      permission_override_for_nth_;
  std::set<url::Origin> embargoed_origins_;
  size_t api_invocation_counter{0};

  ApiPermissionStatus GetApiPermissionStatus(
      const url::Origin& origin) override {
    ++api_invocation_counter;

    if (embargoed_origins_.count(origin)) {
      return ApiPermissionStatus::BLOCKED_EMBARGO;
    }

    if (permission_override_for_nth_ &&
        permission_override_for_nth_->first == api_invocation_counter) {
      return (origin == permission_override_for_nth_->second.first)
                 ? permission_override_for_nth_->second.second
                 : ApiPermissionStatus::GRANTED;
    }

    return (origin == permission_override_.first)
               ? permission_override_.second
               : ApiPermissionStatus::GRANTED;
  }

  void RecordDismissAndEmbargo(const url::Origin& origin) override {
    embargoed_origins_.insert(origin);
  }

  void RemoveEmbargoAndResetCounts(const url::Origin& origin) override {
    embargoed_origins_.erase(origin);
  }
};

class TestPermissionDelegate : public NiceMock<MockPermissionDelegate> {
 public:
  std::map<url::Origin, std::optional<bool>> idp_signin_statuses_;
  std::map<url::Origin, std::vector<IdentityRequestAccountPtr>>
      idp_account_profiles_;

  TestPermissionDelegate() = default;
  ~TestPermissionDelegate() override = default;

  TestPermissionDelegate(TestPermissionDelegate&) = delete;
  TestPermissionDelegate& operator=(TestPermissionDelegate&) = delete;

  std::optional<bool> GetIdpSigninStatus(
      const url::Origin& idp_origin) override {
    auto it = idp_signin_statuses_.find(idp_origin);
    return (it != idp_signin_statuses_.end()) ? it->second : std::nullopt;
  }

  void SetIdpSigninStatus(
      const url::Origin& idp_origin,
      bool idp_signin_status,
      base::optional_ref<const blink::common::webid::LoginStatusOptions>
          options) override {
    idp_signin_statuses_[idp_origin] = idp_signin_status;

    // Call parent so that EXPECT_CALL() works.
    NiceMock<MockPermissionDelegate>::SetIdpSigninStatus(
        idp_origin, idp_signin_status, std::nullopt);
  }

  void SetIdpAccounts(
      const url::Origin& idp_origin,
      std::vector<IdentityRequestAccountPtr>& request_accounts) {
    idp_account_profiles_[idp_origin] = std::move(request_accounts);
  }
};

class TestAutoReauthnPermissionDelegate
    : public MockAutoReauthnPermissionDelegate {
 public:
  std::set<url::Origin> embargoed_origins_;

  void RecordEmbargoForAutoReauthn(const url::Origin& origin) override {
    embargoed_origins_.insert(origin);
  }
};

class TestIdentityRegistry : public NiceMock<MockIdentityRegistry> {
 public:
  bool notified_{false};

  explicit TestIdentityRegistry(
      content::WebContents* web_contents,
      base::WeakPtr<IdentityRegistryDelegate> delegate,
      const GURL& idp_config_url)
      : NiceMock<MockIdentityRegistry>(web_contents, delegate, idp_config_url) {
  }

  void NotifyClose(const url::Origin& notifier_origin) override {
    notified_ = true;
  }
};

}  // namespace

class RequestServiceTest : public RenderViewHostImplTestHarness {
 protected:
  explicit RequestServiceTest(std::string_view rp_url = kRpUrl)
      : rp_url_(rp_url) {
    ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
  }
  ~RequestServiceTest() override = default;

  void InitConstants() {
    kSingleAccount = {base::MakeRefCounted<IdentityRequestAccount>(
        kAccountId,                  // id
        kEmail,                      // display_identifier
        "Ken R. Example",            // display_name
        kEmail,                      // email
        "Ken R. Example",            // name
        "Ken",                       // given_name
        GURL(),                      // picture
        "(650) 312-3223",            // phone number
        "kenr",                      // username
        std::vector<std::string>(),  // login_hints
        std::vector<std::string>(),  // domain_hints
        std::vector<std::string>()   // labels
        )};
    kDefaultIdentityProviderInfo = {
        {kWellKnown, {ParseStatus::kSuccess, net::HTTP_OK}},
        {{ParseStatus::kSuccess, net::HTTP_OK},
         kAccountsEndpoint,
         kTokenEndpoint,
         kClientMetadataEndpoint,
         kMetricsEndpoint,
         kIdpLoginUrl,
         kIdpDisconnectUrl,
         /*brand_background_color=*/std::nullopt,
         /*brand_text_color=*/std::nullopt},
        kDefaultClientMetadata,
        {ParseStatus::kSuccess, net::HTTP_OK},
        kSingleAccount,
    };
    kSingleProviderInfo = {{kProviderUrlFull, kDefaultIdentityProviderInfo}};
    kSingleAccountWithHint = {base::MakeRefCounted<IdentityRequestAccount>(
        kAccountId,                  // id
        kEmail,                      // display_identifier
        "Ken R. Example",            // display_name
        kEmail,                      // email
        "Ken R. Example",            // name
        "Ken",                       // given_name
        GURL(),                      // picture
        "(650) 312-3223",            // phone number
        "kenr",                      // username
        kLoginHints,                 // login_hints
        std::vector<std::string>(),  // domain_hints
        std::vector<std::string>()   // labels
        )};
    kSingleAccountWithDomainHint = {
        base::MakeRefCounted<IdentityRequestAccount>(
            kAccountId,                  // id
            kEmail,                      // display_identifier
            "Ken R. Example",            // display_name
            kEmail,                      // email
            "Ken R. Example",            // name
            "Ken",                       // given_name
            GURL(),                      // picture
            "(650) 312-3223",            // phone number
            "kenr",                      // username
            std::vector<std::string>(),  // login_hints
            kDomainHintVector,           // domain_hints
            std::vector<std::string>()   // labels
            )};
    kTwoAccounts = {base::MakeRefCounted<IdentityRequestAccount>(
                        kAccountIdNicolas,           // id
                        kAccountEmailNicolas,        // display_identifier
                        "Nicolas P",                 // display_name
                        kAccountEmailNicolas,        // email
                        "Nicolas P",                 // name
                        "Nicolas",                   // given_name
                        GURL(),                      // picture
                        "(650) 312-3223",            // phone number
                        "npm",                       // username
                        std::vector<std::string>(),  // login_hints
                        std::vector<std::string>(),  // domain_hints
                        std::vector<std::string>(),  // labels
                        LoginState::kSignUp          // login_state
                        ),
                    base::MakeRefCounted<IdentityRequestAccount>(
                        kAccountIdZach,              // id
                        "zach@email.com",            // display_identifier
                        "Zachary T",                 // display_name
                        "zach@email.com",            // email
                        "Zachary T",                 // name
                        "Zach",                      // given_name
                        GURL(),                      // picture
                        "(650) 312-3223",            // phone number
                        "tanz",                      // username
                        std::vector<std::string>(),  // login_hints
                        std::vector<std::string>(),  // domain_hints
                        std::vector<std::string>(),  // labels
                        LoginState::kSignUp          // login_state
                        )};
    kMultipleAccounts = {base::MakeRefCounted<IdentityRequestAccount>(
                             kAccountIdNicolas,           // id
                             kAccountEmailNicolas,        // display_identifier
                             "Nicolas P",                 // display_name
                             kAccountEmailNicolas,        // email
                             "Nicolas P",                 // name
                             "Nicolas",                   // given_name
                             GURL(),                      // picture
                             "(650) 312-3223",            // phone number
                             "npm",                       // username
                             std::vector<std::string>(),  // login_hints
                             std::vector<std::string>(),  // domain_hints
                             std::vector<std::string>(),  // labels
                             LoginState::kSignUp          // login_state
                             ),
                         base::MakeRefCounted<IdentityRequestAccount>(
                             kAccountIdPeter,             // id
                             kAccountEmailPeter,          // display_identifier
                             "Peter K",                   // display_name
                             kAccountEmailPeter,          // email
                             "Peter K",                   // name
                             "Peter",                     // given_name
                             GURL(),                      // picture
                             "(650) 312-3223",            // phone number
                             "peter",                     // username
                             std::vector<std::string>(),  // login_hints
                             std::vector<std::string>(),  // domain_hints
                             std::vector<std::string>(),  // labels
                             LoginState::kSignIn          // login_state
                             ),
                         base::MakeRefCounted<IdentityRequestAccount>(
                             kAccountIdZach,              // id
                             "zach@email.com",            // display_identifier
                             "Zachary T",                 // display_name
                             "zach@email.com",            // email
                             "Zachary T",                 // name
                             "Zach",                      // given_name
                             GURL(),                      // picture
                             "(650) 312-3223",            // phone number
                             "zacht",                     // username
                             std::vector<std::string>(),  // login_hints
                             std::vector<std::string>(),  // domain_hints
                             std::vector<std::string>(),  // labels
                             LoginState::kSignUp          // login_state
                             )};
    kMultipleAccountsWithHintsAndDomains = {
        base::MakeRefCounted<IdentityRequestAccount>(
            kAccountIdNicolas,           // id
            kAccountEmailNicolas,        // display_identifier
            "Nicolas P",                 // display_name
            kAccountEmailNicolas,        // email
            "Nicolas P",                 // name
            "Nicolas",                   // given_name
            GURL(),                      // picture
            "(650) 312-3223",            // phone number
            "npm",                       // username
            kNicolasHints,               // login_hints
            kDomainHintVector,           // domain_hints
            std::vector<std::string>(),  // labels
            LoginState::kSignUp          // login_state
            ),
        base::MakeRefCounted<IdentityRequestAccount>(
            kAccountIdPeter,             // id
            kAccountEmailPeter,          // display_identifier
            "Peter K",                   // display_name
            kAccountEmailPeter,          // email
            "Peter K",                   // name
            "Peter",                     // given_name
            GURL(),                      // picture
            "(650) 312-3223",            // phone number
            "peterk",                    // username
            kPeterHints,                 // login_hints
            std::vector<std::string>(),  // domain_hints
            kLabelVector,                // labels
            LoginState::kSignIn          // login_state
            ),
        base::MakeRefCounted<IdentityRequestAccount>(
            kAccountIdZach,              // id
            kAccountEmailZach,           // display_identifier
            "Zachary T",                 // display_name
            kAccountEmailZach,           // email
            "Zachary T",                 // name
            "Zach",                      // given_name
            GURL(),                      // picture
            "(650) 312-3223",            // phone number
            "zacht",                     // username
            kZachHints,                  // login_hints
            kTwoDomainHints,             // domain_hints
            std::vector<std::string>(),  // labels
            LoginState::kSignUp          // login_state
            )};
    kProviderTwoInfo = {{{kProviderTwoUrlFull}},
                        {{ParseStatus::kSuccess, net::HTTP_OK},
                         "https://idp2.example/accounts",
                         "https://idp2.example/token",
                         "https://idp2.example/client_metadata",
                         "https://idp2.example/metrics",
                         "https://idp2.example/login_url",
                         "https://idp2.example/disconnect",
                         /*brand_background_color=*/std::nullopt,
                         /*brand_text_color=*/std::nullopt},
                        kDefaultClientMetadata,
                        {ParseStatus::kSuccess, net::HTTP_OK},
                        kMultipleAccounts};
    kConfigurationValid = {kToken,
                           kSingleProviderInfo,
                           {ParseStatus::kSuccess, net::HTTP_OK},
                           /*delay_token_response=*/false,
                           AccountsDialogAction::kSelectFirstAccount,
                           IdpSigninStatusMismatchDialogAction::kNone,
                           ErrorDialogAction::kClose,
                           LoadingDialogAction::kNone};
    kConfigurationMultiIdpValid = {
        kToken,
        {{kProviderUrlFull, kDefaultIdentityProviderInfo},
         {kProviderTwoUrlFull, kProviderTwoInfo}},
        {ParseStatus::kSuccess, net::HTTP_OK},
        false /* delay_token_response */,
        AccountsDialogAction::kSelectFirstAccount,
        IdpSigninStatusMismatchDialogAction::kNone,
        ErrorDialogAction::kClose,
        LoadingDialogAction::kNone};
  }

  void SetUp() override {
    RenderViewHostImplTestHarness::SetUp();
    // Initialize the accounts and account-dependent constants on SetUp() to
    // ensure they are initialized correctly in every test.
    InitConstants();

    test_api_permission_delegate_ =
        std::make_unique<TestApiPermissionDelegate>();
    test_permission_delegate_ = std::make_unique<TestPermissionDelegate>();
    test_auto_reauthn_permission_delegate_ =
        std::make_unique<TestAutoReauthnPermissionDelegate>();
    test_identity_registry_ = std::make_unique<TestIdentityRegistry>(
        web_contents(), /*delegate=*/nullptr, GURL(kIdpUrl));
    auth_helper_ = std::make_unique<AuthRequestCallbackHelper>();

    static_cast<TestWebContents*>(web_contents())
        ->NavigateAndCommit(GURL(rp_url_), ui::PAGE_TRANSITION_LINK);

    federated_auth_request_impl_ = &RequestService::CreateForTesting(
        *main_test_rfh(), test_api_permission_delegate_.get(),
        test_auto_reauthn_permission_delegate_.get(),
        test_permission_delegate_.get(), test_identity_registry_.get(),
        request_remote_.BindNewPipeAndPassReceiver());

    std::unique_ptr<TestIdpNetworkRequestManager> network_request_manager =
        std::make_unique<TestIdpNetworkRequestManager>();
    SetNetworkRequestManager(std::move(network_request_manager));
  }

  void SetNetworkRequestManager(
      std::unique_ptr<TestIdpNetworkRequestManager> manager) {
    test_network_request_manager_ = std::move(manager);
    // DelegatedIdpNetworkRequestManager is owned by
    // |federated_auth_request_impl_|.
    federated_auth_request_impl_->SetNetworkManagerForTests(
        std::make_unique<DelegatedIdpNetworkRequestManager>(
            test_network_request_manager_.get()));
  }

  // Sets the TestDialogController to be used for the next call of
  // RunAuthTest().
  void SetDialogController(
      std::unique_ptr<TestDialogController> dialog_controller) {
    custom_dialog_controller_ = std::move(dialog_controller);
  }

  void RunAuthTest(
      const RequestParameters& request_parameters,
      const RequestExpectations& expectations,
      const MockConfiguration& configuration,
      AuthRequestCallbackHelper* concurrent_auth_helper = nullptr) {
    AuthRequestCallbackHelper* auth_helper =
        concurrent_auth_helper ?: auth_helper_.get();
    request_remote_.set_disconnect_handler(auth_helper->quit_closure());

    RunAuthDontWaitForCallback(request_parameters, configuration, auth_helper);
    WaitForCurrentAuthRequest(/*should_fast_forward=*/true, auth_helper);
    CheckAuthExpectations(configuration, expectations, auth_helper);
  }

  void RunAuthDontWaitForCallback(
      const RequestParameters& request_parameters,
      const MockConfiguration& configuration,
      AuthRequestCallbackHelper* auth_helper = nullptr) {
    if (!custom_dialog_controller_) {
      custom_dialog_controller_ =
          std::make_unique<TestDialogController>(configuration);
    }

    dialog_controller_state_ = TestDialogController::State();
    custom_dialog_controller_->SetState(&dialog_controller_state_);
    federated_auth_request_impl_->SetDialogControllerForTests(
        std::move(custom_dialog_controller_));

    SetConfig(configuration);

    // If multiple IdPs are received, add them to a single get call. Unittests
    // for multiple get calls can be added later as needed.
    std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> idp_ptrs;
    for (const auto& identity_provider :
         request_parameters.identity_providers) {
      blink::mojom::IdentityProviderRequestOptionsPtr options =
          blink::mojom::IdentityProviderRequestOptions::New();
      options->config = blink::mojom::IdentityProviderConfig::New();
      options->config->config_url = GURL(identity_provider.provider);
      options->config->client_id = identity_provider.client_id;
      options->config->from_idp_registration_api =
          identity_provider.from_idp_registration_api;
      options->nonce = identity_provider.nonce;
      options->login_hint = identity_provider.login_hint;
      options->domain_hint = identity_provider.domain_hint;
      options->fields = std::move(identity_provider.fields);
      if (identity_provider.params_json) {
        options->params_json = identity_provider.params_json;
      }
      if (identity_provider.type) {
        options->config->type = *identity_provider.type;
      }
      idp_ptrs.push_back(std::move(options));
    }
    blink::mojom::IdentityProviderGetParametersPtr get_params =
        blink::mojom::IdentityProviderGetParameters::New(
            std::move(idp_ptrs), request_parameters.rp_context,
            request_parameters.rp_mode);
    std::vector<blink::mojom::IdentityProviderGetParametersPtr> idp_get_params;
    idp_get_params.push_back(std::move(get_params));

    auth_helper = auth_helper ?: auth_helper_.get();
    PerformAuthRequest(std::move(idp_get_params),
                       configuration.mediation_requirement, auth_helper);
  }

  void CheckAuthExpectations(const MockConfiguration& configuration,
                             const RequestExpectations& expectation,
                             AuthRequestCallbackHelper* auth_helper = nullptr) {
    auth_helper = auth_helper ?: auth_helper_.get();
    ASSERT_EQ(expectation.return_status, auth_helper->status());
    if (expectation.return_status == RequestTokenStatus::kSuccess) {
      EXPECT_EQ(configuration.token, auth_helper->token());
    } else {
      EXPECT_TRUE(auth_helper->token() == std::nullopt ||
                  auth_helper->token() == kEmptyToken);
    }

    if (expectation.return_status == RequestTokenStatus::kSuccess) {
      EXPECT_TRUE(DidFetchWellKnownAndConfig());
      if (!base::FeatureList::IsEnabled(features::kFedCmLightweightMode)) {
        EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
      }
      EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
      // FetchedEndpoint::CLIENT_METADATA is optional.

      EXPECT_EQ(did_show_accounts_dialog(),
                !expectation.is_auto_selected ||
                    configuration.rp_mode != blink::mojom::RpMode::kActive);
    }

    EXPECT_EQ(expectation.is_auto_selected, auth_helper->is_auto_selected());

    EXPECT_EQ(expectation.selected_idp_config_url,
              auth_helper->selected_idp_config_url());

    if (expectation.devtools_issue_status !=
        FederatedAuthRequestResult::kSuccess) {
      int issue_count = main_test_rfh()->GetFederatedAuthRequestIssueCount(
          expectation.devtools_issue_status);
      EXPECT_LE(1, issue_count);
    } else {
      int issue_count =
          main_test_rfh()->GetFederatedAuthRequestIssueCount(std::nullopt);
      if (!expectation.standalone_console_message) {
        EXPECT_EQ(0, issue_count);
      } else {
        EXPECT_GE(1, issue_count);
      }
    }
    CheckConsoleMessages(expectation.devtools_issue_status,
                         expectation.standalone_console_message);
  }

  void SetConfig(const MockConfiguration& config) {
    test_network_request_manager_->SetTestConfig(config);
  }

  void CheckConsoleMessages(
      FederatedAuthRequestResult devtools_issue_status,
      const std::optional<std::string>& standalone_console_message) {
    std::vector<std::string> messages =
        RenderFrameHostTester::For(main_rfh())->GetConsoleMessages();

    // TODO(crbug.com/451219310): Remove when FedCM deprecation warnings
    // removed. Filter out known deprecation warnings
    std::vector<std::string> filtered_messages;
    for (const auto& message : messages) {
      if (message.find("Top-level nonce support will be removed") ==
              std::string::npos &&
          message.find("The FedCM configuration uses client_metadata") ==
              std::string::npos) {
        filtered_messages.push_back(message);
      }
    }
    messages = std::move(filtered_messages);

    bool did_expect_any_messages = false;
    size_t expected_message_index = messages.size() - 1;
    if (devtools_issue_status != FederatedAuthRequestResult::kSuccess) {
      std::string expected_message =
          GetConsoleErrorMessageFromResult(devtools_issue_status);
      did_expect_any_messages = true;
      ASSERT_GE(expected_message_index, 0u);
      EXPECT_EQ(expected_message, messages[expected_message_index--]);
    }
    if (standalone_console_message) {
      did_expect_any_messages = true;
      ASSERT_EQ(expected_message_index, 0u);
      EXPECT_EQ(*standalone_console_message, messages[0]);
    }

    if (!did_expect_any_messages) {
      EXPECT_EQ(0u, messages.size());
    }
  }

  void PerformAuthRequest(
      std::vector<blink::mojom::IdentityProviderGetParametersPtr>
          idp_get_params,
      MediationRequirement mediation_requirement,
      AuthRequestCallbackHelper* auth_helper = nullptr) {
    auth_helper = auth_helper ?: auth_helper_.get();
    request_remote_->RequestToken(std::move(idp_get_params),
                                  mediation_requirement,
                                  auth_helper->callback());

    // Ensure that the request makes its way to RequestService.
    request_remote_.FlushForTesting();
    base::RunLoop().RunUntilIdle();
  }

  void WaitForCurrentAuthRequest(
      bool should_fast_forward = true,
      AuthRequestCallbackHelper* auth_helper = nullptr) {
    auth_helper = auth_helper ?: auth_helper_.get();
    request_remote_.set_disconnect_handler(auth_helper->quit_closure());

    // Fast forward clock so that the pending
    // RequestService::OnRejectRequest() task, if any, gets a
    // chance to run.
    if (should_fast_forward) {
      task_environment()->FastForwardBy(base::Minutes(10));
    }
    auth_helper->WaitForCallback();

    request_remote_.set_disconnect_handler(base::OnceClosure());
  }

  void CloseDialog() {
    federated_auth_request_impl_->OnDialogDismissed(
        IdentityRequestDialogController::DismissReason::kCloseButton);
  }

  void CompleteDisconnectRequest() {
    std::unique_ptr<TestIdpNetworkRequestManager> network_request_manager =
        std::make_unique<TestIdpNetworkRequestManager>();
    std::unique_ptr<Metrics> fedcm_metrics =
        std::make_unique<Metrics>(main_test_rfh()->GetPageUkmSourceId());
    blink::mojom::IdentityCredentialDisconnectOptionsPtr options =
        blink::mojom::IdentityCredentialDisconnectOptions::New();
    options->config = blink::mojom::IdentityProviderConfig::New();
    options->config->config_url = GURL(kProviderUrlFull);
    federated_auth_request_impl_->disconnect_request_ =
        DisconnectRequest::Create(
            std::move(network_request_manager), test_permission_delegate_.get(),
            main_test_rfh(), std::move(fedcm_metrics), std::move(options));
    federated_auth_request_impl_->disconnect_request_->callback_ =
        base::DoNothing();
    federated_auth_request_impl_->disconnect_request_->Complete(
        blink::mojom::DisconnectStatus::kSuccess, DisconnectStatus::kSuccess);
  }

  base::span<const IdentityRequestAccountPtr> all_accounts_for_display() const {
    return dialog_controller_state_.all_accounts_for_display;
  }

  base::span<const IdentityRequestAccountPtr> new_accounts() const {
    return dialog_controller_state_.new_accounts;
  }

  std::vector<std::string> displayed_mismatch_idps() const {
    return dialog_controller_state_.displayed_mismatch_idps;
  }

  bool did_show_accounts_dialog() const {
    return !all_accounts_for_display().empty();
  }
  bool did_show_idp_signin_status_mismatch_dialog() const {
    return dialog_controller_state_
        .num_show_idp_signin_status_mismatch_dialog_requests;
  }

  std::optional<SkColor> brand_background_color() const {
    return dialog_controller_state_.brand_background_color;
  }

  std::optional<SkColor> brand_text_color() const {
    return dialog_controller_state_.brand_text_color;
  }

  int CountNumLoginStateIsSignin() {
    int num_sign_in_login_state = 0;
    for (const auto& account : all_accounts_for_display()) {
      if (account->idp_claimed_login_state.value_or(
              account->browser_trusted_login_state) == LoginState::kSignIn) {
        ++num_sign_in_login_state;
      }
    }
    return num_sign_in_login_state;
  }

  bool DidFetchAnyEndpoint() {
    for (auto& [endpoint, num] : test_network_request_manager_->num_fetched_) {
      if (num > 0) {
        return true;
      }
    }
    return false;
  }

  // Convenience method as WELL_KNOWN and CONFIG endpoints are fetched in
  // parallel.
  bool DidFetchWellKnownAndConfig() {
    return DidFetch(FetchedEndpoint::WELL_KNOWN) &&
           DidFetch(FetchedEndpoint::CONFIG);
  }

  bool DidFetch(FetchedEndpoint endpoint) { return NumFetched(endpoint) > 0u; }

  size_t NumFetched(FetchedEndpoint endpoint) {
    return test_network_request_manager_->num_fetched_[endpoint];
  }

  ukm::TestAutoSetUkmRecorder* ukm_recorder() { return ukm_recorder_.get(); }

  void ExpectStatusMetrics(
      TokenStatus status,
      MediationRequirement requirement = MediationRequirement::kOptional) {
    histogram_tester_.ExpectUniqueSample("Blink.FedCm.Status.RequestIdToken",
                                         status, 1);
    histogram_tester_.ExpectUniqueSample(
        "Blink.FedCm.Status.MediationRequirement", requirement, 1);
    if (status == RequestIdTokenStatus::kSuccessUsingTokenInHttpResponse ||
        status == RequestIdTokenStatus::kSuccessUsingIdentityProviderResolve) {
      histogram_tester_.ExpectUniqueSample(
          kBrowserAssistedLoginTypeHistogram,
          BrowserAssistedLoginType::kFedCmPassive, 1);
    }
    ExpectStatusUKMInternal(status, requirement, FedCmEntry::kEntryName);
    ExpectStatusUKMInternal(status, requirement, FedCmIdpEntry::kEntryName);
  }

  void ExpectStatusUKMInternal(TokenStatus status,
                               MediationRequirement requirement,
                               const char* entry_name) {
    auto entries = ukm_recorder()->GetEntriesByName(entry_name);

    ASSERT_FALSE(entries.empty())
        << "No " << entry_name << " entry was recorded";

    // There are multiple types of metrics under the same FedCM UKM. We need to
    // make sure that the metric only includes the expected one.
    bool metric_found = false;
    for (const ukm::mojom::UkmEntry* const entry : entries) {
      const int64_t* metric =
          ukm_recorder()->GetEntryMetric(entry, "Status.RequestIdToken");
      if (!metric) {
        continue;
      }
      EXPECT_FALSE(metric_found)
          << "Found more than one entry with Status.RequestIdToken in "
          << entry_name;
      metric_found = true;
      EXPECT_EQ(static_cast<int>(status), *metric)
          << "Unexpected status recorded in " << entry_name;
    }
    EXPECT_TRUE(metric_found)
        << "No Status.RequestIdToken entry was found in " << entry_name;
  }

  void ExpectUKMPresence(const std::string& metric_name) {
    ExpectUKMPresenceInternal(metric_name, FedCmEntry::kEntryName);
    ExpectUKMPresenceInternal(metric_name, FedCmIdpEntry::kEntryName);
  }

  void ExpectUKMPresenceInternal(const std::string& metric_name,
                                 const char* entry_name) {
    auto entries = ukm_recorder()->GetEntriesByName(entry_name);

    ASSERT_FALSE(entries.empty())
        << "No " << entry_name << " entry was recorded";

    for (const ukm::mojom::UkmEntry* const entry : entries) {
      if (ukm_recorder()->GetEntryMetric(entry, metric_name)) {
        SUCCEED();
        return;
      }
    }
    FAIL() << "Expected UKM " << metric_name << " was not recorded in "
           << entry_name;
  }

  void ExpectNoUKMPresence(const std::string& metric_name) {
    ExpectNoUKMPresenceInternal(metric_name, FedCmEntry::kEntryName);
    ExpectNoUKMPresenceInternal(metric_name, FedCmIdpEntry::kEntryName);
  }

  void ExpectNoUKMPresenceInternal(const std::string& metric_name,
                                   const char* entry_name) {
    auto entries = ukm_recorder()->GetEntriesByName(entry_name);

    ASSERT_FALSE(entries.empty())
        << "No " << entry_name << " entry was recorded";

    for (const ukm::mojom::UkmEntry* const entry : entries) {
      if (ukm_recorder()->GetEntryMetric(entry, metric_name)) {
        FAIL() << "Unexpectedly found " << metric_name << " UKM in "
               << entry_name;
      }
    }
    SUCCEED();
  }

  void ExpectUKMCount(const std::string& metric_name,
                      const char* entry_name,
                      int expected_count) {
    int count = 0;
    auto entries = ukm_recorder()->GetEntriesByName(entry_name);
    for (const ukm::mojom::UkmEntry* const entry : entries) {
      if (ukm_recorder()->GetEntryMetric(entry, metric_name)) {
        ++count;
      }
    }
    EXPECT_EQ(count, expected_count) << "Did not find the expected count for "
                                     << metric_name << " in " << entry_name;
  }

  void ExpectUkmValue(const std::string& metric_name,
                      int expected_value,
                      int num_idps = 1) {
    ExpectUkmValueInEntry(metric_name, FedCmEntry::kEntryName, expected_value);
    ExpectUkmValueInEntry(metric_name, FedCmIdpEntry::kEntryName,
                          expected_value, num_idps);
  }

  void ExpectUkmValueInEntry(const std::string& metric_name,
                             const char* entry_name,
                             int expected_value,
                             int expected_count = 1,
                             bool other_values_allowed = false) {
    auto entries = ukm_recorder()->GetEntriesByName(entry_name);
    int count = 0;
    for (const ukm::mojom::UkmEntry* const entry : entries) {
      const int64_t* value = ukm_recorder()->GetEntryMetric(entry, metric_name);
      if (!value) {
        continue;
      }
      ++count;
      if (!other_values_allowed) {
        EXPECT_EQ(*value, expected_value);
      }
    }
    EXPECT_EQ(count, expected_count);
    EXPECT_GT(count, 0) << "Did not find " << metric_name << " in "
                        << entry_name;
  }

  void ExpectSignInStateMatchStatusUKM(SignInStateMatchStatus status) {
    ExpectSignInStateMatchStatusUKMInternal(status, FedCmEntry::kEntryName);
    ExpectSignInStateMatchStatusUKMInternal(status, FedCmIdpEntry::kEntryName);
  }

  void ExpectSignInStateMatchStatusUKMInternal(SignInStateMatchStatus status,
                                               const char* entry_name) {
    auto entries = ukm_recorder()->GetEntriesByName(entry_name);

    ASSERT_FALSE(entries.empty()) << "No FedCm entry was recorded";

    // There are multiple types of metrics under the same FedCM UKM. We need to
    // make sure that the metric only includes the expected one.
    bool metric_found = false;
    for (const ukm::mojom::UkmEntry* const entry : entries) {
      const int64_t* metric =
          ukm_recorder()->GetEntryMetric(entry, "Status.SignInStateMatch");
      if (!metric) {
        continue;
      }
      EXPECT_FALSE(metric_found)
          << "Found more than one Status.SignInStateMatch";
      metric_found = true;
      EXPECT_EQ(static_cast<int>(status), *metric);
    }
    EXPECT_TRUE(metric_found) << "No Status.SignInStateMatch was found";
  }

  void ExpectAutoReauthnMetrics(
      std::optional<Metrics::NumAccounts> expected_returning_accounts,
      bool expected_succeeded,
      bool expected_auto_reauthn_setting_blocked,
      bool expected_auto_reauthn_embargoed,
      bool expected_prevent_silent_access,
      bool expected_auto_reauthn_blocked_by_embedder) {
    // UMA checks
    histogram_tester_.ExpectUniqueSample("Blink.FedCm.AutoReauthn.Succeeded",
                                         expected_succeeded, 1);
    if (expected_returning_accounts.has_value()) {
      histogram_tester_.ExpectUniqueSample(
          "Blink.FedCm.AutoReauthn.ReturningAccounts",
          static_cast<int>(*expected_returning_accounts), 1);
    } else {
      histogram_tester_.ExpectTotalCount(
          "Blink.FedCm.AutoReauthn.ReturningAccounts", 0);
    }
    histogram_tester_.ExpectUniqueSample(
        "Blink.FedCm.AutoReauthn.BlockedByEmbedder",
        expected_auto_reauthn_blocked_by_embedder, 1);
    histogram_tester_.ExpectUniqueSample(
        "Blink.FedCm.AutoReauthn.BlockedByContentSettings",
        expected_auto_reauthn_setting_blocked, 1);
    histogram_tester_.ExpectUniqueSample(
        "Blink.FedCm.AutoReauthn.BlockedByEmbargo",
        expected_auto_reauthn_embargoed, 1);
    histogram_tester_.ExpectTotalCount(
        "Blink.FedCm.AutoReauthn.TimeFromEmbargoWhenBlocked",
        expected_auto_reauthn_embargoed ? 1 : 0);
    histogram_tester_.ExpectUniqueSample(
        "Blink.FedCm.AutoReauthn.BlockedByPreventSilentAccess",
        expected_prevent_silent_access, 1);
    if (expected_succeeded) {
      histogram_tester_.ExpectTotalCount(
          "Blink.FedCm.Timing.AccountsDialogShownDuration2", 0);
      histogram_tester_.ExpectUniqueSample(
          "Blink.FedCm.VerifyingDialogResult",
          VerifyingDialogResult::kSuccessAutoReauthn, 1);
    }

    // UKM checks
    auto entries = ukm_recorder()->GetEntriesByName(FedCmEntry::kEntryName);
    ASSERT_FALSE(entries.empty()) << "No FedCM UKM entry was found!";

    bool metric_found = false;
    for (const ukm::mojom::UkmEntry* entry : entries) {
      const int64_t* metric =
          ukm_recorder()->GetEntryMetric(entry, "AutoReauthn.Succeeded");
      if (!metric) {
        EXPECT_FALSE(ukm_recorder()->GetEntryMetric(
            entry, "AutoReauthn.ReturningAccounts"));
        EXPECT_FALSE(ukm_recorder()->GetEntryMetric(
            entry, "AutoReauthn.BlockedByContentSettings"));
        EXPECT_FALSE(ukm_recorder()->GetEntryMetric(
            entry, "AutoReauthn.BlockedByEmbargo"));
        EXPECT_FALSE(ukm_recorder()->GetEntryMetric(
            entry, "AutoReauthn.TimeFromEmbargoWhenBlocked"));
        EXPECT_FALSE(ukm_recorder()->GetEntryMetric(
            entry, "AutoReauthn.BlockedByPreventSilentAccess"));
        continue;
      }
      EXPECT_FALSE(metric_found) << "Found more than one AutoReauthn entry";
      metric_found = true;
      EXPECT_EQ(expected_succeeded, *metric);

      metric = ukm_recorder()->GetEntryMetric(entry,
                                              "AutoReauthn.ReturningAccounts");
      if (expected_returning_accounts) {
        ASSERT_TRUE(metric) << "AutoReauthn.ReturningAccounts was not found";
        EXPECT_EQ(static_cast<int>(*expected_returning_accounts), *metric);
      } else {
        EXPECT_FALSE(metric)
            << "AutoReauthn.ReturningAccounts should not have been recorded";
      }

      metric = ukm_recorder()->GetEntryMetric(
          entry, "AutoReauthn.BlockedByContentSettings");
      ASSERT_TRUE(metric)
          << "AutoReauthn.BlockedByContentSettings was not found";
      EXPECT_EQ(expected_auto_reauthn_setting_blocked, *metric);

      metric =
          ukm_recorder()->GetEntryMetric(entry, "AutoReauthn.BlockedByEmbargo");
      ASSERT_TRUE(metric) << "AutoReauthn.BlockedByEmbargo was not found";
      EXPECT_EQ(expected_auto_reauthn_embargoed, *metric);

      metric = ukm_recorder()->GetEntryMetric(
          entry, "AutoReauthn.TimeFromEmbargoWhenBlocked");
      EXPECT_EQ(expected_auto_reauthn_embargoed, !!metric);

      metric = ukm_recorder()->GetEntryMetric(
          entry, "AutoReauthn.BlockedByPreventSilentAccess");
      ASSERT_TRUE(metric)
          << "AutoReauthn.BlockedByPreventSilentAccess was not found";
      EXPECT_EQ(expected_prevent_silent_access, *metric);
    }
    EXPECT_TRUE(metric_found) << "Did not find AutoReauthn metrics";
    if (expected_succeeded) {
      ExpectNoUKMPresence("Timing.AccountsDialogShownDuration");
      ExpectUKMPresence("VerifyingDialogResult");
    }
  }

  void CheckAllFedCmSessionIDs(size_t expected_num_session_ids = 1u,
                               bool check_request_id_token = false) {
    auto CheckUKMSessionID = [&](const auto& ukm_entries) {
      std::set<int> session_ids;
      std::set<int> session_ids_with_request_id_token;
      ASSERT_FALSE(ukm_entries.empty());
      for (const ukm::mojom::UkmEntry* const entry : ukm_entries) {
        const auto* metric =
            ukm_recorder()->GetEntryMetric(entry, "NumRequestsPerDocument");
        if (metric) {
          continue;
        }
        metric = ukm_recorder()->GetEntryMetric(entry, "FedCmSessionID");
        ASSERT_TRUE(metric)
            << "All UKM events except for NumRequestsPerDocument should have "
               "the SessionID metric";
        int session_id = *metric;
        session_ids.insert(session_id);
        metric = ukm_recorder()->GetEntryMetric(entry, "Status.RequestIdToken");
        if (!metric || !check_request_id_token) {
          continue;
        }
        ASSERT_FALSE(session_ids_with_request_id_token.contains(session_id))
            << "A single session ID should only have one RequestIdToken";
        session_ids_with_request_id_token.insert(session_id);
      }
      EXPECT_EQ(session_ids.size(), expected_num_session_ids);
      if (check_request_id_token) {
        EXPECT_EQ(session_ids_with_request_id_token.size(),
                  expected_num_session_ids);
      }
    };
    CheckUKMSessionID(ukm_recorder()->GetEntriesByName(FedCmEntry::kEntryName));
    CheckUKMSessionID(
        ukm_recorder()->GetEntriesByName(FedCmIdpEntry::kEntryName));
  }

  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr>
  MaybeAddRegisteredProviders(
      std::vector<blink::mojom::IdentityProviderRequestOptionsPtr>& providers) {
    return federated_auth_request_impl_->MaybeAddRegisteredProviders(providers);
  }

  void ExpectTwoUniqueSessionIDs() {
    auto CheckSessionIDs([&](const char* entry_name) {
      std::vector<int64_t> session_ids =
          ukm_recorder()->GetMetricsEntryValues(entry_name, "FedCmSessionID");
      ASSERT_EQ(2, session_ids.size());
      ASSERT_NE(session_ids[0], session_ids[1]);
    });
    CheckSessionIDs(FedCmEntry::kEntryName);
    CheckSessionIDs(FedCmIdpEntry::kEntryName);
  }

  blink::mojom::IdentityProviderRequestOptionsPtr
  NewNamedIdP(GURL config_url, std::string client_id, bool is_registered) {
    blink::mojom::IdentityProviderRequestOptionsPtr options =
        blink::mojom::IdentityProviderRequestOptions::New();
    blink::mojom::IdentityProviderConfigPtr config =
        blink::mojom::IdentityProviderConfig::New();
    config->config_url = config_url;
    config->client_id = client_id;
    options->config = std::move(config);
    options->config->from_idp_registration_api = is_registered;
    return options;
  }

  blink::mojom::IdentityProviderRequestOptionsPtr NewRegisteredIdP(
      std::string client_id) {
    blink::mojom::IdentityProviderConfigPtr config =
        blink::mojom::IdentityProviderConfig::New();
    config->from_idp_registration_api = true;
    config->client_id = client_id;
    blink::mojom::IdentityProviderRequestOptionsPtr options =
        blink::mojom::IdentityProviderRequestOptions::New();

    options->config = std::move(config);
    return options;
  }

  blink::mojom::IdentityProviderRequestOptionsPtr NewIDPWithFields(
      const std::optional<std::vector<std::string>>& fields) {
    blink::mojom::IdentityProviderRequestOptionsPtr options =
        blink::mojom::IdentityProviderRequestOptions::New();
    blink::mojom::IdentityProviderConfigPtr config =
        blink::mojom::IdentityProviderConfig::New();
    config->config_url = GURL(kProviderUrlFull);
    config->client_id = "";
    options->config = std::move(config);
    options->fields = fields;
    return options;
  }

  void SimulateLoginToIdP(std::string login_url = kIdpLoginUrl) {
    federated_auth_request_impl_->LoginToIdP(/*can_append_hints=*/true,
                                             GURL(kIdpUrl), GURL(login_url));
  }

  void ExpectSuccessfulActiveFlow() {
    test_permission_delegate_
        ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = false;

    auto dialog_controller =
        std::make_unique<TestDialogController>(kConfigurationValid);
    base::WeakPtr<TestDialogController> weak_dialog_controller =
        dialog_controller->AsWeakPtr();
    SetDialogController(std::move(dialog_controller));

    // Expect a modal dialog to be opened to sign-in to the IdP.
    std::unique_ptr<WebContents> modal(CreateTestWebContents());

    base::RunLoop loop;
    EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
        .WillOnce(::testing::WithArg<0>([&modal, &loop](const GURL& url) {
          loop.Quit();
          return modal.get();
        }));

    RequestParameters parameters = kDefaultRequestParameters;
    parameters.rp_mode = blink::mojom::RpMode::kActive;

    request_remote_.set_disconnect_handler(auth_helper_->quit_closure());

    static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
        ->SimulateUserActivation();

    RunAuthDontWaitForCallback(parameters, kConfigurationValid);

    loop.Run();

    // When the modal dialog is opened, emulate the user signing-in by
    // updating the internal sign-in status state and notifying the
    // observers.
    test_permission_delegate_
        ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;
    federated_auth_request_impl_->OnIdpSigninStatusReceived(
        OriginFromString(kProviderUrlFull), true);

    WaitForCurrentAuthRequest(/*should_fast_forward=*/false);
    CheckAuthExpectations(kConfigurationValid, kExpectationSuccess);

    // These metrics are not recorded when a user's LoginStatus is "logged-out"
    // such that they need to sign in to the IdP in the active flow.
    histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ShowAccountsDialog",
                                       0);
    histogram_tester_.ExpectTotalCount(
        "Blink.FedCm.Timing.ShowAccountsDialogBreakdown."
        "WellKnownAndConfigFetch",
        0);
    histogram_tester_.ExpectTotalCount(
        "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.AccountsFetch", 0);
    histogram_tester_.ExpectTotalCount(
        "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch",
        0);

    histogram_tester_.ExpectUniqueSample(kBrowserAssistedLoginTypeHistogram,
                                         BrowserAssistedLoginType::kFedCmActive,
                                         1);
  }

 protected:
  std::string rp_url_;

  mojo::Remote<blink::mojom::FederatedAuthRequest> request_remote_;
  raw_ptr<RequestService, AcrossTasksDanglingUntriaged>
      federated_auth_request_impl_;

  std::unique_ptr<TestIdpNetworkRequestManager> test_network_request_manager_;

  std::unique_ptr<TestApiPermissionDelegate> test_api_permission_delegate_;
  std::unique_ptr<TestPermissionDelegate> test_permission_delegate_;
  std::unique_ptr<TestAutoReauthnPermissionDelegate>
      test_auto_reauthn_permission_delegate_;
  std::unique_ptr<TestIdentityRegistry> test_identity_registry_;
  std::unique_ptr<AuthRequestCallbackHelper> auth_helper_;

  // Enables test to inspect TestDialogController state after
  // RequestService destroys TestDialogController. Recreated during
  // each run of RunAuthTest().
  TestDialogController::State dialog_controller_state_;

  base::HistogramTester histogram_tester_;

 private:
  std::unique_ptr<TestDialogController> custom_dialog_controller_;
  std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;
};

// Test successful FedCM request.
TEST_F(RequestServiceTest, SuccessfulRequest) {
  // Use IdpNetworkRequestManagerParamChecker to validate passed-in parameters
  // to IdpNetworkRequestManager methods.
  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectations(kClientId, kAccountId);
  SetNetworkRequestManager(std::move(checker));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  // Check that client metadata is fetched. Using `kExpectationSuccess`
  // expectation does not check that the client metadata was fetched because
  // client metadata is optional.
  EXPECT_TRUE(DidFetch(FetchedEndpoint::CLIENT_METADATA));
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", true, 1);
  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, true);
}

// Test successful well-known fetching.
TEST_F(RequestServiceTest, WellKnownSuccess) {
  // Use IdpNetworkRequestManagerParamChecker to validate passed-in parameters
  // to IdpNetworkRequestManager methods.
  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectations(kClientId, kAccountId);
  SetNetworkRequestManager(std::move(checker));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
}

// Test the provider url is not in the well-known.
TEST_F(RequestServiceTest, WellKnownNotInList) {
  RequestExpectations request_not_in_list = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigNotInWellKnown,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  const char* idp_config_url =
      kDefaultRequestParameters.identity_providers[0].provider;
  const char* kWellKnownMismatchConfigUrl = "https://mismatch.example";
  EXPECT_NE(std::string(idp_config_url), kWellKnownMismatchConfigUrl);

  MockConfiguration config = kConfigurationValid;
  config.idp_info[idp_config_url].well_known = {
      {kWellKnownMismatchConfigUrl}, {ParseStatus::kSuccess, net::HTTP_OK}};
  RunAuthTest(kDefaultRequestParameters, request_not_in_list, config);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));
}

// Test that when the provider url is not in the well-known, it succeeds when it
// is registered.
TEST_F(RequestServiceTest, WellKnownNotInListButRegistered) {
  base::test::ScopedFeatureList list;
  list.InitAndEnableFeature(features::kFedCmIdPRegistration);

  const char* idp_config_url =
      kDefaultRequestParameters.identity_providers[0].provider;
  const char* kWellKnownMismatchConfigUrl = "https://mismatch.example";
  EXPECT_NE(std::string(idp_config_url), kWellKnownMismatchConfigUrl);

  MockConfiguration config = kConfigurationValid;
  config.idp_info[idp_config_url].well_known = {
      {kWellKnownMismatchConfigUrl}, {ParseStatus::kSuccess, net::HTTP_OK}};
  RequestParameters requestParameters = kDefaultRequestParameters;
  requestParameters.identity_providers[0].from_idp_registration_api = true;

  // Need to simulate there is actually a registered IdP, or the call will fail.
  std::vector<GURL> registry;
  registry.emplace_back(kProviderUrlFull);
  EXPECT_CALL(*test_permission_delegate_, GetRegisteredIdPs())
      .WillOnce(Return(registry));

  RunAuthTest(requestParameters, kExpectationSuccess, config);
  EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));
}

// Test that the well-known file has too many provider urls.
TEST_F(RequestServiceTest, WellKnownHasTooManyProviderUrls) {
  RequestExpectations expectation = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kWellKnownTooBig,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration config = kConfigurationValid;
  config.idp_info[kProviderUrlFull].well_known = {
      {kProviderUrlFull, kProviderTwoUrlFull},
      {ParseStatus::kSuccess, net::HTTP_OK}};
  RunAuthTest(kDefaultRequestParameters, expectation, config);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));
}

// Test that the well-known enforcement is bypassed.
TEST_F(RequestServiceTest, WellKnownEnforcementBypassed) {
  base::test::ScopedFeatureList list;
  list.InitAndEnableFeature(features::kFedCmWithoutWellKnownEnforcement);

  MockConfiguration config = kConfigurationValid;
  // The provider is not in the provider_list from the well-known.
  config.idp_info[kProviderUrlFull].well_known = {
      {kProviderTwoUrlFull}, {ParseStatus::kSuccess, net::HTTP_OK}};
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, config);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
}

// Test that not having the filename in the well-known fails.
TEST_F(RequestServiceTest, WellKnownHasNoFilename) {
  MockConfiguration config{kConfigurationValid};
  config.idp_info[kProviderUrlFull].well_known.provider_urls =
      std::set<std::string>{GURL(kProviderUrlFull).GetWithoutFilename().spec()};

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigNotInWellKnown,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, config);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));
}

// Test that request fails if config is missing token endpoint.
TEST_F(RequestServiceTest, MissingTokenEndpoint) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.token_endpoint = "";
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));

  std::vector<std::string> messages =
      RenderFrameHostTester::For(main_rfh())->GetConsoleMessages();
  ASSERT_EQ(2U, messages.size());
  EXPECT_EQ(
      "Config file is missing or has an invalid URL for the following:\n"
      "\"id_assertion_endpoint\"\n",
      messages[0]);
  EXPECT_EQ("Provider's FedCM config file is invalid.", messages[1]);
}

// Test that request fails if config is missing accounts endpoint.
TEST_F(RequestServiceTest, MissingAccountsEndpoint) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.accounts_endpoint = "";
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));

  std::vector<std::string> messages =
      RenderFrameHostTester::For(main_rfh())->GetConsoleMessages();
  ASSERT_EQ(2U, messages.size());
  EXPECT_EQ(
      "Config file is missing or has an invalid URL for the following:\n"
      "\"accounts_endpoint\"\n",
      messages[0]);
  EXPECT_EQ("Provider's FedCM config file is invalid.", messages[1]);
}

// Test that request fails if config is missing an IDP login URL.
TEST_F(RequestServiceTest, MissingLoginURL) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.idp_login_url = "";
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());

  std::vector<std::string> messages =
      RenderFrameHostTester::For(main_rfh())->GetConsoleMessages();
  ASSERT_EQ(2U, messages.size());
  EXPECT_EQ(
      "Config file is missing or has an invalid URL for the following:\n"
      "\"login_url\"\n",
      messages[0]);
  EXPECT_EQ("Provider's FedCM config file is invalid.", messages[1]);
}

// Test that client metadata endpoint is not required in config.
TEST_F(RequestServiceTest, MissingClientMetadataEndpoint) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.client_metadata_endpoint = "";
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
  EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));
}

// Test that request fails if the accounts endpoint is in a different origin
// than identity provider.
TEST_F(RequestServiceTest, AccountEndpointDifferentOriginIdp) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.accounts_endpoint =
      kCrossOriginAccountsEndpoint;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));
}

// Test that request fails if IDP login URL is different origin from IDP config
// URL.
TEST_F(RequestServiceTest, LoginUrlDifferentOriginIdp) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.idp_login_url =
      "https://idp2.example/login_url";
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());

  std::vector<std::string> messages =
      RenderFrameHostTester::For(main_rfh())->GetConsoleMessages();
  ASSERT_EQ(2U, messages.size());
  EXPECT_EQ(
      "Config file is missing or has an invalid URL for the following:\n"
      "\"login_url\"\n",
      messages[0]);
  EXPECT_EQ("Provider's FedCM config file is invalid.", messages[1]);
}

// Test that request fails if the idp is not https.
TEST_F(RequestServiceTest, ProviderNotTrustworthy) {
  IdentityProviderParameters identity_provider{
      "http://idp.example/fedcm.json", kClientId, kNonce, /*login_hint=*/"",
      /*domain_hint=*/""};
  RequestParameters request{
      std::vector<IdentityProviderParameters>{identity_provider},
      /*rp_context=*/blink::mojom::RpContext::kSignIn,
      /*rp_mode=*/blink::mojom::RpMode::kPassive};
  MockConfiguration configuration = kConfigurationValid;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdpNotPotentiallyTrustworthy,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(request, expectations, configuration);
  EXPECT_FALSE(DidFetchAnyEndpoint());

  ExpectStatusMetrics(TokenStatus::kIdpNotPotentiallyTrustworthy);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", false, 1);
  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, false);
}

// Test that request fails if accounts endpoint cannot be reached.
TEST_F(RequestServiceTest, AccountEndpointCannotBeReached) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kNoResponseError;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsNoResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
}

// Test that request fails if account endpoint response cannot be parsed.
TEST_F(RequestServiceTest, AccountsCannotBeParsed) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());

  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsSize.Raw", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsSize.ReadyToShow", 0);

  // Only records the following histograms if there are accounts to be shown.
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch",
      0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.AccountsFetch", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch", 0);
  ExpectNoUKMPresence(
      "Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch");
  ExpectNoUKMPresence("Timing.ShowAccountsDialogBreakdown.AccountsFetch");
  ExpectNoUKMPresence("Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch");
  // Records the following histogram as long as the well-known and config file
  // is fetched.
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.WellKnownAndConfigFetch", 1);
}

// Test that privacy policy, terms of service or RP brand icon URLs are not
// required in client metadata.
TEST_F(RequestServiceTest, ClientMetadataNoUrls) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].client_metadata =
      kDefaultClientMetadata;
  configuration.idp_info[kProviderUrlFull].client_metadata.privacy_policy_url =
      "";
  configuration.idp_info[kProviderUrlFull]
      .client_metadata.terms_of_service_url = "";
  configuration.idp_info[kProviderUrlFull].client_metadata.brand_icon_url = "";
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
}

// Test that privacy policy URL is not required in client metadata.
TEST_F(RequestServiceTest, ClientMetadataNoPrivacyPolicyUrl) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].client_metadata =
      kDefaultClientMetadata;
  configuration.idp_info[kProviderUrlFull].client_metadata.privacy_policy_url =
      "";
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
}

// Test that terms of service URL is not required in client metadata.
TEST_F(RequestServiceTest, ClientMetadataNoTermsOfServiceUrl) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].client_metadata =
      kDefaultClientMetadata;
  configuration.idp_info[kProviderUrlFull]
      .client_metadata.terms_of_service_url = "";
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
}

// Test that RP brand icon URL is not required in client metadata.
TEST_F(RequestServiceTest, ClientMetadataNoRpBrandIconUrl) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].client_metadata =
      kDefaultClientMetadata;
  configuration.idp_info[kProviderUrlFull].client_metadata.brand_icon_url = "";
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
}

// Test that request fails if all of the endpoints in the config are invalid.
TEST_F(RequestServiceTest, AllInvalidEndpoints) {
  // Both an empty url and cross origin urls are invalid endpoints.
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.accounts_endpoint =
      "https://cross-origin-1.com";
  configuration.idp_info[kProviderUrlFull].config.token_endpoint = "";
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetchWellKnownAndConfig());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));
  std::vector<std::string> messages =
      RenderFrameHostTester::For(main_rfh())->GetConsoleMessages();
  ASSERT_EQ(2U, messages.size());
  EXPECT_EQ(
      "Config file is missing or has an invalid URL for the following:\n"
      "\"id_assertion_endpoint\"\n"
      "\"accounts_endpoint\"\n",
      messages[0]);
  EXPECT_EQ("Provider's FedCM config file is invalid.", messages[1]);
}

// Tests for browser trusted login states.
TEST_F(RequestServiceTest,
       BrowserTrustedLoginStateShouldBeSignUpForFirstTimeUser) {
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  EXPECT_EQ(LoginState::kSignUp,
            all_accounts_for_display()[0]->browser_trusted_login_state);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.HasSigninAccount", false,
                                       1);
}

TEST_F(RequestServiceTest,
       BrowserTrustedLoginStateShouldBeSignInForReturningUser) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::make_optional<base::Time>()));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  EXPECT_EQ(LoginState::kSignIn,
            all_accounts_for_display()[0]->browser_trusted_login_state);

  // CLIENT_METADATA only needs to be fetched for obtaining links to display in
  // the disclosure text. The disclosure text is not displayed for returning
  // users, thus fetching the client metadata endpoint should be skipped.
  EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch",
      1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.AccountsFetch", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch", 1);
  histogram_tester_.ExpectUniqueTimeSample(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch",
      base::TimeDelta(), 1);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.HasSigninAccount", true, 1);
}

TEST_F(RequestServiceTest, LoginStateSuccessfulSignUpGrantsSharingPermission) {
  EXPECT_CALL(*test_permission_delegate_, GetLastUsedTimestamp(_, _, _, _))
      .WillRepeatedly(Return(std::nullopt));
  EXPECT_CALL(
      *test_permission_delegate_,
      GrantSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                             OriginFromString(kProviderUrlFull), kAccountId))
      .Times(1);
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
}

TEST_F(RequestServiceTest, LoginStateFailedSignUpNotGrantSharingPermission) {
  EXPECT_CALL(*test_permission_delegate_, GetLastUsedTimestamp(_, _, _, _))
      .WillRepeatedly(Return(std::nullopt));
  EXPECT_CALL(*test_permission_delegate_, GrantSharingPermission(_, _, _, _))
      .Times(0);

  MockConfiguration configuration = kConfigurationValid;
  configuration.token_response.parse_status =
      ParseStatus::kInvalidResponseError;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
}

// Test that auto re-authn permission is not embargoed upon explicit sign-in.
TEST_F(RequestServiceTest, ExplicitSigninEmbargo) {
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
  EXPECT_TRUE(
      test_auto_reauthn_permission_delegate_->embargoed_origins_.empty());
}

// Test that auto re-authn permission is embargoed upon successful auto
// re-authn.
TEST_F(RequestServiceTest, AutoReauthnEmbargo) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::make_optional<base::Time>()));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  RequestExpectations expectation = kExpectationSuccess;
  expectation.is_auto_selected = true;
  RunAuthTest(kDefaultRequestParameters, expectation, kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignIn);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kAuto);
  EXPECT_TRUE(test_auto_reauthn_permission_delegate_->embargoed_origins_.count(
      OriginFromString(kRpUrl)));

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kOne,
                           /*expected_succeeded=*/true,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that sign-in state is enforced when the content embedder blocks the
// sign-in, for example if there is an ongoing task by an actor.
TEST_F(RequestServiceTest, ExplicitSigninBlockedByEmbedder) {
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::make_optional<base::Time>()));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));
  // Pretend actor task is active.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnDisabledByEmbedder(web_contents()))
      .WillOnce(Return(true));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignIn);
  EXPECT_FALSE(test_auto_reauthn_permission_delegate_->embargoed_origins_.count(
      OriginFromString(kRpUrl)));
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kOne,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/true);
}

// Test that auto re-authn with a single account where the account is a
// returning user sets the sign-in mode to auto.
TEST_F(RequestServiceTest, AutoReauthnForSingleReturningUserSingleAccount) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::make_optional<base::Time>()));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  for (const auto& idp_info : kConfigurationValid.idp_info) {
    ASSERT_EQ(idp_info.second.accounts.size(), 1u);
  }
  RequestExpectations expectation = kExpectationSuccess;
  expectation.is_auto_selected = true;

  RunAuthTest(kDefaultRequestParameters, expectation, kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignIn);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kAuto);

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kOne,
                           /*expected_succeeded=*/true,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that auto re-authn with multiple accounts and a single returning user
// sets the sign-in mode to auto.
TEST_F(RequestServiceTest, AutoReauthnForSingleReturningUserMultipleAccounts) {
  // Pretend the sharing permission has not been granted for this account.
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderUrlFull), kAccountIdNicolas))
      .WillRepeatedly(Return(std::nullopt));

  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountIdPeter))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend the sharing permission has not been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountIdZach))
      .WillRepeatedly(Return(std::nullopt));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kMultipleAccounts;
  RequestExpectations expectation = kExpectationSuccess;
  expectation.is_auto_selected = true;
  RunAuthTest(kDefaultRequestParameters, expectation, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdPeter);
  EXPECT_EQ(CountNumLoginStateIsSignin(), 1);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kAuto);

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kOne,
                           /*expected_succeeded=*/true,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that auto re-authn with multiple accounts and multiple returning users
// sets the sign-in mode to explicit.
TEST_F(RequestServiceTest,
       AutoReauthnForMultipleReturningUsersMultipleAccounts) {
  // Pretend the sharing permission has not been granted for this account.
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderUrlFull), kAccountIdNicolas))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountIdPeter))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend the sharing permission has not been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountIdZach))
      .WillRepeatedly(Return(std::nullopt));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  std::vector<IdentityRequestAccountPtr> multiple_accounts = kMultipleAccounts;
  multiple_accounts[0]->idp_claimed_login_state = LoginState::kSignIn;
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = multiple_accounts;
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 3u);
  EXPECT_EQ(CountNumLoginStateIsSignin(), 2);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kMultiple,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that auto re-authn with single non-returning account sets the sign-in
// mode to explicit.
TEST_F(RequestServiceTest, AutoReauthnForZeroReturningUsers) {
  // Pretend the sharing permission has not been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::nullopt));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  for (const auto& idp_info : kConfigurationValid.idp_info) {
    ASSERT_EQ(idp_info.second.accounts.size(), 1u);
  }
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kZero,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that auto re-authn with multiple accounts and a single returning user
// sets the sign-in mode to kExplicit if `mediation: required` is specified.
TEST_F(RequestServiceTest,
       AutoReauthnForSingleReturningUserWithoutSettingAutoReauthn) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  MockConfiguration configuration = kConfigurationValid;
  configuration.mediation_requirement = MediationRequirement::kRequired;
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(CountNumLoginStateIsSignin(), 1);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
  ExpectStatusMetrics(TokenStatus::kSuccessUsingTokenInHttpResponse,
                      MediationRequirement::kRequired);
}

// Test that auto re-authn with multiple accounts and a single returning user
// sets the sign-in mode to kExplicit if `RequiresUserMediation` is set
TEST_F(RequestServiceTest,
       AutoReauthnForSingleReturningUserWithRequiresUserMediation) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend that auto re-authn is not disabled in settings.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));

  // Pretend that auto re-authn is not in embargo state.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  // Pretend that re-authn requires user mediation.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              RequiresUserMediation(url::Origin::Create(GURL(kRpUrl))))
      .WillOnce(Return(true));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(CountNumLoginStateIsSignin(), 1);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kOne,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/true,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that auto re-authn with multiple accounts and a single returning user
// sets the sign-in mode to kExplicit if "auto sign-in" is disabled.
TEST_F(RequestServiceTest,
       AutoReauthnForSingleReturningUserWithAutoSigninDisabled) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend that auto re-authn is not in embargo state.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  // Pretend that re-authn does not require user mediation.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              RequiresUserMediation(url::Origin::Create(GURL(kRpUrl))))
      .WillOnce(Return(false));

  // Pretend that auto re-authn is disabled in settings.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(false));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(CountNumLoginStateIsSignin(), 1);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
}

// Test that if browser has not observed sign-in in the past, the sign-in mode
// is set to explicit regardless the account's login state.
TEST_F(RequestServiceTest, AutoReauthnBrowserNotObservedSigninBefore) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::nullopt));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  // Set IDP claims user is signed in.
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull]
      .accounts[0]
      ->idp_claimed_login_state = LoginState::kSignIn;

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(CountNumLoginStateIsSignin(), 1);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
}

// Test that if browser has not observed sign-in in the past, but the IdP has
// third-party cookies access, the sign-in mode is set to auto if IdP claims
// that the user is returning.
TEST_F(RequestServiceTest,
       AutoReauthnBrowserNotObservedSigninButIdpHasThirdPartyCookiesAccess) {
  // Pretend the sharing permission has not been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::nullopt));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  // Pretend the IdP was given third-party cookies access.
  EXPECT_CALL(*test_api_permission_delegate_,
              HasThirdPartyCookiesAccess(_, GURL(kProviderUrlFull),
                                         OriginFromString(kRpUrl)))
      .WillRepeatedly(Return(true));

  // Sharing permission won't be granted with this setup.
  EXPECT_CALL(*test_permission_delegate_,
              GrantSharingPermission(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderUrlFull), std::string(kAccountId)))
      .Times(0);

  // Set IDP claims user is signed in.
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull]
      .accounts[0]
      ->idp_claimed_login_state = LoginState::kSignIn;
  RequestExpectations expectation = kExpectationSuccess;
  expectation.is_auto_selected = true;
  RunAuthTest(kDefaultRequestParameters, expectation, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(CountNumLoginStateIsSignin(), 1);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kAuto);
}

// Test that auto re-authn for a first time user sets the sign-in mode to
// explicit.
TEST_F(RequestServiceTest, AutoReauthnForFirstTimeUser) {
  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
}

// Test that auto re-authn where the auto re-authn permission is blocked sets
// the sign-in mode to explicit.
TEST_F(RequestServiceTest, AutoReauthnWithBlockedAutoReauthnPermissions) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend the auto re-authn permission has been blocked for this account.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(false));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignIn);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kOne,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/true,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that auto re-authn where the auto re-authn cooldown is on sets
// the sign-in mode to explicit.
TEST_F(RequestServiceTest, AutoReauthnWithCooldown) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend the auto re-authn permission has been granted for this account.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  // Pretend that auto re-authn is embargoed.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(true));

  RequestExpectations expectations = kExpectationSuccess;
  expectations.standalone_console_message =
      "Auto re-authn was previously triggered less than 10 minutes ago. Only "
      "one auto re-authn request can be made every 10 minutes.";
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignIn);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kOne,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/true,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that no network request is sent if `mediation: silent` is used and user
// has not granted sharing permission in the past.
TEST_F(RequestServiceTest,
       AutoReauthnMediationSilentFailWithNoSharingPermission) {
  // Pretend the sharing permission has not been granted for any account.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull)))
      .WillOnce(Return(false));

  // Pretend the auto re-authn is disabled in settings.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kSilentMediationFailure,
      /*standalone_console_message=*/
      "Silent mediation issue: the user has not used FedCM on this "
      "site with this identity provider.",
      /*selected_idp_config_url=*/std::nullopt};
  MockConfiguration configuration = kConfigurationValid;
  configuration.mediation_requirement = MediationRequirement::kSilent;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  EXPECT_FALSE(DidFetchAnyEndpoint());

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(configuration, expectations);

  ExpectStatusMetrics(TokenStatus::kSilentMediationFailure,
                      MediationRequirement::kSilent);

  ExpectAutoReauthnMetrics(/*expected_returning_accounts=*/std::nullopt,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that no network request is sent if `mediation: silent` is used and auto
// re-authn is in cooldown.
TEST_F(RequestServiceTest, AutoReauthnMediationSilentFailWithEmbargo) {
  // Pretend the sharing permission has been granted for some account.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull)))
      .WillOnce(Return(true));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(true));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kSilentMediationFailure,
      /*standalone_console_message=*/
      "Silent mediation issue: auto re-authn is in quiet period "
      "because "
      "it was recently used on this site.",
      /*selected_idp_config_url=*/std::nullopt};
  MockConfiguration configuration = kConfigurationValid;
  configuration.mediation_requirement = MediationRequirement::kSilent;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  EXPECT_FALSE(DidFetchAnyEndpoint());

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(configuration, expectations);
  ExpectStatusMetrics(TokenStatus::kSilentMediationFailure,
                      MediationRequirement::kSilent);

  ExpectAutoReauthnMetrics(/*expected_returning_accounts=*/std::nullopt,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/true,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that no network request is sent if `mediation: silent` is used and user
// mediation is required, e.g. `preventSilentAccess` has been invoked
TEST_F(RequestServiceTest,
       AutoReauthnMediationSilentFailWithRequiresUserMediation) {
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull)))
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              RequiresUserMediation(url::Origin::Create(GURL(kRpUrl))))
      .WillOnce(Return(true));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kSilentMediationFailure,
      /*standalone_console_message=*/
      "Silent mediation issue: preventSilentAccess() has been invoked "
      "on the site.",
      /*selected_idp_config_url=*/std::nullopt};
  MockConfiguration configuration = kConfigurationValid;
  configuration.mediation_requirement = MediationRequirement::kSilent;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  EXPECT_FALSE(DidFetchAnyEndpoint());

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(configuration, expectations);

  ExpectStatusMetrics(TokenStatus::kSilentMediationFailure,
                      MediationRequirement::kSilent);

  ExpectAutoReauthnMetrics(/*expected_returning_accounts=*/std::nullopt,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/true,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test that no network request is sent if `mediation: silent` is used and user
// has disabled "auto sign-in".
TEST_F(RequestServiceTest,
       AutoReauthnMediationSilentFailWithPasswordManagerAutoSigninDisabled) {
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(false));
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull)))
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              RequiresUserMediation(url::Origin::Create(GURL(kRpUrl))))
      .WillOnce(Return(false));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kSilentMediationFailure,
      /*standalone_console_message=*/
      "Silent mediation issue: the user has disabled auto re-authn.",
      /*selected_idp_config_url=*/std::nullopt};
  MockConfiguration configuration = kConfigurationValid;
  configuration.mediation_requirement = MediationRequirement::kSilent;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  EXPECT_FALSE(DidFetchAnyEndpoint());

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(configuration, expectations);

  ExpectStatusMetrics(TokenStatus::kSilentMediationFailure,
                      MediationRequirement::kSilent);

  ExpectAutoReauthnMetrics(/*expected_returning_accounts=*/std::nullopt,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/true,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test `mediation: silent` could fail silently after fetching accounts
TEST_F(RequestServiceTest,
       AutoReauthnMediationSilentFailWithTwoReturningAccounts) {
  // Pretend the sharing permission has been granted for some account.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull)))
      .WillOnce(Return(true));

  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderUrlFull), kAccountIdNicolas))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountIdPeter))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend the sharing permission has not been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountIdZach))
      .WillRepeatedly(Return(std::nullopt));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillRepeatedly(Return(false));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kSilentMediationFailure,
      /*standalone_console_message=*/
      "Silent mediation issue: the user has used FedCM with multiple "
      "accounts on this site.",
      /*selected_idp_config_url=*/std::nullopt};
  MockConfiguration configuration = kConfigurationValid;
  configuration.mediation_requirement = MediationRequirement::kSilent;
  std::vector<IdentityRequestAccountPtr> multiple_accounts = kMultipleAccounts;
  multiple_accounts[0]->idp_claimed_login_state = LoginState::kSignIn;
  multiple_accounts[1]->idp_claimed_login_state = LoginState::kSignIn;
  configuration.idp_info[kProviderUrlFull].accounts = multiple_accounts;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(configuration, expectations);

  ExpectStatusMetrics(TokenStatus::kSilentMediationFailure,
                      MediationRequirement::kSilent);

  ExpectAutoReauthnMetrics(Metrics::NumAccounts::kMultiple,
                           /*expected_succeeded=*/false,
                           /*expected_auto_reauthn_setting_blocked=*/false,
                           /*expected_auto_reauthn_embargoed=*/false,
                           /*expected_prevent_silent_access=*/false,
                           /*expected_auto_reauthn_blocked_by_embedder=*/false);
}

// Test `mediation: silent` fails silently after a failed accounts fetch.
TEST_F(RequestServiceTest,
       AutoReauthnMediationSilentFailNotShowMismatchAfterAccountsFetch) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;

  // Pretend the sharing permission has been granted for exactly one account for
  // the first IdP.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull)))
      .WillOnce(Return(true));

  // Ensure auto reauthn is not considered as disabled.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillRepeatedly(Return(false));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kSilentMediationFailure,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;
  configuration.mediation_requirement = MediationRequirement::kSilent;
  // Let the first IDP accounts fetch fail.
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kNoResponseError;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(configuration, expectations);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());
}

// Test that `mediation: required` sets the sign-in mode to explicit even though
// other auto re-authn conditions are met.
TEST_F(RequestServiceTest, AutoReauthnMediationRequired) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::nullopt));

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull]
      .accounts[0]
      ->idp_claimed_login_state = LoginState::kSignIn;
  configuration.mediation_requirement = MediationRequirement::kRequired;

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->idp_claimed_login_state,
            LoginState::kSignIn);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);

  ExpectStatusMetrics(TokenStatus::kSuccessUsingTokenInHttpResponse,
                      MediationRequirement::kRequired);
}

TEST_F(RequestServiceTest, MetricsForSuccessfulSignInCase) {
  // Pretends that the sharing permission has been granted for this account.
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(_, _, OriginFromString(kProviderUrlFull),
                                   kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  EXPECT_EQ(LoginState::kSignIn,
            all_accounts_for_display()[0]->browser_trusted_login_state);

  ukm_loop.Run();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", true, 1);
  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, true);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch",
      1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.AccountsFetch", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch", 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ShowAccountsDialog",
                                     1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ContinueOnDialog", 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.CancelOnDialog", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.IdTokenResponse", 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.TurnaroundTime", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 0);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.IsSignInUser", 1, 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.AccountFieldsType",
      static_cast<int>(AccountFieldsType::kNameOrEmailAndOtherIdentifier), 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.Raw", 1, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.ReadyToShow",
                                       1, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.RpMode",
                                       static_cast<int>(RpMode::kPassive), 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.VerifyingDialogResult",
      static_cast<int>(VerifyingDialogResult::kSuccessExplicit), 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.FrameType", static_cast<int>(RequesterFrameType::kMainFrame),
      1);

  ExpectUKMPresence("Timing.ShowAccountsDialog");
  ExpectUKMPresenceInternal(
      "Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch",
      FedCmEntry::kEntryName);
  ExpectUKMPresenceInternal("Timing.ShowAccountsDialogBreakdown.AccountsFetch",
                            FedCmEntry::kEntryName);
  ExpectUKMPresenceInternal(
      "Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch",
      FedCmEntry::kEntryName);
  ExpectUKMPresence("Timing.ContinueOnDialog");
  ExpectUKMPresence("Timing.IdTokenResponse");
  ExpectUKMPresence("Timing.TurnaroundTime");
  ExpectNoUKMPresence("Timing.CancelOnDialog");
  ExpectUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectNoUKMPresence("Timing.MismatchDialogShownDuration");
  ExpectUkmValue("RpMode", static_cast<int>(RpMode::kPassive));
  ExpectUkmValue("VerifyingDialogResult",
                 static_cast<int>(VerifyingDialogResult::kSuccessExplicit));
  ExpectUkmValue("FrameType", static_cast<int>(RequesterFrameType::kMainFrame));

  ExpectStatusMetrics(TokenStatus::kSuccessUsingTokenInHttpResponse);
}

// Test that request fails if account picker is explicitly dismissed.
TEST_F(RequestServiceTest, MetricsForUIExplicitlyDismissed) {
  base::HistogramTester histogram_tester_;
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  for (const auto& idp_info : kConfigurationValid.idp_info) {
    ASSERT_EQ(idp_info.second.accounts.size(), 1u);
  }
  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kClose;
  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_FALSE(DidFetch(FetchedEndpoint::TOKEN));

  ukm_loop.Run();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", true, 1);
  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, true);
  ASSERT_TRUE(did_show_accounts_dialog());
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignUp);

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch",
      1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.AccountsFetch", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch", 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ShowAccountsDialog",
                                     1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ContinueOnDialog", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.CancelOnDialog", 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.IdTokenResponse", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.TurnaroundTime", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 0);

  ExpectUKMPresence("Timing.ShowAccountsDialog");
  ExpectUKMPresence("Timing.CancelOnDialog");
  ExpectNoUKMPresence("Timing.ContinueOnDialog");
  ExpectNoUKMPresence("Timing.IdTokenResponse");
  ExpectNoUKMPresence("Timing.TurnaroundTime");
  ExpectUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectNoUKMPresence("Timing.MismatchDialogShownDuration");

  ExpectStatusMetrics(TokenStatus::kShouldEmbargo);
}

// Test that request is not completed if user ignores the UI.
TEST_F(RequestServiceTest, UIIsIgnored) {
  base::HistogramTester histogram_tester_;

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kNone;

  auto dialog_controller =
      std::make_unique<TestDialogController>(configuration);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  task_environment()->FastForwardBy(base::Minutes(10));

  EXPECT_FALSE(auth_helper_->was_callback_called());

  // The dialog should have been shown. The dialog controller should not be
  // destroyed.
  ASSERT_TRUE(did_show_accounts_dialog());
  EXPECT_TRUE(weak_dialog_controller);

  // Only the time to show the account dialog gets recorded.
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch",
      1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.AccountsFetch", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch", 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ShowAccountsDialog",
                                     1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ContinueOnDialog", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.CancelOnDialog", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.IdTokenResponse", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.TurnaroundTime", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Status.RequestIdToken", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 0);
}

TEST_F(RequestServiceTest, MetricsForWebContentsVisible) {
  base::HistogramTester histogram_tester;
  // Sets RenderFrameHost to visible
  test_rvh()->SimulateWasShown();
  ASSERT_EQ(test_rvh()->GetMainRenderFrameHost()->GetVisibilityState(),
            content::PageVisibilityState::kVisible);

  // Pretends that the sharing permission has been granted for this account.
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(_, _, OriginFromString(kProviderUrlFull),
                                   kAccountId))
      .WillRepeatedly(Return(std::make_optional<base::Time>()));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  EXPECT_EQ(LoginState::kSignIn,
            all_accounts_for_display()[0]->browser_trusted_login_state);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.WebContentsVisible", 1, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.WebContentsActive", 1, 1);
}

// Test that request could succeed with auto re-authn even if the web contents
// invisible.
TEST_F(RequestServiceTest, MetricsForWebContentsInvisible) {
  base::HistogramTester histogram_tester;
  test_rvh()->SimulateWasShown();
  ASSERT_EQ(test_rvh()->GetMainRenderFrameHost()->GetVisibilityState(),
            content::PageVisibilityState::kVisible);

  // Sets the RenderFrameHost to invisible
  test_rvh()->SimulateWasHidden();
  ASSERT_NE(test_rvh()->GetMainRenderFrameHost()->GetVisibilityState(),
            content::PageVisibilityState::kVisible);

  // Pretends that the sharing permission has been granted for this account.
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(_, _, OriginFromString(kProviderUrlFull),
                                   kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  EXPECT_EQ(LoginState::kSignIn,
            all_accounts_for_display()[0]->browser_trusted_login_state);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.WebContentsVisible", 0, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.WebContentsActive", 1, 1);
}

TEST_F(RequestServiceTest, MetricsForFeatureIsDisabled) {
  test_api_permission_delegate_->permission_override_ =
      std::make_pair(main_test_rfh()->GetLastCommittedOrigin(),
                     ApiPermissionStatus::BLOCKED_VARIATIONS);

  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kDisabledInFlags,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  EXPECT_FALSE(DidFetchAnyEndpoint());

  ExpectStatusMetrics(TokenStatus::kDisabledInFlags);
}

TEST_F(RequestServiceTest,
       MetricsForFeatureIsDisabledNotDoubleCountedWithUnhandledRequest) {
  test_api_permission_delegate_->permission_override_ =
      std::make_pair(main_test_rfh()->GetLastCommittedOrigin(),
                     ApiPermissionStatus::BLOCKED_VARIATIONS);

  RunAuthDontWaitForCallback(kDefaultRequestParameters, kConfigurationValid);
  EXPECT_FALSE(DidFetchAnyEndpoint());

  // Delete the request before DelayTimer kicks in.
  federated_auth_request_impl_->ResetAndDeleteThis();

  // If double counted, these samples would not be unique so the following
  // checks will fail.
  ExpectStatusMetrics(TokenStatus::kDisabledInFlags);
}

TEST_F(RequestServiceTest,
       MetricsForFeatureIsDisabledNotDoubleCountedWithAbortedRequest) {
  test_api_permission_delegate_->permission_override_ =
      std::make_pair(main_test_rfh()->GetLastCommittedOrigin(),
                     ApiPermissionStatus::BLOCKED_VARIATIONS);

  RunAuthDontWaitForCallback(kDefaultRequestParameters, kConfigurationValid);
  EXPECT_FALSE(DidFetchAnyEndpoint());

  // Abort the request before DelayTimer kicks in.
  federated_auth_request_impl_->CancelTokenRequest();

  // If double counted, these samples would not be unique so the following
  // checks will fail.
  ExpectStatusMetrics(TokenStatus::kDisabledInFlags);
}

// Test that sign-in states match if IDP claims that user is signed in and
// browser also observes that user is signed in.
TEST_F(RequestServiceTest, MetricsForSignedInOnBothIdpAndBrowser) {
  // Set browser observes user is signed in.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  // Set IDP claims user is signed in.
  MockConfiguration configuration = kConfigurationValid;
  std::vector<IdentityRequestAccountPtr> all_accounts_for_display =
      std::vector<IdentityRequestAccountPtr>(kSingleAccount.begin(),
                                             kSingleAccount.end());
  all_accounts_for_display[0]->idp_claimed_login_state = LoginState::kSignIn;
  configuration.idp_info[kProviderUrlFull].accounts = all_accounts_for_display;
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
  EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));

  ukm_loop.Run();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Status.SignInStateMatch",
                                       SignInStateMatchStatus::kMatch, 1);
  ExpectSignInStateMatchStatusUKM(SignInStateMatchStatus::kMatch);
}

// Test that sign-in states match if IDP claims that user is not signed in and
// browser also observes that user is not signed in.
TEST_F(RequestServiceTest, MetricsForNotSignedInOnBothIdpAndBrowser) {
  // Set browser observes user is not signed in.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::nullopt));

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  // By default, IDP claims user is not signed in.
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ukm_loop.Run();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Status.SignInStateMatch",
                                       SignInStateMatchStatus::kMatch, 1);
  ExpectSignInStateMatchStatusUKM(SignInStateMatchStatus::kMatch);
}

// Test that sign-in states mismatch if IDP claims that user is signed in but
// browser observes that user is not signed in.
TEST_F(RequestServiceTest, MetricsForOnlyIdpClaimedSignIn) {
  // Set browser observes user is not signed in.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::nullopt));

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  // Set IDP claims user is signed in.
  MockConfiguration configuration = kConfigurationValid;
  std::vector<IdentityRequestAccountPtr> all_accounts_for_display =
      std::vector<IdentityRequestAccountPtr>(kSingleAccount.begin(),
                                             kSingleAccount.end());
  all_accounts_for_display[0]->idp_claimed_login_state = LoginState::kSignIn;
  configuration.idp_info[kProviderUrlFull].accounts = all_accounts_for_display;
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
  EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));

  ukm_loop.Run();

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.Status.SignInStateMatch",
      SignInStateMatchStatus::kIdpClaimedSignIn, 1);
  ExpectSignInStateMatchStatusUKM(SignInStateMatchStatus::kIdpClaimedSignIn);
}

// Test that sign-in states mismatch if IDP claims that user is not signed in
// but browser observes that user is signed in.
TEST_F(RequestServiceTest, MetricsForOnlyBrowserObservedSignIn) {
  // Set browser observes user is signed in.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));

  ukm_loop.Run();

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.Status.SignInStateMatch",
      SignInStateMatchStatus::kBrowserObservedSignIn, 1);
  ExpectSignInStateMatchStatusUKM(
      SignInStateMatchStatus::kBrowserObservedSignIn);
}

// Test that embargo is requested if the
// IdentityRequestDialogController::ShowAccountsDialog() callback requests it.
TEST_F(RequestServiceTest, RequestEmbargo) {
  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kClose;

  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(test_api_permission_delegate_->embargoed_origins_.count(
      main_test_rfh()->GetLastCommittedOrigin()));
}

// Test that the embargo dismiss count is reset when the user grants consent via
// the FedCM dialog.
TEST_F(RequestServiceTest, RemoveEmbargoOnUserConsent) {
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  EXPECT_TRUE(test_api_permission_delegate_->embargoed_origins_.empty());
}

// Test that token request fails if FEDERATED_IDENTITY_API content setting is
// disabled for the RP origin.
TEST_F(RequestServiceTest, ApiBlockedForOrigin) {
  test_api_permission_delegate_->permission_override_ =
      std::make_pair(main_test_rfh()->GetLastCommittedOrigin(),
                     ApiPermissionStatus::BLOCKED_SETTINGS);
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kDisabledInSettings,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  EXPECT_FALSE(DidFetchAnyEndpoint());
  ExpectStatusMetrics(TokenStatus::kDisabledInSettings);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.DidShowUI", false, 1);
  ExpectUkmValueInEntry("DidShowUI", FedCmEntry::kEntryName, false);
}

// Test that token request succeeds if FEDERATED_IDENTITY_API content setting is
// enabled for RP origin but disabled for an unrelated origin.
TEST_F(RequestServiceTest, ApiBlockedForUnrelatedOrigin) {
  const url::Origin kUnrelatedOrigin = OriginFromString("https://rp2.example/");

  test_api_permission_delegate_->permission_override_ =
      std::make_pair(kUnrelatedOrigin, ApiPermissionStatus::BLOCKED_SETTINGS);
  ASSERT_NE(main_test_rfh()->GetLastCommittedOrigin(), kUnrelatedOrigin);
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
}

class RequestServiceTestCancelConsistency
    : public RequestServiceTest,
      public ::testing::WithParamInterface<int> {};
INSTANTIATE_TEST_SUITE_P(/*no prefix*/,
                         RequestServiceTestCancelConsistency,
                         ::testing::Values(false, true),
                         ::testing::PrintToStringParamName());

// Test that the RP cannot use CancelTokenRequest() to determine whether
// Option 1: FedCM dialog is shown but user has not interacted with it
// Option 2: FedCM API is disabled via variations
TEST_P(RequestServiceTestCancelConsistency, AccountNotSelected) {
  const bool fedcm_disabled = GetParam();

  if (fedcm_disabled) {
    test_api_permission_delegate_->permission_override_ =
        std::make_pair(main_test_rfh()->GetLastCommittedOrigin(),
                       ApiPermissionStatus::BLOCKED_VARIATIONS);
  }

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kNone;
  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  request_remote_->CancelTokenRequest();

  WaitForCurrentAuthRequest();
  FederatedAuthRequestResult result =
      fedcm_disabled ? FederatedAuthRequestResult::kDisabledInFlags
                     : FederatedAuthRequestResult::kCanceled;
  RequestExpectations expectations{RequestTokenStatus::kErrorCanceled, result,
                                   /*standalone_console_message=*/std::nullopt,
                                   /*selected_idp_config_url=*/std::nullopt};
  CheckAuthExpectations(configuration, expectations);
}

namespace {

// TestDialogController which disables FedCM API when FedCM account selection
// dialog is shown.
class DisableApiWhenDialogShownDialogController : public TestDialogController {
 public:
  DisableApiWhenDialogShownDialogController(
      MockConfiguration configuration,
      TestApiPermissionDelegate* api_permission_delegate,
      const url::Origin rp_origin_to_disable)
      : TestDialogController(configuration),
        api_permission_delegate_(api_permission_delegate),
        rp_origin_to_disable_(rp_origin_to_disable) {}
  ~DisableApiWhenDialogShownDialogController() override = default;

  DisableApiWhenDialogShownDialogController(
      const DisableApiWhenDialogShownDialogController&) = delete;
  DisableApiWhenDialogShownDialogController& operator=(
      DisableApiWhenDialogShownDialogController&) = delete;

  bool ShowAccountsDialog(
      content::RelyingPartyData rp_data,
      const std::vector<IdentityProviderDataPtr>& idp_list,
      const std::vector<IdentityRequestAccountPtr>& accounts,
      blink::mojom::RpMode rp_mode,
      const std::vector<IdentityRequestAccountPtr>& new_accounts,
      IdentityRequestDialogController::AccountSelectionCallback on_selected,
      IdentityRequestDialogController::LoginToIdPCallback on_add_account,
      IdentityRequestDialogController::DismissCallback dismiss_callback,
      IdentityRequestDialogController::AccountsDisplayedCallback
          accounts_displayed_callback) override {
    // Disable FedCM API
    api_permission_delegate_->permission_override_ = std::make_pair(
        rp_origin_to_disable_, ApiPermissionStatus::BLOCKED_SETTINGS);

    // Call parent class method in order to store callback parameters.
    return TestDialogController::ShowAccountsDialog(
        std::move(rp_data), idp_list, accounts, rp_mode, new_accounts,
        std::move(on_selected), std::move(on_add_account),
        std::move(dismiss_callback), std::move(accounts_displayed_callback));
  }

 private:
  raw_ptr<TestApiPermissionDelegate> api_permission_delegate_;
  url::Origin rp_origin_to_disable_;
};

}  // namespace

// Test that the request fails if user proceeds with the sign in workflow after
// disabling the API while an existing accounts dialog is shown.
TEST_F(RequestServiceTest, ApiDisabledAfterAccountsDialogShown) {
  base::HistogramTester histogram_tester_;

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kDisabledInSettings,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  url::Origin rp_origin_to_disable = main_test_rfh()->GetLastCommittedOrigin();
  SetDialogController(
      std::make_unique<DisableApiWhenDialogShownDialogController>(
          kConfigurationValid, test_api_permission_delegate_.get(),
          rp_origin_to_disable));

  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::TOKEN));

  ukm_loop.Run();

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch",
      1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.AccountsFetch", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch", 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ShowAccountsDialog",
                                     1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ContinueOnDialog", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.IdTokenResponse", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.TurnaroundTime", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 0);

  ExpectUKMPresence("Timing.ShowAccountsDialog");
  ExpectNoUKMPresence("Timing.ContinueOnDialog");
  ExpectNoUKMPresence("Timing.IdTokenResponse");
  ExpectNoUKMPresence("Timing.TurnaroundTime");
  ExpectUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectNoUKMPresence("Timing.MismatchDialogShownDuration");

  ExpectStatusMetrics(TokenStatus::kDisabledInSettings);
}

// Test the disclosure_text_shown value in the token post data for sign-up case.
TEST_F(RequestServiceTest, DisclosureTextShownForFirstTimeUser) {
  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectedTokenPostData(
      "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) +
      "&account_id=" + std::string(kAccountId) + "&disclosure_text_shown=true" +
      "&is_auto_selected=false&mode=passive&fields=name,email,picture&"
      "disclosure_shown_for="
      "name,email,picture");
  SetNetworkRequestManager(std::move(checker));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
}

// Test the disclosure_text_shown value in the token post data for returning
// user case.
TEST_F(RequestServiceTest, DisclosureTextNotShownForReturningUser) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectedTokenPostData(
      "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) +
      "&account_id=" + std::string(kAccountId) +
      "&disclosure_text_shown=false&is_auto_"
      "selected=false&mode=passive&fields=name,email,picture");
  SetNetworkRequestManager(std::move(checker));

  MockConfiguration config = kConfigurationValid;
  config.mediation_requirement = MediationRequirement::kRequired;
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, config);
}

// Test that the values in the token post data are escaped according to the
// application/x-www-form-urlencoded spec.
TEST_F(RequestServiceTest, TokenEndpointPostDataEscaping) {
  const std::string kAccountIdWithSpace("account id");
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts[0]->id =
      kAccountIdWithSpace;

  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectedTokenPostData(
      "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) +
      "&account_id=account+id&disclosure_text_"
      "shown=true&is_auto_selected=false&mode=passive&fields=name,email,"
      "picture&disclosure_"
      "shown_for=name,email,picture");
  SetNetworkRequestManager(std::move(checker));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
}

// Test that the is_auto_selected value in the token post
// data for sign-up case.
TEST_F(RequestServiceTest, AutoSelectedFlagForNewUser) {
  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectedTokenPostData(
      "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) +
      "&account_id=" + std::string(kAccountId) + "&disclosure_text_shown=true" +
      "&is_auto_selected=false&mode=passive&fields=name,email,picture&"
      "disclosure_shown_for="
      "name,email,picture");
  SetNetworkRequestManager(std::move(checker));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
}

// Test that the is_auto_selected value in the token post
// data for returning user with `mediation:required`.
TEST_F(RequestServiceTest,
       AutoSelectedFlagForReturningUserWithMediationRequired) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectedTokenPostData(
      "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) +
      "&account_id=" + std::string(kAccountId) +
      "&disclosure_text_shown=false" +
      "&is_auto_selected=false&mode=passive&fields=name,email,picture");
  SetNetworkRequestManager(std::move(checker));

  MockConfiguration config = kConfigurationValid;
  config.mediation_requirement = MediationRequirement::kRequired;

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, config);
}

// Test that the is_auto_selected value in the token post
// data for returning user with `mediation:optional`.
TEST_F(RequestServiceTest,
       AutoSelectedFlagForReturningUserWithMediationOptional) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));

  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectedTokenPostData(
      "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) +
      "&account_id=" + std::string(kAccountId) +
      "&disclosure_text_shown=false" +
      "&is_auto_selected=true&mode=passive&fields=name,email,picture");
  SetNetworkRequestManager(std::move(checker));

  MockConfiguration config = kConfigurationValid;
  config.mediation_requirement = MediationRequirement::kOptional;
  RequestExpectations expectation = kExpectationSuccess;
  expectation.is_auto_selected = true;

  RunAuthTest(kDefaultRequestParameters, expectation, config);
}

// Test that the is_auto_selected value in the token post
// data for the quiet period use case.
TEST_F(RequestServiceTest, AutoSelectedFlagIfInQuietPeriod) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::make_optional<base::Time>()));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));

  // Pretend the auto re-authn is in quiet period.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(true));

  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectedTokenPostData(
      "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) +
      "&account_id=" + std::string(kAccountId) +
      "&disclosure_text_shown=false&is_auto_"
      "selected=false&mode=passive&fields=name,email,picture");
  SetNetworkRequestManager(std::move(checker));

  RequestExpectations expectations = kExpectationSuccess;
  expectations.standalone_console_message =
      "Auto re-authn was previously triggered less than 10 minutes ago. Only "
      "one auto re-authn request can be made every 10 minutes.";
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
}

TEST_F(RequestServiceTest, RegisteredIdpInIdAssertion) {
  base::test::ScopedFeatureList list;
  list.InitAndEnableFeature(features::kFedCmIdPRegistration);
  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  RequestParameters request = kDefaultRequestParameters;
  constexpr char kType[] = "someType";
  request.identity_providers[0].type = kType;
  checker->SetExpectedTokenPostData(
      "client_id=" + std::string(kClientId) + "&nonce=" + std::string(kNonce) +
      "&account_id=" + std::string(kAccountId) + "&disclosure_text_shown=true" +
      "&is_auto_selected=false&mode=passive&fields=name,email,picture&"
      "disclosure_shown_for="
      "name,email,picture"
      "&type=" +
      kType);
  SetNetworkRequestManager(std::move(checker));

  MockConfiguration config = kConfigurationValid;
  config.idp_info[kProviderUrlFull].config.types = {kType};
  RunAuthTest(request, kExpectationSuccess, config);
}

namespace {

// TestIdpNetworkRequestManager subclass which runs the `account_list_task`
// passed-in to the constructor prior to the accounts endpoint returning.
class IdpNetworkRequestManagerClientMetadataTaskRunner
    : public TestIdpNetworkRequestManager {
 public:
  explicit IdpNetworkRequestManagerClientMetadataTaskRunner(
      base::OnceClosure client_metadata_task)
      : client_metadata_task_(std::move(client_metadata_task)) {}

  IdpNetworkRequestManagerClientMetadataTaskRunner(
      const IdpNetworkRequestManagerClientMetadataTaskRunner&) = delete;
  IdpNetworkRequestManagerClientMetadataTaskRunner& operator=(
      const IdpNetworkRequestManagerClientMetadataTaskRunner&) = delete;

  void FetchClientMetadata(const GURL& client_metadata_endpoint_url,
                           const std::string& client_id,
                           int rp_brand_icon_ideal_size,
                           int rp_brand_icon_minimum_size,
                           FetchClientMetadataCallback callback) override {
    // Make copies because running the task might destroy
    // RequestService and invalidate the references.
    GURL client_metadata_endpoint_url_copy = client_metadata_endpoint_url;
    std::string client_id_copy = client_id;

    if (client_metadata_task_) {
      std::move(client_metadata_task_).Run();
    }
    TestIdpNetworkRequestManager::FetchClientMetadata(
        client_metadata_endpoint_url_copy, client_id_copy,
        rp_brand_icon_ideal_size, rp_brand_icon_minimum_size,
        std::move(callback));
  }

 private:
  base::OnceClosure client_metadata_task_;
};

void NavigateToUrl(content::WebContents* web_contents, const GURL& url) {
  static_cast<TestWebContents*>(web_contents)
      ->NavigateAndCommit(url, ui::PAGE_TRANSITION_LINK);
}

}  // namespace

// Test that the account chooser is not shown if the page navigates prior to the
// client metadata endpoint request completing and BFCache is enabled.
TEST_F(RequestServiceTest, NavigateDuringClientMetadataFetchBFCacheEnabled) {
  base::test::ScopedFeatureList list;
  list.InitWithFeaturesAndParameters(
      GetBasicBackForwardCacheFeatureForTesting(),
      GetDefaultDisabledBackForwardCacheFeaturesForTesting());
  ASSERT_TRUE(IsBackForwardCacheEnabled());

  SetNetworkRequestManager(
      std::make_unique<IdpNetworkRequestManagerClientMetadataTaskRunner>(
          base::BindOnce(&NavigateToUrl, web_contents(), GURL(kRpOtherUrl))));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      // No console message is received, so pass
      // FederatedAuthRequestResult::kSuccess.
      FederatedAuthRequestResult::kSuccess,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.WebContentsActive", 0, 1);
}

// Test that the account chooser is not shown if the page navigates prior to the
// accounts endpoint request completing and BFCache is disabled.
TEST_F(RequestServiceTest, NavigateDuringClientMetadataFetchBFCacheDisabled) {
  base::test::ScopedFeatureList list;
  list.InitAndDisableFeature(features::kBackForwardCache);
  ASSERT_FALSE(IsBackForwardCacheEnabled());

  SetNetworkRequestManager(
      std::make_unique<IdpNetworkRequestManagerClientMetadataTaskRunner>(
          base::BindOnce(&NavigateToUrl, web_contents(), GURL(kRpOtherUrl))));

  RequestExpectations expectations = {
      /*return_status=*/std::nullopt,
      // When the RenderFrameHost changes on navigation, no console message is
      // received, so pass FederatedAuthRequestResult::kSuccess.
      main_rfh()->ShouldChangeRenderFrameHostOnSameSiteNavigation()
          ? FederatedAuthRequestResult::kSuccess
          : FederatedAuthRequestResult::kError,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
}

// Test that the accounts are reordered so that accounts with a LoginState equal
// to kSignIn are listed before accounts with a LoginState equal to kSignUp.
TEST_F(RequestServiceTest, ReorderMultipleAccounts) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kMultipleAccounts;
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);

  // Check the account order using the account ids.
  ASSERT_EQ(all_accounts_for_display().size(), 3u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdPeter);
  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdNicolas);
  EXPECT_EQ(all_accounts_for_display()[2]->id, kAccountIdZach);
}

// Test that first API call with a given IDP is not affected by the
// IdpSigninStatus bit.
TEST_F(RequestServiceTest, IdpSigninStatusTestFirstTimeFetchSuccess) {
  EXPECT_CALL(*test_permission_delegate_,
              SetIdpSigninStatus(OriginFromString(kProviderUrlFull), true, _))
      .Times(1);

  std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
      std::make_unique<IdpNetworkRequestManagerParamChecker>();
  checker->SetExpectations(kClientId, kAccountId);
  SetNetworkRequestManager(std::move(checker));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
}

// Test that first API call with a given IDP will not show a UI in case of
// failure during fetching accounts.
TEST_F(RequestServiceTest, IdpSigninStatusTestFirstTimeFetchNoFailureUi) {
  EXPECT_CALL(*test_permission_delegate_,
              SetIdpSigninStatus(OriginFromString(kProviderUrlFull), false, _))
      .Times(1);
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());
}

// Test that a failure UI will be displayed if the accounts fetch is failed but
// the IdpSigninStatus claims that the user is signed in.
TEST_F(RequestServiceTest, IdpSigninStatusTestShowFailureUi) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;
  configuration.idp_signin_status_mismatch_dialog_action =
      IdpSigninStatusMismatchDialogAction::kClose;
  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());
}

// Test that API calls will fail before sending any network request if
// IdpSigninStatus shows that the user is not signed in with the IDP. No failure
// UI is displayed.
TEST_F(RequestServiceTest,
       IdpSigninStatusTestApiFailedIfUserNotSignedInWithIdp) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = false;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kNotSignedInWithIdp,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  EXPECT_FALSE(DidFetchAnyEndpoint());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());
}

namespace {

// TestIdpNetworkRequestManager which enables specifying the ParseStatus for
// config and accounts endpoint fetch.
class ParseStatusOverrideIdpNetworkRequestManager
    : public TestIdpNetworkRequestManager {
 public:
  ParseStatus config_parse_status_{ParseStatus::kSuccess};
  ParseStatus accounts_parse_status_{ParseStatus::kSuccess};

  ParseStatusOverrideIdpNetworkRequestManager() = default;
  ~ParseStatusOverrideIdpNetworkRequestManager() override = default;

  ParseStatusOverrideIdpNetworkRequestManager(
      const ParseStatusOverrideIdpNetworkRequestManager&) = delete;
  ParseStatusOverrideIdpNetworkRequestManager& operator=(
      const ParseStatusOverrideIdpNetworkRequestManager&) = delete;

  void FetchConfig(const GURL& provider,
                   blink::mojom::RpMode rp_mode,
                   int idp_brand_icon_ideal_size,
                   int idp_brand_icon_minimum_size,
                   FetchConfigCallback callback) override {
    if (config_parse_status_ != ParseStatus::kSuccess) {
      ++num_fetched_[FetchedEndpoint::CONFIG];

      FetchStatus fetch_status{config_parse_status_, net::HTTP_OK};
      base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
          FROM_HERE, base::BindOnce(std::move(callback), fetch_status,
                                    IdpNetworkRequestManager::Endpoints(),
                                    IdentityProviderMetadata()));
      return;
    }
    TestIdpNetworkRequestManager::FetchConfig(
        provider, rp_mode, idp_brand_icon_ideal_size,
        idp_brand_icon_minimum_size, std::move(callback));
  }

  bool SendAccountsRequest(const url::Origin& idp_origin,
                           const GURL& accounts_url,
                           const std::string& client_id,
                           AccountsRequestCallback callback) override {
    if (accounts_parse_status_ != ParseStatus::kSuccess) {
      ++num_fetched_[FetchedEndpoint::ACCOUNTS];

      FetchStatus fetch_status{accounts_parse_status_, net::HTTP_OK};
      base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
          FROM_HERE, base::BindOnce(std::move(callback), fetch_status,
                                    std::vector<IdentityRequestAccountPtr>()));
      return true;
    }

    return TestIdpNetworkRequestManager::SendAccountsRequest(
        idp_origin, accounts_url, client_id, std::move(callback));
  }
};

}  // namespace

// Test behavior for the following sequence of events:
// 1) Failure dialog is shown due to IdP sign-in status mismatch
// 2) User signs-in
// 3) User selects "Continue" in account chooser dialog.
TEST_F(RequestServiceTest, FailureUiThenSuccessfulSignin) {
  SetNetworkRequestManager(
      std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>());
  auto* network_manager =
      static_cast<ParseStatusOverrideIdpNetworkRequestManager*>(
          test_network_request_manager_.get());

  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);

  // Setup IdP sign-in status mismatch.
  network_manager->accounts_parse_status_ = ParseStatus::kInvalidResponseError;
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, kConfigurationValid);
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());
  EXPECT_FALSE(did_show_accounts_dialog());

  // Simulate user signing into IdP by updating the IdP sign-in status and
  // calling the observer.
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;
  network_manager->accounts_parse_status_ = ParseStatus::kSuccess;
  federated_auth_request_impl_->OnIdpSigninStatusReceived(
      kIdpOrigin, /*idp_signin_status=*/true);

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(kConfigurationValid, kExpectationSuccess);

  EXPECT_TRUE(did_show_accounts_dialog());

  // After the IdP sign-in status was updated, the endpoints should have been
  // fetched a 2nd time.
  EXPECT_EQ(NumFetched(FetchedEndpoint::WELL_KNOWN), 2u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 2u);

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 1);

  ExpectUKMPresence("AccountsDialogShown2");
  ExpectUKMPresence("MismatchDialogShown2");
  ExpectUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectUKMPresence("Timing.MismatchDialogShownDuration");
}

// Test behavior for the following sequence of events:
// 1) Failure dialog is shown due to IdP sign-in status mismatch
// 2) User switches tabs
// 3) User signs into IdP in different tab
TEST_F(RequestServiceTest, FailureUiThenSuccessfulSigninButHidden) {
  SetNetworkRequestManager(
      std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>());
  auto* network_manager =
      static_cast<ParseStatusOverrideIdpNetworkRequestManager*>(
          test_network_request_manager_.get());

  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);

  // Setup IdP sign-in status mismatch.
  network_manager->accounts_parse_status_ = ParseStatus::kInvalidResponseError;
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, kConfigurationValid);
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());
  EXPECT_FALSE(did_show_accounts_dialog());

  // Simulate the user switching to a different tab.
  test_rvh()->SimulateWasHidden();

  // Simulate user signing into IdP by updating the IdP signin status and
  // calling observer.
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;
  network_manager->accounts_parse_status_ = ParseStatus::kSuccess;
  federated_auth_request_impl_->OnIdpSigninStatusReceived(
      kIdpOrigin, /*idp_signin_status=*/true);

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(kConfigurationValid, kExpectationSuccess);

  // The FedCM dialog should switch to the account picker. The user should
  // see a new dialog when they switch back to the FedCM tab.
  EXPECT_TRUE(did_show_accounts_dialog());

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 1);

  ExpectUKMPresence("AccountsDialogShown2");
  ExpectUKMPresence("MismatchDialogShown2");
  ExpectUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectUKMPresence("Timing.MismatchDialogShownDuration");
}

// Test behavior for the following sequence of events:
// 1) Failure dialog is shown due to IdP sign-in status mismatch
// 2) In a different tab, user signs into different IdP
TEST_F(RequestServiceTest, FailureUiSigninFromDifferentIdp) {
  SetNetworkRequestManager(
      std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>());
  auto* network_manager =
      static_cast<ParseStatusOverrideIdpNetworkRequestManager*>(
          test_network_request_manager_.get());

  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);
  url::Origin kOtherOrigin = OriginFromString("https://idp.other");

  // Setup IdP sign-in status mismatch.
  network_manager->accounts_parse_status_ = ParseStatus::kInvalidResponseError;
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;

  // Close mismatch dialog upon sign-in status change to check that the
  // appropriate metrics are recorded.
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_signin_status_mismatch_dialog_action =
      IdpSigninStatusMismatchDialogAction::kClose;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());
  EXPECT_FALSE(did_show_accounts_dialog());

  size_t num_well_known_fetches = NumFetched(FetchedEndpoint::WELL_KNOWN);

  // Simulate user signing into different IdP by updating the IdP signin status
  // and calling observer.
  test_permission_delegate_->idp_signin_statuses_[kOtherOrigin] = true;
  federated_auth_request_impl_->OnIdpSigninStatusReceived(
      kOtherOrigin, /*idp_signin_status=*/true);
  base::RunLoop().RunUntilIdle();

  // No fetches should have been triggered.
  EXPECT_EQ(NumFetched(FetchedEndpoint::WELL_KNOWN), num_well_known_fetches);

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 1);

  ExpectNoUKMPresence("AccountsDialogShown2");
  ExpectUKMPresence("MismatchDialogShown2");
  ExpectNoUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectUKMPresence("Timing.MismatchDialogShownDuration");
}

// Test that for the following sequence of events:
// 1) Failure dialog is shown due to IdP sign-in status mismatch
// 2) IdP sign-in status is updated
// 3) Accounts endpoint still returns an empty list
// That ShowFailureDialog() is called a 2nd time after the IdP sign-in status
// update.
TEST_F(RequestServiceTest, FailureUiAccountEndpointKeepsFailing) {
  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);

  MockConfiguration configuration = kConfigurationValid;

  // Setup IdP sign-in status mismatch.
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;

  auto dialog_controller =
      std::make_unique<TestDialogController>(configuration);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());
  EXPECT_FALSE(did_show_accounts_dialog());

  // Update IdP sign-in status. Keep accounts endpoint returning empty list.
  // Close mismatch dialog upon sign-in status change to check that the
  // appropriate metrics are recorded.
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;
  weak_dialog_controller->SetIdpSigninStatusMismatchDialogAction(
      IdpSigninStatusMismatchDialogAction::kClose);
  federated_auth_request_impl_->OnIdpSigninStatusReceived(
      kIdpOrigin, /*idp_signin_status=*/true);

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(2u, dialog_controller_state_
                    .num_show_idp_signin_status_mismatch_dialog_requests);

  // After the IdP sign-in status was updated, the endpoints should have been
  // fetched a 2nd time.
  EXPECT_EQ(NumFetched(FetchedEndpoint::WELL_KNOWN), 2u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 2u);

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 1);

  ExpectNoUKMPresence("AccountsDialogShown2");
  ExpectUKMPresence("MismatchDialogShown2");
  ExpectNoUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectUKMPresence("Timing.MismatchDialogShownDuration");
}

// Test that for the following sequence of events:
// 1) Failure dialog is shown due to IdP sign-in status mismatch
// 2) IdP sign-in status is updated
// 3) A different endpoint fails during the fetch initiated by the IdP sign-in
// status update.
// That user is shown IdP-sign-in-failure dialog.
TEST_F(RequestServiceTest, FailureUiThenFailDifferentEndpoint) {
  SetNetworkRequestManager(
      std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>());
  auto* network_manager =
      static_cast<ParseStatusOverrideIdpNetworkRequestManager*>(
          test_network_request_manager_.get());

  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);

  // Setup IdP sign-in status mismatch.
  network_manager->accounts_parse_status_ = ParseStatus::kInvalidResponseError;
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, kConfigurationValid);
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());
  EXPECT_FALSE(did_show_accounts_dialog());

  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 1u);

  // Make the fetch triggered by the IdP sign-in status changing fail for a
  // different endpoint.
  network_manager->config_parse_status_ = ParseStatus::kInvalidResponseError;

  // Simulate user signing into IdP by updating the IdP signin status and
  // calling the observer.
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;
  network_manager->accounts_parse_status_ = ParseStatus::kSuccess;
  federated_auth_request_impl_->OnIdpSigninStatusReceived(
      kIdpOrigin, /*idp_signin_status=*/true);

  WaitForCurrentAuthRequest();
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  CheckAuthExpectations(kConfigurationValid, expectations);

  // The user should be shown IdP-sign-in-failure dialog.
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_EQ(1u, dialog_controller_state_
                    .num_show_idp_signin_status_mismatch_dialog_requests);

  // After the IdP sign-in status was updated, the endpoints should have been
  // fetched a 2nd time.
  EXPECT_EQ(NumFetched(FetchedEndpoint::WELL_KNOWN), 2u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 1u);

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 1);

  ExpectNoUKMPresence("AccountsDialogShown2");
  ExpectUKMPresence("MismatchDialogShown2");
  ExpectNoUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectUKMPresence("Timing.MismatchDialogShownDuration");
}

// Test that when IdpSigninStatus API does not have any state for an IDP, that
// the state transitions to sign-in if the accounts endpoint returns a
// non-empty list of accounts.
TEST_F(
    RequestServiceTest,
    IdpSigninStatusMetricsModeUndefinedTransitionsToSignedinWhenHaveAccounts) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = std::nullopt;
  EXPECT_CALL(*test_permission_delegate_,
              SetIdpSigninStatus(OriginFromString(kProviderUrlFull), true, _));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
}

TEST_F(RequestServiceTest, AllSuccessfulMultiIdpRequestWithoutIdpReorder) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  // Set the account from the first IDP as returning as well, so the first
  // selected account should be that one (second IDP also has returning accounts
  // and no reordering should happen).
  MockConfiguration config = kConfigurationMultiIdpValid;
  config.idp_info[kProviderUrlFull].accounts[0]->idp_claimed_login_state =
      LoginState::kSignIn;
  RunAuthTest(kDefaultMultiIdpRequestParameters, kExpectationSuccess, config);
  EXPECT_EQ(2u, NumFetched(FetchedEndpoint::ACCOUNTS));

  // Check that the appropriate metrics are recorded upon destruction.
  federated_auth_request_impl_->ResetAndDeleteThis();
  ukm_loop.Run();
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.NumRequestsPerDocument", 1,
                                       1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ShowAccountsDialog",
                                     1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ContinueOnDialog", 1);
  ExpectUKMPresence("Timing.ContinueOnDialog");
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.IdTokenResponse", 1);
  ExpectUKMPresence("Timing.IdTokenResponse");

  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.TurnaroundTime", 1);
  ExpectUKMPresence("Timing.TurnaroundTime");

  ExpectUkmValueInEntry("AccountsRequestSent2", FedCmEntry::kEntryName, 2);
  ExpectUkmValueInEntry("AccountsRequestSent2", FedCmIdpEntry::kEntryName, 1,
                        2);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsRequestSent", 2);

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 1);
  ExpectUKMCount("Timing.AccountsDialogShownDuration", FedCmEntry::kEntryName,
                 1);
  ExpectUKMCount("Timing.AccountsDialogShownDuration",
                 FedCmIdpEntry::kEntryName, 2);

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 0);
  ExpectNoUKMPresence("Timing.MismatchDialogShownDuration");
  ExpectNoUKMPresence("Timing.MismatchDialogShown2");
  ExpectUKMCount("Timing.ShowAccountsDialog", FedCmEntry::kEntryName, 1);
  ExpectUKMCount("Timing.ShowAccountsDialog", FedCmIdpEntry::kEntryName, 2);
  ExpectUKMPresenceInternal("NumRequestsPerDocument", FedCmEntry::kEntryName);

  ExpectUkmValue("NumIdpsRequested", 2, 2);
  ExpectUkmValue("NumIdpsMismatch", 0, 2);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.IdentityProvidersCount", 2,
                                       1);
  ExpectUKMCount("IdentityProvidersCount", FedCmEntry::kEntryName, 1);
  ExpectUkmValueInEntry("IdentityProvidersCount", FedCmEntry::kEntryName, 2);
}

// Test successful multi IDP FedCM request.
TEST_F(RequestServiceTest, AllSuccessfulMultiIdpRequestWithIdpReorder) {
  RequestExpectations expectations = kExpectationSuccess;
  // Since the first IDP does not set the login state of the account but the
  // second IDP has one with state set to SignIn, selecting the first account
  // means that the second IDP is the one that is selected.
  expectations.selected_idp_config_url = kProviderTwoUrlFull;
  RunAuthTest(kDefaultMultiIdpRequestParameters, expectations,
              kConfigurationMultiIdpValid);
  EXPECT_EQ(2u, NumFetched(FetchedEndpoint::ACCOUNTS));

  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ShowAccountsDialog",
                                     1);
  ExpectUKMCount("Timing.ShowAccountsDialog", FedCmEntry::kEntryName, 1);
  ExpectUKMCount("Timing.ShowAccountsDialog", FedCmIdpEntry::kEntryName, 2);

  ExpectUkmValueInEntry(
      "Status.RequestIdToken", FedCmEntry::kEntryName,
      static_cast<int>(TokenStatus::kSuccessUsingTokenInHttpResponse));
  ExpectUkmValueInEntry(
      "Status.RequestIdToken", FedCmIdpEntry::kEntryName,
      static_cast<int>(TokenStatus::kSuccessUsingTokenInHttpResponse),
      /*expected_count=*/2,
      /*other_values_allowed=*/true);
  ExpectUkmValueInEntry("Status.RequestIdToken", FedCmIdpEntry::kEntryName,
                        static_cast<int>(TokenStatus::kOtherIdpChosen),
                        /*expected_count=*/2,
                        /*other_values_allowed=*/true);
  ExpectUkmValue("NumIdpsRequested", 2, 2);
  ExpectUkmValue("NumIdpsMismatch", 0, 2);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.IdentityProvidersCount", 2,
                                       1);
  ExpectUKMCount("IdentityProvidersCount", FedCmEntry::kEntryName, 1);
  ExpectUkmValueInEntry("IdentityProvidersCount", FedCmEntry::kEntryName, 2);
}

// Test fetching information for the 1st IdP failing, and succeeding for the
// second.
TEST_F(RequestServiceTest, FirstIdpWellKnownInvalid) {
  // Intentionally fail the 1st provider's request by having an invalid
  // well-known file.
  MockConfiguration configuration = kConfigurationMultiIdpValid;
  configuration.idp_info[kProviderUrlFull].well_known.provider_urls =
      std::set<std::string>{"https://not-in-list.example"};

  RequestExpectations expectations = {
      RequestTokenStatus::kSuccess,
      FederatedAuthRequestResult::kConfigNotInWellKnown,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/kProviderTwoUrlFull};

  RunAuthTest(kDefaultMultiIdpRequestParameters, expectations, configuration);
  EXPECT_EQ(NumFetched(FetchedEndpoint::WELL_KNOWN), 2u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::CONFIG), 2u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 1u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::TOKEN), 1u);

  ExpectUKMCount("AccountsRequestSent2", FedCmEntry::kEntryName, 1);
  ExpectUKMCount("AccountsRequestSent2", FedCmIdpEntry::kEntryName, 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsRequestSent", 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.IdentityProvidersCount", 2,
                                       1);
  ExpectUKMCount("IdentityProvidersCount", FedCmEntry::kEntryName, 1);
  ExpectUkmValueInEntry("IdentityProvidersCount", FedCmEntry::kEntryName, 2);
}

// Test fetching information for the 1st IdP succeeding, and failing for the
// second.
TEST_F(RequestServiceTest, SecondIdpWellKnownInvalid) {
  // Intentionally fail the 2nd provider's request by having an invalid
  // well-known file.
  MockConfiguration configuration = kConfigurationMultiIdpValid;
  configuration.idp_info[kProviderTwoUrlFull].well_known.provider_urls =
      std::set<std::string>{"https://not-in-list.example"};

  RequestExpectations expectations = {
      RequestTokenStatus::kSuccess,
      FederatedAuthRequestResult::kConfigNotInWellKnown,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/kProviderUrlFull};

  RunAuthTest(kDefaultMultiIdpRequestParameters, expectations, configuration);
  EXPECT_EQ(NumFetched(FetchedEndpoint::WELL_KNOWN), 2u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::CONFIG), 2u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 1u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::TOKEN), 1u);

  ExpectUKMCount("AccountsRequestSent2", FedCmEntry::kEntryName, 1);
  ExpectUKMCount("AccountsRequestSent2", FedCmIdpEntry::kEntryName, 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsRequestSent", 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.IdentityProvidersCount", 2,
                                       1);
  ExpectUKMCount("IdentityProvidersCount", FedCmEntry::kEntryName, 1);
  ExpectUkmValueInEntry("IdentityProvidersCount", FedCmEntry::kEntryName, 2);
}

// Test fetching information for all of the IdPs failing.
TEST_F(RequestServiceTest, AllWellKnownsInvalid) {
  // Intentionally fail the requests for both IdPs by returning an invalid
  // well-known file.
  MockConfiguration configuration = kConfigurationMultiIdpValid;
  configuration.idp_info[kProviderUrlFull].well_known.provider_urls =
      std::set<std::string>{"https://not-in-list.example"};
  configuration.idp_info[kProviderTwoUrlFull].well_known.provider_urls =
      std::set<std::string>{"https://not-in-list.example"};

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigNotInWellKnown,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  RunAuthTest(kDefaultMultiIdpRequestParameters, expectations, configuration);
  EXPECT_EQ(NumFetched(FetchedEndpoint::WELL_KNOWN), 2u);
  EXPECT_EQ(NumFetched(FetchedEndpoint::CONFIG), 2u);
  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));

  ExpectNoUKMPresence("Timing.ShowAccountsDialog");
  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsRequestSent", 0);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.IdentityProvidersCount", 2,
                                       1);
  ExpectUKMCount("IdentityProvidersCount", FedCmEntry::kEntryName, 1);
  ExpectUkmValueInEntry("IdentityProvidersCount", FedCmEntry::kEntryName, 2);
}

// Test multi IDP FedCM request with duplicate IDPs should throw an error.
TEST_F(RequestServiceTest, DuplicateIdpMultiIdpRequest) {
  RequestParameters request_parameters = kDefaultMultiIdpRequestParameters;
  request_parameters.identity_providers =
      std::vector<IdentityProviderParameters>{
          request_parameters.identity_providers[0],
          request_parameters.identity_providers[0]};

  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kError,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  RunAuthTest(request_parameters, expectations, kConfigurationMultiIdpValid);
  EXPECT_FALSE(DidFetchAnyEndpoint());
  EXPECT_FALSE(did_show_accounts_dialog());

  histogram_tester_.ExpectTotalCount("Blink.FedCm.IdentityProvidersCount", 0);
  ExpectUKMCount("IdentityProvidersCount", FedCmEntry::kEntryName, 0);
}

// Test that API can succeed with multiple IdPs, if one IdP is signed out but
// the other isn't.
TEST_F(RequestServiceTest, MultiIdpWithOneIdpSignedOut) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = false;

  RequestExpectations expectations = kExpectationSuccess;
  expectations.selected_idp_config_url = kProviderTwoUrlFull;

  RunAuthTest(kDefaultMultiIdpRequestParameters, expectations,
              kConfigurationMultiIdpValid);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());
}

// Test that API shows all accounts if the user logs in to the IDP with the
// mismatch UI.
TEST_F(RequestServiceTest, MultiIdpLoginToOneIdp) {
  url::Origin providerOrigin = OriginFromString(kProviderUrlFull);
  test_permission_delegate_->idp_signin_statuses_[providerOrigin] = true;

  MockConfiguration config = kConfigurationMultiIdpValid;
  // Second IDP has invalid accounts response.
  config.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;
  config.accounts_dialog_action = AccountsDialogAction::kNone;

  RunAuthDontWaitForCallback(kDefaultMultiIdpRequestParameters, config);

  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 2u);
  EXPECT_TRUE(did_show_accounts_dialog());
  // The second IDP has 3 accounts, so those should be showing up.
  EXPECT_EQ(all_accounts_for_display().size(), 3u);

  EXPECT_FALSE(federated_auth_request_impl_->HasUserTriedToSignInToIdp(
      GURL(kProviderUrlFull)));
  EXPECT_FALSE(federated_auth_request_impl_->HasUserTriedToSignInToIdp(
      GURL(kProviderTwoUrlFull)));
  // First, simulate the user clicking on the sign in to IDP active.
  SimulateLoginToIdP();
  // Then, simulate user signing into IdP by updating the IdP signin status and
  // calling the observer.
  test_permission_delegate_->idp_signin_statuses_[providerOrigin] = true;
  // Second IDP will now correctly return its account.
  config.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kSuccess;
  SetConfig(config);
  federated_auth_request_impl_->OnIdpSigninStatusReceived(
      providerOrigin, /*idp_signin_status=*/true);

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 3u);
  EXPECT_TRUE(did_show_accounts_dialog());
  // The first IDP only has a single account, and the total of accounts is
  // now 4.
  EXPECT_EQ(all_accounts_for_display().size(), 4u);
  EXPECT_EQ(new_accounts().size(), 1u);
  EXPECT_TRUE(federated_auth_request_impl_->HasUserTriedToSignInToIdp(
      GURL(kProviderUrlFull)));
  EXPECT_FALSE(federated_auth_request_impl_->HasUserTriedToSignInToIdp(
      GURL(kProviderTwoUrlFull)));
}

// Test that API can succeed with multiple IdPs, if all IDPs have login status
// mismatch.
TEST_F(RequestServiceTest, MultiIdpWithAllIdpsMismatch) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderTwoUrlFull)] = true;

  // Set the config so that both accounts fetches result in failure.
  MockConfiguration config = kConfigurationMultiIdpValid;
  config.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kEmptyListError;
  config.idp_info[kProviderTwoUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;
  // Need to change the accounts dialog action since we won't get any accounts.
  config.accounts_dialog_action = AccountsDialogAction::kClose;

  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  RunAuthTest(kDefaultMultiIdpRequestParameters, expectations, config);

  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 2u);
  EXPECT_TRUE(all_accounts_for_display().empty());
  auto mismatch_idps = displayed_mismatch_idps();
  ASSERT_EQ(mismatch_idps.size(), 2u);
  EXPECT_EQ(mismatch_idps[0], "idp.example");
  EXPECT_EQ(mismatch_idps[1], "idp2.example");
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 1);

  ExpectNoUKMPresence("Timing.AccountsDialogShownDuration");

  ExpectUKMCount("Timing.MismatchDialogShownDuration", FedCmEntry::kEntryName,
                 1);
  ExpectUKMCount("Timing.MismatchDialogShownDuration",
                 FedCmIdpEntry::kEntryName, 2);

  ExpectUkmValue("Status.RequestIdToken",
                 static_cast<int>(TokenStatus::kShouldEmbargo), 2);
  ExpectUkmValue("NumIdpsRequested", 2, 2);
  ExpectUkmValue("NumIdpsMismatch", 2, 2);
}

TEST_F(RequestServiceTest, MultiIdpWithOneIdpMismatch) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderTwoUrlFull)] = true;

  // Set the config so that both accounts fetches result in failure.
  MockConfiguration config = kConfigurationMultiIdpValid;
  config.idp_info[kProviderTwoUrlFull].accounts_response.parse_status =
      ParseStatus::kEmptyListError;

  RunAuthTest(kDefaultMultiIdpRequestParameters, kExpectationSuccess, config);

  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 2u);
  EXPECT_FALSE(all_accounts_for_display().empty());
  auto mismatch_idps = displayed_mismatch_idps();
  ASSERT_EQ(mismatch_idps.size(), 1u);
  EXPECT_EQ(mismatch_idps[0], "idp2.example");
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 1);
  ExpectUKMCount("Timing.AccountsDialogShownDuration", FedCmEntry::kEntryName,
                 1);
  ExpectUKMCount("Timing.AccountsDialogShownDuration",
                 FedCmIdpEntry::kEntryName, 1);

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 0);
  ExpectUKMCount("Timing.MismatchDialogShownDuration", FedCmEntry::kEntryName,
                 0);
  ExpectUKMCount("Timing.MismatchDialogShownDuration",
                 FedCmIdpEntry::kEntryName, 1);

  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ShowAccountsDialog",
                                     1);
  ExpectUKMCount("Timing.ShowAccountsDialog", FedCmEntry::kEntryName, 1);
  ExpectUKMCount("Timing.ShowAccountsDialog", FedCmIdpEntry::kEntryName, 1);

  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsDialogShown", 1);
  ExpectUKMCount("AccountsDialogShown2", FedCmEntry::kEntryName, 1);
  ExpectUKMCount("AccountsDialogShown2", FedCmIdpEntry::kEntryName, 1);

  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.MismatchDialogShown2",
                                     0);
  ExpectUKMCount("MismatchDialogShown2", FedCmEntry::kEntryName, 0);
  ExpectUKMCount("MismatchDialogShown2", FedCmIdpEntry::kEntryName, 1);

  ExpectUkmValueInEntry(
      "Status.RequestIdToken", FedCmEntry::kEntryName,
      static_cast<int>(TokenStatus::kSuccessUsingTokenInHttpResponse));
  ExpectUkmValueInEntry(
      "Status.RequestIdToken", FedCmIdpEntry::kEntryName,
      static_cast<int>(TokenStatus::kSuccessUsingTokenInHttpResponse),
      /*expected_count=*/2,
      /*other_values_allowed=*/true);
  ExpectUkmValueInEntry("Status.RequestIdToken", FedCmIdpEntry::kEntryName,
                        static_cast<int>(TokenStatus::kOtherIdpChosen),
                        /*expected_count=*/2,
                        /*other_values_allowed=*/true);
  ExpectUkmValue("NumIdpsRequested", 2, 2);
  ExpectUkmValue("NumIdpsMismatch", 1, 2);
}

// Test that API can succeed with multiple IdPs, if silent mediation is used but
// only one IdP has a returning account.
TEST_F(RequestServiceTest,
       MultiIdpWithSilentMediationAndReturningAccountInSecondIdp) {
  // Pretend the sharing permission has not been granted for any account for the
  // first IdP.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull)))
      .WillOnce(Return(false));

  // Pretend the sharing permission has been granted for exactly one account for
  // the second IdP.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderTwoUrlFull)))
      .WillOnce(Return(true));
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderTwoUrlFull), kAccountIdPeter))
      .WillRepeatedly(Return(std::make_optional<base::Time>()));
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderTwoUrlFull), kAccountIdNicolas))
      .WillRepeatedly(Return(std::nullopt));
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderTwoUrlFull), kAccountIdZach))
      .WillRepeatedly(Return(std::nullopt));

  // Ensure auto reauthn is not considered as disabled.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .Times(3)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .Times(3)
      .WillRepeatedly(Return(false));

  RequestExpectations expectations = kExpectationSuccess;
  expectations.selected_idp_config_url = kProviderTwoUrlFull;
  expectations.is_auto_selected = true;
  // There will be a console message due to using mediation:silent and having an
  // IdP that does not have a returning account.
  expectations.standalone_console_message =
      "Silent mediation issue: the user has not used FedCM on this site with "
      "this identity provider.";

  MockConfiguration configuration = kConfigurationMultiIdpValid;
  configuration.mediation_requirement = MediationRequirement::kSilent;

  RunAuthDontWaitForCallback(kDefaultMultiIdpRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(configuration, expectations);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());
}

// Test that API fails with multiple IdPs, if silent mediation is used and two
// IdPs have a single returning account.
TEST_F(RequestServiceTest,
       MultiIdpWithSilentMediationAndReturningAccountInTwoIdps) {
  // Pretend the sharing permission has been granted for exactly one account for
  // the first IdP.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull)))
      .WillOnce(Return(true));
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  // Pretend the sharing permission has been granted for exactly one account for
  // the second IdP.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderTwoUrlFull)))
      .WillOnce(Return(true));
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderTwoUrlFull), kAccountIdPeter))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderTwoUrlFull), kAccountIdNicolas))
      .WillRepeatedly(Return(std::nullopt));
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderTwoUrlFull), kAccountIdZach))
      .WillRepeatedly(Return(std::nullopt));

  // Ensure auto reauthn is not considered as disabled.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillRepeatedly(Return(false));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kSilentMediationFailure,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationMultiIdpValid;
  configuration.mediation_requirement = MediationRequirement::kSilent;

  RunAuthDontWaitForCallback(kDefaultMultiIdpRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  // Accounts still need to be fetched since there could have been a single
  // returning account.
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());
}

// Test that when there are two IDPs with sharing permissions but the account
// fetch fails for one of them, mediation silent can still succeed.
TEST_F(RequestServiceTest, MultiIdpWithSilentMediationAndOneIdpFetchFailure) {
  // Mark both IDPs as logged in.
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderTwoUrlFull)] = true;

  // Pretend the sharing permission has been granted for exactly one account for
  // the first IdP.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull)))
      .WillOnce(Return(true));

  // Pretend the sharing permission has been granted for exactly one account for
  // the second IdP.
  EXPECT_CALL(
      *test_permission_delegate_,
      HasSharingPermission(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderTwoUrlFull)))
      .WillOnce(Return(true));
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderTwoUrlFull), kAccountIdPeter))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderTwoUrlFull), kAccountIdZach))
      .WillRepeatedly(Return(std::nullopt));
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderTwoUrlFull), kAccountIdNicolas))
      .WillRepeatedly(Return(std::nullopt));

  // Ensure auto reauthn is not considered as disabled.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .Times(3)
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .Times(3)
      .WillRepeatedly(Return(false));

  RequestExpectations expectations = kExpectationSuccess;
  expectations.selected_idp_config_url = kProviderTwoUrlFull;
  expectations.is_auto_selected = true;
  expectations.standalone_console_message =
      "Silent mediation was requested, but the conditions to achieve it were "
      "not met.";

  MockConfiguration configuration = kConfigurationMultiIdpValid;
  configuration.mediation_requirement = MediationRequirement::kSilent;
  // Let the first IDP accounts fetch fail.
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kNoResponseError;

  RunAuthDontWaitForCallback(kDefaultMultiIdpRequestParameters, configuration);
  EXPECT_FALSE(auth_helper_->was_callback_called());

  WaitForCurrentAuthRequest();
  CheckAuthExpectations(configuration, expectations);

  // Accounts still need to be fetched since there could have been a single
  // returning account.
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
}

TEST_F(RequestServiceTest, MultiIdpLoggedOut) {
  // Mark both IDPs as logged out so the request fails early.
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = false;
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderTwoUrlFull)] = false;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kNotSignedInWithIdp,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  request_remote_.set_disconnect_handler(auth_helper_->quit_closure());

  RunAuthDontWaitForCallback(kDefaultMultiIdpRequestParameters,
                             kConfigurationMultiIdpValid);
  base::RunLoop().RunUntilIdle();
  // The callback must be delayed.
  EXPECT_FALSE(auth_helper_->was_callback_called());
  WaitForCurrentAuthRequest();
  CheckAuthExpectations(kConfigurationMultiIdpValid, expectations);
}

TEST_F(RequestServiceTest, MultiIdpWithError) {
  MockConfiguration configuration = kConfigurationMultiIdpValid;
  ErrorDialogType error_dialog_type =
      ErrorDialogType::kGenericNonEmptyWithoutUrl;
  TokenResponseType token_response_type =
      TokenResponseType::kTokenReceivedAndErrorReceivedAndContinueOnNotReceived;
  configuration.token_response.parse_status =
      ParseStatus::kInvalidResponseError;
  configuration.error_dialog_type = error_dialog_type;
  configuration.token_response_type = token_response_type;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(dialog_controller_state_.did_show_error_dialog);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.ErrorDialogType",
                                       error_dialog_type, 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.Error.ErrorDialogResult",
      ErrorDialogResult::kCloseWithoutMoreDetails, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.TokenResponseType",
                                       token_response_type, 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Error.ErrorUrlType", 0);

  ExpectUKMPresence("Error.ErrorDialogType");
  ExpectUKMPresence("Error.ErrorDialogResult");
  ExpectUKMPresence("Error.TokenResponseType");
  ExpectNoUKMPresence("Error.ErrorUrlType");
}

TEST_F(RequestServiceTest, TooManyRequests) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kNone;
  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());

  // Reset the network request manager so we can check that we fetch no
  // endpoints in the subsequent call.
  configuration.accounts_dialog_action =
      AccountsDialogAction::kSelectFirstAccount;
  SetNetworkRequestManager(std::make_unique<TestIdpNetworkRequestManager>());
  // The next FedCM request should fail since the initial request has not yet
  // been finalized.
  RequestExpectations expectations = {
      RequestTokenStatus::kErrorTooManyRequests,
      FederatedAuthRequestResult::kTooManyRequests,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_FALSE(DidFetchAnyEndpoint());

  // Check that the appropriate metrics are recorded upon destruction.
  federated_auth_request_impl_->ResetAndDeleteThis();

  ukm_loop.Run();

  // Only count the first request, the second request that resulted in
  // RequestTokenStatus::kErrorTooManyRequests should not be counted.
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.NumRequestsPerDocument", 1,
                                       1);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.MultipleRequestsRpMode", 0,
                                       1);
  ExpectUkmValue("MultipleRequestsRpMode",
                 static_cast<int>(MultipleRequestsRpMode::kPassiveThenPassive));

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.MultipleRequestsFromDifferentIdPs", 0, 1);
  ExpectUkmValueInEntry("MultipleRequestsFromDifferentIdPs",
                        FedCmEntry::kEntryName, false);

  // Check for RP-keyed UKM presence.
  ExpectUKMPresenceInternal("NumRequestsPerDocument", FedCmEntry::kEntryName);

  // Metrics for each request should be recorded separately with different
  // session IDs.
  ExpectTwoUniqueSessionIDs();
}

TEST_F(RequestServiceTest, TooManyRequestsDifferentIdP) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kNone;
  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());

  // Reset the network request manager so we can check that we fetch no
  // endpoints in the subsequent call.
  configuration.accounts_dialog_action =
      AccountsDialogAction::kSelectFirstAccount;
  SetNetworkRequestManager(std::make_unique<TestIdpNetworkRequestManager>());
  // The next FedCM request should fail since the initial request has not yet
  // been finalized.
  RequestExpectations expectations = {
      RequestTokenStatus::kErrorTooManyRequests,
      FederatedAuthRequestResult::kTooManyRequests,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  // Initiates a new API call with a different IdP.
  RequestParameters request{kDefaultRequestParameters};
  request.identity_providers[0].provider = kProviderTwoUrlFull;
  RunAuthTest(request, expectations, configuration);
  EXPECT_FALSE(DidFetchAnyEndpoint());

  // Check that the appropriate metrics are recorded upon destruction.
  federated_auth_request_impl_->ResetAndDeleteThis();

  ukm_loop.Run();

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.MultipleRequestsFromDifferentIdPs", 1, 1);
  ExpectUkmValueInEntry("MultipleRequestsFromDifferentIdPs",
                        FedCmEntry::kEntryName, true);
}

TEST_F(RequestServiceTest, ActiveModeTooManyRequestsWithNewPassiveFlow) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kNone;

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RunAuthDontWaitForCallback(parameters, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());

  // Reset the network request manager so we can check that we fetch no
  // endpoints in the subsequent call.
  configuration.accounts_dialog_action =
      AccountsDialogAction::kSelectFirstAccount;
  SetNetworkRequestManager(std::make_unique<TestIdpNetworkRequestManager>());
  // The next FedCM request should fail since a passive flow cannot replace
  // another active flow.
  RequestExpectations expectations = {
      RequestTokenStatus::kErrorTooManyRequests,
      FederatedAuthRequestResult::kTooManyRequests,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_FALSE(DidFetchAnyEndpoint());

  // Check that the appropriate metrics are recorded upon destruction.
  federated_auth_request_impl_->ResetAndDeleteThis();

  ukm_loop.Run();

  // Only count the first request, the second request that resulted in
  // RequestTokenStatus::kErrorTooManyRequests should not be counted.
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.NumRequestsPerDocument", 1,
                                       1);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.MultipleRequestsRpMode", 2,
                                       1);
  ExpectUkmValue("MultipleRequestsRpMode",
                 static_cast<int>(MultipleRequestsRpMode::kActiveThenPassive));

  // Check for RP-keyed UKM presence.
  ExpectUKMPresenceInternal("NumRequestsPerDocument", FedCmEntry::kEntryName);
}

TEST_F(RequestServiceTest, ActiveModeTooManyRequestsWithNewActiveFlow) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kNone;

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RunAuthDontWaitForCallback(parameters, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());

  // Reset the network request manager so we can check that we fetch no
  // endpoints in the subsequent call.
  configuration.accounts_dialog_action =
      AccountsDialogAction::kSelectFirstAccount;
  SetNetworkRequestManager(std::make_unique<TestIdpNetworkRequestManager>());
  // The next FedCM request should fail since a active flow cannot replace
  // another active flow.
  RequestExpectations expectations = {
      RequestTokenStatus::kErrorTooManyRequests,
      FederatedAuthRequestResult::kTooManyRequests,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RunAuthTest(parameters, expectations, configuration);
  EXPECT_FALSE(DidFetchAnyEndpoint());

  // Check that the appropriate metrics are recorded upon destruction.
  federated_auth_request_impl_->ResetAndDeleteThis();

  ukm_loop.Run();

  // Only count the first request, the second request that resulted in
  // RequestTokenStatus::kErrorTooManyRequests should not be counted.
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.NumRequestsPerDocument", 1,
                                       1);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.MultipleRequestsRpMode", 3,
                                       1);
  ExpectUkmValue("MultipleRequestsRpMode",
                 static_cast<int>(MultipleRequestsRpMode::kActiveThenActive));

  // Check for RP-keyed UKM presence.
  ExpectUKMPresenceInternal("NumRequestsPerDocument", FedCmEntry::kEntryName);
}

TEST_F(RequestServiceTest, PassiveReplacedByActiveFlow) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kNone;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  RequestExpectations active_flow_expectations = kExpectationSuccess;
  active_flow_expectations.standalone_console_message =
      "The request is replaced by a new one with active mode.";

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  // Create new test helpers so that we can send the second request.
  SetNetworkRequestManager(std::make_unique<TestIdpNetworkRequestManager>());
  std::unique_ptr<AuthRequestCallbackHelper> active_flow_auth_helper =
      std::make_unique<AuthRequestCallbackHelper>();

  RunAuthTest(parameters, active_flow_expectations, kConfigurationValid,
              active_flow_auth_helper.get());

  RequestExpectations passive_flow_expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kReplacedByActiveMode,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  CheckAuthExpectations(configuration, passive_flow_expectations);

  // Check that the appropriate metrics are recorded upon destruction.
  federated_auth_request_impl_->ResetAndDeleteThis();

  ukm_loop.Run();

  // Count both the replaced passive request and the active request.
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.NumRequestsPerDocument", 2,
                                       1);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.MultipleRequestsRpMode", 1,
                                       1);
  ExpectUkmValue("MultipleRequestsRpMode",
                 static_cast<std::underlying_type_t<MultipleRequestsRpMode>>(
                     MultipleRequestsRpMode::kPassiveThenActive));

  // Check for RP-keyed UKM presence.
  ExpectUKMPresenceInternal("NumRequestsPerDocument", FedCmEntry::kEntryName);

  // Metrics for each request should be recorded separately with different
  // session IDs.
  ExpectTwoUniqueSessionIDs();
}

// TestIdpNetworkRequestManager subclass which records requests to metrics
// endpoint.
class IdpNetworkRequestMetricsRecorder : public TestIdpNetworkRequestManager {
 public:
  IdpNetworkRequestMetricsRecorder() = default;
  IdpNetworkRequestMetricsRecorder(const IdpNetworkRequestMetricsRecorder&) =
      delete;
  IdpNetworkRequestMetricsRecorder& operator=(
      const IdpNetworkRequestMetricsRecorder&) = delete;

  void SendSuccessfulTokenRequestMetrics(
      const GURL& metrics_endpoint_url,
      base::TimeDelta api_call_to_show_dialog_time,
      base::TimeDelta show_dialog_to_continue_clicked_time,
      base::TimeDelta account_selected_to_token_response_time,
      base::TimeDelta api_call_to_token_response_time) override {
    metrics_endpoints_notified_success_.push_back(metrics_endpoint_url);
  }

  void SendFailedTokenRequestMetrics(
      const GURL& metrics_endpoint_url,
      bool did_show_ui,
      MetricsEndpointErrorCode error_code) override {
    metrics_endpoints_notified_failure_.push_back(metrics_endpoint_url);
  }

  const std::vector<GURL>& get_metrics_endpoints_notified_success() {
    return metrics_endpoints_notified_success_;
  }

  const std::vector<GURL>& get_metrics_endpoints_notified_failure() {
    return metrics_endpoints_notified_failure_;
  }

 private:
  std::vector<GURL> metrics_endpoints_notified_success_;
  std::vector<GURL> metrics_endpoints_notified_failure_;
};

// Test that the metrics endpoint is not notified when the FedCM API is in
// cooldown.
TEST_F(RequestServiceTest, MetricsEndpointDuringCooldown) {
  base::test::ScopedFeatureList list;
  list.InitAndEnableFeature(features::kFedCmMetricsEndpoint);

  test_api_permission_delegate_->RecordDismissAndEmbargo(
      OriginFromString(kRpUrl));
  std::unique_ptr<IdpNetworkRequestMetricsRecorder> unique_metrics_recorder =
      std::make_unique<IdpNetworkRequestMetricsRecorder>();
  IdpNetworkRequestMetricsRecorder* metrics_recorder =
      unique_metrics_recorder.get();
  SetNetworkRequestManager(std::move(unique_metrics_recorder));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kDisabledInSettings,
      /*standalone_console_message=*/std::nullopt,
      /* selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  EXPECT_FALSE(DidFetchAnyEndpoint());
  EXPECT_TRUE(
      metrics_recorder->get_metrics_endpoints_notified_success().empty());
  EXPECT_TRUE(
      metrics_recorder->get_metrics_endpoints_notified_failure().empty());
}

// Test that the metrics endpoint is notified as a result of a successful
// multi-IDP RequestService::RequestToken() call.
TEST_F(RequestServiceTest, MetricsEndpointMultiIdp) {
  base::test::ScopedFeatureList list;
  list.InitAndEnableFeature(features::kFedCmMetricsEndpoint);

  std::unique_ptr<IdpNetworkRequestMetricsRecorder> unique_metrics_recorder =
      std::make_unique<IdpNetworkRequestMetricsRecorder>();
  IdpNetworkRequestMetricsRecorder* metrics_recorder =
      unique_metrics_recorder.get();
  SetNetworkRequestManager(std::move(unique_metrics_recorder));

  // Since the first IDP does not set the login state of the account but the
  // second IDP has one with state set to SignIn, selecting the first account
  // means that the second IDP is the one that is selected.
  RequestExpectations expectations = kExpectationSuccess;
  expectations.selected_idp_config_url = kProviderTwoUrlFull;
  RunAuthTest(kDefaultMultiIdpRequestParameters, expectations,
              kConfigurationMultiIdpValid);
  EXPECT_THAT(metrics_recorder->get_metrics_endpoints_notified_success(),
              ElementsAre("https://idp2.example/metrics"));
  EXPECT_THAT(metrics_recorder->get_metrics_endpoints_notified_failure(),
              ElementsAre(kMetricsEndpoint));
}

// Test that the metrics endpoint is notified when
// RequestService::RequestToken() call fails.
TEST_F(RequestServiceTest, MetricsEndpointMultiIdpFail) {
  base::test::ScopedFeatureList list;
  list.InitAndEnableFeature(features::kFedCmMetricsEndpoint);

  std::unique_ptr<IdpNetworkRequestMetricsRecorder> unique_metrics_recorder =
      std::make_unique<IdpNetworkRequestMetricsRecorder>();
  IdpNetworkRequestMetricsRecorder* metrics_recorder =
      unique_metrics_recorder.get();
  SetNetworkRequestManager(std::move(unique_metrics_recorder));

  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /* selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationMultiIdpValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kClose;

  RunAuthTest(kDefaultMultiIdpRequestParameters, expectations, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());

  EXPECT_TRUE(
      metrics_recorder->get_metrics_endpoints_notified_success().empty());
  EXPECT_THAT(metrics_recorder->get_metrics_endpoints_notified_failure(),
              ElementsAre(kMetricsEndpoint, "https://idp2.example/metrics"));
}

TEST_F(RequestServiceTest, AccountsSortedWithTimestamps) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kMultipleAccounts;
  // First account is kSignUp so the fact that it has a last used timestamp
  // should not affect its relative ordering.
  EXPECT_CALL(*test_permission_delegate_,
              GetLastUsedTimestamp(
                  OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                  OriginFromString(kProviderUrlFull), kAccountIdNicolas))
      .WillRepeatedly(Return(std::make_optional<base::Time>(
          base::Time() + base::Microseconds(10))));
  // The second account is marked signed in but has no last used timestamp.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountIdPeter))
      .WillRepeatedly(Return(std::nullopt));
  // The third account is marked sign (as is the second), but since it has a
  // timestamp it should show first.
  configuration.idp_info[kProviderUrlFull]
      .accounts[2]
      ->idp_claimed_login_state = LoginState::kSignIn;
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountIdZach))
      .WillRepeatedly(Return(std::make_optional<base::Time>(
          base::Time() + base::Microseconds(1))));

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 3u);
  // Account order should be: accounts[2], accounts[1], accounts[0].
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdZach);
  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdPeter);
  EXPECT_EQ(all_accounts_for_display()[2]->id, kAccountIdNicolas);
}

TEST_F(RequestServiceTest, AccountLabelMultipleAccountsNoMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  const RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsListEmpty,
      {kFilterNoMatchMessage},
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.requested_label =
      "invalid_label";
  configuration.idp_info[kProviderUrlFull].accounts =
      kMultipleAccountsWithHintsAndDomains;

  RunAuthTest(parameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.AccountLabel.NumMatchingAccounts",
      Metrics::NumAccounts::kZero, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.Raw", 3, 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsSize.ReadyToShow", 0);
  ExpectUkmValueInEntry("AccountLabel.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 0);
  ExpectNoUKMPresence("DomainHint.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, AccountLabelMultipleAccountsOneMatch) {
  RequestParameters parameters = kDefaultRequestParameters;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.requested_label = "label";
  configuration.idp_info[kProviderUrlFull].accounts =
      kMultipleAccountsWithHintsAndDomains;

  RunAuthTest(parameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdPeter);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.AccountLabel.NumMatchingAccounts",
      Metrics::NumAccounts::kOne, 1);
  ExpectUkmValueInEntry("AccountLabel.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 1);
  ExpectNoUKMPresence("DomainHint.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, LoginHintSingleAccountIdMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].login_hint = kAccountId;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kSingleAccountWithHint;

  RunAuthTest(parameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountId);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.LoginHint.NumMatchingAccounts", Metrics::NumAccounts::kOne,
      1);
  ExpectUkmValueInEntry("LoginHint.NumMatchingAccounts", FedCmEntry::kEntryName,
                        1);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("DomainHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, LoginHintSingleAccountEmailMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].login_hint = kEmail;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kSingleAccountWithHint;

  RunAuthTest(parameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->display_identifier, kEmail);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.LoginHint.NumMatchingAccounts", Metrics::NumAccounts::kOne,
      1);
  ExpectUkmValueInEntry("LoginHint.NumMatchingAccounts", FedCmEntry::kEntryName,
                        1);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("DomainHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, LoginHintSingleAccountNoMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].login_hint = "incorrect_login_hint";
  const RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsListEmpty,
      {kFilterNoMatchMessage},
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kSingleAccountWithHint;

  RunAuthTest(parameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
  ExpectNoUKMPresence("HasSigninAccount");

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.LoginHint.NumMatchingAccounts", Metrics::NumAccounts::kZero,
      1);
  ExpectUkmValueInEntry("LoginHint.NumMatchingAccounts", FedCmEntry::kEntryName,
                        0);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("DomainHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, LoginHintFirstAccountMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].login_hint = kAccountIdNicolas;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kMultipleAccountsWithHintsAndDomains;

  RunAuthTest(parameters, kExpectationSuccess, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdNicolas);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.LoginHint.NumMatchingAccounts", Metrics::NumAccounts::kOne,
      1);
  ExpectUkmValueInEntry("LoginHint.NumMatchingAccounts", FedCmEntry::kEntryName,
                        1);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("DomainHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, LoginHintLastAccountMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].login_hint = kAccountIdZach;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kMultipleAccountsWithHintsAndDomains;

  RunAuthTest(parameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdZach);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.LoginHint.NumMatchingAccounts", Metrics::NumAccounts::kOne,
      1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.Raw", 3, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.ReadyToShow",
                                       1, 1);
  ExpectUkmValueInEntry("LoginHint.NumMatchingAccounts", FedCmEntry::kEntryName,
                        1);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("DomainHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, LoginHintMultipleAccountsNoMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].login_hint = "incorrect_login_hint";
  const RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsListEmpty,
      {kFilterNoMatchMessage},
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kMultipleAccountsWithHintsAndDomains;

  RunAuthTest(parameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.LoginHint.NumMatchingAccounts", Metrics::NumAccounts::kZero,
      1);
  ExpectUkmValueInEntry("LoginHint.NumMatchingAccounts", FedCmEntry::kEntryName,
                        0);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("DomainHint.NumMatchingAccounts");
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.Raw", 3, 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsSize.ReadyToShow", 0);
}

TEST_F(RequestServiceTest, DomainHintSingleAccountMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint = kDomainHint;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kSingleAccountWithDomainHint;

  RunAuthTest(parameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountId);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.DomainHint.NumMatchingAccounts", Metrics::NumAccounts::kOne,
      1);
  ExpectUkmValueInEntry("DomainHint.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 1);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, DomainHintSingleAccountStarMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint =
      RequestService::kWildcardDomainHint;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kSingleAccountWithDomainHint;

  RunAuthTest(parameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountId);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.DomainHint.NumMatchingAccounts", Metrics::NumAccounts::kOne,
      1);
  ExpectUkmValueInEntry("DomainHint.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 1);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, DomainHintSingleAccountStarNoMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint =
      RequestService::kWildcardDomainHint;

  const RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsListEmpty,
      {kFilterNoMatchMessage},
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;

  RunAuthTest(parameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.DomainHint.NumMatchingAccounts", Metrics::NumAccounts::kZero,
      1);
  ExpectUkmValueInEntry("DomainHint.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 0);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, DomainHintSingleAccountNoMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint = "incorrect_domain_hint";
  const RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsListEmpty,
      {kFilterNoMatchMessage},
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kSingleAccountWithDomainHint;

  RunAuthTest(parameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.DomainHint.NumMatchingAccounts", Metrics::NumAccounts::kZero,
      1);
  ExpectUkmValueInEntry("DomainHint.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 0);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.Raw", 1, 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.AccountsSize.ReadyToShow", 0);
}

TEST_F(RequestServiceTest, DomainHintNoMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint = kDomainHint;
  const RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsListEmpty,
      {kFilterNoMatchMessage},
      /*selected_idp_config_url=*/std::nullopt};

  RunAuthTest(parameters, expectations, kConfigurationValid);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.DomainHint.NumMatchingAccounts", Metrics::NumAccounts::kZero,
      1);
  ExpectUkmValueInEntry("DomainHint.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 0);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, DomainHintMultipleAccountsSingleMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint = kOtherDomainHint;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kMultipleAccountsWithHintsAndDomains;

  RunAuthTest(parameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdZach);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.DomainHint.NumMatchingAccounts", Metrics::NumAccounts::kOne,
      1);
  ExpectUkmValueInEntry("DomainHint.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 1);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.Raw", 3, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.ReadyToShow",
                                       1, 1);
}

TEST_F(RequestServiceTest, DomainHintMultipleAccountsMultipleMatches) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint = kDomainHint;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kMultipleAccountsWithHintsAndDomains;

  RunAuthTest(parameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 2u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdNicolas);
  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdZach);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.DomainHint.NumMatchingAccounts",
      Metrics::NumAccounts::kMultiple, 1);
  ExpectUkmValueInEntry("DomainHint.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 2);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.Raw", 3, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsSize.ReadyToShow",
                                       2, 1);
}

TEST_F(RequestServiceTest, DomainHintMultipleAccountsStar) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint =
      RequestService::kWildcardDomainHint;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kMultipleAccountsWithHintsAndDomains;

  RunAuthTest(parameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 2u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdNicolas);
  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdZach);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.DomainHint.NumMatchingAccounts",
      Metrics::NumAccounts::kMultiple, 1);
  ExpectUkmValueInEntry("DomainHint.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 2);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, DomainHintMultipleAccountsNoMatch) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint = "incorrect_domain_hint";
  const RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsListEmpty,
      {kFilterNoMatchMessage},
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts =
      kMultipleAccountsWithHintsAndDomains;

  RunAuthTest(parameters, expectations, configuration);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.DomainHint.NumMatchingAccounts", Metrics::NumAccounts::kZero,
      1);
  ExpectUkmValueInEntry("DomainHint.NumMatchingAccounts",
                        FedCmEntry::kEntryName, 0);
  ExpectNoUKMPresence("AccountLabel.NumMatchingAccounts");
  ExpectNoUKMPresence("LoginHint.NumMatchingAccounts");
}

TEST_F(RequestServiceTest, PictureFetch) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts[0]->picture =
      GURL(kAccountPicture);
  // This ensures we don't fetch client metadata, to test a different codepath.
  configuration.idp_info[kProviderUrlFull]
      .accounts[0]
      ->idp_claimed_login_state = LoginState::kSignIn;

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountId);
  EXPECT_FALSE(all_accounts_for_display()[0]->decoded_picture.IsEmpty());
  EXPECT_EQ(kAccountPictureSize,
            all_accounts_for_display()[0]->decoded_picture.Width());
  EXPECT_EQ(kAccountPictureSize,
            all_accounts_for_display()[0]->decoded_picture.Height());
}

TEST_F(RequestServiceTest, PictureFetchMultipleAccounts) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kMultipleAccounts;
  configuration.idp_info[kProviderUrlFull].accounts[0]->picture =
      GURL(kAccountPicture);
  configuration.idp_info[kProviderUrlFull].accounts[1]->picture =
      GURL(kAccountPicture);
  configuration.idp_info[kProviderUrlFull].accounts[2]->picture =
      GURL(kAccountPicture404);

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
  ASSERT_EQ(all_accounts_for_display().size(), 3u);
  EXPECT_FALSE(all_accounts_for_display()[0]->decoded_picture.IsEmpty());
  EXPECT_EQ(kAccountPictureSize,
            all_accounts_for_display()[0]->decoded_picture.Width());
  EXPECT_EQ(kAccountPictureSize,
            all_accounts_for_display()[0]->decoded_picture.Height());
  EXPECT_FALSE(all_accounts_for_display()[1]->decoded_picture.IsEmpty());
  EXPECT_EQ(kAccountPictureSize,
            all_accounts_for_display()[1]->decoded_picture.Width());
  EXPECT_EQ(kAccountPictureSize,
            all_accounts_for_display()[1]->decoded_picture.Height());
  EXPECT_TRUE(all_accounts_for_display()[2]->decoded_picture.IsEmpty());
}

// Test that when FedCmRpContext flag is enabled and rp_context is specified,
// the FedCM request succeeds with the specified rp_context.
TEST_F(RequestServiceTest, RpContextIsSetToNonDefaultValue) {
  RequestParameters request_parameters = kDefaultRequestParameters;
  request_parameters.rp_context = blink::mojom::RpContext::kContinue;
  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action =
      AccountsDialogAction::kSelectFirstAccount;
  RunAuthTest(request_parameters, kExpectationSuccess, configuration);

  EXPECT_EQ(dialog_controller_state_.rp_context,
            blink::mojom::RpContext::kContinue);
}

TEST_F(RequestServiceTest, WellKnownInvalidContentType) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull]
      .well_known.fetch_status.parse_status =
      ParseStatus::kInvalidContentTypeError;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kWellKnownInvalidContentType,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  ukm_loop.Run();

  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  ExpectStatusMetrics(TokenStatus::kWellKnownInvalidContentType);
}

TEST_F(RequestServiceTest, ConfigInvalidContentType) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.fetch_status.parse_status =
      ParseStatus::kInvalidContentTypeError;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigInvalidContentType,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  ukm_loop.Run();

  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  ExpectStatusMetrics(TokenStatus::kConfigInvalidContentType);
}

TEST_F(RequestServiceTest, ClientMetadataInvalidContentType) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull]
      .client_metadata.fetch_status.parse_status =
      ParseStatus::kInvalidContentTypeError;

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  // The FedCM flow succeeds even if the client metadata fetch fails.
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
  ukm_loop.Run();

  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  ExpectStatusMetrics(TokenStatus::kSuccessUsingTokenInHttpResponse);
}

TEST_F(RequestServiceTest, AccountsInvalidContentType) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidContentTypeError;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kAccountsInvalidContentType,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  ukm_loop.Run();

  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  ExpectStatusMetrics(TokenStatus::kAccountsInvalidContentType);
}

TEST_F(RequestServiceTest, IdTokenInvalidContentType) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.token_response.parse_status =
      ParseStatus::kInvalidContentTypeError;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenInvalidContentType,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  ukm_loop.Run();

  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  ExpectStatusMetrics(TokenStatus::kIdTokenInvalidContentType);
}

// Test successful AuthZ request that returns tokens without opening
// pop-up windows.
TEST_F(RequestServiceTest, SuccessfulAuthZRequestNoPopUpWindow) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].fields = {"non_default_field"};

  RunAuthTest(parameters, kExpectationSuccess, kConfigurationValid);

  // When the authorization is delegated and the feature is enabled
  // we don't fetch the client metadata endpoint (which is used to
  // mediate - but not to delegate - the authorization prompt).
  EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));
  // Ensure that metrics were recorded.
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.RpParametersAndScopeState",
                                       RpParameters::kHasNonDefaultScope, 1);
}

// Test successful AuthZ request that request the opening of pop-up
// windows.
TEST_F(RequestServiceTest, SuccessfulAuthZRequestWithPopUpWindow) {
  base::test::ScopedFeatureList list;
  list.InitAndEnableFeature(features::kFedCmMetricsEndpoint);

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].fields = {"non_default_field"};

  MockConfiguration config = kConfigurationValid;
  // Expect an access token to be produced, rather the typical idtoken.
  config.token = "an-access-token";

  // Set up the network expectations to return a "continue_on" response
  // rather than the typical idtoken response.
  GURL continue_on = GURL(kProviderUrlFull).Resolve("/more-permissions.php");
  config.continue_on = std::move(continue_on);

  std::unique_ptr<IdpNetworkRequestMetricsRecorder> unique_metrics_recorder =
      std::make_unique<IdpNetworkRequestMetricsRecorder>();
  IdpNetworkRequestMetricsRecorder* metrics_recorder =
      unique_metrics_recorder.get();
  SetNetworkRequestManager(std::move(unique_metrics_recorder));

  // Set up the UI dialog controller to show a pop-up window, rather
  // than the typical mediated authorization prompt that generates
  // an idtoken.
  auto dialog_controller =
      std::make_unique<TestDialogController>(kConfigurationValid);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  // When the pop-up window is opened, resolve it immediately by
  // producing an access token.
  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  auto impl = federated_auth_request_impl_;
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, &impl](const GURL& url) {
        impl->OnResolve(GURL(kProviderUrlFull), std::nullopt,
                        base::Value("an-access-token"));
        return modal.get();
      }));

  RunAuthTest(parameters, kExpectationSuccess, config);
  ExpectStatusMetrics(TokenStatus::kSuccessUsingIdentityProviderResolve);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.ContinueOn.PopupWindowStatus",
      ContinueOnPopupStatus::kPopupOpened, 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.ContinueOn.PopupWindowResult",
      ContinueOnPopupResult::kTokenReceived, 1);

  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ContinueOn.Response",
                                     1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ContinueOn.TurnaroundTime", 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.IdTokenResponse", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.TurnaroundTime", 0);
  // Authz popup should not be confused with use other account.
  ExpectNoUKMPresence("UseOtherAccountResult");

  EXPECT_THAT(metrics_recorder->get_metrics_endpoints_notified_success(),
              ElementsAre("https://idp.example/metrics"));
  EXPECT_TRUE(
      metrics_recorder->get_metrics_endpoints_notified_failure().empty());

  // When the authorization is delegated and the feature is enabled
  // we don't fetch the client metadata endpoint (which is used to
  // mediate - but not to delegate - the authorization prompt).
  EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));
}

// Test the continuation popup calling close().
TEST_F(RequestServiceTest, ContinuationPopupCallingClose) {
  RequestParameters parameters = kDefaultRequestParameters;

  MockConfiguration config = kConfigurationValid;
  // Expect an access token to be produced, rather the typical idtoken.
  config.token = "an-access-token";

  // Set up the network expectations to return a "continue_on" response
  // rather than the typical idtoken response.
  GURL continue_on = GURL(kProviderUrlFull).Resolve("/more-permissions.php");
  config.continue_on = std::move(continue_on);

  // Set up the UI dialog controller to show a pop-up window, rather
  // than the typical mediated authorization prompt that generates
  // an idtoken.
  auto dialog_controller =
      std::make_unique<TestDialogController>(kConfigurationValid);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  // When the pop-up window is opened, resolve it immediately by
  // producing an access token.
  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  auto impl = federated_auth_request_impl_;
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, &impl](const GURL& url) {
        impl->OnClose();
        return modal.get();
      }));

  RequestExpectations error = {RequestTokenStatus::kError,
                               FederatedAuthRequestResult::kError,
                               /*standalone_console_message=*/std::nullopt,
                               /*selected_idp_config_url=*/std::nullopt};

  RunAuthTest(parameters, error, config);
  ExpectStatusMetrics(
      TokenStatus::kContinuationPopupClosedByIdentityProviderClose);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.ContinueOn.PopupWindowStatus",
      ContinueOnPopupStatus::kPopupOpened, 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.ContinueOn.PopupWindowResult",
      ContinueOnPopupResult::kClosedByIdentityProviderClose, 1);

  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ContinueOn.Response",
                                     0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ContinueOn.TurnaroundTime", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.IdTokenResponse", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.TurnaroundTime", 0);
}

// Test successful AuthZ request that request the opening of pop-up
// windows.
TEST_F(RequestServiceTest, FailsLoadingAContinueOnForADifferentOrigin) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].fields = {"non_default_field"};

  MockConfiguration config = kConfigurationValid;

  // Set up the network expectations to return a "continue_on" response
  // rather than the typical idtoken response.
  GURL continue_on =
      GURL("https://another-origin.example").Resolve("/more-permissions.php");
  config.continue_on = std::move(continue_on);

  RequestExpectations error = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenInvalidResponse,
      // TODO(crbug.com/40262526): introduce a more granular error.
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  RunAuthTest(parameters, error, config);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.ContinueOn.PopupWindowStatus",
      ContinueOnPopupStatus::kUrlNotSameOrigin, 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.ContinueOn.PopupWindowResult",
      ContinueOnPopupResult::kTokenReceived, 0);

  // We only record timing on success.
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ContinueOn.Response",
                                     0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.ContinueOn.TurnaroundTime", 0);
}

// Test metrics for a request with parameters.
TEST_F(RequestServiceTest, RequestWithParameters) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].params_json = "{\"foo\", \"bar\"}";

  RunAuthTest(parameters, kExpectationSuccess, kConfigurationValid);

  // Ensure that metrics were recorded.
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.RpParametersAndScopeState",
                                       RpParameters::kHasParameters, 1);
}

// Test metrics for a request with parameters and scopes.
TEST_F(RequestServiceTest, RequestWithParametersAndScopes) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].fields = {"non_default_field"};
  parameters.identity_providers[0].params_json = "{\"foo\", \"bar\"}";

  RunAuthTest(parameters, kExpectationSuccess, kConfigurationValid);

  // When the authorization is delegated and the feature is enabled
  // we don't fetch the client metadata endpoint (which is used to
  // mediate - but not to delegate - the authorization prompt).
  EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));
  // Ensure that metrics were recorded.
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.RpParametersAndScopeState",
      RpParameters::kHasParametersAndNonDefaultScope, 1);
}

// Test successfully signing-in users when they are signed-out on
// active flows.
TEST_F(RequestServiceTest, SignInWhenSignedOutOnActiveModeWithUserActivation) {
  ExpectSuccessfulActiveFlow();
}

// Test active flow failure outside of user activation.
TEST_F(RequestServiceTest, ActiveFlowRequiresUserActivation) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = false;

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  request_remote_.set_disconnect_handler(auth_helper_->quit_closure());

  RequestExpectations error = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kMissingTransientUserActivation,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  // Active flow request gets rejected without delay.
  RunAuthDontWaitForCallback(parameters, kConfigurationValid);
  CheckAuthExpectations(kConfigurationValid, error);

  EXPECT_FALSE(DidFetchAnyEndpoint());
}

// Test the active flow request fails without delay if IdP config is wrong.
TEST_F(RequestServiceTest, ActiveFlowWellKnownNotInList) {
  RequestExpectations request_not_in_list = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kConfigNotInWellKnown,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  const char* idp_config_url =
      kDefaultRequestParameters.identity_providers[0].provider;
  const char* kWellKnownMismatchConfigUrl = "https://mismatch.example";
  EXPECT_NE(std::string(idp_config_url), kWellKnownMismatchConfigUrl);

  MockConfiguration config = kConfigurationValid;
  config.idp_info[idp_config_url].well_known = {
      {kWellKnownMismatchConfigUrl}, {ParseStatus::kSuccess, net::HTTP_OK}};

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  // Active flow request gets rejected without delay.
  RunAuthDontWaitForCallback(parameters, config);
  CheckAuthExpectations(config, request_not_in_list);

  EXPECT_TRUE(DidFetchWellKnownAndConfig());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::ACCOUNTS));
}

TEST_F(RequestServiceTest, ActiveFlowWithUnknownLoginStatus) {
  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;

  // Check that the LoginStatus is "unknown".
  EXPECT_EQ(test_permission_delegate_->idp_signin_statuses_.count(kIdpOrigin),
            0u);

  auto dialog_controller =
      std::make_unique<TestDialogController>(configuration);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  // Check that the pop-up window is displayed.
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(Return(nullptr));

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RunAuthDontWaitForCallback(parameters, configuration);
}

// Test that active flow can skip the mismatch UI.
TEST_F(RequestServiceTest, ActiveFlowSkipsMismatchUI) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;

  auto dialog_controller =
      std::make_unique<TestDialogController>(configuration);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));
  // Check that the pop-up window is displayed.
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(Return(nullptr));

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;
  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RunAuthDontWaitForCallback(parameters, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());
}

// Test that active flow shows the loading dialog.
TEST_F(RequestServiceTest, ActiveFlowShowsLoadingUI) {
  ExpectSuccessfulActiveFlow();
  EXPECT_TRUE(dialog_controller_state_.did_show_loading_dialog);
}

// Test dismissing a active flow through the loading UI.
TEST_F(RequestServiceTest, ActiveFlowDismissLoadingUI) {
  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kUiDismissedNoEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;
  configuration.loading_dialog_action = LoadingDialogAction::kClose;

  RunAuthTest(parameters, expectations, configuration);
  EXPECT_TRUE(dialog_controller_state_.did_show_loading_dialog);
}

TEST_F(RequestServiceTest, CloseModalDialogView) {
  // Test that IdentityRegistry is notified when modal dialog view is closed.
  EXPECT_FALSE(test_identity_registry_->notified_);
  federated_auth_request_impl_->CloseModalDialogView();
  EXPECT_TRUE(test_identity_registry_->notified_);
}

class RequestServiceNewTabTest : public RequestServiceTest {
 protected:
  void SetUp() override {
    RenderViewHostImplTestHarness::SetUp();
    InitConstants();
    test_api_permission_delegate_ =
        std::make_unique<TestApiPermissionDelegate>();
    test_permission_delegate_ = std::make_unique<TestPermissionDelegate>();
    test_auto_reauthn_permission_delegate_ =
        std::make_unique<TestAutoReauthnPermissionDelegate>();
    test_identity_registry_ = std::make_unique<TestIdentityRegistry>(
        web_contents(), /*delegate=*/nullptr, GURL(kIdpUrl));
    auth_helper_ = std::make_unique<AuthRequestCallbackHelper>();

    static_cast<TestWebContents*>(web_contents())
        ->NavigateAndCommit(GURL("chrome://newtab/"), ui::PAGE_TRANSITION_LINK);

    federated_auth_request_impl_ = &RequestService::CreateForTesting(
        *main_test_rfh(), test_api_permission_delegate_.get(),
        test_auto_reauthn_permission_delegate_.get(),
        test_permission_delegate_.get(), test_identity_registry_.get(),
        request_remote_.BindNewPipeAndPassReceiver());

    std::unique_ptr<TestIdpNetworkRequestManager> network_request_manager =
        std::make_unique<TestIdpNetworkRequestManager>();
    SetNetworkRequestManager(std::move(network_request_manager));
  }
};

TEST_F(RequestServiceNewTabTest, SuccessfulFlow) {
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
}

class UserInfoCallbackHelper {
 public:
  UserInfoCallbackHelper() = default;
  ~UserInfoCallbackHelper() = default;

  // This can only be called once per lifetime of this object.
  blink::mojom::FederatedAuthRequest::RequestUserInfoCallback callback() {
    return base::BindOnce(&UserInfoCallbackHelper::Complete,
                          base::Unretained(this));
  }

  // Returns when callback() is called, which can be immediately if it has
  // already been called.
  void WaitForCallback() {
    if (was_called_) {
      return;
    }
    wait_for_callback_loop_.Run();
  }

  void Complete(
      blink::mojom::RequestUserInfoStatus user_info_status,
      std::optional<std::vector<blink::mojom::IdentityUserInfoPtr>> user_info) {
    CHECK(!was_called_);
    was_called_ = true;
    wait_for_callback_loop_.Quit();
  }

 private:
  bool was_called_{false};
  base::RunLoop wait_for_callback_loop_;
};

TEST_F(RequestServiceTest, RequestUserInfoFailure) {
  blink::mojom::IdentityProviderConfigPtr config =
      blink::mojom::IdentityProviderConfig::New();
  config->config_url = GURL(kIdpUrl);
  UserInfoCallbackHelper callback_helper;
  // This request will fail right away (not from IDP origin).
  federated_auth_request_impl_->RequestUserInfo(
      std::move(config), base::BindOnce(&UserInfoCallbackHelper::Complete,
                                        base::Unretained(&callback_helper)));
  // This is a regression test and it passes if the test does not crash.
  callback_helper.WaitForCallback();
}

// Tests that when an accounts dialog is shown, the appropriate metrics are
// recorded.
TEST_F(RequestServiceTest, AccountsDialogShownMetric) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  ukm_loop.Run();

  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsDialogShown", 1, 1);
  ExpectUKMPresence("AccountsDialogShown2");
  ExpectNoUKMPresence("MismatchDialogShown2");
}

// Tests that when a mismatch dialog is shown, the appropriate metrics are
// recorded.
TEST_F(RequestServiceTest, MismatchDialogShownMetric) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_signin_status_mismatch_dialog_action =
      IdpSigninStatusMismatchDialogAction::kClose;

  // Setup IdP sign-in status mismatch.
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);

  ukm_loop.Run();

  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.MismatchDialogShown", 1, 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.MismatchDialogType",
      Metrics::MismatchDialogType::kFirstWithoutHints, 1);
  ExpectUKMPresence("MismatchDialogShown2");
  ExpectNoUKMPresence("AccountsDialogShown2");
  ExpectNoUKMPresence("HasSigninAccount");
}

// Tests that a mismatch dialog is shown twice.
TEST_F(RequestServiceTest, DoubleMismatchDialog) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);
  MockConfiguration configuration = kConfigurationValid;

  // Setup IdP sign-in status mismatch.
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kHttpNotFoundError;

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].login_hint = "hint";

  RunAuthDontWaitForCallback(parameters, configuration);

  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());

  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;
  federated_auth_request_impl_->OnIdpSigninStatusReceived(kIdpOrigin, true);
  base::RunLoop().RunUntilIdle();

  // Check that the appropriate metrics are recorded upon destruction.
  federated_auth_request_impl_->ResetAndDeleteThis();
  ukm_loop.Run();

  // The additional mismatch should be recorded in the metrics.
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.MismatchDialogShown", 1, 2);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.MismatchDialogType", 2);
  histogram_tester_.ExpectBucketCount(
      "Blink.FedCm.MismatchDialogType",
      Metrics::MismatchDialogType::kFirstWithHints, 1);
  histogram_tester_.ExpectBucketCount(
      "Blink.FedCm.MismatchDialogType",
      Metrics::MismatchDialogType::kRepeatedWithHints, 1);
}

// Tests that when an accounts request is sent, the appropriate metrics are
// recorded.
TEST_F(RequestServiceTest, AccountsRequestSentMetric) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  ukm_loop.Run();

  EXPECT_EQ(NumFetched(FetchedEndpoint::ACCOUNTS), 1u);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.AccountsRequestSent", 1, 1);
  ExpectUKMPresence("AccountsRequestSent2");
}

// Tests that when an accounts dialog is aborted, the appropriate duration
// metrics are recorded.
TEST_F(RequestServiceTest, AbortedAccountsDialogShownDurationMetric) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kNone;
  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  // Abort the request.
  federated_auth_request_impl_->CancelTokenRequest();

  WaitForCurrentAuthRequest();
  RequestExpectations expectations{RequestTokenStatus::kErrorCanceled,
                                   FederatedAuthRequestResult::kCanceled,
                                   /*standalone_console_message=*/std::nullopt,
                                   /*selected_idp_config_url=*/std::nullopt};
  CheckAuthExpectations(configuration, expectations);

  ukm_loop.Run();

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 1);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 0);

  ExpectUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectNoUKMPresence("Timing.MismatchDialogShownDuration");
}

// Tests that when a mismatch dialog is aborted, the appropriate duration
// metrics are recorded.
TEST_F(RequestServiceTest, AbortedMismatchDialogShownDurationMetric) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  SetNetworkRequestManager(
      std::make_unique<ParseStatusOverrideIdpNetworkRequestManager>());
  auto* network_manager =
      static_cast<ParseStatusOverrideIdpNetworkRequestManager*>(
          test_network_request_manager_.get());

  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);

  // Setup IdP sign-in status mismatch.
  network_manager->accounts_parse_status_ = ParseStatus::kInvalidResponseError;
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, kConfigurationValid);
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());
  EXPECT_FALSE(did_show_accounts_dialog());

  // Abort the request.
  federated_auth_request_impl_->CancelTokenRequest();

  RequestExpectations expectations{RequestTokenStatus::kErrorCanceled,
                                   FederatedAuthRequestResult::kCanceled,
                                   /*standalone_console_message=*/std::nullopt,
                                   /*selected_idp_config_url=*/std::nullopt};
  WaitForCurrentAuthRequest();
  CheckAuthExpectations(kConfigurationValid, expectations);

  ukm_loop.Run();

  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 0);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.MismatchDialogShownDuration", 1);

  ExpectNoUKMPresence("Timing.AccountsDialogShownDuration");
  ExpectUKMPresence("Timing.MismatchDialogShownDuration");
}

// Tests that when requests are made to FedCM in succession, the appropriate
// metrics are recorded upon destruction.
TEST_F(RequestServiceTest, RecordNumRequestsPerDocumentMetric) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  // First auth request.
  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kNone;
  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  // Abort the first auth request.
  federated_auth_request_impl_->CancelTokenRequest();

  WaitForCurrentAuthRequest();
  RequestExpectations expectations{RequestTokenStatus::kErrorCanceled,
                                   FederatedAuthRequestResult::kCanceled,
                                   /*standalone_console_message=*/std::nullopt,
                                   /*selected_idp_config_url=*/std::nullopt};
  CheckAuthExpectations(configuration, expectations);

  // Reset test classes for second auth request.
  SetNetworkRequestManager(std::make_unique<TestIdpNetworkRequestManager>());
  auth_helper_ = std::make_unique<AuthRequestCallbackHelper>();

  // Second auth request.
  configuration.accounts_dialog_action = AccountsDialogAction::kClose;
  expectations = {RequestTokenStatus::kError,
                  FederatedAuthRequestResult::kShouldEmbargo,
                  /*standalone_console_message=*/std::nullopt,
                  /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(did_show_idp_signin_status_mismatch_dialog());

  // Check that the appropriate metrics are recorded upon destruction.
  federated_auth_request_impl_->ResetAndDeleteThis();

  ukm_loop.Run();

  // Both requests should have been counted.
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.NumRequestsPerDocument", 2,
                                       1);

  // Check for RP-keyed UKM presence.
  ExpectUKMPresenceInternal("NumRequestsPerDocument", FedCmEntry::kEntryName);
}

// Test that an error dialog is shown when the token response is invalid.
TEST_F(RequestServiceTest, InvalidResponseErrorDialogShown) {
  MockConfiguration configuration = kConfigurationValid;
  ErrorDialogType error_dialog_type = ErrorDialogType::kGenericEmptyWithoutUrl;
  TokenResponseType token_response_type = TokenResponseType::
      kTokenNotReceivedAndErrorNotReceivedAndContinueOnNotReceived;
  configuration.token_response.parse_status =
      ParseStatus::kInvalidResponseError;
  configuration.error_dialog_type = error_dialog_type;
  configuration.token_response_type = token_response_type;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenInvalidResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(dialog_controller_state_.did_show_error_dialog);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.ErrorDialogType",
                                       error_dialog_type, 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.Error.ErrorDialogResult",
      ErrorDialogResult::kCloseWithoutMoreDetails, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.TokenResponseType",
                                       token_response_type, 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Error.ErrorUrlType", 0);

  ExpectUKMPresence("Error.ErrorDialogType");
  ExpectUKMPresence("Error.ErrorDialogResult");
  ExpectUKMPresence("Error.TokenResponseType");
  ExpectNoUKMPresence("Error.ErrorUrlType");
}

// Test that an error dialog is shown when the token response is missing.
TEST_F(RequestServiceTest, NoResponseErrorDialogShown) {
  MockConfiguration configuration = kConfigurationValid;
  ErrorDialogType error_dialog_type = ErrorDialogType::kGenericEmptyWithoutUrl;
  TokenResponseType token_response_type = TokenResponseType::
      kTokenNotReceivedAndErrorNotReceivedAndContinueOnNotReceived;
  configuration.token_response.parse_status = ParseStatus::kNoResponseError;
  configuration.error_dialog_type = error_dialog_type;
  configuration.token_response_type = token_response_type;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenNoResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(dialog_controller_state_.did_show_error_dialog);

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.ErrorDialogType",
                                       error_dialog_type, 1);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.Error.ErrorDialogResult",
      ErrorDialogResult::kCloseWithoutMoreDetails, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.TokenResponseType",
                                       token_response_type, 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.Error.ErrorUrlType", 0);

  ExpectUKMPresence("Error.ErrorDialogType");
  ExpectUKMPresence("Error.ErrorDialogResult");
  ExpectUKMPresence("Error.TokenResponseType");
  ExpectNoUKMPresence("Error.ErrorUrlType");
}

// Test that the error UI has proper url set.
TEST_F(RequestServiceTest, ErrorUrlDisplayedWithProperUrl) {
  MockConfiguration configuration = kConfigurationValid;
  ErrorDialogType error_dialog_type = ErrorDialogType::kGenericEmptyWithUrl;
  TokenResponseType token_response_type = TokenResponseType::
      kTokenNotReceivedAndErrorNotReceivedAndContinueOnNotReceived;
  ErrorUrlType error_url_type = ErrorUrlType::kCrossOriginSameSite;
  configuration.token_error =
      TokenError(/*code=*/"", GURL("https://foo.idp.example/error"));
  configuration.error_dialog_type = error_dialog_type;
  configuration.token_response_type = token_response_type;
  configuration.error_url_type = error_url_type;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenIdpErrorResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(dialog_controller_state_.did_show_error_dialog);
  EXPECT_EQ(dialog_controller_state_.token_error->url,
            GURL("https://foo.idp.example/error"));

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.ErrorDialogType",
                                       error_dialog_type, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.ErrorDialogResult",
                                       ErrorDialogResult::kCloseWithMoreDetails,
                                       1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.TokenResponseType",
                                       token_response_type, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.ErrorUrlType",
                                       error_url_type, 1);

  ExpectUKMPresence("Error.ErrorDialogType");
  ExpectUKMPresence("Error.ErrorDialogResult");
  ExpectUKMPresence("Error.TokenResponseType");
  ExpectUKMPresenceInternal("Error.ErrorUrlType", FedCmIdpEntry::kEntryName);
}

// Test that permission is embargoed upon closing a mismatch dialog.
TEST_F(RequestServiceTest, IdpSigninStatusCloseMismatchEmbargo) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;
  configuration.idp_signin_status_mismatch_dialog_action =
      IdpSigninStatusMismatchDialogAction::kClose;
  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());
  EXPECT_TRUE(test_api_permission_delegate_->embargoed_origins_.count(
      main_test_rfh()->GetLastCommittedOrigin()));
}

// Test that permission is not embargoed upon closing an IDP sign-in flow
// pop-up.
TEST_F(RequestServiceTest, IdpSigninStatusClosePopupEmbargo) {
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;
  configuration.idp_signin_status_mismatch_dialog_action =
      IdpSigninStatusMismatchDialogAction::kClosePopup;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kUiDismissedNoEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());
  EXPECT_TRUE(test_api_permission_delegate_->embargoed_origins_.empty());
}

// Test that no registered IdP is added without a registry requested.
TEST_F(RequestServiceTest, MaybeAddRegisteredProvidersEmptyList) {
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> providers;

  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> result =
      MaybeAddRegisteredProviders(providers);

  EXPECT_TRUE(result.empty());
}

// Test that no registered IdP with only named providers requested.
TEST_F(RequestServiceTest, MaybeAddRegisteredProvidersNamed) {
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> providers;
  providers.emplace_back(NewNamedIdP(GURL("https://idp.example"), kClientId,
                                     /*is_registered=*/false));

  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> result =
      MaybeAddRegisteredProviders(providers);

  // Expects the vector to be the same.
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> expected;
  expected.emplace_back(NewNamedIdP(GURL("https://idp.example"), kClientId,
                                    /*is_registered=*/false));

  EXPECT_EQ(expected, result);
}

// Test that a registered provider is added.
TEST_F(RequestServiceTest, MaybeAddRegisteredProvidersAdded) {
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> providers;
  providers.emplace_back(NewRegisteredIdP(kClientId));

  std::vector<GURL> registry;
  registry.emplace_back("https://idp.example");

  EXPECT_CALL(*test_permission_delegate_, GetRegisteredIdPs())
      .WillOnce(Return(registry));

  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> result =
      MaybeAddRegisteredProviders(providers);

  // Expects that the registered IdP gets replaced by a named IdP.
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> expected;
  expected.emplace_back(NewNamedIdP(GURL("https://idp.example"), kClientId,
                                    /*is_registered=*/true));

  EXPECT_EQ(expected, result);
}

// Test that all registered IdPs are expanded.
TEST_F(RequestServiceTest,
       MaybeAddRegisteredProvidersAllRequestsForRegisteredIdPsAreExpanded) {
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> providers;
  providers.emplace_back(NewRegisteredIdP(kClientId));
  providers.emplace_back(NewRegisteredIdP(kClientId));

  std::vector<GURL> registry;
  registry.emplace_back("https://idp.example");

  EXPECT_CALL(*test_permission_delegate_, GetRegisteredIdPs())
      .WillOnce(Return(registry));

  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> result =
      MaybeAddRegisteredProviders(providers);

  // Expects that the registered IdP gets replaced by a named IdP.
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> expected;
  expected.emplace_back(NewNamedIdP(GURL("https://idp.example"), kClientId,
                                    /*is_registered=*/true));
  expected.emplace_back(NewNamedIdP(GURL("https://idp.example"), kClientId,
                                    /*is_registered=*/true));

  EXPECT_EQ(expected, result);
}

// Test that the registry can add two idps.
TEST_F(RequestServiceTest, MaybeAddRegisteredProvidersTwoRegisteredIdPs) {
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> providers;
  providers.emplace_back(NewRegisteredIdP(kClientId));

  std::vector<GURL> registry;
  registry.emplace_back("https://idp1.example");
  registry.emplace_back("https://idp2.example");

  EXPECT_CALL(*test_permission_delegate_, GetRegisteredIdPs())
      .WillOnce(Return(registry));

  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> result =
      MaybeAddRegisteredProviders(providers);

  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> expected;
  expected.emplace_back(NewNamedIdP(GURL("https://idp2.example"), kClientId,
                                    /*is_registered=*/true));
  expected.emplace_back(NewNamedIdP(GURL("https://idp1.example"), kClientId,
                                    /*is_registered=*/true));

  EXPECT_EQ(expected, result);
}

// Test that registered idps are inserted inline.
TEST_F(RequestServiceTest, MaybeAddRegisteredProvidersInsertedInline) {
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> providers;
  providers.emplace_back(NewNamedIdP(GURL("https://idp1.example"), kClientId,
                                     /*is_registered=*/false));
  providers.emplace_back(NewRegisteredIdP(kClientId));
  providers.emplace_back(NewNamedIdP(GURL("https://idp2.example"), kClientId,
                                     /*is_registered=*/false));

  std::vector<GURL> registry;
  registry.emplace_back("https://idp-registered1.example");
  registry.emplace_back("https://idp-registered2.example");

  EXPECT_CALL(*test_permission_delegate_, GetRegisteredIdPs())
      .WillOnce(Return(registry));

  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> result =
      MaybeAddRegisteredProviders(providers);

  // Expects that the registered IdP gets replaced by a named IdP.
  std::vector<blink::mojom::IdentityProviderRequestOptionsPtr> expected;
  expected.emplace_back(NewNamedIdP(GURL("https://idp1.example"), kClientId,
                                    /*is_registered=*/false));
  expected.emplace_back(NewNamedIdP(GURL("https://idp-registered2.example"),
                                    kClientId, /*is_registered=*/true));
  expected.emplace_back(NewNamedIdP(GURL("https://idp-registered1.example"),
                                    kClientId, /*is_registered=*/true));
  expected.emplace_back(NewNamedIdP(GURL("https://idp2.example"), kClientId,
                                    /*is_registered=*/false));

  EXPECT_EQ(expected, result);
}

// Test that error dialog type metrics are recorded.
TEST_F(RequestServiceTest, ErrorDialogTypeMetrics) {
  MockConfiguration configuration = kConfigurationValid;
  ErrorDialogType error_dialog_type = ErrorDialogType::kInvalidRequestWithUrl;
  configuration.token_error = TokenError(/*code=*/"invalid_request",
                                         GURL("https://foo.idp.example/error"));
  configuration.error_dialog_type = error_dialog_type;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenIdpErrorResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(dialog_controller_state_.did_show_error_dialog);

  base::RunLoop().RunUntilIdle();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.ErrorDialogType",
                                       error_dialog_type, 1);

  ExpectUKMPresence("Error.ErrorDialogType");
}

// Test that error dialog result metrics are recorded.
TEST_F(RequestServiceTest, ErrorDialogResultMetrics) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.token_error =
      TokenError(/*code=*/"", GURL("https://foo.idp.example/error"));
  configuration.error_dialog_action = ErrorDialogAction::kGotIt;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenIdpErrorResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(dialog_controller_state_.did_show_error_dialog);

  base::RunLoop().RunUntilIdle();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.ErrorDialogResult",
                                       ErrorDialogResult::kGotItWithMoreDetails,
                                       1);

  ExpectUKMPresence("Error.ErrorDialogResult");
}

// Test that token response type metrics are recorded.
TEST_F(RequestServiceTest, TokenResponseTypeMetrics) {
  MockConfiguration configuration = kConfigurationValid;
  TokenResponseType token_response_type = TokenResponseType::
      kTokenNotReceivedAndErrorReceivedAndContinueOnNotReceived;
  configuration.token_error = TokenError(/*code=*/"invalid_request",
                                         GURL("https://foo.idp.example/error"));
  configuration.token_response_type = token_response_type;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenIdpErrorResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(dialog_controller_state_.did_show_error_dialog);

  base::RunLoop().RunUntilIdle();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.TokenResponseType",
                                       token_response_type, 1);

  ExpectUKMPresence("Error.TokenResponseType");
}

// Test that error url type metrics are recorded.
TEST_F(RequestServiceTest, ErrorUrlTypeMetrics) {
  MockConfiguration configuration = kConfigurationValid;
  ErrorUrlType error_url_type = ErrorUrlType::kCrossOriginSameSite;
  configuration.token_error = TokenError(/*code=*/"invalid_request",
                                         GURL("https://foo.idp.example/error"));
  configuration.error_url_type = error_url_type;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenIdpErrorResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(dialog_controller_state_.did_show_error_dialog);

  base::RunLoop().RunUntilIdle();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.Error.ErrorUrlType",
                                       error_url_type, 1);

  ExpectUKMPresenceInternal("Error.ErrorUrlType", FedCmIdpEntry::kEntryName);
}

// Test that cross-site URL fails the request with the appropriate devtools
// issue.
TEST_F(RequestServiceTest, CrossSiteErrorDialogDevtoolsIssue) {
  MockConfiguration configuration = kConfigurationValid;
  ErrorUrlType error_url_type = ErrorUrlType::kCrossSite;
  configuration.token_error = TokenError(
      /*code=*/"invalid_request", GURL("https://cross-site.example/error"));
  configuration.error_url_type = error_url_type;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kIdTokenCrossSiteIdpErrorResponse,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_TRUE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_TRUE(dialog_controller_state_.did_show_error_dialog);
}

// Test that the account UI is not displayed if FedCM is disabled after accounts
// fetch.
TEST_F(RequestServiceTest,
       AccountUiNotDisplayedIfFedCmDisabledAfterAccountsFetch) {
  test_api_permission_delegate_->permission_override_for_nth_ = std::make_pair(
      /*override the nth invocation=*/2,
      std::make_pair(main_test_rfh()->GetLastCommittedOrigin(),
                     ApiPermissionStatus::BLOCKED_EMBARGO));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kDisabledInSettings,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  EXPECT_TRUE(DidFetch(FetchedEndpoint::ACCOUNTS));
  EXPECT_FALSE(did_show_accounts_dialog());
}

TEST_F(RequestServiceTest, DomainHintInLoginUrl) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint = kDomainHint;

  // Need to have sign in status set to signed in to prompt login url
  // computations.
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;

  auto dialog_controller =
      std::make_unique<TestDialogController>(kConfigurationValid);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  GURL login_url;
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, &login_url](const GURL& url) {
        login_url = url;
        return modal.get();
      }));

  RunAuthDontWaitForCallback(parameters, kConfigurationValid);
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());

  SimulateLoginToIdP();

  std::string expected_url = kIdpLoginUrl;
  expected_url += "?domain_hint=domain%40corp.com";
  EXPECT_EQ(login_url, expected_url);
}

TEST_F(RequestServiceTest, LoginHintInLoginUrl) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].login_hint = "hint";

  // Need to have sign in status set to signed in to prompt login url
  // computations.
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;

  auto dialog_controller =
      std::make_unique<TestDialogController>(kConfigurationValid);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  GURL login_url;
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, &login_url](const GURL& url) {
        login_url = url;
        return modal.get();
      }));

  RunAuthDontWaitForCallback(parameters, kConfigurationValid);
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());

  SimulateLoginToIdP();

  std::string expected_url = kIdpLoginUrl;
  expected_url += "?login_hint=hint";
  EXPECT_EQ(login_url, expected_url);
}

TEST_F(RequestServiceTest, DomainHintAndLoginHintInLoginUrl) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint = kDomainHint;
  parameters.identity_providers[0].login_hint = "hint";

  // Need to have sign in status set to signed in to prompt login url
  // computations.
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;

  auto dialog_controller =
      std::make_unique<TestDialogController>(kConfigurationValid);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  GURL login_url;
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, &login_url](const GURL& url) {
        login_url = url;
        return modal.get();
      }));

  RunAuthDontWaitForCallback(parameters, kConfigurationValid);
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());

  SimulateLoginToIdP();

  std::string expected_url = kIdpLoginUrl;
  expected_url += "?login_hint=hint&domain_hint=domain%40corp.com";
  EXPECT_EQ(login_url, expected_url);
}

TEST_F(RequestServiceTest, DomainHintAndLoginHintInLoginUrlWithQuery) {
  RequestParameters parameters = kDefaultRequestParameters;
  // Testing that spaces are transformed in the url.
  parameters.identity_providers[0].domain_hint = "domain hint";
  parameters.identity_providers[0].login_hint = "login hint";

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.idp_login_url += "?q=1&t=2";

  // Need to have sign in status set to signed in to prompt login url
  // computations.
  test_permission_delegate_
      ->idp_signin_statuses_[OriginFromString(kProviderUrlFull)] = true;

  auto dialog_controller =
      std::make_unique<TestDialogController>(kConfigurationValid);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  GURL login_url;
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, &login_url](const GURL& url) {
        login_url = url;
        return modal.get();
      }));

  RunAuthDontWaitForCallback(parameters, configuration);
  EXPECT_FALSE(did_show_accounts_dialog());
  EXPECT_TRUE(did_show_idp_signin_status_mismatch_dialog());

  SimulateLoginToIdP(
      configuration.idp_info[kProviderUrlFull].config.idp_login_url);

  std::string expected_url = kIdpLoginUrl;
  expected_url += "?q=1&t=2&login_hint=login%20hint&domain_hint=domain%20hint";
  EXPECT_EQ(login_url, expected_url);
}

TEST_F(RequestServiceTest, DomainHintAddAccount) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].domain_hint = kDomainHint;

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kAddAccount;
  configuration.idp_info[kProviderUrlFull].accounts =
      kSingleAccountWithDomainHint;

  auto dialog_controller =
      std::make_unique<TestDialogController>(configuration);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  GURL login_url;
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, &login_url](const GURL& url) {
        login_url = url;
        return modal.get();
      }));

  RunAuthDontWaitForCallback(parameters, configuration);
  EXPECT_TRUE(did_show_accounts_dialog());

  // The `login_url` used when invoking AddAccounts should not include hints.
  EXPECT_EQ(login_url, kIdpLoginUrl);
}

// Test that auto re-authn works in active mode.
TEST_F(RequestServiceTest, AutoReauthnInActiveMode) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  for (const auto& idp_info : kConfigurationValid.idp_info) {
    ASSERT_EQ(idp_info.second.accounts.size(), 1u);
  }
  // The following checks work in active mode.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              RequiresUserMediation(url::Origin::Create(GURL(kRpUrl))))
      .WillOnce(Return(false));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  RunAuthDontWaitForCallback(parameters, kConfigurationValid);

  ASSERT_EQ(all_accounts_for_display().size(), 1u);
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignIn);
  EXPECT_EQ(CountNumLoginStateIsSignin(), 1);
  EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kAuto);
}

// Test that IdP claimed SignUp takes precedence over browser observed SignIn.
TEST_F(RequestServiceTest,
       IdPClaimedSignUpTakesPrecedenceOverBrowserObservedSignIn) {
  // Pretend the sharing permission has been granted for all accounts.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), _))
      .WillRepeatedly(
          Return(std::make_optional<base::Time>(base::Time::Now())));

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kMultipleAccounts;

  RunAuthDontWaitForCallback(parameters, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 3u);
  // Accounts are reordered to have sign-in users displayed first.
  EXPECT_EQ(all_accounts_for_display()[0]->idp_claimed_login_state,
            LoginState::kSignIn);
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignIn);
  EXPECT_EQ(all_accounts_for_display()[1]->idp_claimed_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[1]->browser_trusted_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[2]->idp_claimed_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[2]->browser_trusted_login_state,
            LoginState::kSignUp);

  ExpectUkmValue("HasSigninAccount", true);
}

// Test that IdP claimed SignIn does not affect browser observed SignUp.
TEST_F(RequestServiceTest, IdPClaimedSignInDoesNotAffectBrowserObservedSignUp) {
  // Pretend the sharing permission has NOT been granted for any account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), _))
      .WillRepeatedly(Return(std::nullopt));

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kMultipleAccounts;

  RunAuthDontWaitForCallback(parameters, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 3u);
  EXPECT_EQ(all_accounts_for_display()[0]->idp_claimed_login_state,
            LoginState::kSignIn);
  // This should be kSignUp regardless of IdP's claim.
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[1]->idp_claimed_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[1]->browser_trusted_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[2]->idp_claimed_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[2]->browser_trusted_login_state,
            LoginState::kSignUp);
}

// Test that IdP claimed SignIn can affect browser observed SignUp if they have
// third-party cookies access.
TEST_F(RequestServiceTest,
       IdPClaimedSignInAffectsBrowserObservedSignUpWith3PCAccess) {
  // Pretend the sharing permission has NOT been granted for any account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), _))
      .WillRepeatedly(Return(std::nullopt));

  // Pretend the IdP was given third-party cookies access.
  EXPECT_CALL(*test_api_permission_delegate_,
              HasThirdPartyCookiesAccess(_, GURL(kProviderUrlFull),
                                         OriginFromString(kRpUrl)))
      .WillRepeatedly(Return(true));

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].accounts = kMultipleAccounts;

  RunAuthDontWaitForCallback(parameters, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 3u);
  EXPECT_EQ(all_accounts_for_display()[0]->idp_claimed_login_state,
            LoginState::kSignIn);
  // This should be kSignIn to match IdP's claim due to it has 3PC access.
  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
            LoginState::kSignIn);
  EXPECT_EQ(all_accounts_for_display()[1]->idp_claimed_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[1]->browser_trusted_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[2]->idp_claimed_login_state,
            LoginState::kSignUp);
  EXPECT_EQ(all_accounts_for_display()[2]->browser_trusted_login_state,
            LoginState::kSignUp);
}

// Test active flow is exempted if the FedCM is disabled in  settings.
TEST_F(RequestServiceTest, ActiveFlowNotAffectedBySettings) {
  test_api_permission_delegate_->permission_override_ =
      std::make_pair(main_test_rfh()->GetLastCommittedOrigin(),
                     ApiPermissionStatus::BLOCKED_SETTINGS);
  ExpectSuccessfulActiveFlow();
}

// Test active flow is exempted if the FedCM is embargoed in the passive flow.
TEST_F(RequestServiceTest, ActiveFlowNotAffectedByEmbargo) {
  test_api_permission_delegate_->RecordDismissAndEmbargo(
      OriginFromString(kRpUrl));
  ExpectSuccessfulActiveFlow();
}

// Test dismissing UI in active flow does not trigger embargo.
TEST_F(RequestServiceTest, ActiveFlowNotAffectEmbargo) {
  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame())
      ->SimulateUserActivation();

  RequestParameters parameters = kDefaultRequestParameters;
  parameters.rp_mode = blink::mojom::RpMode::kActive;

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kUiDismissedNoEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kClose;

  RunAuthTest(parameters, expectations, configuration);

  ukm_loop.Run();
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.RpMode",
                                       static_cast<int>(RpMode::kActive), 1);
  ExpectUkmValue("RpMode", static_cast<int>(RpMode::kActive));

  EXPECT_TRUE(did_show_accounts_dialog());
  EXPECT_FALSE(DidFetch(FetchedEndpoint::TOKEN));
  EXPECT_FALSE(test_api_permission_delegate_->embargoed_origins_.count(
      main_test_rfh()->GetLastCommittedOrigin()));
}

// Tests that when background text is passed but no background color, the
// background text is ignored.
TEST_F(RequestServiceTest, BrandingWithTextColorAndNoBackgroundColor) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.brand_text_color =
      SkColorSetRGB(10, 10, 10);
  RequestExpectations expectations = kExpectationSuccess;
  expectations.standalone_console_message =
      "The FedCM text color is ignored because background color was not "
      "provided";
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_EQ(brand_background_color(), std::nullopt);
  EXPECT_EQ(brand_text_color(), std::nullopt);
}

// Tests that when background text does not contrast enough with the background
// color, the text color is ignored.
TEST_F(RequestServiceTest, BrandingWithInsufficientContrastTextColor) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info[kProviderUrlFull].config.brand_background_color =
      SkColorSetRGB(0, 0, 0);
  configuration.idp_info[kProviderUrlFull].config.brand_text_color =
      SkColorSetRGB(1, 1, 1);
  RequestExpectations expectations = kExpectationSuccess;
  expectations.standalone_console_message =
      "The FedCM text color is ignored because it does not contrast enough "
      "with the provided background color";
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);

  EXPECT_EQ(brand_background_color(), SkColorSetRGB(0, 0, 0));
  EXPECT_EQ(brand_text_color(), std::nullopt);
}

class FederatedAuthRequestExampleOrgTest : public RequestServiceTest {
 public:
  FederatedAuthRequestExampleOrgTest()
      : RequestServiceTest("https://rp.example.org/") {}
};

TEST_F(FederatedAuthRequestExampleOrgTest, WellKnownSameSite) {
  static const char kExampleOrgProviderUrl[] =
      "https://idp.example.org/fedcm.json";

  MockIdpInfo idp_info = kDefaultIdentityProviderInfo;
  idp_info.well_known.fetch_status.parse_status =
      ParseStatus::kInvalidContentTypeError;
  idp_info.config.accounts_endpoint = "https://idp.example.org/accounts";
  idp_info.config.token_endpoint = "https://idp.example.org/token";
  idp_info.config.client_metadata_endpoint =
      "https://idp.example.org/client_metadata";
  idp_info.config.metrics_endpoint = "";
  idp_info.config.idp_login_url = "https://idp.example.org/login";
  idp_info.config.disconnect_endpoint = "";

  // We make the request from rp.example to idp.example, so it should
  // only succeed despite the well-known failure if the flag is on.
  MockConfiguration configuration = kConfigurationValid;
  configuration.idp_info.clear();
  configuration.idp_info[kExampleOrgProviderUrl] = idp_info;

  RequestParameters request{kDefaultRequestParameters};
  request.identity_providers[0].provider = kExampleOrgProviderUrl;

  RequestExpectations expectation = kExpectationSuccess;
  expectation.selected_idp_config_url = kExampleOrgProviderUrl;

  RunAuthTest(request, expectation, configuration);
}

class TestDialogControllerWithImmediateDismiss : public TestDialogController {
 public:
  explicit TestDialogControllerWithImmediateDismiss(
      MockConfiguration configuration)
      : TestDialogController(configuration) {}

  ~TestDialogControllerWithImmediateDismiss() override = default;

  TestDialogControllerWithImmediateDismiss(
      const TestDialogControllerWithImmediateDismiss&) = delete;
  TestDialogControllerWithImmediateDismiss& operator=(
      TestDialogControllerWithImmediateDismiss&) = delete;

  bool ShowAccountsDialog(
      content::RelyingPartyData rp_data,
      const std::vector<IdentityProviderDataPtr>& idp_list,
      const std::vector<IdentityRequestAccountPtr>& accounts,
      blink::mojom::RpMode rp_mode,
      const std::vector<IdentityRequestAccountPtr>& new_accounts,
      IdentityRequestDialogController::AccountSelectionCallback on_selected,
      IdentityRequestDialogController::LoginToIdPCallback on_add_account,
      IdentityRequestDialogController::DismissCallback dismiss_callback,
      IdentityRequestDialogController::AccountsDisplayedCallback
          accounts_displayed_callback) override {
    std::move(dismiss_callback).Run(DismissReason::kOther);
    return false;
  }

  bool ShowFailureDialog(
      const RelyingPartyData& rp_data,
      const std::string& idp_for_display,
      blink::mojom::RpContext rp_context,
      blink::mojom::RpMode rp_mode,
      const IdentityProviderMetadata& idp_metadata,
      IdentityRequestDialogController::DismissCallback dismiss_callback,
      IdentityRequestDialogController::LoginToIdPCallback
          identity_registry_callback) override {
    std::move(dismiss_callback).Run(DismissReason::kOther);
    return false;
  }
};

// Crash test for crbug.com/328945371.
TEST_F(RequestServiceTest, ImmediateDismiss) {
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kUiDismissedNoEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};

  SetDialogController(
      std::make_unique<TestDialogControllerWithImmediateDismiss>(
          kConfigurationValid));

  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  histogram_tester_.ExpectTotalCount(
      "Blink.FedCm.Timing.AccountsDialogShownDuration2", 0);
}

// Tests that dismissing during ShowFailureDialog() does not crash.
TEST_F(RequestServiceTest, FailureDialogImmediateDismiss) {
  url::Origin kIdpOrigin = OriginFromString(kProviderUrlFull);

  MockConfiguration configuration = kConfigurationValid;

  // Setup IdP sign-in status mismatch.
  test_permission_delegate_->idp_signin_statuses_[kIdpOrigin] = true;
  configuration.idp_info[kProviderUrlFull].accounts_response.parse_status =
      ParseStatus::kInvalidResponseError;

  SetDialogController(
      std::make_unique<TestDialogControllerWithImmediateDismiss>(
          configuration));

  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kUiDismissedNoEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
}

TEST_F(RequestServiceTest, UseOtherAccountAccountOrder) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kAddAccount;

  // User has accounts, kAccountIdNicolas and kAccountIdZach, in that order.
  configuration.idp_info[kProviderUrlFull].accounts = kTwoAccounts;

  auto dialog_controller =
      std::make_unique<TestDialogController>(configuration);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, this](const GURL& url) {
        // The user signs in with account, kAccountIdPeter. User now has
        // accounts, kAccountIdNicolas, kAccountIdPeter and kAccountIdZach,
        // in that order.
        test_network_request_manager_->accounts_list_ = kMultipleAccounts;
        federated_auth_request_impl_->OnIdpSigninStatusReceived(
            OriginFromString(kProviderUrlFull), true);
        return modal.get();
      }));

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 3u);
  ASSERT_EQ(new_accounts().size(), 1u);

  // Accounts are reordered to have the most recently signed in account,
  // kAccountIdPeter, displayed first.
  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdPeter);
  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdNicolas);
  EXPECT_EQ(all_accounts_for_display()[2]->id, kAccountIdZach);
  EXPECT_EQ(new_accounts()[0]->id, kAccountIdPeter);

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  WaitForCurrentAuthRequest();
  ukm_loop.Run();

  // The first account is selected, and this is a new account.
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.UseOtherAccountResult",
      static_cast<int>(UseOtherAccountResult::kUserSignsInWithNewAccount), 1);
  ExpectUkmValue(
      "UseOtherAccountResult",
      static_cast<int>(UseOtherAccountResult::kUserSignsInWithNewAccount));
}

// Tests that when use a different account is used and multiple accounts are
// logged in at once, all the new accounts are part of the new_accounts().
TEST_F(RequestServiceTest, UseOtherAccountMultipleNewAccounts) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kAddAccount;
  auto dialog_controller =
      std::make_unique<TestDialogController>(configuration);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, this](const GURL& url) {
        // The user signs in with kAccountIdNicolas and kAccountIdZach. User now
        // has accounts kAccountId, kAccountIdNicolas, and kAccountIdZach, in
        // that order.
        test_network_request_manager_->accounts_list_ = {
            kSingleAccount[0], kTwoAccounts[0], kTwoAccounts[1]};
        federated_auth_request_impl_->OnIdpSigninStatusReceived(
            OriginFromString(kProviderUrlFull), true);
        return modal.get();
      }));

  RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);

  ASSERT_EQ(all_accounts_for_display().size(), 3u);
  ASSERT_EQ(new_accounts().size(), 2u);

  // Accounts are reordered to have the most recently signed in accounts
  // displayed first.
  EXPECT_EQ(all_accounts_for_display()[0]->id, kTwoAccounts[0]->id);
  EXPECT_EQ(all_accounts_for_display()[1]->id, kTwoAccounts[1]->id);
  EXPECT_EQ(all_accounts_for_display()[2]->id, kSingleAccount[0]->id);
  EXPECT_EQ(new_accounts()[0]->id, kTwoAccounts[0]->id);
  EXPECT_EQ(new_accounts()[1]->id, kTwoAccounts[1]->id);

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  WaitForCurrentAuthRequest();
  ukm_loop.Run();

  // The first account is selected, and this is a new account.
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.UseOtherAccountResult",
      static_cast<int>(UseOtherAccountResult::kUserSignsInWithNewAccount), 1);
  ExpectUkmValue(
      "UseOtherAccountResult",
      static_cast<int>(UseOtherAccountResult::kUserSignsInWithNewAccount));
}

TEST_F(RequestServiceTest, UseOtherAccountNoNewAccount) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kAddAccount;
  auto dialog_controller =
      std::make_unique<TestDialogController>(configuration);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>([&modal, this](const GURL& url) {
        // No changes to the accounts being logged in. But set the login status
        // to force the popup to close.
        federated_auth_request_impl_->OnIdpSigninStatusReceived(
            OriginFromString(kProviderUrlFull), true);
        return modal.get();
      }));

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
  ukm_loop.Run();

  // The first account is selected, and this is an existing account since there
  // is no new account.
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.UseOtherAccountResult",
      static_cast<int>(UseOtherAccountResult::kUserSignsInWithExistingAccount),
      1);
  ExpectUkmValue(
      "UseOtherAccountResult",
      static_cast<int>(UseOtherAccountResult::kUserSignsInWithExistingAccount));
}

TEST_F(RequestServiceTest, UseOtherAccountThenClose) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.accounts_dialog_action = AccountsDialogAction::kAddAccount;
  auto dialog_controller =
      std::make_unique<TestDialogController>(configuration);
  base::WeakPtr<TestDialogController> weak_dialog_controller =
      dialog_controller->AsWeakPtr();
  SetDialogController(std::move(dialog_controller));

  std::unique_ptr<WebContents> modal(CreateTestWebContents());
  EXPECT_CALL(*weak_dialog_controller, ShowModalDialog)
      .WillOnce(::testing::WithArg<0>(
          [&modal, &weak_dialog_controller, this](const GURL& url) {
            // Signs in to new accounts.
            test_network_request_manager_->accounts_list_ = {
                kSingleAccount[0], kTwoAccounts[0], kTwoAccounts[1]};
            federated_auth_request_impl_->OnIdpSigninStatusReceived(
                OriginFromString(kProviderUrlFull), true);
            // The action is set to close, so the request will be rejected.
            weak_dialog_controller->accounts_dialog_action_ =
                AccountsDialogAction::kClose;
            return modal.get();
          }));

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());
  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
  ukm_loop.Run();

  // The first account is selected, and this is an existing account since there
  // is no new account.
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.UseOtherAccountResult",
      static_cast<int>(UseOtherAccountResult::kUserDoesNotSignIn), 1);
  ExpectUkmValue("UseOtherAccountResult",
                 static_cast<int>(UseOtherAccountResult::kUserDoesNotSignIn));
}

TEST_F(RequestServiceTest, MultipleIdpSigninDueToHint) {
  url::Origin providerOrigin = OriginFromString(kProviderUrlFull);

  // Use an invalid login hint so login to IDP URL is shown.
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].login_hint = "not_a_valid_email";

  MockConfiguration config = kConfigurationValid;
  config.accounts_dialog_action = AccountsDialogAction::kNone;

  RunAuthDontWaitForCallback(kDefaultMultiIdpRequestParameters, config);

  EXPECT_FALSE(federated_auth_request_impl_->HasUserTriedToSignInToIdp(
      GURL(kProviderUrlFull)));

  for (int i = 0; i < 5; ++i) {
    // First, simulate the user clicking on the sign in to IDP active.
    SimulateLoginToIdP();
    // Then, simulate user signing into IdP by updating the IdP signin status
    // and calling the observer.
    test_permission_delegate_->idp_signin_statuses_[providerOrigin] = true;
    // We do not update the accounts so they would still be filtered out.
    federated_auth_request_impl_->OnIdpSigninStatusReceived(
        providerOrigin, /*idp_signin_status=*/true);

    base::RunLoop().RunUntilIdle();
    EXPECT_TRUE(federated_auth_request_impl_->HasUserTriedToSignInToIdp(
        GURL(kProviderUrlFull)));
  }
}

TEST_F(RequestServiceTest, VerifyingDialogCancelExplicitMetrics) {
  MockConfiguration config = kConfigurationValid;
  config.delay_token_response = true;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, config);
  CloseDialog();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.VerifyingDialogResult",
                                       VerifyingDialogResult::kCancelExplicit,
                                       1);
  ExpectUkmValue("VerifyingDialogResult",
                 static_cast<int>(VerifyingDialogResult::kCancelExplicit));
}

TEST_F(RequestServiceTest, VerifyingDialogCancelAutoReauthnMetrics) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::make_optional<base::Time>()));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  MockConfiguration config = kConfigurationValid;
  config.delay_token_response = true;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, config);
  CloseDialog();

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.VerifyingDialogResult",
      VerifyingDialogResult::kCancelAutoReauthn, 1);
  ExpectUkmValue("VerifyingDialogResult",
                 static_cast<int>(VerifyingDialogResult::kCancelAutoReauthn));
}

TEST_F(RequestServiceTest, VerifyingDialogDestroyExplicitMetrics) {
  MockConfiguration config = kConfigurationValid;
  config.delay_token_response = true;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, config);
  federated_auth_request_impl_->ResetAndDeleteThis();

  histogram_tester_.ExpectUniqueSample("Blink.FedCm.VerifyingDialogResult",
                                       VerifyingDialogResult::kDestroyExplicit,
                                       1);
  ExpectUkmValue("VerifyingDialogResult",
                 static_cast<int>(VerifyingDialogResult::kDestroyExplicit));
}

TEST_F(RequestServiceTest, VerifyingDialogDestroyAutoReauthnMetrics) {
  // Pretend the sharing permission has been granted for this account.
  EXPECT_CALL(
      *test_permission_delegate_,
      GetLastUsedTimestamp(OriginFromString(kRpUrl), OriginFromString(kRpUrl),
                           OriginFromString(kProviderUrlFull), kAccountId))
      .WillRepeatedly(Return(std::make_optional<base::Time>()));

  // Pretend the auto re-authn permission has been granted.
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnSettingEnabled())
      .WillOnce(Return(true));
  EXPECT_CALL(*test_auto_reauthn_permission_delegate_,
              IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
      .WillOnce(Return(false));

  MockConfiguration config = kConfigurationValid;
  config.delay_token_response = true;

  RunAuthDontWaitForCallback(kDefaultRequestParameters, config);
  federated_auth_request_impl_->ResetAndDeleteThis();

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.VerifyingDialogResult",
      VerifyingDialogResult::kDestroyAutoReauthn, 1);
  ExpectUkmValue("VerifyingDialogResult",
                 static_cast<int>(VerifyingDialogResult::kDestroyAutoReauthn));
}

TEST_F(RequestServiceTest, MetricsForThirdPartyCookiesEnabledInSettings) {
  // Pretend that third party cookies are enabled in settings.
  EXPECT_CALL(*test_api_permission_delegate_,
              AreThirdPartyCookiesEnabledInSettings())
      .WillOnce(Return(true));

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ukm_loop.Run();

  ExpectUkmValue("ThirdPartyCookiesStatus",
                 static_cast<int>(ThirdPartyCookiesStatus::kEnabledInSettings));

  ExpectStatusMetrics(TokenStatus::kSuccessUsingTokenInHttpResponse);
}

TEST_F(RequestServiceTest, MetricsForThirdPartyCookiesDisabledInSettings) {
  // Pretend that third party cookies are disabled in settings.
  EXPECT_CALL(*test_api_permission_delegate_,
              AreThirdPartyCookiesEnabledInSettings())
      .WillOnce(Return(false));

  base::RunLoop ukm_loop;
  ukm_recorder()->SetOnAddEntryCallback(FedCmEntry::kEntryName,
                                        ukm_loop.QuitClosure());

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ukm_loop.Run();

  ExpectUkmValue(
      "ThirdPartyCookiesStatus",
      static_cast<int>(ThirdPartyCookiesStatus::kDisabledInSettings));

  ExpectStatusMetrics(TokenStatus::kSuccessUsingTokenInHttpResponse);
}

// Tests that we record whether the RP's URL has a path when an accounts dialog
// is shown.
TEST_F(RequestServiceTest, MetricsForRpUrlHasPath) {
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);
  EXPECT_TRUE(did_show_accounts_dialog());

  ExpectUkmValueInEntry("RpUrlHasPath", FedCmEntry::kEntryName, false);
}

// Tests that we record the scroll position when an account is selected.
TEST_F(RequestServiceTest, MetricsForAccountSelectionScrollPosition) {
  // Mock the `GetScrollPosition` call.
  TestRenderFrameHost* test_rfh =
      static_cast<TestRenderFrameHost*>(web_contents()->GetPrimaryMainFrame());
  test_rfh->ResetLocalFrame();
  FakeLocalFrame local_frame;
  local_frame.Init(test_rfh->GetRemoteAssociatedInterfaces());

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  ExpectUkmValueInEntry("AccountSelectionScrollPosition",
                        FedCmEntry::kEntryName, 0);
}

TEST_F(RequestServiceTest, CancelReasonMetrics) {
  MockConfiguration config = kConfigurationValid;
  config.accounts_dialog_action = AccountsDialogAction::kClose;
  RequestExpectations expectations = {
      RequestTokenStatus::kError, FederatedAuthRequestResult::kShouldEmbargo,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, config);

  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.CancelReason",
      IdentityRequestDialogController::DismissReason::kCloseButton, 1);
  ExpectUkmValueInEntry(
      "CancelReason", FedCmEntry::kEntryName,
      static_cast<std::underlying_type_t<
          IdentityRequestDialogController::DismissReason>>(
          IdentityRequestDialogController::DismissReason::kCloseButton));
}

// Tests that the correct FederatedAuthRequestResult is returned when the
// accounts dialog is suppressed by segmentation platform.
TEST_F(RequestServiceTest, SuppressedBySegmentationPlatform) {
  MockConfiguration configuration = kConfigurationValid;
  configuration.suppressed_by_segmentation_platform = true;
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      FederatedAuthRequestResult::kSuppressedBySegmentationPlatform,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, configuration);
}

TEST_F(RequestServiceTest, MetricsForConsecutiveSuccessfulRequests) {
  // First successful auth request.
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  // Reset some test helpers so that we can send the second request.
  std::unique_ptr<TestIdpNetworkRequestManager> network_request_manager =
      std::make_unique<TestIdpNetworkRequestManager>();
  SetNetworkRequestManager(std::move(network_request_manager));
  auth_helper_ = std::make_unique<AuthRequestCallbackHelper>();

  // Second successful auth request.
  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  // There should be two samples, one for each successful request.
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.Status.RequestIdToken",
      TokenStatus::kSuccessUsingTokenInHttpResponse, 2);
  auto CheckUkmMetrics([&](const char* entry_name) {
    auto entries = ukm_recorder()->GetEntriesByName(entry_name);
    int num_token_status_ukm = 0;
    for (const ukm::mojom::UkmEntry* const entry : entries) {
      const int64_t* metric =
          ukm_recorder()->GetEntryMetric(entry, "Status.RequestIdToken");
      if (!metric) {
        continue;
      }
      EXPECT_EQ(static_cast<int>(TokenStatus::kSuccessUsingTokenInHttpResponse),
                *metric);
      ++num_token_status_ukm;
    }
    ASSERT_EQ(2, num_token_status_ukm);
  });
  CheckUkmMetrics(FedCmEntry::kEntryName);
  CheckUkmMetrics(FedCmIdpEntry::kEntryName);
}

// Test that completing a disconnect request while there is a pending request
// and then later completing the pending request does not crash.
TEST_F(RequestServiceTest, DisconnectWithPendingRequest) {
  // Start an auth request.
  RunAuthDontWaitForCallback(kDefaultRequestParameters, kConfigurationValid);

  // Complete a disconnect request.
  CompleteDisconnectRequest();

  // Complete the auth request.
  WaitForCurrentAuthRequest();
  CheckAuthExpectations(kConfigurationValid, kExpectationSuccess);

  // Auth request and disconnect request metrics should be recorded separately
  // with different session IDs.
  ExpectTwoUniqueSessionIDs();
}

class FakeLocalFrameWithDelayedCallback : public FakeLocalFrame {
 public:
  FakeLocalFrameWithDelayedCallback(RenderFrameHost* rfh) {
    TestRenderFrameHost* test_rfh = static_cast<TestRenderFrameHost*>(rfh);
    test_rfh->ResetLocalFrame();
    Init(test_rfh->GetRemoteAssociatedInterfaces());
  }

  void RunCallback() {
    if (!callback_) {
      return;
    }

    std::move(callback_).Run(gfx::Point(0, 0));
  }

  // FakeLocalFrame:
  void GetScrollPosition(GetScrollPositionCallback callback) override {
    callback_ = std::move(callback);
  }

 private:
  GetScrollPositionCallback callback_;
};

// Tests that we record the scroll position when an account is selected, even
// when `GetScrollPosition` runs its callback after the RequestService
// object is destroyed.
TEST_F(RequestServiceTest,
       MetricsForAccountSelectionScrollPositionDelayedCallback) {
  // Mock the `GetScrollPosition` call.
  FakeLocalFrameWithDelayedCallback frame(
      web_contents()->GetPrimaryMainFrame());

  RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
              kConfigurationValid);

  frame.RunCallback();
  base::RunLoop().RunUntilIdle();

  ExpectUkmValueInEntry("AccountSelectionScrollPosition",
                        FedCmEntry::kEntryName, 0);
}

TEST_F(RequestServiceTest, RecordsNoncePresence) {
  // TODO(crbug.com/441895082): Remove this test when FedCmNonceInParams is
  // enabled by default. Nonce should be passed via params field, not as a
  // separate field.
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].nonce = "12345";
  RunAuthTest(parameters, kExpectationSuccess, kConfigurationValid);
  ExpectUkmValue("HasNonce", true);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.HasNonce", true, 1);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.HasNonceOutsideParamsOnly",
                                       true, 1);
}

// Test that Blink.FedCm.HasNonceOutsideParamsOnly is not recorded when a nonce
// is present in params.
TEST_F(RequestServiceTest, HasNonceOutsideParamsOnly_ParamsWithNonce) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].params_json = "{\"nonce\":\"abc\"}";
  RunAuthTest(parameters, kExpectationSuccess, kConfigurationValid);
  histogram_tester_.ExpectUniqueSample("Blink.FedCm.HasNonce", true, 1);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.HasNonceOutsideParamsOnly",
                                     0);
  ExpectUkmValue("HasNonce", true);
}

// Test that Blink.FedCm.HasNonceOutsideParamsOnly is not recorded when a nonce
// is not present.
TEST_F(RequestServiceTest, HasNonceOutsideParamsOnly_NoNonce) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].nonce = "";
  RunAuthTest(parameters, kExpectationSuccess, kConfigurationValid);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.HasNonce", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.HasNonceOutsideParamsOnly",
                                     0);
  ExpectNoUKMPresence("HasNonce");
}

// Test that Blink.FedCm.HasNonceOutsideParamsOnly is not recorded when a nonce
// is only present in params.
TEST_F(RequestServiceTest, HasNonceOutsideParamsOnly_NonceOnlyInParams) {
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].nonce = "";
  parameters.identity_providers[0].params_json = "{\"nonce\":\"abc\"}";
  RunAuthTest(parameters, kExpectationSuccess, kConfigurationValid);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.HasNonce", 0);
  histogram_tester_.ExpectTotalCount("Blink.FedCm.HasNonceOutsideParamsOnly",
                                     0);
  ExpectNoUKMPresence("HasNonce");
}

TEST_F(RequestServiceTest, NonceAbsenceNoRecord) {
  // TODO(crbug.com/441895082): Remove this test when FedCmNonceInParams is
  // enabled by default. Nonce should be passed via params field, not as a
  // separate field.
  RequestParameters parameters = kDefaultRequestParameters;
  parameters.identity_providers[0].nonce = "";
  RunAuthTest(parameters, kExpectationSuccess, kConfigurationValid);
  ExpectNoUKMPresence("HasNonce");
  histogram_tester_.ExpectTotalCount("Blink.FedCm.HasNonce", 0);
}

// Tests that LifecycleStateFailureReason is recorded when page is non-primary.
TEST_F(RequestServiceTest, NonPrimaryPageMetrics) {
  static_cast<RenderFrameHostImpl*>(web_contents()->GetPrimaryMainFrame())
      ->SetLifecycleState(
          RenderFrameHostImpl::LifecycleStateImpl::kInBackForwardCache);
  RequestExpectations expectations = {
      RequestTokenStatus::kError,
      // When the RenderFrameHost changes on navigation, no console message is
      // received, so pass FederatedAuthRequestResult::kSuccess.
      FederatedAuthRequestResult::kSuccess,
      /*standalone_console_message=*/std::nullopt,
      /*selected_idp_config_url=*/std::nullopt};
  RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
  histogram_tester_.ExpectUniqueSample(
      "Blink.FedCm.LifecycleStateFailureReason",
      LifecycleStateFailureReason::kInBackForwardCache, 1);
}

}  // namespace content::webid
