diff --git a/BitwardenShared/Core/Auth/Services/AuthServiceTests.swift b/BitwardenShared/Core/Auth/Services/AuthServiceTests.swift index bbed5e23c8..fb58f0ba2e 100644 --- a/BitwardenShared/Core/Auth/Services/AuthServiceTests.swift +++ b/BitwardenShared/Core/Auth/Services/AuthServiceTests.swift @@ -309,7 +309,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ loginRequestId: "1" ) XCTAssertEqual(client.requests.last?.body, try tokenRequest.encode()) - assertGetConfig() + await assertGetConfig() } /// `loginWithDevice(_:email:captchaToken:)` throws an error if there's no cached data. @@ -320,6 +320,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ } /// `loginWithMasterPassword(_:username:captchaToken:)` logs in with the password. + @MainActor func test_loginWithMasterPassword() async throws { // swiftlint:disable:this function_body_length // Set up the mock data. client.results = [ @@ -389,6 +390,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ /// `loginWithMasterPassword(_:username:captchaToken:)` logs the user in with the password for /// a newly created account. + @MainActor func test_loginWithMasterPassword_isNewAccount() async throws { // swiftlint:disable:this function_body_length client.results = [ .httpSuccess(testData: .preLoginSuccess), @@ -460,6 +462,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ /// `loginWithMasterPassword(_:username:captchaToken:)` logs the user in with the password for /// a newly created account and sets their autofill account setup progress to complete if /// autofill is already enabled. + @MainActor func test_loginWithMasterPassword_isNewAccount_autofillEnabled() async throws { client.results = [ .httpSuccess(testData: .preLoginSuccess), @@ -486,6 +489,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ /// `loginWithMasterPassword(_:username:captchaToken:)` logs in with the password updates AccountProfile's /// `.forcePasswordResetReason` value if policy requires user to update password. + @MainActor func test_loginWithMasterPassword_updatesAccountProfile() async throws { // Set up the mock data. client.results = [ @@ -584,7 +588,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ let unlockMethod = try await subject.loginWithSingleSignOn(code: "super_cool_secret_code", email: "") XCTAssertEqual(unlockMethod, .deviceKey) - assertGetConfig() + await assertGetConfig() } /// `loginWithSingleSignOn(code:email:)` returns the key connector unlock method if the user @@ -598,7 +602,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ unlockMethod, .keyConnector(keyConnectorURL: URL(string: "https://vault.bitwarden.com/key-connector")!) ) - assertGetConfig() + await assertGetConfig() } // `loginWithSingleSignOn(code:email:)` returns the master password unlock method if the user @@ -618,7 +622,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ unlockMethod, .masterPassword(account) ) - assertGetConfig() + await assertGetConfig() } /// `loginWithSingleSignOn(code:email:)` throws an error if the user doesn't have a master password set. @@ -628,7 +632,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ await assertAsyncThrows(error: AuthError.requireSetPassword) { _ = try await subject.loginWithSingleSignOn(code: "super_cool_secret_code", email: "") } - assertGetConfig() + await assertGetConfig() } /// `loginWithSingleSignOn(code:email:)` returns an account if the vault is still locked after authenticating. @@ -679,7 +683,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ ) XCTAssertEqual(unlockMethod, .masterPassword(.fixtureAccountLogin())) - assertGetConfig() + await assertGetConfig() } /// `loginWithTwoFactorCode(email:code:method:remember:captchaToken:)` uses the cached request but with two factor @@ -754,7 +758,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ ) XCTAssertEqual(unlockMethod, .masterPassword(.fixtureAccountLogin())) - assertGetConfig() + await assertGetConfig() } /// `loginWithTwoFactorCode()` returns the device key unlock method if the user uses trusted @@ -794,7 +798,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ remember: true ) XCTAssertEqual(unlockMethod, .deviceKey) - assertGetConfig() + await assertGetConfig() } /// `loginWithTwoFactorCode()` returns the key connector unlock method if the user uses key connector. @@ -836,7 +840,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ unlockMethod, .keyConnector(keyConnectorURL: URL(string: "https://vault.bitwarden.com/key-connector")!) ) - assertGetConfig() + await assertGetConfig() } /// `requirePasswordChange(email:masterPassword:policy)` returns `false` if there @@ -944,6 +948,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_ // MARK: Private /// Asserts that `getConfig` is called with the proper parameters + @MainActor private func assertGetConfig() { configService.configMocker.assertUnwrapping { forceRefresh, isPreAuth in forceRefresh && !isPreAuth diff --git a/BitwardenShared/Core/Platform/Services/ClientServiceTests.swift b/BitwardenShared/Core/Platform/Services/ClientServiceTests.swift index 95603732d4..77432c450c 100644 --- a/BitwardenShared/Core/Platform/Services/ClientServiceTests.swift +++ b/BitwardenShared/Core/Platform/Services/ClientServiceTests.swift @@ -101,6 +101,7 @@ final class ClientServiceTests: BitwardenTestCase { // swiftlint:disable:this ty } /// `client(for:)` loads flags into the SDK. + @MainActor func test_client_loadFlags() async throws { configService.configMocker.withResult(ServerConfig( date: Date(year: 2024, month: 2, day: 14, hour: 7, minute: 50, second: 0), @@ -123,6 +124,7 @@ final class ClientServiceTests: BitwardenTestCase { // swiftlint:disable:this ty } /// `client(for:)` loads `enableCipherKeyEncryption` flag as `false` into the SDK. + @MainActor func test_client_loadFlagsEnableCipherKeyEncryptionFalse() async throws { configService.configMocker.withResult(ServerConfig( date: Date(year: 2024, month: 2, day: 14, hour: 7, minute: 50, second: 0), @@ -145,6 +147,7 @@ final class ClientServiceTests: BitwardenTestCase { // swiftlint:disable:this ty } /// `client(for:)` loading flags throws. + @MainActor func test_client_loadFlagsThrows() async throws { configService.configMocker.withResult(ServerConfig( date: Date(year: 2024, month: 2, day: 14, hour: 7, minute: 50, second: 0), @@ -166,6 +169,7 @@ final class ClientServiceTests: BitwardenTestCase { // swiftlint:disable:this ty } /// `client(for:)` does not load flags when config is `nil`. + @MainActor func test_client_doesNotloadFlags() async throws { configService.configMocker.withResult(nil) @@ -179,6 +183,7 @@ final class ClientServiceTests: BitwardenTestCase { // swiftlint:disable:this ty } /// `configPublisher` loads flags into the SDK. + @MainActor func test_configPublisher_loadFlags() async throws { configService.configSubject.send( MetaServerConfig( @@ -207,6 +212,7 @@ final class ClientServiceTests: BitwardenTestCase { // swiftlint:disable:this ty } /// `configPublisher` loads flags into the SDK on a already created client. + @MainActor func test_configPublisher_loadFlagsOverride() async throws { configService.configMocker.withResult(ServerConfig( date: Date(year: 2024, month: 2, day: 14, hour: 7, minute: 50, second: 0), @@ -251,6 +257,7 @@ final class ClientServiceTests: BitwardenTestCase { // swiftlint:disable:this ty } /// `configPublisher` does not load flags into the SDK when the config sent is pre authentication. + @MainActor func test_configPublisher_doesNotloadFlagsWhenIsPreAuth() async throws { configService.configSubject.send( MetaServerConfig( @@ -273,6 +280,7 @@ final class ClientServiceTests: BitwardenTestCase { // swiftlint:disable:this ty } /// `configPublisher` does not load flags into the SDK when the config sent doesn't have a user id. + @MainActor func test_configPublisher_doesNotloadFlagsWhenUserIdIsNil() async throws { configService.configSubject.send( MetaServerConfig( @@ -295,6 +303,7 @@ final class ClientServiceTests: BitwardenTestCase { // swiftlint:disable:this ty } /// `configPublisher` does not load flags into the SDK when the config sent doesn't have a server config. + @MainActor func test_configPublisher_doesNotloadFlagsWhenServerConfigIsNil() async throws { configService.configSubject.send( MetaServerConfig( diff --git a/BitwardenShared/Core/Platform/Services/TestHelpers/MockConfigService.swift b/BitwardenShared/Core/Platform/Services/TestHelpers/MockConfigService.swift index 00236e9930..98a87674ff 100644 --- a/BitwardenShared/Core/Platform/Services/TestHelpers/MockConfigService.swift +++ b/BitwardenShared/Core/Platform/Services/TestHelpers/MockConfigService.swift @@ -3,6 +3,7 @@ import Foundation @testable import BitwardenShared +@MainActor class MockConfigService: ConfigService { // MARK: Properties @@ -16,6 +17,8 @@ class MockConfigService: ConfigService { var refreshDebugFeatureFlagsCalled = false var toggleDebugFeatureFlagCalled = false + nonisolated init() {} + // MARK: Methods func configPublisher( diff --git a/BitwardenShared/UI/Auth/AuthRouterTests.swift b/BitwardenShared/UI/Auth/AuthRouterTests.swift index e5b935ac86..a1805cb7ad 100644 --- a/BitwardenShared/UI/Auth/AuthRouterTests.swift +++ b/BitwardenShared/UI/Auth/AuthRouterTests.swift @@ -224,6 +224,7 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ /// `handleAndRoute(_ :)` redirects `.didCompleteAuth` to `.landing` and doesn't set the /// carousel shown flag if the carousel feature flag is off. + @MainActor func test_handleAndRoute_didCompleteAuth_carouselNotShown() async { authRepository.activeAccount = .fixture() configService.featureFlagsBool[.nativeCarouselFlow] = false @@ -236,6 +237,7 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ /// `handleAndRoute(_ :)` redirects `.didCompleteAuth` to `.landing` and sets the carousel shown /// flag if the carousel feature flag is on and the carousel hasn't been shown yet. + @MainActor func test_handleAndRoute_didCompleteAuth_carouselShown() async { authRepository.activeAccount = .fixture() configService.featureFlagsBool[.nativeCarouselFlow] = true @@ -878,6 +880,7 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ /// `handleAndRoute(_ :)` redirects `.didStart` to `.introCarousel` if there's no accounts and /// the carousel flow is enabled. + @MainActor func test_handleAndRoute_didStart_carouselFlow() async { configService.featureFlagsBool[.nativeCarouselFlow] = true @@ -888,6 +891,7 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ /// `handleAndRoute(_ :)` redirects `.didStart` to `.landing` if there's no accounts, the /// carousel flow is enabled, but the carousel has already been shown. + @MainActor func test_handleAndRoute_didStart_carouselFlow_carouselShown() async { configService.featureFlagsBool[.nativeCarouselFlow] = true stateService.introCarouselShown = true @@ -898,10 +902,11 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ } /// `handleAndRoute(_ :)` redirects `.didStart` to `.landing` if it's running in an extension. + @MainActor func test_handleAndRoute_didStart_carouselFlow_extension() async { configService.featureFlagsBool[.nativeCarouselFlow] = true - subject = await AuthRouter( + subject = AuthRouter( isInAppExtension: true, services: ServiceContainer.withMocks( authRepository: authRepository, @@ -919,6 +924,7 @@ final class AuthRouterTests: BitwardenTestCase { // swiftlint:disable:this type_ /// `handleAndRoute(_ :)` redirects `.didStart` to `.completeWithNeverUnlockKey` if there's an /// existing account with never lock enabled and sets the intro carousel as shown. + @MainActor func test_handleAndRoute_didStart_carouselFlow_existingAccountNeverLock() async { let account = Account.fixture() authRepository.activeAccount = .fixture()