diff --git a/bun.lockb b/bun.lockb index e3f5918..1b0c329 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/relay.test.ts b/relay.test.ts index 76e6fac..e4e484e 100644 --- a/relay.test.ts +++ b/relay.test.ts @@ -1,78 +1,44 @@ import { expect, test } from 'bun:test' -import { Server } from 'mock-socket' import { finalizeEvent, generateSecretKey, getPublicKey } from './pure.ts' import { Relay } from './relay.ts' +import { newMockRelay } from './test-helpers.ts' test('connectivity', async () => { - const mockRelayURL = 'wss://mock.relay.url' - const mockRelay = new Server(mockRelayURL) - - const relay = new Relay(mockRelayURL) + const { url } = newMockRelay() + const relay = new Relay(url) await relay.connect() - expect(relay.connected).toBeTrue() - relay.close() - mockRelay.stop() }) test('connectivity, with Relay.connect()', async () => { - const mockRelayURL = 'wss://mock.relay.url' - const mockRelay = new Server(mockRelayURL) - - const relay = await Relay.connect(mockRelayURL) - + const { url } = newMockRelay() + const relay = await Relay.connect(url) expect(relay.connected).toBeTrue() - relay.close() - mockRelay.stop() }) test('querying', async done => { - const sk = generateSecretKey() - const pk = getPublicKey(sk) + const { url, authors } = newMockRelay() const kind = 0 - const mockRelayURL = 'wss://mock.relay.url' - const mockRelay = new Server(mockRelayURL) - - mockRelay.on('connection', socket => { - socket.on('message', message => { - const data = JSON.parse(message as string) - - const event = finalizeEvent( - { - kind, - content: '', - created_at: Math.floor(Date.now() / 1000), - tags: [], - }, - sk, - ) - - socket.send(JSON.stringify(['EVENT', data[1], event])) - }) - }) - - const relay = new Relay(mockRelayURL) + const relay = new Relay(url) await relay.connect() relay.subscribe( [ { - authors: [pk], + authors: authors, kinds: [kind], }, ], { onevent(event) { - expect(event).toHaveProperty('pubkey', pk) + expect(authors).toContain(event.pubkey) expect(event).toHaveProperty('kind', kind) relay.close() - mockRelay.stop() - done() }, }, @@ -84,27 +50,8 @@ test('listening and publishing and closing', async done => { const pk = getPublicKey(sk) const kind = 23571 - const mockRelayURL = 'wss://mock.relay.url' - const mockRelay = new Server(mockRelayURL) - - mockRelay.on('connection', socket => { - let subId: string | null = null - - socket.on('message', message => { - const data = JSON.parse(message as string) - - if (data[0] === 'REQ') { - subId = data[1] - socket.send(JSON.stringify(['EOSE', data[1]])) - } else if (data[0] === 'EVENT') { - socket.send(JSON.stringify(['OK', data[1].id, 'true'])) - - socket.send(JSON.stringify(['EVENT', subId, data[1]])) - } - }) - }) - - const relay = new Relay(mockRelayURL) + const { url } = newMockRelay() + const relay = new Relay(url) await relay.connect() let sub = relay.subscribe( @@ -119,14 +66,11 @@ test('listening and publishing and closing', async done => { expect(event).toHaveProperty('pubkey', pk) expect(event).toHaveProperty('kind', kind) expect(event).toHaveProperty('content', 'content') - sub.close() }, oneose() {}, onclose() { relay.close() - mockRelay.stop() - done() }, }, diff --git a/test-helpers.ts b/test-helpers.ts index b75f510..0d79c84 100644 --- a/test-helpers.ts +++ b/test-helpers.ts @@ -1,6 +1,8 @@ -import type { Event } from './pure.ts' +import { Server } from 'mock-socket' + +import { finalizeEvent, type Event, getPublicKey, generateSecretKey } from './pure.ts' +import { matchFilters, type Filter } from './filter.ts' -/** Build an event for testing purposes. */ export function buildEvent(params: Partial): Event { return { id: '', @@ -13,3 +15,65 @@ export function buildEvent(params: Partial): Event { ...params, } } + +let serial = 0 + +// the mock relay will always return 3 events before eose and then do ok with everything +export function newMockRelay(): { url: string; authors: string[] } { + serial++ + const url = `wss://mock.relay.url/${serial}` + const relay = new Server(url) + const secretKeys = [generateSecretKey(), generateSecretKey(), generateSecretKey(), generateSecretKey()] + + relay.on('connection', (conn: any) => { + let subs: { [subId: string]: { conn: any; filters: Filter[] } } = {} + + conn.on('message', (message: string) => { + const data = JSON.parse(message) + switch (data[0]) { + case 'REQ': { + let subId = data[1] + let filters = data.slice(2) + subs[subId] = { conn, filters } + filters.forEach((filter: Filter) => { + const kinds = filter.kinds?.length ? filter.kinds : [1] + kinds.forEach(kind => { + secretKeys.forEach(sk => { + const event = finalizeEvent( + { + kind, + content: '', + created_at: Math.floor(Date.now() / 1000), + tags: [], + }, + sk, + ) + conn.send(JSON.stringify(['EVENT', subId, event])) + }) + }) + }) + conn.send(JSON.stringify(['EOSE', subId])) + break + } + case 'CLOSE': { + let subId = data[1] + delete subs[subId] + break + } + case 'EVENT': { + let event = data[1] + conn.send(JSON.stringify(['OK', event.id, 'true'])) + for (let subId in subs) { + const { filters, conn: listener } = subs[subId] + if (matchFilters(filters, event)) { + listener.send(JSON.stringify(['EVENT', subId, event])) + } + } + break + } + } + }) + }) + + return { url, authors: secretKeys.map(getPublicKey) } +}