1
+ //
2
+ // PostgresActionTests.swift
3
+ // Supabase
4
+ //
5
+ // Created by Guilherme Souza on 29/07/25.
6
+ //
7
+
8
+ import XCTest
9
+
10
+ @testable import Realtime
11
+
12
+ final class PostgresActionTests : XCTestCase {
13
+ private let sampleMessage = RealtimeMessageV2 (
14
+ joinRef: nil ,
15
+ ref: nil ,
16
+ topic: " test:table " ,
17
+ event: " postgres_changes " ,
18
+ payload: [ : ]
19
+ )
20
+
21
+ private let sampleColumns = [
22
+ Column ( name: " id " , type: " int8 " ) ,
23
+ Column ( name: " name " , type: " text " ) ,
24
+ Column ( name: " email " , type: " text " )
25
+ ]
26
+
27
+ private let sampleDate = Date ( timeIntervalSince1970: 1722246000 ) // Fixed timestamp for consistency
28
+
29
+ func testColumnEquality( ) {
30
+ let column1 = Column ( name: " id " , type: " int8 " )
31
+ let column2 = Column ( name: " id " , type: " int8 " )
32
+ let column3 = Column ( name: " email " , type: " text " )
33
+
34
+ XCTAssertEqual ( column1, column2)
35
+ XCTAssertNotEqual ( column1, column3)
36
+ }
37
+
38
+ func testInsertActionEventType( ) {
39
+ XCTAssertEqual ( InsertAction . eventType, . insert)
40
+ }
41
+
42
+ func testInsertActionProperties( ) {
43
+ let record : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John " ) ]
44
+ let insertAction = InsertAction (
45
+ columns: sampleColumns,
46
+ commitTimestamp: sampleDate,
47
+ record: record,
48
+ rawMessage: sampleMessage
49
+ )
50
+
51
+ XCTAssertEqual ( insertAction. columns, sampleColumns)
52
+ XCTAssertEqual ( insertAction. commitTimestamp, sampleDate)
53
+ XCTAssertEqual ( insertAction. record, record)
54
+ XCTAssertEqual ( insertAction. rawMessage. topic, " test:table " )
55
+ }
56
+
57
+ func testUpdateActionEventType( ) {
58
+ XCTAssertEqual ( UpdateAction . eventType, . update)
59
+ }
60
+
61
+ func testUpdateActionProperties( ) {
62
+ let record : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John Updated " ) ]
63
+ let oldRecord : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John " ) ]
64
+
65
+ let updateAction = UpdateAction (
66
+ columns: sampleColumns,
67
+ commitTimestamp: sampleDate,
68
+ record: record,
69
+ oldRecord: oldRecord,
70
+ rawMessage: sampleMessage
71
+ )
72
+
73
+ XCTAssertEqual ( updateAction. columns, sampleColumns)
74
+ XCTAssertEqual ( updateAction. commitTimestamp, sampleDate)
75
+ XCTAssertEqual ( updateAction. record, record)
76
+ XCTAssertEqual ( updateAction. oldRecord, oldRecord)
77
+ XCTAssertEqual ( updateAction. rawMessage. topic, " test:table " )
78
+ }
79
+
80
+ func testDeleteActionEventType( ) {
81
+ XCTAssertEqual ( DeleteAction . eventType, . delete)
82
+ }
83
+
84
+ func testDeleteActionProperties( ) {
85
+ let oldRecord : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John " ) ]
86
+
87
+ let deleteAction = DeleteAction (
88
+ columns: sampleColumns,
89
+ commitTimestamp: sampleDate,
90
+ oldRecord: oldRecord,
91
+ rawMessage: sampleMessage
92
+ )
93
+
94
+ XCTAssertEqual ( deleteAction. columns, sampleColumns)
95
+ XCTAssertEqual ( deleteAction. commitTimestamp, sampleDate)
96
+ XCTAssertEqual ( deleteAction. oldRecord, oldRecord)
97
+ XCTAssertEqual ( deleteAction. rawMessage. topic, " test:table " )
98
+ }
99
+
100
+ func testAnyActionEventType( ) {
101
+ XCTAssertEqual ( AnyAction . eventType, . all)
102
+ }
103
+
104
+ func testAnyActionInsertCase( ) {
105
+ let record : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John " ) ]
106
+ let insertAction = InsertAction (
107
+ columns: sampleColumns,
108
+ commitTimestamp: sampleDate,
109
+ record: record,
110
+ rawMessage: sampleMessage
111
+ )
112
+
113
+ let anyAction = AnyAction . insert ( insertAction)
114
+ XCTAssertEqual ( anyAction. rawMessage. topic, " test:table " )
115
+
116
+ if case let . insert( wrappedAction) = anyAction {
117
+ XCTAssertEqual ( wrappedAction. record, record)
118
+ } else {
119
+ XCTFail ( " Expected insert case " )
120
+ }
121
+ }
122
+
123
+ func testAnyActionUpdateCase( ) {
124
+ let record : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John Updated " ) ]
125
+ let oldRecord : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John " ) ]
126
+
127
+ let updateAction = UpdateAction (
128
+ columns: sampleColumns,
129
+ commitTimestamp: sampleDate,
130
+ record: record,
131
+ oldRecord: oldRecord,
132
+ rawMessage: sampleMessage
133
+ )
134
+
135
+ let anyAction = AnyAction . update ( updateAction)
136
+ XCTAssertEqual ( anyAction. rawMessage. topic, " test:table " )
137
+
138
+ if case let . update( wrappedAction) = anyAction {
139
+ XCTAssertEqual ( wrappedAction. record, record)
140
+ XCTAssertEqual ( wrappedAction. oldRecord, oldRecord)
141
+ } else {
142
+ XCTFail ( " Expected update case " )
143
+ }
144
+ }
145
+
146
+ func testAnyActionDeleteCase( ) {
147
+ let oldRecord : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John " ) ]
148
+
149
+ let deleteAction = DeleteAction (
150
+ columns: sampleColumns,
151
+ commitTimestamp: sampleDate,
152
+ oldRecord: oldRecord,
153
+ rawMessage: sampleMessage
154
+ )
155
+
156
+ let anyAction = AnyAction . delete ( deleteAction)
157
+ XCTAssertEqual ( anyAction. rawMessage. topic, " test:table " )
158
+
159
+ if case let . delete( wrappedAction) = anyAction {
160
+ XCTAssertEqual ( wrappedAction. oldRecord, oldRecord)
161
+ } else {
162
+ XCTFail ( " Expected delete case " )
163
+ }
164
+ }
165
+
166
+ func testAnyActionEquality( ) {
167
+ let record : JSONObject = [ " id " : . string( " 123 " ) ]
168
+ let insertAction1 = InsertAction (
169
+ columns: sampleColumns,
170
+ commitTimestamp: sampleDate,
171
+ record: record,
172
+ rawMessage: sampleMessage
173
+ )
174
+ let insertAction2 = InsertAction (
175
+ columns: sampleColumns,
176
+ commitTimestamp: sampleDate,
177
+ record: record,
178
+ rawMessage: sampleMessage
179
+ )
180
+
181
+ let anyAction1 = AnyAction . insert ( insertAction1)
182
+ let anyAction2 = AnyAction . insert ( insertAction2)
183
+
184
+ XCTAssertEqual ( anyAction1, anyAction2)
185
+ }
186
+
187
+ func testDecodeRecord( ) throws {
188
+ struct TestRecord : Codable , Equatable {
189
+ let id : String
190
+ let name : String
191
+ let email : String ?
192
+ }
193
+
194
+ let record : JSONObject = [
195
+ " id " : . string( " 123 " ) ,
196
+ " name " : . string( " John " ) ,
197
+ " email " : . string( " john@example.com " )
198
+ ]
199
+
200
+ let insertAction = InsertAction (
201
+ columns: sampleColumns,
202
+ commitTimestamp: sampleDate,
203
+ record: record,
204
+ rawMessage: sampleMessage
205
+ )
206
+
207
+ let decoder = JSONDecoder ( )
208
+ let decodedRecord = try insertAction. decodeRecord ( as: TestRecord . self, decoder: decoder)
209
+
210
+ let expectedRecord = TestRecord ( id: " 123 " , name: " John " , email: " john@example.com " )
211
+ XCTAssertEqual ( decodedRecord, expectedRecord)
212
+ }
213
+
214
+ func testDecodeOldRecord( ) throws {
215
+ struct TestRecord : Codable , Equatable {
216
+ let id : String
217
+ let name : String
218
+ }
219
+
220
+ let record : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John Updated " ) ]
221
+ let oldRecord : JSONObject = [ " id " : . string( " 123 " ) , " name " : . string( " John " ) ]
222
+
223
+ let updateAction = UpdateAction (
224
+ columns: sampleColumns,
225
+ commitTimestamp: sampleDate,
226
+ record: record,
227
+ oldRecord: oldRecord,
228
+ rawMessage: sampleMessage
229
+ )
230
+
231
+ let decoder = JSONDecoder ( )
232
+ let decodedOldRecord = try updateAction. decodeOldRecord ( as: TestRecord . self, decoder: decoder)
233
+
234
+ let expectedOldRecord = TestRecord ( id: " 123 " , name: " John " )
235
+ XCTAssertEqual ( decodedOldRecord, expectedOldRecord)
236
+ }
237
+
238
+ func testDecodeRecordError( ) {
239
+ struct TestRecord : Codable {
240
+ let id : Int // This will cause decode error since we're passing string
241
+ let name : String
242
+ }
243
+
244
+ let record : JSONObject = [
245
+ " id " : . string( " not-a-number " ) , // This should cause decoding to fail
246
+ " name " : . string( " John " )
247
+ ]
248
+
249
+ let insertAction = InsertAction (
250
+ columns: sampleColumns,
251
+ commitTimestamp: sampleDate,
252
+ record: record,
253
+ rawMessage: sampleMessage
254
+ )
255
+
256
+ let decoder = JSONDecoder ( )
257
+ XCTAssertThrowsError ( try insertAction. decodeRecord ( as: TestRecord . self, decoder: decoder) )
258
+ }
259
+ }
0 commit comments