| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import <memory> |
| #import <set> |
| |
| #import "base/files/file_path.h" |
| #import "base/functional/callback.h" |
| #import "base/functional/callback_helpers.h" |
| #import "base/strings/sys_string_conversions.h" |
| #import "base/test/bind.h" |
| #import "base/test/task_environment.h" |
| #import "components/autofill/core/browser/studies/autofill_experiments.h" |
| #import "components/autofill/core/common/autofill_prefs.h" |
| #import "components/image_fetcher/ios/ios_image_decoder_impl.h" |
| #import "components/password_manager/core/browser/features/password_manager_features_util.h" |
| #import "components/password_manager/core/common/password_manager_features.h" |
| #import "components/password_manager/core/common/password_manager_pref_names.h" |
| #import "components/prefs/pref_registry_simple.h" |
| #import "components/prefs/testing_pref_service.h" |
| #import "components/signin/public/base/consent_level.h" |
| #import "components/signin/public/base/signin_pref_names.h" |
| #import "components/signin/public/base/test_signin_client.h" |
| #import "components/signin/public/identity_manager/device_accounts_synchronizer.h" |
| #import "components/signin/public/identity_manager/identity_manager_builder.h" |
| #import "components/signin/public/identity_manager/identity_test_environment.h" |
| #import "components/signin/public/identity_manager/primary_account_mutator.h" |
| #import "components/sync/service/sync_service_observer.h" |
| #import "components/sync/test/test_sync_service.h" |
| #import "google_apis/gaia/google_service_auth_error.h" |
| #import "ios/web_view/internal/signin/web_view_device_accounts_provider_impl.h" |
| #import "ios/web_view/internal/sync/cwv_sync_controller_internal.h" |
| #import "ios/web_view/public/cwv_identity.h" |
| #import "ios/web_view/public/cwv_sync_controller_data_source.h" |
| #import "ios/web_view/public/cwv_sync_controller_delegate.h" |
| #import "ios/web_view/public/cwv_web_view.h" |
| #import "testing/gtest/include/gtest/gtest.h" |
| #import "testing/gtest_mac.h" |
| #import "testing/platform_test.h" |
| #import "third_party/ocmock/OCMock/OCMock.h" |
| |
| namespace ios_web_view { |
| namespace { |
| |
| const char kTestEmail[] = "johndoe@chromium.org"; |
| |
| } // namespace |
| |
| class CWVSyncControllerTest : public PlatformTest { |
| protected: |
| CWVSyncControllerTest() { |
| pref_service_.registry()->RegisterDictionaryPref( |
| autofill::prefs::kAutofillSyncTransportOptIn); |
| |
| sync_service_.SetSignedOut(); |
| } |
| |
| base::test::TaskEnvironment task_environment_; |
| signin::IdentityTestEnvironment identity_test_environment_; |
| syncer::TestSyncService sync_service_; |
| TestingPrefServiceSimple pref_service_; |
| }; |
| |
| TEST_F(CWVSyncControllerTest, StartSyncWithIdentity) { |
| CoreAccountInfo account_info = |
| identity_test_environment_.MakeAccountAvailable(kTestEmail); |
| |
| CWVIdentity* identity = |
| [[CWVIdentity alloc] initWithEmail:@(kTestEmail) |
| fullName:nil |
| gaiaID:account_info.gaia.ToNSString()]; |
| |
| // Preconfigure TestSyncService as if it was enabled in transport mode. |
| sync_service_.SetSignedIn(signin::ConsentLevel::kSignin); |
| |
| CWVSyncController* sync_controller = [[CWVSyncController alloc] |
| initWithSyncService:&sync_service_ |
| identityManager:identity_test_environment_.identity_manager() |
| prefService:&pref_service_]; |
| [sync_controller startSyncWithIdentity:identity]; |
| EXPECT_NSEQ(sync_controller.currentIdentity.gaiaID, identity.gaiaID); |
| |
| CoreAccountInfo primary_account_info = |
| identity_test_environment_.identity_manager()->GetPrimaryAccountInfo( |
| signin::ConsentLevel::kSignin); |
| EXPECT_EQ(primary_account_info, account_info); |
| |
| EXPECT_TRUE( |
| password_manager::features_util::IsAccountStorageActive(&sync_service_)); |
| |
| [sync_controller shutDown]; |
| } |
| |
| TEST_F(CWVSyncControllerTest, StartSyncWithIdentityInAuthError) { |
| CWVWebView.skipAccountStorageCheckEnabled = true; |
| AccountInfo account_info = |
| identity_test_environment_.MakeAccountAvailable(kTestEmail); |
| sync_service_.SetSignedIn(signin::ConsentLevel::kSignin, account_info); |
| sync_service_.SetPersistentAuthError(); |
| ASSERT_FALSE( |
| password_manager::features_util::IsAccountStorageActive(&sync_service_)); |
| |
| // Should not crash. |
| CWVSyncController* sync_controller = [[CWVSyncController alloc] |
| initWithSyncService:&sync_service_ |
| identityManager:identity_test_environment_.identity_manager() |
| prefService:&pref_service_]; |
| [sync_controller |
| startSyncWithIdentity:[[CWVIdentity alloc] |
| initWithEmail:@(kTestEmail) |
| fullName:base::SysUTF8ToNSString( |
| account_info.GetFullName() |
| .value_or("")) |
| gaiaID:account_info.gaia.ToNSString()]]; |
| |
| CWVWebView.skipAccountStorageCheckEnabled = false; |
| |
| [sync_controller shutDown]; |
| } |
| |
| TEST_F(CWVSyncControllerTest, StopSyncAndClearIdentity) { |
| CoreAccountInfo account_info = |
| identity_test_environment_.MakePrimaryAccountAvailable( |
| kTestEmail, signin::ConsentLevel::kSignin); |
| |
| CWVSyncController* sync_controller = [[CWVSyncController alloc] |
| initWithSyncService:&sync_service_ |
| identityManager:identity_test_environment_.identity_manager() |
| prefService:&pref_service_]; |
| CWVIdentity* current_identity = sync_controller.currentIdentity; |
| ASSERT_TRUE(current_identity); |
| EXPECT_NSEQ(current_identity.gaiaID, account_info.gaia.ToNSString()); |
| EXPECT_NSEQ(current_identity.email, base::SysUTF8ToNSString(kTestEmail)); |
| |
| [sync_controller stopSyncAndClearIdentity]; |
| EXPECT_FALSE(sync_controller.currentIdentity); |
| |
| [sync_controller shutDown]; |
| } |
| |
| TEST_F(CWVSyncControllerTest, PassphraseNeeded) { |
| CWVSyncController* sync_controller = [[CWVSyncController alloc] |
| initWithSyncService:&sync_service_ |
| identityManager:identity_test_environment_.identity_manager() |
| prefService:&pref_service_]; |
| sync_service_.SetSignedIn(signin::ConsentLevel::kSignin); |
| ASSERT_FALSE(sync_service_.GetUserSettings()->IsPassphraseRequired()); |
| EXPECT_FALSE(sync_controller.passphraseNeeded); |
| sync_service_.SetPassphraseRequired(); |
| EXPECT_TRUE(sync_controller.passphraseNeeded); |
| |
| [sync_controller shutDown]; |
| } |
| |
| TEST_F(CWVSyncControllerTest, TrustedVaultKeysRequired) { |
| CWVSyncController* sync_controller = [[CWVSyncController alloc] |
| initWithSyncService:&sync_service_ |
| identityManager:identity_test_environment_.identity_manager() |
| prefService:&pref_service_]; |
| sync_service_.SetSignedIn(signin::ConsentLevel::kSignin); |
| ASSERT_FALSE(sync_service_.GetUserSettings()->IsTrustedVaultKeyRequired()); |
| EXPECT_FALSE(sync_controller.trustedVaultKeysRequired); |
| sync_service_.SetTrustedVaultKeyRequired(true); |
| EXPECT_TRUE(sync_controller.trustedVaultKeysRequired); |
| |
| [sync_controller shutDown]; |
| } |
| |
| TEST_F(CWVSyncControllerTest, TrustedVaultRecoverabilityDegraded) { |
| CWVSyncController* sync_controller = [[CWVSyncController alloc] |
| initWithSyncService:&sync_service_ |
| identityManager:identity_test_environment_.identity_manager() |
| prefService:&pref_service_]; |
| sync_service_.SetTrustedVaultRecoverabilityDegraded(false); |
| EXPECT_FALSE(sync_controller.trustedVaultRecoverabilityDegraded); |
| sync_service_.SetTrustedVaultRecoverabilityDegraded(true); |
| EXPECT_TRUE(sync_controller.trustedVaultRecoverabilityDegraded); |
| |
| [sync_controller shutDown]; |
| } |
| |
| TEST_F(CWVSyncControllerTest, DelegateDidStartAndStopSync) { |
| CWVSyncController* sync_controller = [[CWVSyncController alloc] |
| initWithSyncService:&sync_service_ |
| identityManager:identity_test_environment_.identity_manager() |
| prefService:&pref_service_]; |
| |
| id delegate = OCMStrictProtocolMock(@protocol(CWVSyncControllerDelegate)); |
| [delegate setExpectationOrderMatters:YES]; |
| sync_controller.delegate = delegate; |
| |
| // TestSyncService's transport state has to actually change before a callback |
| // will be fired, so we have to start it before we can stop it. |
| OCMExpect([delegate syncControllerDidStartSync:sync_controller]); |
| OCMExpect([delegate syncControllerDidUpdateState:sync_controller]); |
| OCMExpect([delegate syncControllerDidStopSync:sync_controller]); |
| OCMExpect([delegate syncControllerDidUpdateState:sync_controller]); |
| sync_service_.SetSignedIn(signin::ConsentLevel::kSignin); |
| sync_service_.FireStateChanged(); |
| sync_service_.SetSignedOut(); |
| sync_service_.FireStateChanged(); |
| |
| [delegate verify]; |
| |
| [sync_controller shutDown]; |
| } |
| |
| TEST_F(CWVSyncControllerTest, DelegateDidUpdateState) { |
| CWVSyncController* sync_controller = [[CWVSyncController alloc] |
| initWithSyncService:&sync_service_ |
| identityManager:identity_test_environment_.identity_manager() |
| prefService:&pref_service_]; |
| |
| id delegate = OCMStrictProtocolMock(@protocol(CWVSyncControllerDelegate)); |
| sync_controller.delegate = delegate; |
| |
| OCMExpect([delegate syncControllerDidUpdateState:sync_controller]); |
| sync_service_.FireStateChanged(); |
| [delegate verify]; |
| |
| [sync_controller shutDown]; |
| } |
| |
| } // namespace ios_web_view |