| // 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. |
| |
| #import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.h" |
| |
| #import <UIKit/UIKit.h> |
| |
| #import "base/functional/callback_helpers.h" |
| #import "base/run_loop.h" |
| #import "ios/chrome/browser/shared/model/application_context/application_context.h" |
| #import "ios/chrome/browser/shared/model/browser/test/test_browser.h" |
| #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" |
| #import "ios/chrome/browser/signin/authentication_service.h" |
| #import "ios/chrome/browser/signin/authentication_service_factory.h" |
| #import "ios/chrome/browser/signin/chrome_account_manager_service_factory.h" |
| #import "ios/chrome/browser/signin/fake_authentication_service_delegate.h" |
| #import "ios/chrome/browser/signin/fake_system_identity.h" |
| #import "ios/chrome/browser/signin/fake_system_identity_manager.h" |
| #import "ios/chrome/browser/signin/identity_manager_factory.h" |
| #import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.h" |
| #import "ios/chrome/browser/unified_consent/unified_consent_service_factory.h" |
| #import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h" |
| #import "ios/web/public/test/web_task_environment.h" |
| #import "testing/gmock/include/gmock/gmock.h" |
| #import "testing/gtest_mac.h" |
| #import "testing/platform_test.h" |
| #import "third_party/ocmock/OCMock/OCMock.h" |
| #import "third_party/ocmock/gtest_support.h" |
| #import "third_party/ocmock/ocmock_extensions.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| class UnifiedConsentMediatorTest : public PlatformTest { |
| public: |
| void SetUp() override { |
| PlatformTest::SetUp(); |
| identity1_ = [FakeSystemIdentity fakeIdentity1]; |
| identity2_ = [FakeSystemIdentity fakeIdentity2]; |
| identity3_ = [FakeSystemIdentity fakeIdentity3]; |
| |
| TestChromeBrowserState::Builder builder; |
| builder.AddTestingFactory( |
| AuthenticationServiceFactory::GetInstance(), |
| AuthenticationServiceFactory::GetDefaultFactory()); |
| browser_state_ = builder.Build(); |
| AuthenticationServiceFactory::CreateAndInitializeForBrowserState( |
| browser_state_.get(), |
| std::make_unique<FakeAuthenticationServiceDelegate>()); |
| view_controller_ = [[UnifiedConsentViewController alloc] |
| initWithPostRestoreSigninPromo:NO]; |
| |
| mediator_delegate_mock_ = |
| OCMProtocolMock(@protocol(UnifiedConsentMediatorDelegate)); |
| } |
| |
| void TearDown() override { |
| // Ensures that the prefService is no longer observing changes. |
| [mediator_ disconnect]; |
| |
| EXPECT_OCMOCK_VERIFY((id)mediator_delegate_mock_); |
| PlatformTest::TearDown(); |
| } |
| // Identity services. |
| AuthenticationService* GetAuthenticationService() { |
| return AuthenticationServiceFactory::GetForBrowserState( |
| browser_state_.get()); |
| } |
| |
| FakeSystemIdentityManager* GetIdentityService() { |
| return FakeSystemIdentityManager::FromSystemIdentityManager( |
| GetApplicationContext()->GetSystemIdentityManager()); |
| } |
| |
| void AddIdentities() { |
| GetIdentityService()->AddIdentity(identity1_); |
| GetIdentityService()->AddIdentity(identity2_); |
| GetIdentityService()->AddIdentity(identity3_); |
| } |
| |
| void CreateMediator() { |
| mediator_ = [[UnifiedConsentMediator alloc] |
| initWithUnifiedConsentViewController:view_controller_ |
| authenticationService:GetAuthenticationService() |
| accountManagerService: |
| ChromeAccountManagerServiceFactory:: |
| GetForBrowserState(browser_state_.get())]; |
| mediator_.delegate = mediator_delegate_mock_; |
| } |
| |
| protected: |
| // Needed for test browser state created by TestChromeBrowserState(). |
| web::WebTaskEnvironment task_environment_; |
| IOSChromeScopedTestingLocalState scoped_testing_local_state_; |
| std::unique_ptr<TestChromeBrowserState> browser_state_; |
| |
| id<SystemIdentity> identity1_ = nil; |
| id<SystemIdentity> identity2_ = nil; |
| id<SystemIdentity> identity3_ = nil; |
| |
| UnifiedConsentMediator* mediator_ = nullptr; |
| |
| id<UnifiedConsentMediatorDelegate> mediator_delegate_mock_ = nil; |
| UnifiedConsentViewController* view_controller_ = nullptr; |
| }; |
| |
| // Tests that there is no selected default identity for a signed-out user with |
| // no accounts on the device. |
| TEST_F(UnifiedConsentMediatorTest, |
| SelectDefaultIdentityForSignedOutUserWithNoAccounts) { |
| CreateMediator(); |
| [mediator_ start]; |
| |
| ASSERT_NSEQ(nil, mediator_.selectedIdentity); |
| } |
| |
| // Tests that the default identity selected for a signed-out user with accounts |
| // on the device is the first option. |
| TEST_F(UnifiedConsentMediatorTest, |
| SelectDefaultIdentityForSignedOutUserWithAccounts) { |
| AddIdentities(); |
| CreateMediator(); |
| |
| [mediator_ start]; |
| |
| ASSERT_NSEQ(identity1_, mediator_.selectedIdentity); |
| } |
| |
| // Tests that the default identity becomes the next identity on the device after |
| // forgetting the default identity. |
| TEST_F(UnifiedConsentMediatorTest, SelectDefaultIdentityAfterForgetIdentity) { |
| AddIdentities(); |
| CreateMediator(); |
| |
| [mediator_ start]; |
| ASSERT_NSEQ(identity1_, mediator_.selectedIdentity); |
| |
| { |
| base::RunLoop run_loop; |
| GetIdentityService()->ForgetIdentity( |
| identity1_, base::IgnoreArgs<NSError*>(run_loop.QuitClosure())); |
| run_loop.Run(); |
| } |
| |
| ASSERT_NSEQ(identity2_, mediator_.selectedIdentity); |
| } |
| |
| // Tests that the default identity selected for a signed-in user is the |
| // authenticated identity. |
| TEST_F(UnifiedConsentMediatorTest, SelectDefaultIdentityForSignedInUser) { |
| AddIdentities(); |
| CreateMediator(); |
| |
| GetAuthenticationService()->SignIn( |
| identity2_, signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN); |
| [mediator_ start]; |
| |
| ASSERT_NSEQ(identity2_, mediator_.selectedIdentity); |
| } |
| |
| // Tests that the default identity is the next identity on the device after |
| // sign-out and forgetting the authenticated identity. |
| TEST_F(UnifiedConsentMediatorTest, |
| SelectDefaultIdentityAfterSignOutAndForgetIdentity) { |
| AddIdentities(); |
| CreateMediator(); |
| |
| GetAuthenticationService()->SignIn( |
| identity3_, signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN); |
| [mediator_ start]; |
| ASSERT_NSEQ(identity3_, mediator_.selectedIdentity); |
| GetAuthenticationService()->SignOut(signin_metrics::ProfileSignout::kTest, |
| false, nil); |
| |
| { |
| base::RunLoop run_loop; |
| GetIdentityService()->ForgetIdentity( |
| identity3_, base::IgnoreArgs<NSError*>(run_loop.QuitClosure())); |
| run_loop.Run(); |
| } |
| |
| ASSERT_NSEQ(identity1_, mediator_.selectedIdentity); |
| } |
| |
| // Tests that the selected identity before start is kept. |
| TEST_F(UnifiedConsentMediatorTest, SelectIdentity) { |
| AddIdentities(); |
| CreateMediator(); |
| |
| mediator_.selectedIdentity = identity2_; |
| [mediator_ start]; |
| |
| ASSERT_NSEQ(identity2_, mediator_.selectedIdentity); |
| } |
| |
| // Tests that `start` will not override the selected identity with a |
| // pre-determined default identity based on the accounts on the device and user |
| // sign-in state. |
| TEST_F(UnifiedConsentMediatorTest, DontOverrideIdentityForSignedInUser) { |
| AddIdentities(); |
| CreateMediator(); |
| |
| GetAuthenticationService()->SignIn( |
| identity1_, signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN); |
| mediator_.selectedIdentity = identity2_; |
| [mediator_ start]; |
| |
| ASSERT_NSEQ(identity2_, mediator_.selectedIdentity); |
| } |