DittoAPIStore: test that kind 0 with nip05 updates author_stats table

This commit is contained in:
Alex Gleason 2025-02-23 12:41:59 -06:00
parent 3f9f0468d2
commit 44f3721d36
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
3 changed files with 74 additions and 1 deletions

View file

@ -0,0 +1,71 @@
import { DittoPolyPg } from '@ditto/db';
import { DittoConf } from '@ditto/conf';
import { genEvent, MockRelay } from '@nostrify/nostrify/test';
import { assertEquals } from '@std/assert';
import { generateSecretKey, getPublicKey } from 'nostr-tools';
import { DittoAPIStore } from './DittoAPIStore.ts';
import type { NostrMetadata } from '@nostrify/types';
Deno.test('updateAuthorData sets nip05', async () => {
const alex = generateSecretKey();
await using test = setupTest((req) => {
switch (req.url) {
case 'https://gleasonator.dev/.well-known/nostr.json?name=alex':
return jsonResponse({ names: { alex: getPublicKey(alex) } });
default:
return new Response('Not found', { status: 404 });
}
});
const { db, store } = test;
const metadata: NostrMetadata = { nip05: 'alex@gleasonator.dev' };
const event = genEvent({ kind: 0, content: JSON.stringify(metadata) }, alex);
await store.updateAuthorData(event);
const row = await db.kysely
.selectFrom('author_stats')
.select(['nip05', 'nip05_domain', 'nip05_hostname'])
.where('pubkey', '=', getPublicKey(alex))
.executeTakeFirstOrThrow();
assertEquals(row.nip05, 'alex@gleasonator.dev');
assertEquals(row.nip05_domain, 'gleasonator.dev');
assertEquals(row.nip05_hostname, 'gleasonator.dev');
});
function setupTest(cb: (req: Request) => Response | Promise<Response>) {
const conf = new DittoConf(Deno.env);
const db = new DittoPolyPg(conf.databaseUrl);
const pool = new MockRelay();
const relay = new MockRelay();
const mockFetch: typeof fetch = async (input, init) => {
const req = new Request(input, init);
return await cb(req);
};
const store = new DittoAPIStore({ conf, db, relay, pool, fetch: mockFetch });
return {
db,
store,
[Symbol.asyncDispose]: async () => {
await store[Symbol.asyncDispose]();
await db[Symbol.asyncDispose]();
},
};
}
function jsonResponse(body: unknown): Response {
return new Response(JSON.stringify(body), {
headers: {
'Content-Type': 'application/json',
},
});
}

View file

@ -48,6 +48,7 @@ interface DittoAPIStoreOpts {
conf: DittoConf;
pool: NRelay;
relay: NRelay;
fetch?: typeof fetch;
}
export class DittoAPIStore implements NRelay {

View file

@ -11,6 +11,7 @@ interface GetNip05Opts {
conf: DittoConf;
relay: NStore;
signal?: AbortSignal;
fetch?: typeof fetch;
}
export async function lookupNip05(nip05: string, opts: GetNip05Opts): Promise<nip19.ProfilePointer> {
@ -35,7 +36,7 @@ export async function lookupNip05(nip05: string, opts: GetNip05Opts): Promise<ni
throw new Error(`Not found: ${nip05}`);
}
} else {
const pointer = await NIP05.lookup(nip05, { fetch: safeFetch, signal });
const pointer = await NIP05.lookup(nip05, { fetch: opts.fetch ?? safeFetch, signal });
logi({ level: 'info', ns: 'ditto.nip05', nip05, state: 'found', source: 'fetch', pubkey: pointer.pubkey });
return pointer;
}