From b660ec332da7bd132d03bb536448292fc8ae7f21 Mon Sep 17 00:00:00 2001 From: Engin Kurutepe Date: Thu, 11 Jul 2024 10:42:03 +0200 Subject: [PATCH 1/2] fix macOS behavior --- Sources/Auth/Internal/Keychain.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/Auth/Internal/Keychain.swift b/Sources/Auth/Internal/Keychain.swift index 9c3ca88d..0d84378f 100644 --- a/Sources/Auth/Internal/Keychain.swift +++ b/Sources/Auth/Internal/Keychain.swift @@ -67,6 +67,11 @@ query[kSecAttrAccessGroup as String] = accessGroup } + // this is highly recommended for all keychain operations and makes the + // macOS keychain item behave like an iOS keychain item + // https://developer.apple.com/documentation/security/ksecusedataprotectionkeychain + query[kSecUseDataProtectionKeychain as String] = kCFBooleanTrue + return query } From f023744122272c2d31eb7585dcc5b11e450ec606 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Thu, 11 Jul 2024 08:02:02 -0300 Subject: [PATCH 2/2] fix failing auth tests --- Tests/AuthTests/SessionManagerTests.swift | 86 +++++++++++------------ 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/Tests/AuthTests/SessionManagerTests.swift b/Tests/AuthTests/SessionManagerTests.swift index d8c9f21c..69ce7753 100644 --- a/Tests/AuthTests/SessionManagerTests.swift +++ b/Tests/AuthTests/SessionManagerTests.swift @@ -41,12 +41,6 @@ final class SessionManagerTests: XCTestCase { ) } - override func invokeTest() { - withMainSerialExecutor { - super.invokeTest() - } - } - func testSession_shouldFailWithSessionNotFound() async { do { _ = try await sut.session() @@ -58,53 +52,57 @@ final class SessionManagerTests: XCTestCase { } func testSession_shouldReturnValidSession() async throws { - let session = Session.validSession - try Dependencies[clientID].sessionStorage.store(session) + try await withMainSerialExecutor { + let session = Session.validSession + try Dependencies[clientID].sessionStorage.store(session) - let returnedSession = try await sut.session() - XCTAssertNoDifference(returnedSession, session) + let returnedSession = try await sut.session() + XCTAssertNoDifference(returnedSession, session) + } } func testSession_shouldRefreshSession_whenCurrentSessionExpired() async throws { - let currentSession = Session.expiredSession - try Dependencies[clientID].sessionStorage.store(currentSession) - - let validSession = Session.validSession - - let refreshSessionCallCount = LockIsolated(0) - - let (refreshSessionStream, refreshSessionContinuation) = AsyncStream.makeStream() - - http.when( - { $0.url.path.contains("/token") }, - return: { _ in - refreshSessionCallCount.withValue { $0 += 1 } - let session = await refreshSessionStream.first(where: { _ in true })! - return .stub(session) + try await withMainSerialExecutor { + let currentSession = Session.expiredSession + try Dependencies[clientID].sessionStorage.store(currentSession) + + let validSession = Session.validSession + + let refreshSessionCallCount = LockIsolated(0) + + let (refreshSessionStream, refreshSessionContinuation) = AsyncStream.makeStream() + + http.when( + { $0.url.path.contains("/token") }, + return: { _ in + refreshSessionCallCount.withValue { $0 += 1 } + let session = await refreshSessionStream.first(where: { _ in true })! + return .stub(session) + } + ) + + // Fire N tasks and call sut.session() + let tasks = (0 ..< 10).map { _ in + Task.detached { [weak self] in + try await self?.sut.session() + } } - ) - // Fire N tasks and call sut.session() - let tasks = (0 ..< 10).map { _ in - Task.detached { [weak self] in - try await self?.sut.session() - } - } + await Task.yield() - await Task.megaYield() + refreshSessionContinuation.yield(validSession) + refreshSessionContinuation.finish() - refreshSessionContinuation.yield(validSession) - refreshSessionContinuation.finish() + // Await for all tasks to complete. + var result: [Result] = [] + for task in tasks { + let value = await task.result + result.append(value) + } - // Await for all tasks to complete. - var result: [Result] = [] - for task in tasks { - let value = await task.result - result.append(value) + // Verify that refresher and storage was called only once. + XCTAssertEqual(refreshSessionCallCount.value, 1) + XCTAssertEqual(try result.map { try $0.get() }, (0 ..< 10).map { _ in validSession }) } - - // Verify that refresher and storage was called only once. - XCTAssertEqual(refreshSessionCallCount.value, 1) - XCTAssertEqual(try result.map { try $0.get() }, (0 ..< 10).map { _ in validSession }) } }