| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SERVICES_IDENTITY_PUBLIC_CPP_IDENTITY_TEST_ENVIRONMENT_H_ |
| #define SERVICES_IDENTITY_PUBLIC_CPP_IDENTITY_TEST_ENVIRONMENT_H_ |
| |
| #include "base/optional.h" |
| #include "components/signin/core/browser/account_tracker_service.h" |
| #include "components/signin/core/browser/fake_gaia_cookie_manager_service.h" |
| #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" |
| #include "components/signin/core/browser/fake_signin_manager.h" |
| #include "services/identity/public/cpp/identity_manager.h" |
| #include "services/identity/public/cpp/identity_test_utils.h" |
| |
| namespace identity { |
| |
| // Internal class that creates and owns dependencies of IdentityManager |
| // when those dependencies are not passed in externally. |
| class IdentityManagerDependenciesOwner; |
| |
| // Class that creates an IdentityManager for use in testing contexts and |
| // provides facilities for driving that IdentityManager. The IdentityManager |
| // instance is brought up in an environment where the primary account is |
| // not available; call MakePrimaryAccountAvailable() as needed. |
| class IdentityTestEnvironment : public IdentityManager::DiagnosticsObserver { |
| #if defined(OS_CHROMEOS) |
| using SigninManagerForTest = FakeSigninManagerBase; |
| #else |
| using SigninManagerForTest = FakeSigninManager; |
| #endif // OS_CHROMEOS |
| |
| public: |
| // Preferred constructor: constructs an IdentityManager object and its |
| // dependencies internally. Cannot be used if the client of this class |
| // is still interacting directly with those dependencies (e.g., if |
| // IdentityTestEnvironment is being introduced to incrementally convert |
| // a test). In that case, use the below constructor and switch to this |
| // constructor once the conversion is complete. |
| IdentityTestEnvironment( |
| bool use_fake_url_loader_for_gaia_cookie_manager = false); |
| |
| // Constructor that takes in instances of the dependencies of |
| // IdentityManager and constructs an IdentityManager instance from those |
| // dependencies. For use in contexts where those dependencies are still |
| // being used directly by the creator of this object (i.e., while a test is |
| // being incrementally converted). Prefer the above constructor, and switch to |
| // that constructor once possible (e.g., when an incremental conversion is |
| // completed). NOTE: The passed-in objects must all outlive this object. |
| IdentityTestEnvironment( |
| AccountTrackerService* account_tracker_service, |
| FakeProfileOAuth2TokenService* token_service, |
| SigninManagerForTest* signin_manager, |
| FakeGaiaCookieManagerService* gaia_cookie_manager_service); |
| ~IdentityTestEnvironment() override; |
| |
| // The IdentityManager instance created and owned by this instance. |
| IdentityManager* identity_manager(); |
| |
| // Sets the primary account for the given email address, generating a GAIA ID |
| // that corresponds uniquely to that email address. On non-ChromeOS, results |
| // in the firing of the IdentityManager and SigninManager callbacks for signin |
| // success. Blocks until the primary account is set. Returns the AccountInfo |
| // of the newly-set account. |
| AccountInfo SetPrimaryAccount(const std::string& email); |
| |
| // Sets a refresh token for the primary account (which must already be set). |
| // Blocks until the refresh token is set. |
| void SetRefreshTokenForPrimaryAccount(); |
| |
| // Sets a special invalid refresh token for the primary account (which must |
| // already be set). Blocks until the refresh token is set. |
| void SetInvalidRefreshTokenForPrimaryAccount(); |
| |
| // Removes any refresh token for the primary account, if present. Blocks until |
| // the refresh token is removed. |
| void RemoveRefreshTokenForPrimaryAccount(); |
| |
| // Makes the primary account available for the given email address, generating |
| // a GAIA ID and refresh token that correspond uniquely to that email address. |
| // On non-ChromeOS platforms, this will also result in the firing of the |
| // IdentityManager and SigninManager callbacks for signin success. On all |
| // platforms, this method blocks until the primary account is available. |
| // Returns the AccountInfo of the newly-available account. |
| AccountInfo MakePrimaryAccountAvailable(const std::string& email); |
| |
| // Clears the primary account if present, with |policy| used to determine |
| // whether to keep or remove all accounts. On non-ChromeOS, results in the |
| // firing of the IdentityManager and SigninManager callbacks for signout. |
| // Blocks until the primary account is cleared. |
| void ClearPrimaryAccount( |
| ClearPrimaryAccountPolicy policy = ClearPrimaryAccountPolicy::DEFAULT); |
| |
| // Makes an account available for the given email address, generating a GAIA |
| // ID and refresh token that correspond uniquely to that email address. Blocks |
| // until the account is available. Returns the AccountInfo of the |
| // newly-available account. |
| AccountInfo MakeAccountAvailable(const std::string& email); |
| |
| // Sets a refresh token for the given account (which must already be |
| // available). Blocks until the refresh token is set. NOTE: See disclaimer at |
| // top of file re: direct usage. |
| void SetRefreshTokenForAccount(const std::string& account_id); |
| |
| // Sets a special invalid refresh token for the given account (which must |
| // already be available). Blocks until the refresh token is set. NOTE: See |
| // disclaimer at top of file re: direct usage. |
| void SetInvalidRefreshTokenForAccount(const std::string& account_id); |
| |
| // Removes any refresh token that is present for the given account. Blocks |
| // until the refresh token is removed. |
| // NOTE: See disclaimer at top of file re: direct usage. |
| void RemoveRefreshTokenForAccount(const std::string& account_id); |
| |
| // Puts the given accounts into the Gaia cookie, replacing any previous |
| // accounts. Blocks until the accounts have been set. |
| void SetCookieAccounts(const std::vector<CookieParams>& cookie_accounts); |
| |
| // When this is set, access token requests will be automatically granted with |
| // an access token value of "access_token". |
| void SetAutomaticIssueOfAccessTokens(bool grant); |
| |
| // Issues |token| in response to any access token request that either has (a) |
| // already occurred and has not been matched by a previous call to this or |
| // other WaitFor... method, or (b) will occur in the future. In the latter |
| // case, waits until the access token request occurs. |
| // NOTE: This method behaves this way to allow IdentityTestEnvironment to be |
| // agnostic with respect to whether access token requests are handled |
| // synchronously or asynchronously in the production code. |
| // NOTE: This version is suitable for use in the common context where access |
| // token requests are only being made for one account. If you need to |
| // disambiguate requests coming for different accounts, see the version below. |
| void WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( |
| const std::string& token, |
| const base::Time& expiration); |
| |
| // Issues |token| in response to any access token request that either has (a) |
| // already occurred and has not been matched by a previous call to this or |
| // other WaitFor... method, or (b) will occur in the future. In the latter |
| // case, waits until the access token request occurs. |
| // NOTE: This method behaves this way to allow IdentityTestEnvironment to be |
| // agnostic with respect to whether access token requests are handled |
| // synchronously or asynchronously in the production code. |
| // NOTE: This version is suitable for use in the common context where access |
| // token requests are only being made for one account. If you need to |
| // disambiguate requests coming for different accounts, see the version below. |
| // NOTE: This version allows passing the uncommon id_token parameter which is |
| // needed to test some cases where checking for that extra info is required. |
| void WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( |
| const std::string& token, |
| const base::Time& expiration, |
| const std::string& id_token); |
| |
| // Issues |token| in response to an access token request for |account_id| that |
| // either already occurred and has not been matched by a previous call to this |
| // or other WaitFor... method , or (b) will occur in the future. In the latter |
| // case, waits until the access token request occurs. |
| // NOTE: This method behaves this way to allow |
| // IdentityTestEnvironment to be agnostic with respect to whether access token |
| // requests are handled synchronously or asynchronously in the production |
| // code. |
| void WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( |
| const std::string& account_id, |
| const std::string& token, |
| const base::Time& expiration); |
| |
| // Issues |error| in response to any access token request that either has (a) |
| // already occurred and has not been matched by a previous call to this or |
| // other WaitFor... method, or (b) will occur in the future via In the latter |
| // case, waits until the access token request occurs. |
| // NOTE: This method behaves this way to allow IdentityTestEnvironment to be |
| // agnostic with respect to whether access token requests are handled |
| // synchronously or asynchronously in the production code. |
| // NOTE: This version is suitable for use in the common context where access |
| // token requests are only being made for one account. If you need to |
| // disambiguate requests coming for different accounts, see the version below. |
| void WaitForAccessTokenRequestIfNecessaryAndRespondWithError( |
| const GoogleServiceAuthError& error); |
| |
| // Issues |error| in response to an access token request for |account_id| that |
| // either has (a) already occurred and has not been matched by a previous call |
| // to this or other WaitFor... method, or (b) will occur in the future. In the |
| // latter case, waits until the access token request occurs. |
| // NOTE: This method behaves this way to allow |
| // IdentityTestEnvironment to be agnostic with respect to whether access token |
| // requests are handled synchronously or asynchronously in the production |
| // code. |
| void WaitForAccessTokenRequestIfNecessaryAndRespondWithError( |
| const std::string& account_id, |
| const GoogleServiceAuthError& error); |
| |
| // Sets a callback that will be invoked on the next incoming access token |
| // request. Note that this can not be combined with the |
| // WaitForAccessTokenRequestIfNecessaryAndRespondWith* methods - you must |
| // either wait for the callback to get called, or explicitly reset it by |
| // passing in a null callback, before the Wait* methods can be used again. |
| void SetCallbackForNextAccessTokenRequest(base::OnceClosure callback); |
| |
| private: |
| struct AccessTokenRequestState { |
| AccessTokenRequestState(); |
| ~AccessTokenRequestState(); |
| AccessTokenRequestState(AccessTokenRequestState&& other); |
| AccessTokenRequestState& operator=(AccessTokenRequestState&& other); |
| |
| enum { |
| kPending, |
| kAvailable, |
| } state; |
| base::Optional<std::string> account_id; |
| base::OnceClosure on_available; |
| }; |
| |
| // Constructs this object and its IdentityManager instance from the supplied |
| // dependencies of IdentityManager, which must be either: |
| // (1) non-null instances of the backing classes, OR |
| // (2) a non-null instance of |dependencies_owner|. |
| IdentityTestEnvironment( |
| AccountTrackerService* account_tracker_service, |
| FakeProfileOAuth2TokenService* token_service, |
| SigninManagerForTest* signin_manager, |
| FakeGaiaCookieManagerService* gaia_cookie_manager_service, |
| std::unique_ptr<IdentityManagerDependenciesOwner> dependencies_owner); |
| |
| // IdentityManager::DiagnosticsObserver: |
| void OnAccessTokenRequested( |
| const std::string& account_id, |
| const std::string& consumer_id, |
| const OAuth2TokenService::ScopeSet& scopes) override; |
| |
| // Handles the notification that an access token request was received for |
| // |account_id|. Invokes |on_access_token_request_callback_| if the latter |
| // is non-null *and* either |*pending_access_token_requester_| equals |
| // |account_id| or |pending_access_token_requester_| is empty. |
| void HandleOnAccessTokenRequested(std::string account_id); |
| |
| // If a token request for |account_id| (or any account if nullopt) has already |
| // been made and not matched by a different call, returns immediately. |
| // Otherwise and runs a nested runloop until a matching access token request |
| // is observed. |
| void WaitForAccessTokenRequestIfNecessary( |
| base::Optional<std::string> account_id); |
| |
| // NOTE: This object must be first in the list, as it owns the objects |
| // pointed to below in the case where those objects are not passed in via |
| // the IdentityTestEnvironment constructor. |
| std::unique_ptr<IdentityManagerDependenciesOwner> dependencies_owner_; |
| AccountTrackerService* account_tracker_service_ = nullptr; |
| FakeProfileOAuth2TokenService* token_service_ = nullptr; |
| SigninManagerForTest* signin_manager_ = nullptr; |
| FakeGaiaCookieManagerService* gaia_cookie_manager_service_ = nullptr; |
| std::unique_ptr<IdentityManager> identity_manager_; |
| |
| base::OnceClosure on_access_token_requested_callback_; |
| std::vector<AccessTokenRequestState> requesters_; |
| |
| DISALLOW_COPY_AND_ASSIGN(IdentityTestEnvironment); |
| }; |
| |
| } // namespace identity |
| |
| #endif // SERVICES_IDENTITY_PUBLIC_CPP_IDENTITY_TEST_ENVIRONMENT_H_ |