@@ -2151,6 +2151,82 @@ final class AuthClientTests: XCTestCase {
21512151 )
21522152 }
21532153
2154+ func testRemoveSessionAndSignoutIfSessionNotFoundErrorReturned( ) async throws {
2155+ let sut = makeSUT ( )
2156+
2157+ Mock (
2158+ url: clientURL. appendingPathComponent ( " user " ) ,
2159+ statusCode: 403 ,
2160+ data: [
2161+ . get: Data (
2162+ """
2163+ {
2164+ " error_code " : " session_not_found " ,
2165+ " message " : " Session not found "
2166+ }
2167+ """ . utf8
2168+ )
2169+ ]
2170+ )
2171+ . register ( )
2172+
2173+ Dependencies [ sut. clientID] . sessionStorage. store ( . validSession)
2174+
2175+ try await assertAuthStateChanges (
2176+ sut: sut,
2177+ action: {
2178+ do {
2179+ _ = try await sut. user ( )
2180+ XCTFail ( " Expected failure " )
2181+ } catch {
2182+ XCTAssertEqual ( error as? AuthError , . sessionMissing)
2183+ }
2184+ } ,
2185+ expectedEvents: [ . initialSession, . signedOut]
2186+ )
2187+
2188+ XCTAssertNil ( Dependencies [ sut. clientID] . sessionStorage. get ( ) )
2189+ }
2190+
2191+ func testRemoveSessionAndSignoutIfRefreshTokenNotFoundErrorReturned( ) async throws {
2192+ let sut = makeSUT ( )
2193+
2194+ Mock (
2195+ url: clientURL. appendingPathComponent ( " token " ) . appendingQueryItems ( [
2196+ URLQueryItem ( name: " grant_type " , value: " refresh_token " )
2197+ ] ) ,
2198+ statusCode: 403 ,
2199+ data: [
2200+ . post: Data (
2201+ """
2202+ {
2203+ " error_code " : " refresh_token_not_found " ,
2204+ " message " : " Invalid Refresh Token: Refresh Token Not Found "
2205+ }
2206+ """ . utf8
2207+ )
2208+ ]
2209+ )
2210+ . register ( )
2211+
2212+ Dependencies [ sut. clientID] . sessionStorage. store ( . expiredSession)
2213+
2214+ try await assertAuthStateChanges (
2215+ sut: sut,
2216+ action: {
2217+ do {
2218+ _ = try await sut. session
2219+ XCTFail ( " Expected failure " )
2220+ } catch {
2221+ XCTAssertEqual ( error as? AuthError , . sessionMissing)
2222+ }
2223+ } ,
2224+ expectedEvents: [ . signedOut]
2225+ )
2226+
2227+ XCTAssertNil ( Dependencies [ sut. clientID] . sessionStorage. get ( ) )
2228+ }
2229+
21542230 private func makeSUT( flowType: AuthFlowType = . pkce) -> AuthClient {
21552231 let sessionConfiguration = URLSessionConfiguration . default
21562232 sessionConfiguration. protocolClasses = [ MockingURLProtocol . self]
@@ -2198,6 +2274,7 @@ final class AuthClientTests: XCTestCase {
21982274 action: ( ) async throws -> T ,
21992275 expectedEvents: [ AuthChangeEvent ] ,
22002276 expectedSessions: [ Session ? ] ? = nil ,
2277+ timeout: TimeInterval = 2 ,
22012278 fileID: StaticString = #fileID,
22022279 filePath: StaticString = #filePath,
22032280 line: UInt = #line,
@@ -2211,14 +2288,30 @@ final class AuthClientTests: XCTestCase {
22112288
22122289 let result = try await action ( )
22132290
2214- let authStateChanges = await eventsTask. value
2291+ let authStateChanges = try await withTimeout ( interval: timeout) {
2292+ await eventsTask. value
2293+ }
22152294 let events = authStateChanges. map ( \. event)
22162295 let sessions = authStateChanges. map ( \. session)
22172296
2218- expectNoDifference ( events, expectedEvents, fileID: fileID, filePath: filePath, line: line, column: column)
2297+ expectNoDifference (
2298+ events,
2299+ expectedEvents,
2300+ fileID: fileID,
2301+ filePath: filePath,
2302+ line: line,
2303+ column: column
2304+ )
22192305
22202306 if let expectedSessions = expectedSessions {
2221- expectNoDifference ( sessions, expectedSessions, fileID: fileID, filePath: filePath, line: line, column: column)
2307+ expectNoDifference (
2308+ sessions,
2309+ expectedSessions,
2310+ fileID: fileID,
2311+ filePath: filePath,
2312+ line: line,
2313+ column: column
2314+ )
22222315 }
22232316
22242317 return result
0 commit comments