From b4573b9dac5134ee713625da9d6cd9db8aaf2622 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Sat, 17 Feb 2024 09:55:43 -0300 Subject: [PATCH] refactor: simplify auth tests mocks --- Sources/Auth/AuthClient.swift | 4 +- Sources/Auth/Internal/EventEmitter.swift | 33 ++- Sources/Auth/Internal/SessionManager.swift | 29 +- Tests/AuthTests/AuthClientTests.swift | 94 +++---- Tests/AuthTests/Mocks/MockEventEmitter.swift | 20 +- .../AuthTests/Mocks/MockSessionManager.swift | 35 +++ Tests/AuthTests/Mocks/Mocks.swift | 12 +- Tests/AuthTests/RequestsTests.swift | 257 ++++++++---------- Tests/AuthTests/SessionManagerTests.swift | 6 +- 9 files changed, 251 insertions(+), 239 deletions(-) create mode 100644 Tests/AuthTests/Mocks/MockSessionManager.swift diff --git a/Sources/Auth/AuthClient.swift b/Sources/Auth/AuthClient.swift index be33b31b..9d3b579c 100644 --- a/Sources/Auth/AuthClient.swift +++ b/Sources/Auth/AuthClient.swift @@ -166,10 +166,10 @@ public actor AuthClient { self.init( configuration: configuration, - sessionManager: .live, + sessionManager: DefaultSessionManager.shared, codeVerifierStorage: .live, api: api, - eventEmitter: EventEmitter(), + eventEmitter: DefaultEventEmitter.shared, sessionStorage: .live, logger: configuration.logger ) diff --git a/Sources/Auth/Internal/EventEmitter.swift b/Sources/Auth/Internal/EventEmitter.swift index 0eff28ad..3dcbc53d 100644 --- a/Sources/Auth/Internal/EventEmitter.swift +++ b/Sources/Auth/Internal/EventEmitter.swift @@ -1,12 +1,37 @@ import ConcurrencyExtras import Foundation -class EventEmitter: @unchecked Sendable { +protocol EventEmitter: Sendable { + func attachListener( + _ listener: @escaping AuthStateChangeListener + ) -> AuthStateChangeListenerHandle + + func emit( + _ event: AuthChangeEvent, + session: Session?, + handle: AuthStateChangeListenerHandle? + ) +} + +extension EventEmitter { + func emit( + _ event: AuthChangeEvent, + session: Session? + ) { + emit(event, session: session, handle: nil) + } +} + +final class DefaultEventEmitter: EventEmitter { + static let shared = DefaultEventEmitter() + + private init() {} + let listeners = LockIsolated<[ObjectIdentifier: AuthStateChangeListener]>([:]) - func attachListener(_ listener: @escaping AuthStateChangeListener) - -> AuthStateChangeListenerHandle - { + func attachListener( + _ listener: @escaping AuthStateChangeListener + ) -> AuthStateChangeListenerHandle { let handle = AuthStateChangeListenerHandle() let key = ObjectIdentifier(handle) diff --git a/Sources/Auth/Internal/SessionManager.swift b/Sources/Auth/Internal/SessionManager.swift index c8855e54..fab67070 100644 --- a/Sources/Auth/Internal/SessionManager.swift +++ b/Sources/Auth/Internal/SessionManager.swift @@ -5,28 +5,23 @@ struct SessionRefresher: Sendable { var refreshSession: @Sendable (_ refreshToken: String) async throws -> Session } -struct SessionManager: Sendable { - var session: @Sendable (_ shouldValidateExpiration: Bool) async throws -> Session - var update: @Sendable (_ session: Session) async throws -> Void - var remove: @Sendable () async -> Void - - func session(shouldValidateExpiration: Bool = true) async throws -> Session { - try await session(shouldValidateExpiration) - } +protocol SessionManager: Sendable { + func session(shouldValidateExpiration: Bool) async throws -> Session + func update(_ session: Session) async throws -> Void + func remove() async } extension SessionManager { - static var live: Self = { - let manager = _LiveSessionManager() - return Self( - session: { try await manager.session(shouldValidateExpiration: $0) }, - update: { try await manager.update($0) }, - remove: { await manager.remove() } - ) - }() + func session() async throws -> Session { + try await session(shouldValidateExpiration: true) + } } -actor _LiveSessionManager { +actor DefaultSessionManager: SessionManager { + static let shared = DefaultSessionManager() + + private init() {} + private var task: Task? private var storage: SessionStorage { diff --git a/Tests/AuthTests/AuthClientTests.swift b/Tests/AuthTests/AuthClientTests.swift index e4575426..cb89723c 100644 --- a/Tests/AuthTests/AuthClientTests.swift +++ b/Tests/AuthTests/AuthClientTests.swift @@ -17,6 +17,7 @@ import ConcurrencyExtras final class AuthClientTests: XCTestCase { var eventEmitter: MockEventEmitter! + var sessionManager: MockSessionManager! var sut: AuthClient! @@ -24,6 +25,7 @@ final class AuthClientTests: XCTestCase { super.setUp() eventEmitter = MockEventEmitter() + sessionManager = MockSessionManager() sut = makeSUT() } @@ -38,66 +40,60 @@ final class AuthClientTests: XCTestCase { sut = nil eventEmitter = nil + sessionManager = nil } func testOnAuthStateChanges() async { let session = Session.validSession + sessionManager.returnSession = .success(session) let events = LockIsolated([AuthChangeEvent]()) - await withDependencies { - $0.sessionManager.session = { @Sendable _ in session } - } operation: { - let handle = await sut.onAuthStateChange { event, _ in - events.withValue { - $0.append(event) - } + let handle = await sut.onAuthStateChange { event, _ in + events.withValue { + $0.append(event) } - addTeardownBlock { [weak handle] in - XCTAssertNil(handle, "handle should be deallocated") - } - - XCTAssertEqual(events.value, [.initialSession]) } + addTeardownBlock { [weak handle] in + XCTAssertNil(handle, "handle should be deallocated") + } + + XCTAssertEqual(events.value, [.initialSession]) } func testAuthStateChanges() async throws { let session = Session.validSession + sessionManager.returnSession = .success(session) let events = ActorIsolated([AuthChangeEvent]()) let (stream, continuation) = AsyncStream.makeStream() - await withDependencies { - $0.sessionManager.session = { @Sendable _ in session } - } operation: { - let authStateStream = await sut.authStateChanges - - let streamTask = Task { - for await (event, _) in authStateStream { - await events.withValue { - $0.append(event) - } + let authStateStream = await sut.authStateChanges - continuation.yield() + let streamTask = Task { + for await (event, _) in authStateStream { + await events.withValue { + $0.append(event) } + + continuation.yield() } + } - _ = await stream.first { _ in true } + _ = await stream.first { _ in true } - let events = await events.value - XCTAssertEqual(events, [.initialSession]) + let receivedEvents = await events.value + XCTAssertEqual(receivedEvents, [.initialSession]) - streamTask.cancel() - } + streamTask.cancel() } func testSignOut() async throws { + sessionManager.returnSession = .success(.validSession) + try await withDependencies { $0.api.execute = { _ in .stub() } - $0.sessionManager = .live - $0.sessionStorage = .inMemory - try $0.sessionStorage.storeSession(StoredSession(session: .validSession)) } operation: { try await sut.signOut() @@ -108,30 +104,27 @@ final class AuthClientTests: XCTestCase { XCTFail("Unexpected error.") } - XCTAssertEqual(eventEmitter.emitReceivedParams.value.map(\.0), [.signedOut]) + XCTAssertEqual(eventEmitter.emitReceivedParams.map(\.0), [.signedOut]) } } func testSignOutWithOthersScopeShouldNotRemoveLocalSession() async throws { + sessionManager.returnSession = .success(.validSession) + try await withDependencies { $0.api.execute = { _ in .stub() } - $0.sessionManager = .live - $0.sessionStorage = .inMemory - try $0.sessionStorage.storeSession(StoredSession(session: .validSession)) } operation: { try await sut.signOut(scope: .others) - // Session should still be valid. - _ = try await sut.session + XCTAssertFalse(sessionManager.removeCalled) } } func testSignOutShouldRemoveSessionIfUserIsNotFound() async throws { - try await withDependencies { + sessionManager.returnSession = .success(.validSession) + + await withDependencies { $0.api.execute = { _ in throw AuthError.api(AuthError.APIError(code: 404)) } - $0.sessionManager = .live - $0.sessionStorage = .inMemory - try $0.sessionStorage.storeSession(StoredSession(session: .validSession)) } operation: { do { try await sut.signOut() @@ -140,23 +133,23 @@ final class AuthClientTests: XCTestCase { XCTFail("Unexpected error: \(error)") } - let emitedParams = eventEmitter.emitReceivedParams.value + let emitedParams = eventEmitter.emitReceivedParams let emitedEvents = emitedParams.map(\.0) let emitedSessions = emitedParams.map(\.1) XCTAssertEqual(emitedEvents, [.signedOut]) XCTAssertEqual(emitedSessions.count, 1) XCTAssertNil(emitedSessions[0]) - XCTAssertNil(try Dependencies.current.value!.sessionStorage.getSession()) + + XCTAssertEqual(sessionManager.removeCallCount, 1) } } func testSignOutShouldRemoveSessionIfJWTIsInvalid() async throws { - try await withDependencies { + sessionManager.returnSession = .success(.validSession) + + await withDependencies { $0.api.execute = { _ in throw AuthError.api(AuthError.APIError(code: 401)) } - $0.sessionManager = .live - $0.sessionStorage = .inMemory - try $0.sessionStorage.storeSession(StoredSession(session: .validSession)) } operation: { do { try await sut.signOut() @@ -165,14 +158,15 @@ final class AuthClientTests: XCTestCase { XCTFail("Unexpected error: \(error)") } - let emitedParams = eventEmitter.emitReceivedParams.value + let emitedParams = eventEmitter.emitReceivedParams let emitedEvents = emitedParams.map(\.0) let emitedSessions = emitedParams.map(\.1) XCTAssertEqual(emitedEvents, [.signedOut]) XCTAssertEqual(emitedSessions.count, 1) XCTAssertNil(emitedSessions[0]) - XCTAssertNil(try Dependencies.current.value!.sessionStorage.getSession()) + + XCTAssertEqual(sessionManager.removeCallCount, 1) } } @@ -186,7 +180,7 @@ final class AuthClientTests: XCTestCase { let sut = AuthClient( configuration: configuration, - sessionManager: .mock, + sessionManager: sessionManager, codeVerifierStorage: .mock, api: .mock, eventEmitter: eventEmitter, diff --git a/Tests/AuthTests/Mocks/MockEventEmitter.swift b/Tests/AuthTests/Mocks/MockEventEmitter.swift index 199af704..7fe75f58 100644 --- a/Tests/AuthTests/Mocks/MockEventEmitter.swift +++ b/Tests/AuthTests/Mocks/MockEventEmitter.swift @@ -10,16 +10,28 @@ import ConcurrencyExtras import Foundation final class MockEventEmitter: EventEmitter { - let emitReceivedParams: LockIsolated<[(AuthChangeEvent, Session?)]> = .init([]) + private let emitter = DefaultEventEmitter.shared - override func emit( + func attachListener(_ listener: @escaping AuthStateChangeListener) + -> AuthStateChangeListenerHandle + { + emitter.attachListener(listener) + } + + private let _emitReceivedParams: LockIsolated<[(AuthChangeEvent, Session?)]> = .init([]) + var emitReceivedParams: [(AuthChangeEvent, Session?)] { + _emitReceivedParams.value + } + + func emit( _ event: AuthChangeEvent, session: Session?, handle: AuthStateChangeListenerHandle? = nil ) { - emitReceivedParams.withValue { + _emitReceivedParams.withValue { $0.append((event, session)) } - super.emit(event, session: session, handle: handle) + + emitter.emit(event, session: session, handle: handle) } } diff --git a/Tests/AuthTests/Mocks/MockSessionManager.swift b/Tests/AuthTests/Mocks/MockSessionManager.swift new file mode 100644 index 00000000..10b62a34 --- /dev/null +++ b/Tests/AuthTests/Mocks/MockSessionManager.swift @@ -0,0 +1,35 @@ +// +// MockSessionManager.swift +// +// +// Created by Guilherme Souza on 16/02/24. +// + +@testable import Auth +import ConcurrencyExtras +import Foundation + +final class MockSessionManager: SessionManager { + private let _returnSession = LockIsolated(Result?.none) + var returnSession: Result? { + get { _returnSession.value } + set { _returnSession.setValue(newValue) } + } + + func session(shouldValidateExpiration _: Bool) async throws -> Auth.Session { + try returnSession!.get() + } + + func update(_: Auth.Session) async throws {} + + private let _removeCallCount = LockIsolated(0) + var removeCallCount: Int { + get { _removeCallCount.value } + set { _removeCallCount.setValue(newValue) } + } + + var removeCalled: Bool { removeCallCount > 0 } + func remove() async { + _removeCallCount.withValue { $0 += 1 } + } +} diff --git a/Tests/AuthTests/Mocks/Mocks.swift b/Tests/AuthTests/Mocks/Mocks.swift index 0b8c12b1..0ae42563 100644 --- a/Tests/AuthTests/Mocks/Mocks.swift +++ b/Tests/AuthTests/Mocks/Mocks.swift @@ -22,14 +22,6 @@ extension CodeVerifierStorage { ) } -extension SessionManager { - static let mock = Self( - session: unimplemented("SessionManager.session"), - update: unimplemented("SessionManager.update"), - remove: unimplemented("SessionManager.remove") - ) -} - extension SessionStorage { static let mock = Self( getSession: unimplemented("SessionStorage.getSession"), @@ -101,9 +93,9 @@ extension Dependencies { localStorage: Self.localStorage, logger: nil ), - sessionManager: .mock, + sessionManager: MockSessionManager(), api: .mock, - eventEmitter: EventEmitter(), + eventEmitter: MockEventEmitter(), sessionStorage: .mock, sessionRefresher: .mock, codeVerifierStorage: .mock, diff --git a/Tests/AuthTests/RequestsTests.swift b/Tests/AuthTests/RequestsTests.swift index 0360c343..26058294 100644 --- a/Tests/AuthTests/RequestsTests.swift +++ b/Tests/AuthTests/RequestsTests.swift @@ -18,125 +18,105 @@ import XCTest struct UnimplementedError: Error {} final class RequestsTests: XCTestCase { + var sessionManager: MockSessionManager! + + override func setUp() { + super.setUp() + + sessionManager = MockSessionManager() + } + func testSignUpWithEmailAndPassword() async { let sut = makeSUT() - await withDependencies { - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.signUp( - email: "example@mail.com", - password: "the.pass", - data: ["custom_key": .string("custom_value")], - redirectTo: URL(string: "https://supabase.com"), - captchaToken: "dummy-captcha" - ) - } + await assert { + try await sut.signUp( + email: "example@mail.com", + password: "the.pass", + data: ["custom_key": .string("custom_value")], + redirectTo: URL(string: "https://supabase.com"), + captchaToken: "dummy-captcha" + ) } } func testSignUpWithPhoneAndPassword() async { let sut = makeSUT() - await withDependencies { - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.signUp( - phone: "+1 202-918-2132", - password: "the.pass", - data: ["custom_key": .string("custom_value")], - captchaToken: "dummy-captcha" - ) - } + await assert { + try await sut.signUp( + phone: "+1 202-918-2132", + password: "the.pass", + data: ["custom_key": .string("custom_value")], + captchaToken: "dummy-captcha" + ) } } func testSignInWithEmailAndPassword() async { let sut = makeSUT() - await withDependencies { - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.signIn( - email: "example@mail.com", - password: "the.pass" - ) - } + await assert { + try await sut.signIn( + email: "example@mail.com", + password: "the.pass" + ) } } func testSignInWithPhoneAndPassword() async { let sut = makeSUT() - await withDependencies { - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.signIn( - phone: "+1 202-918-2132", - password: "the.pass" - ) - } + await assert { + try await sut.signIn( + phone: "+1 202-918-2132", + password: "the.pass" + ) } } func testSignInWithIdToken() async { let sut = makeSUT() - await withDependencies { - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.signInWithIdToken( - credentials: OpenIDConnectCredentials( - provider: .apple, - idToken: "id-token", - accessToken: "access-token", - nonce: "nonce", - gotrueMetaSecurity: AuthMetaSecurity( - captchaToken: "captcha-token" - ) + await assert { + try await sut.signInWithIdToken( + credentials: OpenIDConnectCredentials( + provider: .apple, + idToken: "id-token", + accessToken: "access-token", + nonce: "nonce", + gotrueMetaSecurity: AuthMetaSecurity( + captchaToken: "captcha-token" ) ) - } + ) } } func testSignInWithOTPUsingEmail() async { let sut = makeSUT() - await withDependencies { - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.signInWithOTP( - email: "example@mail.com", - redirectTo: URL(string: "https://supabase.com"), - shouldCreateUser: true, - data: ["custom_key": .string("custom_value")], - captchaToken: "dummy-captcha" - ) - } + await assert { + try await sut.signInWithOTP( + email: "example@mail.com", + redirectTo: URL(string: "https://supabase.com"), + shouldCreateUser: true, + data: ["custom_key": .string("custom_value")], + captchaToken: "dummy-captcha" + ) } } func testSignInWithOTPUsingPhone() async { let sut = makeSUT() - await withDependencies { - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.signInWithOTP( - phone: "+1 202-918-2132", - shouldCreateUser: true, - data: ["custom_key": .string("custom_value")], - captchaToken: "dummy-captcha" - ) - } + await assert { + try await sut.signInWithOTP( + phone: "+1 202-918-2132", + shouldCreateUser: true, + data: ["custom_key": .string("custom_value")], + captchaToken: "dummy-captcha" + ) } } @@ -176,7 +156,6 @@ final class RequestsTests: XCTestCase { let currentDate = Date() try await withDependencies { - $0.sessionManager.update = { _ in } $0.sessionStorage.storeSession = { _ in } $0.codeVerifierStorage.getCodeVerifier = { nil } $0.currentDate = { currentDate } @@ -222,19 +201,15 @@ final class RequestsTests: XCTestCase { } func testSetSessionWithAFutureExpirationDate() async throws { + sessionManager.returnSession = .success(.validSession) + let sut = makeSUT() - await withDependencies { - $0.sessionManager.session = { @Sendable _ in - .validSession - } - } operation: { - let accessToken = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjo0ODUyMTYzNTkzLCJzdWIiOiJmMzNkM2VjOS1hMmVlLTQ3YzQtODBlMS01YmQ5MTlmM2Q4YjgiLCJlbWFpbCI6ImhpQGJpbmFyeXNjcmFwaW5nLmNvIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwidXNlcl9tZXRhZGF0YSI6e30sInJvbGUiOiJhdXRoZW50aWNhdGVkIn0.UiEhoahP9GNrBKw_OHBWyqYudtoIlZGkrjs7Qa8hU7I" + let accessToken = + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjo0ODUyMTYzNTkzLCJzdWIiOiJmMzNkM2VjOS1hMmVlLTQ3YzQtODBlMS01YmQ5MTlmM2Q4YjgiLCJlbWFpbCI6ImhpQGJpbmFyeXNjcmFwaW5nLmNvIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwidXNlcl9tZXRhZGF0YSI6e30sInJvbGUiOiJhdXRoZW50aWNhdGVkIn0.UiEhoahP9GNrBKw_OHBWyqYudtoIlZGkrjs7Qa8hU7I" - await assert { - try await sut.setSession(accessToken: accessToken, refreshToken: "dummy-refresh-token") - } + await assert { + try await sut.setSession(accessToken: accessToken, refreshToken: "dummy-refresh-token") } } @@ -250,94 +225,77 @@ final class RequestsTests: XCTestCase { } func testSignOut() async { + sessionManager.returnSession = .success(.validSession) + let sut = makeSUT() - await withDependencies { - $0.sessionManager.session = { @Sendable _ in .validSession } - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.signOut() - } + + await assert { + try await sut.signOut() } } func testSignOutWithLocalScope() async { + sessionManager.returnSession = .success(.validSession) + let sut = makeSUT() - await withDependencies { - $0.sessionManager.session = { @Sendable _ in .validSession } - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.signOut(scope: .local) - } + + await assert { + try await sut.signOut(scope: .local) } } func testSignOutWithOthersScope() async { + sessionManager.returnSession = .success(.validSession) + let sut = makeSUT() - await withDependencies { - $0.sessionManager.session = { @Sendable _ in .validSession } - } operation: { - await assert { - try await sut.signOut(scope: .others) - } + + await assert { + try await sut.signOut(scope: .others) } } func testVerifyOTPUsingEmail() async { let sut = makeSUT() - await withDependencies { - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.verifyOTP( - email: "example@mail.com", - token: "123456", - type: .magiclink, - redirectTo: URL(string: "https://supabase.com"), - captchaToken: "captcha-token" - ) - } + await assert { + try await sut.verifyOTP( + email: "example@mail.com", + token: "123456", + type: .magiclink, + redirectTo: URL(string: "https://supabase.com"), + captchaToken: "captcha-token" + ) } } func testVerifyOTPUsingPhone() async { let sut = makeSUT() - await withDependencies { - $0.sessionManager.remove = {} - } operation: { - await assert { - try await sut.verifyOTP( - phone: "+1 202-918-2132", - token: "123456", - type: .sms, - captchaToken: "captcha-token" - ) - } + await assert { + try await sut.verifyOTP( + phone: "+1 202-918-2132", + token: "123456", + type: .sms, + captchaToken: "captcha-token" + ) } } func testUpdateUser() async throws { + sessionManager.returnSession = .success(.validSession) + let sut = makeSUT() - await withDependencies { - $0.sessionManager.session = { @Sendable _ in - .validSession - } - } operation: { - await assert { - try await sut.update( - user: UserAttributes( - email: "example@mail.com", - phone: "+1 202-918-2132", - password: "another.pass", - emailChangeToken: "123456", - data: ["custom_key": .string("custom_value")] - ) + await assert { + try await sut.update( + user: UserAttributes( + email: "example@mail.com", + phone: "+1 202-918-2132", + password: "another.pass", + emailChangeToken: "123456", + data: ["custom_key": .string("custom_value")] ) - } + ) } } @@ -411,6 +369,7 @@ final class RequestsTests: XCTestCase { headers: ["Apikey": "dummy.api.key", "X-Client-Info": "gotrue-swift/x.y.z"], flowType: flowType, localStorage: InMemoryLocalStorage(), + logger: nil, encoder: encoder, fetch: { request in DispatchQueue.main.sync { @@ -431,10 +390,10 @@ final class RequestsTests: XCTestCase { return AuthClient( configuration: configuration, - sessionManager: .mock, + sessionManager: sessionManager, codeVerifierStorage: .mock, api: api, - eventEmitter: EventEmitter(), + eventEmitter: MockEventEmitter(), sessionStorage: .mock, logger: nil ) diff --git a/Tests/AuthTests/SessionManagerTests.swift b/Tests/AuthTests/SessionManagerTests.swift index 78f328d8..782d06f1 100644 --- a/Tests/AuthTests/SessionManagerTests.swift +++ b/Tests/AuthTests/SessionManagerTests.swift @@ -23,7 +23,7 @@ final class SessionManagerTests: XCTestCase { await withDependencies { $0.sessionStorage.getSession = { nil } } operation: { - let sut = SessionManager.live + let sut = DefaultSessionManager.shared do { _ = try await sut.session() @@ -41,7 +41,7 @@ final class SessionManagerTests: XCTestCase { .init(session: .validSession) } } operation: { - let sut = SessionManager.live + let sut = DefaultSessionManager.shared let session = try await sut.session() XCTAssertEqual(session, .validSession) @@ -71,7 +71,7 @@ final class SessionManagerTests: XCTestCase { return await refreshSessionStream.first { _ in true } ?? .empty } } operation: { - let sut = SessionManager.live + let sut = DefaultSessionManager.shared // Fire N tasks and call sut.session() let tasks = (0 ..< 10).map { _ in