Add ndb subscription tests
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
@@ -11,7 +11,8 @@ import EmojiPicker
|
||||
|
||||
// Generates a test damus state with configurable mock parameters
|
||||
func generate_test_damus_state(
|
||||
mock_profile_info: [Pubkey: Profile]?
|
||||
mock_profile_info: [Pubkey: Profile]?,
|
||||
home: HomeModel? = nil
|
||||
) -> DamusState {
|
||||
// Create a unique temporary directory
|
||||
let ndb = Ndb.test
|
||||
@@ -32,7 +33,7 @@ func generate_test_damus_state(
|
||||
boosts: .init(our_pubkey: our_pubkey),
|
||||
contacts: .init(our_pubkey: our_pubkey), mutelist_manager: mutelist_manager,
|
||||
profiles: profiles,
|
||||
dms: .init(our_pubkey: our_pubkey),
|
||||
dms: home?.dms ?? .init(our_pubkey: our_pubkey),
|
||||
previews: .init(),
|
||||
zaps: .init(our_pubkey: our_pubkey),
|
||||
lnurls: .init(),
|
||||
@@ -52,6 +53,8 @@ func generate_test_damus_state(
|
||||
emoji_provider: DefaultEmojiProvider(showAllVariations: false),
|
||||
favicon_cache: .init()
|
||||
)
|
||||
|
||||
home?.damus_state = damus
|
||||
|
||||
return damus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// NostrNetworkManagerTests.swift
|
||||
// damus
|
||||
//
|
||||
// Created by Daniel D'Aquino on 2025-08-22.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import damus
|
||||
|
||||
|
||||
class NostrNetworkManagerTests: XCTestCase {
|
||||
var damusState: DamusState? = nil
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
damusState = generate_test_damus_state(mock_profile_info: nil)
|
||||
|
||||
let notesJSONL = getTestNotesJSONL()
|
||||
|
||||
for noteText in notesJSONL.split(separator: "\n") {
|
||||
let _ = damusState!.ndb.process_event("[\"EVENT\",\"subid\",\(String(noteText))]")
|
||||
}
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
damusState = nil
|
||||
}
|
||||
|
||||
func getTestNotesJSONL() -> String {
|
||||
// Get the path for the test_notes.jsonl file in the same folder as this test file
|
||||
let testBundle = Bundle(for: type(of: self))
|
||||
let fileURL = testBundle.url(forResource: "test_notes", withExtension: "jsonl")!
|
||||
|
||||
// Load the contents of the file
|
||||
return try! String(contentsOf: fileURL, encoding: .utf8)
|
||||
}
|
||||
|
||||
func ensureSubscribeGetsAllExpectedNotes(filter: NostrFilter, expectedCount: Int) {
|
||||
let endOfStream = XCTestExpectation(description: "Stream should receive EOSE")
|
||||
let gotAtLeastExpectedCount = XCTestExpectation(description: "Stream should receive at least the expected number of items")
|
||||
var receivedCount = 0
|
||||
var eventIds: Set<NoteId> = []
|
||||
Task {
|
||||
for await item in self.damusState!.nostrNetwork.reader.subscribe(filters: [filter]) {
|
||||
switch item {
|
||||
case .event(borrow: let borrow):
|
||||
try? borrow { event in
|
||||
receivedCount += 1
|
||||
if eventIds.contains(event.id) {
|
||||
XCTFail("Got duplicate event ID: \(event.id) ")
|
||||
}
|
||||
eventIds.insert(event.id)
|
||||
}
|
||||
if receivedCount == expectedCount {
|
||||
gotAtLeastExpectedCount.fulfill()
|
||||
}
|
||||
case .eose:
|
||||
// End of stream, break out of the loop
|
||||
endOfStream.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
wait(for: [endOfStream, gotAtLeastExpectedCount], timeout: 10.0)
|
||||
XCTAssertEqual(receivedCount, expectedCount, "Event IDs: \(eventIds.map({ $0.hex() }))")
|
||||
}
|
||||
|
||||
/// Tests to ensure that subscribing gets the correct amount of events
|
||||
///
|
||||
/// ## Implementation notes:
|
||||
///
|
||||
/// To create a new scenario, `nak` can be used as a reference:
|
||||
/// 1. `cd` into the folder where the `test_notes.jsonl` file is
|
||||
/// 2. Run `nak serve --events test_notes.jsonl`
|
||||
/// 3. On a separate terminal, run `nak` commands with the desired filter against the local relay, and get the line count. Example:
|
||||
/// ```
|
||||
/// nak req --kind 1 ws://localhost:10547 | wc -l
|
||||
/// ```
|
||||
func testNdbSubscription() {
|
||||
ensureSubscribeGetsAllExpectedNotes(filter: NostrFilter(kinds: [.text]), expectedCount: 57)
|
||||
ensureSubscribeGetsAllExpectedNotes(filter: NostrFilter(authors: [Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!]), expectedCount: 22)
|
||||
ensureSubscribeGetsAllExpectedNotes(filter: NostrFilter(kinds: [.boost], referenced_ids: [NoteId(hex: "64b26d0a587f5f894470e1e4783756b4d8ba971226de975ee30ac1b69970d5a1")!]), expectedCount: 5)
|
||||
ensureSubscribeGetsAllExpectedNotes(filter: NostrFilter(kinds: [.text, .boost, .zap], referenced_ids: [NoteId(hex: "64b26d0a587f5f894470e1e4783756b4d8ba971226de975ee30ac1b69970d5a1")!], limit: 500), expectedCount: 5)
|
||||
}
|
||||
}
|
||||
92
damusTests/NostrNetworkManagerTests/test_notes.jsonl
Normal file
92
damusTests/NostrNetworkManagerTests/test_notes.jsonl
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user