@@ -17,13 +17,15 @@ import ConcurrencyExtras
17
17
18
18
final class AuthClientTests : XCTestCase {
19
19
var eventEmitter : MockEventEmitter !
20
+ var sessionManager : MockSessionManager !
20
21
21
22
var sut : AuthClient !
22
23
23
24
override func setUp( ) {
24
25
super. setUp ( )
25
26
26
27
eventEmitter = MockEventEmitter ( )
28
+ sessionManager = MockSessionManager ( )
27
29
sut = makeSUT ( )
28
30
}
29
31
@@ -38,66 +40,60 @@ final class AuthClientTests: XCTestCase {
38
40
39
41
sut = nil
40
42
eventEmitter = nil
43
+ sessionManager = nil
41
44
}
42
45
43
46
func testOnAuthStateChanges( ) async {
44
47
let session = Session . validSession
48
+ sessionManager. returnSession = . success( session)
45
49
46
50
let events = LockIsolated ( [ AuthChangeEvent] ( ) )
47
51
48
- await withDependencies {
49
- $0. sessionManager. session = { @Sendable _ in session }
50
- } operation: {
51
- let handle = await sut. onAuthStateChange { event, _ in
52
- events. withValue {
53
- $0. append ( event)
54
- }
52
+ let handle = await sut. onAuthStateChange { event, _ in
53
+ events. withValue {
54
+ $0. append ( event)
55
55
}
56
- addTeardownBlock { [ weak handle] in
57
- XCTAssertNil ( handle, " handle should be deallocated " )
58
- }
59
-
60
- XCTAssertEqual ( events. value, [ . initialSession] )
61
56
}
57
+ addTeardownBlock { [ weak handle] in
58
+ XCTAssertNil ( handle, " handle should be deallocated " )
59
+ }
60
+
61
+ XCTAssertEqual ( events. value, [ . initialSession] )
62
62
}
63
63
64
64
func testAuthStateChanges( ) async throws {
65
65
let session = Session . validSession
66
+ sessionManager. returnSession = . success( session)
66
67
67
68
let events = ActorIsolated ( [ AuthChangeEvent] ( ) )
68
69
69
70
let ( stream, continuation) = AsyncStream< Void> . makeStream( )
70
71
71
- await withDependencies {
72
- $0. sessionManager. session = { @Sendable _ in session }
73
- } operation: {
74
- let authStateStream = await sut. authStateChanges
75
-
76
- let streamTask = Task {
77
- for await (event, _) in authStateStream {
78
- await events. withValue {
79
- $0. append ( event)
80
- }
72
+ let authStateStream = await sut. authStateChanges
81
73
82
- continuation. yield ( )
74
+ let streamTask = Task {
75
+ for await (event, _) in authStateStream {
76
+ await events. withValue {
77
+ $0. append ( event)
83
78
}
79
+
80
+ continuation. yield ( )
84
81
}
82
+ }
85
83
86
- _ = await stream. first { _ in true }
84
+ _ = await stream. first { _ in true }
87
85
88
- let events = await events. value
89
- XCTAssertEqual ( events , [ . initialSession] )
86
+ let receivedEvents = await events. value
87
+ XCTAssertEqual ( receivedEvents , [ . initialSession] )
90
88
91
- streamTask. cancel ( )
92
- }
89
+ streamTask. cancel ( )
93
90
}
94
91
95
92
func testSignOut( ) async throws {
93
+ sessionManager. returnSession = . success( . validSession)
94
+
96
95
try await withDependencies {
97
96
$0. api. execute = { _ in . stub( ) }
98
- $0. sessionManager = . live
99
- $0. sessionStorage = . inMemory
100
- try $0. sessionStorage. storeSession ( StoredSession ( session: . validSession) )
101
97
} operation: {
102
98
try await sut. signOut ( )
103
99
@@ -108,30 +104,27 @@ final class AuthClientTests: XCTestCase {
108
104
XCTFail ( " Unexpected error. " )
109
105
}
110
106
111
- XCTAssertEqual ( eventEmitter. emitReceivedParams. value . map ( \. 0 ) , [ . signedOut] )
107
+ XCTAssertEqual ( eventEmitter. emitReceivedParams. map ( \. 0 ) , [ . signedOut] )
112
108
}
113
109
}
114
110
115
111
func testSignOutWithOthersScopeShouldNotRemoveLocalSession( ) async throws {
112
+ sessionManager. returnSession = . success( . validSession)
113
+
116
114
try await withDependencies {
117
115
$0. api. execute = { _ in . stub( ) }
118
- $0. sessionManager = . live
119
- $0. sessionStorage = . inMemory
120
- try $0. sessionStorage. storeSession ( StoredSession ( session: . validSession) )
121
116
} operation: {
122
117
try await sut. signOut ( scope: . others)
123
118
124
- // Session should still be valid.
125
- _ = try await sut. session
119
+ XCTAssertFalse ( sessionManager. removeCalled)
126
120
}
127
121
}
128
122
129
123
func testSignOutShouldRemoveSessionIfUserIsNotFound( ) async throws {
130
- try await withDependencies {
124
+ sessionManager. returnSession = . success( . validSession)
125
+
126
+ await withDependencies {
131
127
$0. api. execute = { _ in throw AuthError . api ( AuthError . APIError ( code: 404 ) ) }
132
- $0. sessionManager = . live
133
- $0. sessionStorage = . inMemory
134
- try $0. sessionStorage. storeSession ( StoredSession ( session: . validSession) )
135
128
} operation: {
136
129
do {
137
130
try await sut. signOut ( )
@@ -140,23 +133,23 @@ final class AuthClientTests: XCTestCase {
140
133
XCTFail ( " Unexpected error: \( error) " )
141
134
}
142
135
143
- let emitedParams = eventEmitter. emitReceivedParams. value
136
+ let emitedParams = eventEmitter. emitReceivedParams
144
137
let emitedEvents = emitedParams. map ( \. 0 )
145
138
let emitedSessions = emitedParams. map ( \. 1 )
146
139
147
140
XCTAssertEqual ( emitedEvents, [ . signedOut] )
148
141
XCTAssertEqual ( emitedSessions. count, 1 )
149
142
XCTAssertNil ( emitedSessions [ 0 ] )
150
- XCTAssertNil ( try Dependencies . current. value!. sessionStorage. getSession ( ) )
143
+
144
+ XCTAssertEqual ( sessionManager. removeCallCount, 1 )
151
145
}
152
146
}
153
147
154
148
func testSignOutShouldRemoveSessionIfJWTIsInvalid( ) async throws {
155
- try await withDependencies {
149
+ sessionManager. returnSession = . success( . validSession)
150
+
151
+ await withDependencies {
156
152
$0. api. execute = { _ in throw AuthError . api ( AuthError . APIError ( code: 401 ) ) }
157
- $0. sessionManager = . live
158
- $0. sessionStorage = . inMemory
159
- try $0. sessionStorage. storeSession ( StoredSession ( session: . validSession) )
160
153
} operation: {
161
154
do {
162
155
try await sut. signOut ( )
@@ -165,14 +158,15 @@ final class AuthClientTests: XCTestCase {
165
158
XCTFail ( " Unexpected error: \( error) " )
166
159
}
167
160
168
- let emitedParams = eventEmitter. emitReceivedParams. value
161
+ let emitedParams = eventEmitter. emitReceivedParams
169
162
let emitedEvents = emitedParams. map ( \. 0 )
170
163
let emitedSessions = emitedParams. map ( \. 1 )
171
164
172
165
XCTAssertEqual ( emitedEvents, [ . signedOut] )
173
166
XCTAssertEqual ( emitedSessions. count, 1 )
174
167
XCTAssertNil ( emitedSessions [ 0 ] )
175
- XCTAssertNil ( try Dependencies . current. value!. sessionStorage. getSession ( ) )
168
+
169
+ XCTAssertEqual ( sessionManager. removeCallCount, 1 )
176
170
}
177
171
}
178
172
@@ -186,7 +180,7 @@ final class AuthClientTests: XCTestCase {
186
180
187
181
let sut = AuthClient (
188
182
configuration: configuration,
189
- sessionManager: . mock ,
183
+ sessionManager: sessionManager ,
190
184
codeVerifierStorage: . mock,
191
185
api: . mock,
192
186
eventEmitter: eventEmitter,
0 commit comments