Skip to content

Commit

Permalink
Test
Browse files Browse the repository at this point in the history
  • Loading branch information
grdsdev committed Jan 18, 2024
1 parent bf0ef03 commit e973690
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 136 deletions.
7 changes: 2 additions & 5 deletions Sources/Realtime/V2/RealtimeClientV2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,12 @@ public actor RealtimeClientV2 {
status = .connecting

let realtimeURL = realtimeWebSocketURL

let ws = makeWebSocketClient(realtimeURL, config.headers)
self.ws = ws

await ws.connect()
ws.connect()

let connectionStatus = try? await Task(timeout: config.timeoutInterval) {
await ws.status.first { _ in true }
}.value
let connectionStatus = await ws.status.first { _ in true }

switch connectionStatus {
case .open:
Expand Down
2 changes: 1 addition & 1 deletion Sources/Realtime/V2/WebSocketClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protocol WebSocketClientProtocol: Sendable {

func send(_ message: RealtimeMessageV2) async throws
func receive() -> AsyncThrowingStream<RealtimeMessageV2, Error>
func connect() async
func connect()
func cancel()
}

Expand Down
6 changes: 5 additions & 1 deletion Tests/RealtimeTests/MockWebSocketClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class MockWebSocketClient: WebSocketClientProtocol {
(status, continuation) = AsyncStream<WebSocketClient.ConnectionStatus>.makeStream()
}

func connect() async {}
func connect() {}

func send(_ message: RealtimeMessageV2) async throws {
mutableState.withValue {
Expand Down Expand Up @@ -58,4 +58,8 @@ final class MockWebSocketClient: WebSocketClientProtocol {
func mockReceive(_ message: RealtimeMessageV2) {
mutableState.receiveContinuation?.yield(message)
}

func mockStatus(_ status: WebSocketClient.ConnectionStatus) {
continuation.yield(status)
}
}
278 changes: 149 additions & 129 deletions Tests/RealtimeTests/RealtimeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,137 +14,157 @@ final class RealtimeTests: XCTestCase {
return "\(ref)"
}

// func testConnect() async {
// let mock = MockWebSocketClient()
//
// let realtime = RealtimeClientV2(
// config: RealtimeClientV2.Configuration(url: url, apiKey: apiKey),
// makeWebSocketClient: { _, _ in mock }
// )
//
//// XCTAssertNoLeak(realtime)
//
// await realtime.connect()
//
// let status = await realtime.status.first(where: { _ in true })
// XCTAssertEqual(status, .connected)
// }

// func testChannelSubscription() async throws {
// let mock = MockWebSocketClient()
//
// let realtime = RealtimeClientV2(
// config: RealtimeClientV2.Configuration(url: url, apiKey: apiKey),
// makeWebSocketClient: { _, _ in mock }
// )
//
// let channel = await realtime.channel("users")
//
// let changes = await channel.postgresChange(
// AnyAction.self,
// table: "users"
// )
//
// await channel.subscribe()
//
// let receivedPostgresChangeTask = Task {
// await changes
// .compactMap { $0.wrappedAction as? DeleteAction }
// .first { _ in true }
// }
//
// let sentMessages = mock.mutableState.sentMessages
// let expectedJoinMessage = try RealtimeMessageV2(
// joinRef: nil,
// ref: makeRef(),
// topic: "realtime:users",
// event: "phx_join",
// payload: [
// "config": AnyJSON(
// RealtimeJoinConfig(
// postgresChanges: [
// .init(event: .all, schema: "public", table: "users", filter: nil),
// ]
// )
// ),
// ]
// )
//
// XCTAssertNoDifference(sentMessages, [expectedJoinMessage])
//
// let currentDate = Date(timeIntervalSince1970: 725552399)
//
// let deleteActionRawMessage = try RealtimeMessageV2(
// joinRef: nil,
// ref: makeRef(),
// topic: "realtime:users",
// event: "postgres_changes",
// payload: [
// "data": AnyJSON(
// PostgresActionData(
// type: "DELETE",
// record: nil,
// oldRecord: ["email": "[email protected]"],
// columns: [
// Column(name: "email", type: "string"),
// ],
// commitTimestamp: currentDate
// )
// ),
// "ids": [0],
// ]
// )
//
// let action = DeleteAction(
// columns: [Column(name: "email", type: "string")],
// commitTimestamp: currentDate,
// oldRecord: ["email": "[email protected]"],
// rawMessage: deleteActionRawMessage
// )
//
// let postgresChangeReply = RealtimeMessageV2(
// joinRef: nil,
// ref: makeRef(),
// topic: "realtime:users",
// event: "phx_reply",
// payload: [
// "response": [
// "postgres_changes": [
// [
// "schema": "public",
// "table": "users",
// "filter": nil,
// "event": "*",
// "id": 0,
// ],
// ],
// ],
// "status": "ok",
// ]
// )
//
// mock.mockReceive(postgresChangeReply)
// mock.mockReceive(deleteActionRawMessage)
//
// let receivedChange = await receivedPostgresChangeTask.value
// XCTAssertNoDifference(receivedChange, action)
//
// await channel.unsubscribe()
//
// mock.mockReceive(
// RealtimeMessageV2(
// joinRef: nil,
// ref: nil,
// topic: "realtime:users",
// event: ChannelEvent.leave,
// payload: [:]
// )
// )
//
// await Task.megaYield()
// }
func testConnect() async {
let mock = MockWebSocketClient()

let realtime = RealtimeClientV2(
config: RealtimeClientV2.Configuration(url: url, apiKey: apiKey),
makeWebSocketClient: { _, _ in mock }
)

// XCTAssertNoLeak(realtime)

Task {
await realtime.connect()
}

mock.mockStatus(.open)

await Task.megaYield()

let status = await realtime.status
XCTAssertEqual(status, .connected)
}

func testChannelSubscription() async throws {
let mock = MockWebSocketClient()

let realtime = RealtimeClientV2(
config: RealtimeClientV2.Configuration(url: url, apiKey: apiKey),
makeWebSocketClient: { _, _ in mock }
)

let channel = await realtime.channel("users")

let changes = await channel.postgresChange(
AnyAction.self,
table: "users"
)

let task = Task {
await channel.subscribe()
}

mock.mockStatus(.open)

await Task.megaYield()

await task.value

let receivedPostgresChangeTask = Task {
await changes
.compactMap { $0.wrappedAction as? DeleteAction }
.first { _ in true }
}

let sentMessages = mock.mutableState.sentMessages
let expectedJoinMessage = try RealtimeMessageV2(
joinRef: nil,
ref: makeRef(),
topic: "realtime:users",
event: "phx_join",
payload: [
"config": AnyJSON(
RealtimeJoinConfig(
postgresChanges: [
.init(event: .all, schema: "public", table: "users", filter: nil),
]
)
),
]
)

XCTAssertNoDifference(sentMessages, [expectedJoinMessage])

let currentDate = Date(timeIntervalSince1970: 725552399)

let deleteActionRawMessage = try RealtimeMessageV2(
joinRef: nil,
ref: makeRef(),
topic: "realtime:users",
event: "postgres_changes",
payload: [
"data": AnyJSON(
PostgresActionData(
type: "DELETE",
record: nil,
oldRecord: ["email": "[email protected]"],
columns: [
Column(name: "email", type: "string"),
],
commitTimestamp: currentDate
)
),
"ids": [0],
]
)

let action = DeleteAction(
columns: [Column(name: "email", type: "string")],
commitTimestamp: currentDate,
oldRecord: ["email": "[email protected]"],
rawMessage: deleteActionRawMessage
)

let postgresChangeReply = RealtimeMessageV2(
joinRef: nil,
ref: makeRef(),
topic: "realtime:users",
event: "phx_reply",
payload: [
"response": [
"postgres_changes": [
[
"schema": "public",
"table": "users",
"filter": nil,
"event": "*",
"id": 0,
],
],
],
"status": "ok",
]
)

mock.mockReceive(postgresChangeReply)
mock.mockReceive(deleteActionRawMessage)

let receivedChange = await receivedPostgresChangeTask.value
XCTAssertNoDifference(receivedChange, action)

await channel.unsubscribe()

mock.mockReceive(
RealtimeMessageV2(
joinRef: nil,
ref: nil,
topic: "realtime:users",
event: ChannelEvent.leave,
payload: [:]
)
)

await Task.megaYield()
}

func testHeartbeat() {
// TODO: test heartbeat behavior
}
}

extension AsyncSequence {
func collect() async rethrows -> [Element] {
try await reduce(into: [Element]()) { $0.append($1) }
}
}

0 comments on commit e973690

Please sign in to comment.