commit 603a5a18144abc98786a383356c7c39930861fec
parent 06a1a9aba6f9ee54350d9a64d6897193c2e18f23
Author: Bryan Montz <bryanmontz@me.com>
Date: Sat, 18 Feb 2023 00:27:15 -0600
Refinements to RelayConnection plus tests for creating requests
Closes: #644
Diffstat:
4 files changed, 71 insertions(+), 50 deletions(-)
diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj
@@ -199,6 +199,7 @@
4CF0ABF029857E9200D66079 /* Bech32Object.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABEF29857E9200D66079 /* Bech32Object.swift */; };
4CF0ABF62985CD5500D66079 /* UserSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABF52985CD5500D66079 /* UserSearch.swift */; };
4FE60CDD295E1C5E00105A1F /* Wallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FE60CDC295E1C5E00105A1F /* Wallet.swift */; };
+ 50A50A8D29A09E1C00C01BE7 /* RequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A50A8C29A09E1C00C01BE7 /* RequestTests.swift */; };
5C513FBA297F72980072348F /* CustomPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C513FB9297F72980072348F /* CustomPicker.swift */; };
5C513FCC2984ACA60072348F /* QRCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C513FCB2984ACA60072348F /* QRCodeView.swift */; };
6439E014296790CF0020672B /* ProfileZoomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6439E013296790CF0020672B /* ProfileZoomView.swift */; };
@@ -513,6 +514,7 @@
4CF0ABEF29857E9200D66079 /* Bech32Object.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bech32Object.swift; sourceTree = "<group>"; };
4CF0ABF52985CD5500D66079 /* UserSearch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSearch.swift; sourceTree = "<group>"; };
4FE60CDC295E1C5E00105A1F /* Wallet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wallet.swift; sourceTree = "<group>"; };
+ 50A50A8C29A09E1C00C01BE7 /* RequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestTests.swift; sourceTree = "<group>"; };
5C513FB9297F72980072348F /* CustomPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPicker.swift; sourceTree = "<group>"; };
5C513FCB2984ACA60072348F /* QRCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeView.swift; sourceTree = "<group>"; };
6439E013296790CF0020672B /* ProfileZoomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileZoomView.swift; sourceTree = "<group>"; };
@@ -934,6 +936,7 @@
4CE6DEF627F7A08200C66700 /* damusTests */ = {
isa = PBXGroup;
children = (
+ 50A50A8C29A09E1C00C01BE7 /* RequestTests.swift */,
DD597CBC2963D85A00C64D32 /* MarkdownTests.swift */,
4C90BD1B283AC38E008EE7EF /* Bech32Tests.swift */,
4C363A9F2828A8DD006E126D /* LikeTests.swift */,
@@ -1394,6 +1397,7 @@
4CB883AE2976FA9300DC99E7 /* FormatTests.swift in Sources */,
4C363AA02828A8DD006E126D /* LikeTests.swift in Sources */,
4C90BD1C283AC38E008EE7EF /* Bech32Tests.swift in Sources */,
+ 50A50A8D29A09E1C00C01BE7 /* RequestTests.swift in Sources */,
4CE6DEF827F7A08200C66700 /* damusTests.swift in Sources */,
4CF0ABDC2981A19E00D66079 /* ListTests.swift in Sources */,
);
diff --git a/damus/Nostr/NostrEvent.swift b/damus/Nostr/NostrEvent.swift
@@ -278,21 +278,7 @@ class NostrEvent: Codable, Identifiable, CustomStringConvertible, Equatable, Has
return (self.flags & 1) != 0
}
- init(content: String, pubkey: String, kind: Int = 1, tags: [[String]] = [], createdAt: Int64 = Int64(Date().timeIntervalSince1970)) {
- self.id = ""
- self.sig = ""
-
- self.content = content
- self.pubkey = pubkey
- self.kind = kind
- self.tags = tags
- self.created_at = createdAt
- }
-
- /// Intiialization statement used to specificy ID
- ///
- /// This is mainly used for contant and testing data
- init(id: String, content: String, pubkey: String, kind: Int = 1, tags: [[String]] = []) {
+ init(id: String = "", content: String, pubkey: String, kind: Int = 1, tags: [[String]] = [], createdAt: Int64 = Int64(Date().timeIntervalSince1970)) {
self.id = id
self.sig = ""
@@ -300,7 +286,7 @@ class NostrEvent: Codable, Identifiable, CustomStringConvertible, Equatable, Has
self.pubkey = pubkey
self.kind = kind
self.tags = tags
- self.created_at = Int64(Date().timeIntervalSince1970)
+ self.created_at = createdAt
}
init(from: NostrEvent, content: String? = nil) {
diff --git a/damus/Nostr/RelayConnection.swift b/damus/Nostr/RelayConnection.swift
@@ -13,42 +13,41 @@ enum NostrConnectionEvent {
case nostr_event(NostrResponse)
}
-class RelayConnection: WebSocketDelegate {
- var isConnected: Bool = false
- var isConnecting: Bool = false
- var isReconnecting: Bool = false
- var last_connection_attempt: Double = 0
- var socket: WebSocket
- var handleEvent: (NostrConnectionEvent) -> ()
- let url: URL
+final class RelayConnection: WebSocketDelegate {
+ private(set) var isConnected = false
+ private(set) var isConnecting = false
+ private(set) var isReconnecting = false
+
+ private(set) var last_connection_attempt: TimeInterval = 0
+ private lazy var socket = {
+ let req = URLRequest(url: url)
+ let socket = WebSocket(request: req, compressionHandler: .none)
+ socket.delegate = self
+ return socket
+ }()
+ private var handleEvent: (NostrConnectionEvent) -> ()
+ private let url: URL
init(url: URL, handleEvent: @escaping (NostrConnectionEvent) -> ()) {
self.url = url
self.handleEvent = handleEvent
- // just init, we don't actually use this one
- self.socket = make_websocket(url: url)
}
func reconnect() {
- if self.isConnected {
- self.isReconnecting = true
- self.disconnect()
+ if isConnected {
+ isReconnecting = true
+ disconnect()
} else {
// we're already disconnected, so just connect
- self.connect(force: true)
+ connect(force: true)
}
}
- func connect(force: Bool = false){
- if !force && (self.isConnected || self.isConnecting) {
+ func connect(force: Bool = false) {
+ if !force && (isConnected || isConnecting) {
return
}
-
- var req = URLRequest(url: self.url)
- req.timeoutInterval = 5
- socket = make_websocket(url: url)
- socket.delegate = self
-
+
isConnecting = true
last_connection_attempt = Date().timeIntervalSince1970
socket.connect()
@@ -68,7 +67,9 @@ class RelayConnection: WebSocketDelegate {
socket.write(string: req)
}
-
+
+ // MARK: - WebSocketDelegate
+
func didReceive(event: WebSocketEvent, client: WebSocket) {
switch event {
case .connected:
@@ -83,8 +84,7 @@ class RelayConnection: WebSocketDelegate {
self.connect()
}
- case .cancelled: fallthrough
- case .error:
+ case .cancelled, .error:
self.isConnecting = false
self.isConnected = false
@@ -114,7 +114,6 @@ class RelayConnection: WebSocketDelegate {
handleEvent(.ws_event(event))
}
-
}
func make_nostr_req(_ req: NostrRequest) -> String? {
@@ -138,7 +137,7 @@ func make_nostr_push_event(ev: NostrEvent) -> String? {
}
func make_nostr_unsubscribe_req(_ sub_id: String) -> String? {
- return "[\"CLOSE\",\"\(sub_id)\"]"
+ "[\"CLOSE\",\"\(sub_id)\"]"
}
func make_nostr_subscription_req(_ filters: [NostrFilter], sub_id: String) -> String? {
@@ -155,10 +154,3 @@ func make_nostr_subscription_req(_ filters: [NostrFilter], sub_id: String) -> St
req += "]"
return req
}
-
-func make_websocket(url: URL) -> WebSocket {
- let req = URLRequest(url: url)
- //req.setValue("chat,superchat", forHTTPHeaderField: "Sec-WebSocket-Protocol")
- return WebSocket(request: req, compressionHandler: .none)
-}
-
diff --git a/damusTests/RequestTests.swift b/damusTests/RequestTests.swift
@@ -0,0 +1,39 @@
+//
+// RequestTests.swift
+// damusTests
+//
+// Created by Bryan Montz on 2/17/23.
+//
+
+import XCTest
+@testable import damus
+
+final class RequestTests: XCTestCase {
+
+ func testMakeUnsubscribeRequest() {
+ let request = NostrRequest.unsubscribe("64FD064D-EB9E-4771-8255-8D16981B920B")
+ let result = make_nostr_req(request)
+ let expectedResult = "[\"CLOSE\",\"64FD064D-EB9E-4771-8255-8D16981B920B\"]"
+ XCTAssertEqual(result, expectedResult)
+ }
+
+ func testMakePushEvent() {
+ let now = Int64(Date().timeIntervalSince1970)
+ let event = NostrEvent(id: "59c1cf11a3e9e128c6fd5402f41e8ae0c0c7fbab570203d7410518be68c3115f",
+ content: "Testing",
+ pubkey: "d9fa34214aa9d151c4f4db843e9c2af4f246bab4205137731f91bcfa44d66a62",
+ kind: 1,
+ createdAt: now)
+ let result = make_nostr_req(.event(event))
+ let expectedResult = "[\"EVENT\",{\"pubkey\":\"d9fa34214aa9d151c4f4db843e9c2af4f246bab4205137731f91bcfa44d66a62\",\"content\":\"Testing\",\"id\":\"59c1cf11a3e9e128c6fd5402f41e8ae0c0c7fbab570203d7410518be68c3115f\",\"created_at\":\(now),\"sig\":\"\",\"kind\":1,\"tags\":[]}]"
+ XCTAssertEqual(result, expectedResult)
+ }
+
+ func testMakeSubscriptionRequest() {
+ let filter = NostrFilter(kinds: [3], limit: 1, authors: ["d9fa34214aa9d151c4f4db843e9c2af4f246bab4205137731f91bcfa44d66a62"])
+ let subscribe = NostrSubscribe(filters: [filter], sub_id: "31C737B7-C8F9-41DD-8707-325974F279A4")
+ let result = make_nostr_req(.subscribe(subscribe))
+ let expectedResult = "[\"REQ\",\"31C737B7-C8F9-41DD-8707-325974F279A4\",{\"kinds\":[3],\"authors\":[\"d9fa34214aa9d151c4f4db843e9c2af4f246bab4205137731f91bcfa44d66a62\"],\"limit\":1}]"
+ XCTAssertEqual(result, expectedResult)
+ }
+}