From 829633b0d6451856bb73a9b3211ebb02a38cc3dc Mon Sep 17 00:00:00 2001 From: Sepehr Safari Date: Sat, 20 Jan 2024 10:40:15 +0330 Subject: [PATCH] inhance mock relay and refactor to a class --- test-helpers.ts | 198 +++++++++++++++++++++++++++++++----------------- 1 file changed, 130 insertions(+), 68 deletions(-) diff --git a/test-helpers.ts b/test-helpers.ts index 580169c..61be221 100644 --- a/test-helpers.ts +++ b/test-helpers.ts @@ -16,80 +16,142 @@ export function buildEvent(params: Partial): Event { } } -let serial = 0 +/** + * A mock Relay class for testing purposes. + * This mock relay returns some events before eose and then will be ok with everything. + * @class + * @example + * const mockRelay = new MockRelay() + * const relay = new Relay(mockRelay.getUrl()) + * await relay.connect() + * // Do some testing + * relay.close() + * mockRelay.close() + * mockRelay.stop() + */ +export class MockRelay { + private _url: string + private _server: Server + private _secretKeys: Uint8Array[] + private _preloadedEvents: Event[] -// the mock relay will always return some events before eose and then be ok with everything -export function newMockRelay(): { url: string; authors: string[]; ids: string[] } { - serial++ - const url = `wss://mock.relay.url/${serial}` - const relay = new Server(url) - const secretKeys = [generateSecretKey(), generateSecretKey(), generateSecretKey(), generateSecretKey()] - const preloadedEvents = secretKeys.map(sk => - finalizeEvent( - { - kind: 1, - content: '', - created_at: Math.floor(Date.now() / 1000), - tags: [], - }, - sk, - ), - ) + constructor() { + this._url = `wss://mock.relay.url/` + this._server = new Server(this._url) + this._secretKeys = [generateSecretKey(), generateSecretKey(), generateSecretKey(), generateSecretKey()] + this._preloadedEvents = this._secretKeys.map(sk => + finalizeEvent( + { + kind: 1, + content: '', + created_at: Math.floor(Date.now() / 1000), + tags: [], + }, + sk, + ), + ) - relay.on('connection', (conn: any) => { - let subs: { [subId: string]: { conn: any; filters: Filter[] } } = {} + this._server.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 } + conn.on('message', (message: string) => { + const data = JSON.parse(message) - preloadedEvents.forEach(event => { - conn.send(JSON.stringify(['EVENT', subId, event])) - }) + 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])) + this._preloadedEvents.forEach(event => { + conn.send(JSON.stringify(['EVENT', subId, event])) + }) + + filters.forEach((filter: Filter) => { + const kinds = filter.kinds?.length ? filter.kinds : [1] + + kinds.forEach(kind => { + this._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), ids: preloadedEvents.map(evt => evt.id) } + 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 + } + } + }) + }) + } + + /** + * Get the URL of the mock relay. + * @returns The URL of the mock relay. + */ + getUrl() { + return this._url + } + + /** + * Get the public keys of the authors of the events. + * @returns An array of public keys. + */ + getAuthors() { + return this._secretKeys.map(getPublicKey) + } + + /** + * Get the IDs of the events. + * @returns An array of event IDs. + */ + getEventsIds() { + return this._preloadedEvents.map(evt => evt.id) + } + + /** + * Close the mock relay server. + */ + close() { + this._server.close() + } + + /** + * Stop the mock relay server. + */ + stop() { + this._server.stop() + } }