Skip to content

Commit

Permalink
Add function to RelayDelegate to receive all relay response types
Browse files Browse the repository at this point in the history
  • Loading branch information
tyiu committed Jun 26, 2024
1 parent c36df6c commit 2cd9827
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 15 deletions.
15 changes: 12 additions & 3 deletions Sources/NostrSDK/Relay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,17 @@ public protocol RelayOperating {
var events: PassthroughSubject<RelayEvent, Never> { get }
}

/// An optional interface for receiving state updates and events
/// An optional interface for receiving state updates and responses from relays.
public protocol RelayDelegate: AnyObject {
func relayStateDidChange(_ relay: Relay, state: Relay.State)

func relay(_ relay: Relay, didReceive response: RelayResponse)

@available(*, deprecated, message: "`relay(Relay, didReceive: RelayEvent)` was replaced by `relay(Relay, didReceive: RelayResponse)` and will be removed shortly.")
func relay(_ relay: Relay, didReceive event: RelayEvent)
}

/// A struct containing a nostr event and the subscription ID
/// A struct containing a Nostr event and the subscription ID
public struct RelayEvent {
public let event: NostrEvent
public let subscriptionId: String
Expand Down Expand Up @@ -145,7 +149,12 @@ public final class Relay: ObservableObject, EventVerifying, RelayOperating, Hash

private func receive(_ message: URLSessionWebSocketTask.Message) {
func handle(messageData: Data) {
let response = RelayResponse.decode(data: messageData)
guard let response = RelayResponse.decode(data: messageData) else {
return
}

delegate?.relay(self, didReceive: response)

switch response {
case .event(let subscriptionId, let event):
let relayEvent = RelayEvent(event: event, subscriptionId: subscriptionId)
Expand Down
6 changes: 3 additions & 3 deletions Sources/NostrSDK/RelayResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fileprivate struct EventKindMapper: Decodable { // swiftlint:disable:this pr
}
}

enum RelayResponse: Decodable {
public enum RelayResponse: Decodable {

struct CountResponse: Codable {
let count: Int
Expand All @@ -37,7 +37,7 @@ enum RelayResponse: Decodable {
case count = "COUNT"
}

struct Message {
public struct Message {
let prefix: MessagePrefix
let message: String

Expand Down Expand Up @@ -79,7 +79,7 @@ enum RelayResponse: Decodable {
case auth(challenge: String)
case count(subscriptionId: String, count: Int)

init(from decoder: Decoder) throws {
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
let responseType = try container.decode(MessageType.self)
switch responseType {
Expand Down
44 changes: 35 additions & 9 deletions Tests/NostrSDKTests/RelayTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@ final class RelayTests: XCTestCase {
private var cancellables = Set<AnyCancellable>()

private var connectExpectation: XCTestExpectation?
private var receiveExpectation: XCTestExpectation?
private var receiveEventExpectation: XCTestExpectation?
private var disconnectExpectation: XCTestExpectation?


private var receiveResponseEventExpectation: XCTestExpectation?
private var receiveResponseOkExpectation: XCTestExpectation?
private var receiveResponseEoseExpectation: XCTestExpectation?

func testConnectAndReceive() throws {
connectExpectation = expectation(description: "connect")
receiveExpectation = expectation(description: "receive")
receiveEventExpectation = expectation(description: "receive")
disconnectExpectation = expectation(description: "disconnect")

receiveResponseEventExpectation = expectation(description: "receiveResponseEvent")

let relay = try Relay(url: RelayTests.RelayURL)
XCTAssertEqual(relay.url, RelayTests.RelayURL)
relay.connect()
Expand Down Expand Up @@ -51,11 +57,13 @@ final class RelayTests: XCTestCase {
.sink { [unowned relay] _ in
// we have received an event from the relay. close the subscription.
try? relay.closeSubscription(with: subscriptionId)
self.receiveExpectation?.fulfill()
self.receiveResponseEventExpectation?.fulfill()
self.receiveEventExpectation?.fulfill()
}
.store(in: &cancellables)

wait(for: [receiveExpectation!], timeout: 10)
wait(for: [receiveResponseEventExpectation!], timeout: 10)
wait(for: [receiveEventExpectation!], timeout: 10)

relay.disconnect()

Expand All @@ -81,9 +89,12 @@ final class RelayTests: XCTestCase {

func testRelayDelegate() throws {
connectExpectation = expectation(description: "connect")
receiveExpectation = expectation(description: "receive")
receiveEventExpectation = expectation(description: "receive")
disconnectExpectation = expectation(description: "disconnect")

receiveResponseEventExpectation = expectation(description: "receiveResponseEvent")
receiveResponseEoseExpectation = expectation(description: "receiveResponseEose")

let relay = try Relay(url: RelayTests.RelayURL)
relay.delegate = self
relay.connect()
Expand All @@ -93,8 +104,10 @@ final class RelayTests: XCTestCase {
let filter = try XCTUnwrap(Filter(kinds: [1], limit: 1))
let subscriptionId = try relay.subscribe(with: filter)

wait(for: [receiveExpectation!], timeout: 10)

wait(for: [receiveResponseEventExpectation!], timeout: 10)
wait(for: [receiveEventExpectation!], timeout: 10)
wait(for: [receiveResponseEoseExpectation!], timeout: 10)

try? relay.closeSubscription(with: subscriptionId)

relay.disconnect()
Expand All @@ -117,6 +130,19 @@ extension RelayTests: RelayDelegate {
}

func relay(_ relay: Relay, didReceive event: RelayEvent) {
receiveExpectation?.fulfill()
receiveEventExpectation?.fulfill()
}

func relay(_ relay: NostrSDK.Relay, didReceive response: RelayResponse) {
switch response {
case .event:
receiveResponseEventExpectation?.fulfill()
case .ok:
receiveResponseOkExpectation?.fulfill()
case .eose:
receiveResponseEoseExpectation?.fulfill()
default:
break
}
}
}

0 comments on commit 2cd9827

Please sign in to comment.