@@ -24,247 +24,247 @@ struct TestLogger: SupabaseLogger {
24
24
}
25
25
26
26
#if !os(Android) && !os(Linux)
27
- @available ( macOS 13 . 0 , iOS 16 . 0 , watchOS 9 . 0 , tvOS 16 . 0 , * )
28
- final class RealtimeIntegrationTests : XCTestCase {
27
+ @available ( macOS 13 . 0 , iOS 16 . 0 , watchOS 9 . 0 , tvOS 16 . 0 , * )
28
+ final class RealtimeIntegrationTests : XCTestCase {
29
29
30
- let testClock = TestClock < Duration > ( )
30
+ let testClock = TestClock < Duration > ( )
31
31
32
- let client = SupabaseClient (
33
- supabaseURL: URL ( string: DotEnv . SUPABASE_URL) ?? URL ( string: " http://localhost:54321 " ) !,
34
- supabaseKey: DotEnv . SUPABASE_ANON_KEY
35
- )
36
-
37
- override func setUp( ) {
38
- super. setUp ( )
32
+ let client = SupabaseClient (
33
+ supabaseURL: URL ( string: DotEnv . SUPABASE_URL) ?? URL ( string: " http://localhost:54321 " ) !,
34
+ supabaseKey: DotEnv . SUPABASE_ANON_KEY
35
+ )
39
36
40
- _clock = testClock
41
- }
37
+ override func setUp ( ) {
38
+ super . setUp ( )
42
39
43
- #if !os(Windows) && !os(Linux) && !os(Android)
44
- override func invokeTest( ) {
45
- withMainSerialExecutor {
46
- super. invokeTest ( )
40
+ _clock = testClock
47
41
}
48
- }
49
- #endif
50
42
51
- func testDisconnectByUser_shouldNotReconnect( ) async {
52
- await client. realtimeV2. connect ( )
53
- let status : RealtimeClientStatus = client. realtimeV2. status
54
- XCTAssertEqual ( status, . connected)
43
+ #if !os(Windows) && !os(Linux) && !os(Android)
44
+ override func invokeTest( ) {
45
+ withMainSerialExecutor {
46
+ super. invokeTest ( )
47
+ }
48
+ }
49
+ #endif
55
50
56
- client. realtimeV2. disconnect ( )
51
+ func testDisconnectByUser_shouldNotReconnect( ) async {
52
+ await client. realtimeV2. connect ( )
53
+ let status : RealtimeClientStatus = client. realtimeV2. status
54
+ XCTAssertEqual ( status, . connected)
57
55
58
- /// Wait for the reconnection delay
59
- await testClock. advance ( by: . seconds( RealtimeClientOptions . defaultReconnectDelay) )
56
+ client. realtimeV2. disconnect ( )
60
57
61
- XCTAssertEqual ( client . realtimeV2 . status , . disconnected )
62
- }
58
+ /// Wait for the reconnection delay
59
+ await testClock . advance ( by : . seconds ( RealtimeClientOptions . defaultReconnectDelay ) )
63
60
64
- func testBroadcast( ) async throws {
65
- let channel = client. realtimeV2. channel ( " integration " ) {
66
- $0. broadcast. receiveOwnBroadcasts = true
61
+ XCTAssertEqual ( client. realtimeV2. status, . disconnected)
67
62
}
68
63
69
- let receivedMessagesTask = Task {
70
- await channel. broadcastStream ( event: " test " ) . prefix ( 3 ) . collect ( )
71
- }
64
+ func testBroadcast( ) async throws {
65
+ let channel = client. realtimeV2. channel ( " integration " ) {
66
+ $0. broadcast. receiveOwnBroadcasts = true
67
+ }
72
68
73
- await Task . yield ( )
69
+ let receivedMessagesTask = Task {
70
+ await channel. broadcastStream ( event: " test " ) . prefix ( 3 ) . collect ( )
71
+ }
74
72
75
- await channel . subscribe ( )
73
+ await Task . yield ( )
76
74
77
- struct Message : Codable {
78
- var value : Int
79
- }
75
+ await channel. subscribe ( )
80
76
81
- try await channel . broadcast ( event : " test " , message : Message ( value : 1 ) )
82
- try await channel . broadcast ( event : " test " , message : Message ( value: 2 ) )
83
- try await channel . broadcast ( event : " test " , message : [ " value " : 3 , " another_value " : 42 ] )
77
+ struct Message : Codable {
78
+ var value : Int
79
+ }
84
80
85
- let receivedMessages = try await withTimeout ( interval : 5 ) {
86
- await receivedMessagesTask . value
87
- }
81
+ try await channel . broadcast ( event : " test " , message : Message ( value : 1 ) )
82
+ try await channel . broadcast ( event : " test " , message : Message ( value: 2 ) )
83
+ try await channel . broadcast ( event : " test " , message : [ " value " : 3 , " another_value " : 42 ] )
88
84
89
- assertInlineSnapshot ( of: receivedMessages, as: . json) {
90
- """
91
- [
92
- {
93
- " event " : " test " ,
94
- " payload " : {
95
- " value " : 1
96
- },
97
- " type " : " broadcast "
98
- },
99
- {
100
- " event " : " test " ,
101
- " payload " : {
102
- " value " : 2
85
+ let receivedMessages = try await withTimeout ( interval: 5 ) {
86
+ await receivedMessagesTask. value
87
+ }
88
+
89
+ assertInlineSnapshot ( of: receivedMessages, as: . json) {
90
+ """
91
+ [
92
+ {
93
+ " event " : " test " ,
94
+ " payload " : {
95
+ " value " : 1
96
+ },
97
+ " type " : " broadcast "
103
98
},
104
- " type " : " broadcast "
105
- },
106
- {
107
- " event " : " test " ,
108
- " payload " : {
109
- " another_value " : 42,
110
- " value " : 3
99
+ {
100
+ " event " : " test " ,
101
+ " payload " : {
102
+ " value " : 2
103
+ },
104
+ " type " : " broadcast "
111
105
},
112
- " type " : " broadcast "
113
- }
114
- ]
115
- """
116
- }
117
-
118
- await channel. unsubscribe ( )
119
- }
120
-
121
- func testBroadcastWithUnsubscribedChannel( ) async throws {
122
- let channel = client. realtimeV2. channel ( " integration " ) {
123
- $0. broadcast. acknowledgeBroadcasts = true
124
- }
125
-
126
- struct Message : Codable {
127
- var value : Int
128
- }
129
-
130
- try await channel. broadcast ( event: " test " , message: Message ( value: 1 ) )
131
- try await channel. broadcast ( event: " test " , message: Message ( value: 2 ) )
132
- try await channel. broadcast ( event: " test " , message: [ " value " : 3 , " another_value " : 42 ] )
133
- }
134
-
135
- func testPresence( ) async throws {
136
- let channel = client. realtimeV2. channel ( " integration " ) {
137
- $0. broadcast. receiveOwnBroadcasts = true
138
- }
139
-
140
- let receivedPresenceChangesTask = Task {
141
- await channel. presenceChange ( ) . prefix ( 4 ) . collect ( )
106
+ {
107
+ " event " : " test " ,
108
+ " payload " : {
109
+ " another_value " : 42,
110
+ " value " : 3
111
+ },
112
+ " type " : " broadcast "
113
+ }
114
+ ]
115
+ """
116
+ }
117
+
118
+ await channel. unsubscribe ( )
142
119
}
143
120
144
- await Task . yield ( )
121
+ func testBroadcastWithUnsubscribedChannel( ) async throws {
122
+ let channel = client. realtimeV2. channel ( " integration " ) {
123
+ $0. broadcast. acknowledgeBroadcasts = true
124
+ }
145
125
146
- await channel. subscribe ( )
126
+ struct Message : Codable {
127
+ var value : Int
128
+ }
147
129
148
- struct UserState : Codable , Equatable {
149
- let email : String
130
+ try await channel. broadcast ( event: " test " , message: Message ( value: 1 ) )
131
+ try await channel. broadcast ( event: " test " , message: Message ( value: 2 ) )
132
+ try await channel. broadcast ( event: " test " , message: [ " value " : 3 , " another_value " : 42 ] )
150
133
}
151
134
152
- try await channel. track ( UserState ( email: " test@supabase.com " ) )
153
- try await channel. track ( [ " email " : " test2@supabase.com " ] )
135
+ func testPresence( ) async throws {
136
+ let channel = client. realtimeV2. channel ( " integration " ) {
137
+ $0. broadcast. receiveOwnBroadcasts = true
138
+ }
154
139
155
- await channel. untrack ( )
140
+ let receivedPresenceChangesTask = Task {
141
+ await channel. presenceChange ( ) . prefix ( 4 ) . collect ( )
142
+ }
156
143
157
- let receivedPresenceChanges = try await withTimeout ( interval: 5 ) {
158
- await receivedPresenceChangesTask. value
159
- }
160
-
161
- let joins = try receivedPresenceChanges. map { try $0. decodeJoins ( as: UserState . self) }
162
- let leaves = try receivedPresenceChanges. map { try $0. decodeLeaves ( as: UserState . self) }
163
- expectNoDifference (
164
- joins,
165
- [
166
- [ ] , // This is the first PRESENCE_STATE event.
167
- [ UserState ( email: " test@supabase.com " ) ] ,
168
- [ UserState ( email: " test2@supabase.com " ) ] ,
169
- [ ] ,
170
- ]
171
- )
172
-
173
- expectNoDifference (
174
- leaves,
175
- [
176
- [ ] , // This is the first PRESENCE_STATE event.
177
- [ ] ,
178
- [ UserState ( email: " test@supabase.com " ) ] ,
179
- [ UserState ( email: " test2@supabase.com " ) ] ,
180
- ]
181
- )
182
-
183
- await channel. unsubscribe ( )
184
- }
185
-
186
- func testPostgresChanges( ) async throws {
187
- let channel = client. realtimeV2. channel ( " db-changes " )
188
-
189
- let receivedInsertActions = Task {
190
- await channel. postgresChange ( InsertAction . self, schema: " public " ) . prefix ( 1 ) . collect ( )
191
- }
144
+ await Task . yield ( )
192
145
193
- let receivedUpdateActions = Task {
194
- await channel. postgresChange ( UpdateAction . self, schema: " public " ) . prefix ( 1 ) . collect ( )
195
- }
146
+ await channel. subscribe ( )
196
147
197
- let receivedDeleteActions = Task {
198
- await channel . postgresChange ( DeleteAction . self , schema : " public " ) . prefix ( 1 ) . collect ( )
199
- }
148
+ struct UserState : Codable , Equatable {
149
+ let email : String
150
+ }
200
151
201
- let receivedAnyActionsTask = Task {
202
- await channel. postgresChange ( AnyAction . self, schema: " public " ) . prefix ( 3 ) . collect ( )
203
- }
152
+ try await channel. track ( UserState ( email: " test@supabase.com " ) )
153
+ try await channel. track ( [ " email " : " test2@supabase.com " ] )
204
154
205
- await Task . yield ( )
206
- await channel. subscribe ( )
155
+ await channel. untrack ( )
207
156
208
- struct Entry : Codable , Equatable {
209
- let key : String
210
- let value : AnyJSON
211
- }
157
+ let receivedPresenceChanges = try await withTimeout ( interval: 5 ) {
158
+ await receivedPresenceChangesTask. value
159
+ }
212
160
213
- // Wait until a system event for makind sure DB change listeners are set before making DB changes.
214
- _ = await channel. system ( ) . first ( where: { _ in true } )
215
-
216
- let key = try await
217
- ( client. from ( " key_value_storage " )
218
- . insert ( [ " key " : AnyJSON . string ( UUID ( ) . uuidString) , " value " : " value1 " ] ) . select ( ) . single ( )
219
- . execute ( ) . value as Entry ) . key
220
- try await client. from ( " key_value_storage " ) . update ( [ " value " : " value2 " ] ) . eq ( " key " , value: key)
221
- . execute ( )
222
- try await client. from ( " key_value_storage " ) . delete ( ) . eq ( " key " , value: key) . execute ( )
223
-
224
- let insertedEntries = try await receivedInsertActions. value. map {
225
- try $0. decodeRecord (
226
- as: Entry . self,
227
- decoder: JSONDecoder ( )
228
- )
229
- }
230
- let updatedEntries = try await receivedUpdateActions. value. map {
231
- try $0. decodeRecord (
232
- as: Entry . self,
233
- decoder: JSONDecoder ( )
161
+ let joins = try receivedPresenceChanges. map { try $0. decodeJoins ( as: UserState . self) }
162
+ let leaves = try receivedPresenceChanges. map { try $0. decodeLeaves ( as: UserState . self) }
163
+ expectNoDifference (
164
+ joins,
165
+ [
166
+ [ ] , // This is the first PRESENCE_STATE event.
167
+ [ UserState ( email: " test@supabase.com " ) ] ,
168
+ [ UserState ( email: " test2@supabase.com " ) ] ,
169
+ [ ] ,
170
+ ]
234
171
)
235
- }
236
- let deletedEntryIds = await receivedDeleteActions. value. compactMap {
237
- $0. oldRecord [ " key " ] ? . stringValue
238
- }
239
172
240
- expectNoDifference ( insertedEntries, [ Entry ( key: key, value: " value1 " ) ] )
241
- expectNoDifference ( updatedEntries, [ Entry ( key: key, value: " value2 " ) ] )
242
- expectNoDifference ( deletedEntryIds, [ key] )
243
-
244
- let receivedAnyActions = await receivedAnyActionsTask. value
245
- XCTAssertEqual ( receivedAnyActions. count, 3 )
246
-
247
- if case let . insert( action) = receivedAnyActions [ 0 ] {
248
- let record = try action. decodeRecord ( as: Entry . self, decoder: JSONDecoder ( ) )
249
- expectNoDifference ( record, Entry ( key: key, value: " value1 " ) )
250
- } else {
251
- XCTFail ( " Expected a `AnyAction.insert` on `receivedAnyActions[0]` " )
252
- }
173
+ expectNoDifference (
174
+ leaves,
175
+ [
176
+ [ ] , // This is the first PRESENCE_STATE event.
177
+ [ ] ,
178
+ [ UserState ( email: " test@supabase.com " ) ] ,
179
+ [ UserState ( email: " test2@supabase.com " ) ] ,
180
+ ]
181
+ )
253
182
254
- if case let . update( action) = receivedAnyActions [ 1 ] {
255
- let record = try action. decodeRecord ( as: Entry . self, decoder: JSONDecoder ( ) )
256
- expectNoDifference ( record, Entry ( key: key, value: " value2 " ) )
257
- } else {
258
- XCTFail ( " Expected a `AnyAction.update` on `receivedAnyActions[1]` " )
183
+ await channel. unsubscribe ( )
259
184
}
260
185
261
- if case let . delete( action) = receivedAnyActions [ 2 ] {
262
- expectNoDifference ( key, action. oldRecord [ " key " ] ? . stringValue)
263
- } else {
264
- XCTFail ( " Expected a `AnyAction.delete` on `receivedAnyActions[2]` " )
186
+ func testPostgresChanges( ) async throws {
187
+ let channel = client. realtimeV2. channel ( " db-changes " )
188
+
189
+ let receivedInsertActions = Task {
190
+ await channel. postgresChange ( InsertAction . self, schema: " public " ) . prefix ( 1 ) . collect ( )
191
+ }
192
+
193
+ let receivedUpdateActions = Task {
194
+ await channel. postgresChange ( UpdateAction . self, schema: " public " ) . prefix ( 1 ) . collect ( )
195
+ }
196
+
197
+ let receivedDeleteActions = Task {
198
+ await channel. postgresChange ( DeleteAction . self, schema: " public " ) . prefix ( 1 ) . collect ( )
199
+ }
200
+
201
+ let receivedAnyActionsTask = Task {
202
+ await channel. postgresChange ( AnyAction . self, schema: " public " ) . prefix ( 3 ) . collect ( )
203
+ }
204
+
205
+ await Task . yield ( )
206
+ await channel. subscribe ( )
207
+
208
+ struct Entry : Codable , Equatable {
209
+ let key : String
210
+ let value : AnyJSON
211
+ }
212
+
213
+ // Wait until a system event for makind sure DB change listeners are set before making DB changes.
214
+ _ = await channel. system ( ) . first ( where: { _ in true } )
215
+
216
+ let key = try await
217
+ ( client. from ( " key_value_storage " )
218
+ . insert ( [ " key " : AnyJSON . string ( UUID ( ) . uuidString) , " value " : " value1 " ] ) . select ( ) . single ( )
219
+ . execute ( ) . value as Entry ) . key
220
+ try await client. from ( " key_value_storage " ) . update ( [ " value " : " value2 " ] ) . eq ( " key " , value: key)
221
+ . execute ( )
222
+ try await client. from ( " key_value_storage " ) . delete ( ) . eq ( " key " , value: key) . execute ( )
223
+
224
+ let insertedEntries = try await receivedInsertActions. value. map {
225
+ try $0. decodeRecord (
226
+ as: Entry . self,
227
+ decoder: JSONDecoder ( )
228
+ )
229
+ }
230
+ let updatedEntries = try await receivedUpdateActions. value. map {
231
+ try $0. decodeRecord (
232
+ as: Entry . self,
233
+ decoder: JSONDecoder ( )
234
+ )
235
+ }
236
+ let deletedEntryIds = await receivedDeleteActions. value. compactMap {
237
+ $0. oldRecord [ " key " ] ? . stringValue
238
+ }
239
+
240
+ expectNoDifference ( insertedEntries, [ Entry ( key: key, value: " value1 " ) ] )
241
+ expectNoDifference ( updatedEntries, [ Entry ( key: key, value: " value2 " ) ] )
242
+ expectNoDifference ( deletedEntryIds, [ key] )
243
+
244
+ let receivedAnyActions = await receivedAnyActionsTask. value
245
+ XCTAssertEqual ( receivedAnyActions. count, 3 )
246
+
247
+ if case let . insert( action) = receivedAnyActions [ 0 ] {
248
+ let record = try action. decodeRecord ( as: Entry . self, decoder: JSONDecoder ( ) )
249
+ expectNoDifference ( record, Entry ( key: key, value: " value1 " ) )
250
+ } else {
251
+ XCTFail ( " Expected a `AnyAction.insert` on `receivedAnyActions[0]` " )
252
+ }
253
+
254
+ if case let . update( action) = receivedAnyActions [ 1 ] {
255
+ let record = try action. decodeRecord ( as: Entry . self, decoder: JSONDecoder ( ) )
256
+ expectNoDifference ( record, Entry ( key: key, value: " value2 " ) )
257
+ } else {
258
+ XCTFail ( " Expected a `AnyAction.update` on `receivedAnyActions[1]` " )
259
+ }
260
+
261
+ if case let . delete( action) = receivedAnyActions [ 2 ] {
262
+ expectNoDifference ( key, action. oldRecord [ " key " ] ? . stringValue)
263
+ } else {
264
+ XCTFail ( " Expected a `AnyAction.delete` on `receivedAnyActions[2]` " )
265
+ }
266
+
267
+ await channel. unsubscribe ( )
265
268
}
266
-
267
- await channel. unsubscribe ( )
268
269
}
269
- }
270
270
#endif
0 commit comments