diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 779bbcc3..60526256 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,11 +35,11 @@ test: postgres: stage: test - script: deno task db:migrate + script: deno task db:migrate && deno task test services: - postgres:16 variables: DITTO_NSEC: nsec1zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs4rm7hz DATABASE_URL: postgres://postgres:postgres@postgres:5432/postgres POSTGRES_HOST_AUTH_METHOD: trust - + ALLOW_TO_USE_DATABASE_URL: true diff --git a/deno.json b/deno.json index 190ce017..00b6b764 100644 --- a/deno.json +++ b/deno.json @@ -8,7 +8,7 @@ "db:migrate": "deno run -A scripts/db-migrate.ts", "nostr:pull": "deno run -A scripts/nostr-pull.ts", "debug": "deno run -A --inspect src/server.ts", - "test": "DATABASE_URL=\"sqlite://:memory:\" deno test -A --junit-path=./deno-test.xml", + "test": "deno test -A --junit-path=./deno-test.xml", "check": "deno check src/server.ts", "nsec": "deno run scripts/nsec.ts", "admin:event": "deno run -A scripts/admin-event.ts", diff --git a/src/pipeline.test.ts b/src/pipeline.test.ts index 64cb523b..3a196c16 100644 --- a/src/pipeline.test.ts +++ b/src/pipeline.test.ts @@ -1,11 +1,11 @@ import { assertEquals } from '@std/assert'; import { generateSecretKey } from 'nostr-tools'; -import { genEvent, getTestDB } from '@/test.ts'; +import { createTestDB, genEvent, getTestDB } from '@/test.ts'; import { handleZaps } from '@/pipeline.ts'; Deno.test('store one zap receipt in nostr_events; convert it into event_zaps table format and store it', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const kysely = db.kysely; const sk = generateSecretKey(); diff --git a/src/storages/EventsDB.test.ts b/src/storages/EventsDB.test.ts index 32838fa6..82c4e34a 100644 --- a/src/storages/EventsDB.test.ts +++ b/src/storages/EventsDB.test.ts @@ -1,87 +1,75 @@ -import { Database as Sqlite } from '@db/sqlite'; -import { DenoSqlite3Dialect } from '@soapbox/kysely-deno-sqlite'; import { assertEquals, assertRejects } from '@std/assert'; -import { Kysely } from 'kysely'; import { generateSecretKey } from 'nostr-tools'; -import { Conf } from '@/config.ts'; -import { DittoDB } from '@/db/DittoDB.ts'; -import { DittoTables } from '@/db/DittoTables.ts'; import { RelayError } from '@/RelayError.ts'; -import { EventsDB } from '@/storages/EventsDB.ts'; import { eventFixture, genEvent } from '@/test.ts'; - -/** Create in-memory database for testing. */ -const createDB = async () => { - const kysely = new Kysely({ - dialect: new DenoSqlite3Dialect({ - database: new Sqlite(':memory:'), - }), - }); - const eventsDB = new EventsDB(kysely); - await DittoDB.migrate(kysely); - return { eventsDB, kysely }; -}; +import { Conf } from '@/config.ts'; +import { createTestDB } from '@/test.ts'; Deno.test('count filters', async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; + const event1 = await eventFixture('event-1'); - assertEquals((await eventsDB.count([{ kinds: [1] }])).count, 0); - await eventsDB.event(event1); - assertEquals((await eventsDB.count([{ kinds: [1] }])).count, 1); + assertEquals((await store.count([{ kinds: [1] }])).count, 0); + await store.event(event1); + assertEquals((await store.count([{ kinds: [1] }])).count, 1); }); Deno.test('insert and filter events', async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; const event1 = await eventFixture('event-1'); - await eventsDB.event(event1); + await store.event(event1); - assertEquals(await eventsDB.query([{ kinds: [1] }]), [event1]); - assertEquals(await eventsDB.query([{ kinds: [3] }]), []); - assertEquals(await eventsDB.query([{ since: 1691091000 }]), [event1]); - assertEquals(await eventsDB.query([{ until: 1691091000 }]), []); + assertEquals(await store.query([{ kinds: [1] }]), [event1]); + assertEquals(await store.query([{ kinds: [3] }]), []); + assertEquals(await store.query([{ since: 1691091000 }]), [event1]); + assertEquals(await store.query([{ until: 1691091000 }]), []); assertEquals( - await eventsDB.query([{ '#proxy': ['https://gleasonator.com/objects/8f6fac53-4f66-4c6e-ac7d-92e5e78c3e79'] }]), + await store.query([{ '#proxy': ['https://gleasonator.com/objects/8f6fac53-4f66-4c6e-ac7d-92e5e78c3e79'] }]), [event1], ); }); Deno.test('query events with domain search filter', async () => { - const { eventsDB, kysely } = await createDB(); + await using db = await createTestDB(); + const { store, kysely } = db; const event1 = await eventFixture('event-1'); - await eventsDB.event(event1); + await store.event(event1); - assertEquals(await eventsDB.query([{}]), [event1]); - assertEquals(await eventsDB.query([{ search: 'domain:localhost:4036' }]), []); - assertEquals(await eventsDB.query([{ search: '' }]), [event1]); + assertEquals(await store.query([{}]), [event1]); + assertEquals(await store.query([{ search: 'domain:localhost:4036' }]), []); + assertEquals(await store.query([{ search: '' }]), [event1]); await kysely .insertInto('pubkey_domains') .values({ pubkey: event1.pubkey, domain: 'localhost:4036', last_updated_at: event1.created_at }) .execute(); - assertEquals(await eventsDB.query([{ kinds: [1], search: 'domain:localhost:4036' }]), [event1]); - assertEquals(await eventsDB.query([{ kinds: [1], search: 'domain:example.com' }]), []); + assertEquals(await store.query([{ kinds: [1], search: 'domain:localhost:4036' }]), [event1]); + assertEquals(await store.query([{ kinds: [1], search: 'domain:example.com' }]), []); }); Deno.test('delete events', async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; const [one, two] = [ { id: '1', kind: 1, pubkey: 'abc', content: 'hello world', created_at: 1, sig: '', tags: [] }, { id: '2', kind: 1, pubkey: 'abc', content: 'yolo fam', created_at: 2, sig: '', tags: [] }, ]; - await eventsDB.event(one); - await eventsDB.event(two); + await store.event(one); + await store.event(two); // Sanity check - assertEquals(await eventsDB.query([{ kinds: [1] }]), [two, one]); + assertEquals(await store.query([{ kinds: [1] }]), [two, one]); - await eventsDB.event({ + await store.event({ kind: 5, pubkey: one.pubkey, tags: [['e', one.id]], @@ -91,19 +79,20 @@ Deno.test('delete events', async () => { sig: '', }); - assertEquals(await eventsDB.query([{ kinds: [1] }]), [two]); + assertEquals(await store.query([{ kinds: [1] }]), [two]); }); Deno.test("user cannot delete another user's event", async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; const event = { id: '1', kind: 1, pubkey: 'abc', content: 'hello world', created_at: 1, sig: '', tags: [] }; - await eventsDB.event(event); + await store.event(event); // Sanity check - assertEquals(await eventsDB.query([{ kinds: [1] }]), [event]); + assertEquals(await store.query([{ kinds: [1] }]), [event]); - await eventsDB.event({ + await store.event({ kind: 5, pubkey: 'def', // different pubkey tags: [['e', event.id]], @@ -113,24 +102,25 @@ Deno.test("user cannot delete another user's event", async () => { sig: '', }); - assertEquals(await eventsDB.query([{ kinds: [1] }]), [event]); + assertEquals(await store.query([{ kinds: [1] }]), [event]); }); Deno.test('admin can delete any event', async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; const [one, two] = [ { id: '1', kind: 1, pubkey: 'abc', content: 'hello world', created_at: 1, sig: '', tags: [] }, { id: '2', kind: 1, pubkey: 'abc', content: 'yolo fam', created_at: 2, sig: '', tags: [] }, ]; - await eventsDB.event(one); - await eventsDB.event(two); + await store.event(one); + await store.event(two); // Sanity check - assertEquals(await eventsDB.query([{ kinds: [1] }]), [two, one]); + assertEquals(await store.query([{ kinds: [1] }]), [two, one]); - await eventsDB.event({ + await store.event({ kind: 5, pubkey: Conf.pubkey, // Admin pubkey tags: [['e', one.id]], @@ -140,83 +130,89 @@ Deno.test('admin can delete any event', async () => { sig: '', }); - assertEquals(await eventsDB.query([{ kinds: [1] }]), [two]); + assertEquals(await store.query([{ kinds: [1] }]), [two]); }); Deno.test('throws a RelayError when inserting an event deleted by the admin', async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; const event = genEvent(); - await eventsDB.event(event); + await store.event(event); const deletion = genEvent({ kind: 5, tags: [['e', event.id]] }, Conf.seckey); - await eventsDB.event(deletion); + await store.event(deletion); await assertRejects( - () => eventsDB.event(event), + () => store.event(event), RelayError, 'event deleted by admin', ); }); Deno.test('throws a RelayError when inserting an event deleted by a user', async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; const sk = generateSecretKey(); const event = genEvent({}, sk); - await eventsDB.event(event); + await store.event(event); const deletion = genEvent({ kind: 5, tags: [['e', event.id]] }, sk); - await eventsDB.event(deletion); + await store.event(deletion); await assertRejects( - () => eventsDB.event(event), + () => store.event(event), RelayError, 'event deleted by user', ); }); Deno.test('inserting replaceable events', async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; const event = await eventFixture('event-0'); - await eventsDB.event(event); + await store.event(event); const olderEvent = { ...event, id: '123', created_at: event.created_at - 1 }; - await eventsDB.event(olderEvent); - assertEquals(await eventsDB.query([{ kinds: [0], authors: [event.pubkey] }]), [event]); + await store.event(olderEvent); + assertEquals(await store.query([{ kinds: [0], authors: [event.pubkey] }]), [event]); const newerEvent = { ...event, id: '123', created_at: event.created_at + 1 }; - await eventsDB.event(newerEvent); - assertEquals(await eventsDB.query([{ kinds: [0] }]), [newerEvent]); + await store.event(newerEvent); + assertEquals(await store.query([{ kinds: [0] }]), [newerEvent]); }); Deno.test("throws a RelayError when querying an event with a large 'since'", async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; await assertRejects( - () => eventsDB.query([{ since: 33333333333333 }]), + () => store.query([{ since: 33333333333333 }]), RelayError, 'since filter too far into the future', ); }); Deno.test("throws a RelayError when querying an event with a large 'until'", async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; await assertRejects( - () => eventsDB.query([{ until: 66666666666666 }]), + () => store.query([{ until: 66666666666666 }]), RelayError, 'until filter too far into the future', ); }); Deno.test("throws a RelayError when querying an event with a large 'kind'", async () => { - const { eventsDB } = await createDB(); + await using db = await createTestDB(); + const { store } = db; await assertRejects( - () => eventsDB.query([{ kinds: [99999999999999] }]), + () => store.query([{ kinds: [99999999999999] }]), RelayError, 'kind filter too far into the future', ); diff --git a/src/storages/hydrate.test.ts b/src/storages/hydrate.test.ts index e3b1cf2e..3eb70bf8 100644 --- a/src/storages/hydrate.test.ts +++ b/src/storages/hydrate.test.ts @@ -3,21 +3,23 @@ import { assertEquals } from '@std/assert'; import { DittoEvent } from '@/interfaces/DittoEvent.ts'; import { hydrateEvents } from '@/storages/hydrate.ts'; -import { eventFixture } from '@/test.ts'; +import { createTestDB, eventFixture } from '@/test.ts'; Deno.test('hydrateEvents(): author --- WITHOUT stats', async () => { - const db = new MockRelay(); + const relay = new MockRelay(); + await using db = await createTestDB(); const event0 = await eventFixture('event-0'); const event1 = await eventFixture('event-1'); // Save events to database - await db.event(event0); - await db.event(event1); + await relay.event(event0); + await relay.event(event1); await hydrateEvents({ events: [event1], - store: db, + store: relay, + kysely: db.kysely, }); const expectedEvent = { ...event1, author: event0 }; @@ -25,7 +27,8 @@ Deno.test('hydrateEvents(): author --- WITHOUT stats', async () => { }); Deno.test('hydrateEvents(): repost --- WITHOUT stats', async () => { - const db = new MockRelay(); + const relay = new MockRelay(); + await using db = await createTestDB(); const event0madePost = await eventFixture('event-0-the-one-who-post-and-users-repost'); const event0madeRepost = await eventFixture('event-0-the-one-who-repost'); @@ -33,14 +36,15 @@ Deno.test('hydrateEvents(): repost --- WITHOUT stats', async () => { const event6 = await eventFixture('event-6'); // Save events to database - await db.event(event0madePost); - await db.event(event0madeRepost); - await db.event(event1reposted); - await db.event(event6); + await relay.event(event0madePost); + await relay.event(event0madeRepost); + await relay.event(event1reposted); + await relay.event(event6); await hydrateEvents({ events: [event6], - store: db, + store: relay, + kysely: db.kysely, }); const expectedEvent6 = { @@ -52,7 +56,8 @@ Deno.test('hydrateEvents(): repost --- WITHOUT stats', async () => { }); Deno.test('hydrateEvents(): quote repost --- WITHOUT stats', async () => { - const db = new MockRelay(); + const relay = new MockRelay(); + await using db = await createTestDB(); const event0madeQuoteRepost = await eventFixture('event-0-the-one-who-quote-repost'); const event0 = await eventFixture('event-0'); @@ -60,14 +65,15 @@ Deno.test('hydrateEvents(): quote repost --- WITHOUT stats', async () => { const event1willBeQuoteReposted = await eventFixture('event-1-that-will-be-quote-reposted'); // Save events to database - await db.event(event0madeQuoteRepost); - await db.event(event0); - await db.event(event1quoteRepost); - await db.event(event1willBeQuoteReposted); + await relay.event(event0madeQuoteRepost); + await relay.event(event0); + await relay.event(event1quoteRepost); + await relay.event(event1willBeQuoteReposted); await hydrateEvents({ events: [event1quoteRepost], - store: db, + store: relay, + kysely: db.kysely, }); const expectedEvent1quoteRepost = { @@ -80,7 +86,8 @@ Deno.test('hydrateEvents(): quote repost --- WITHOUT stats', async () => { }); Deno.test('hydrateEvents(): repost of quote repost --- WITHOUT stats', async () => { - const db = new MockRelay(); + const relay = new MockRelay(); + await using db = await createTestDB(); const author = await eventFixture('event-0-makes-repost-with-quote-repost'); const event1 = await eventFixture('event-1-will-be-reposted-with-quote-repost'); @@ -88,14 +95,15 @@ Deno.test('hydrateEvents(): repost of quote repost --- WITHOUT stats', async () const event1quote = await eventFixture('event-1-quote-repost-will-be-reposted'); // Save events to database - await db.event(author); - await db.event(event1); - await db.event(event1quote); - await db.event(event6); + await relay.event(author); + await relay.event(event1); + await relay.event(event1quote); + await relay.event(event6); await hydrateEvents({ events: [event6], - store: db, + store: relay, + kysely: db.kysely, }); const expectedEvent6 = { @@ -107,7 +115,8 @@ Deno.test('hydrateEvents(): repost of quote repost --- WITHOUT stats', async () }); Deno.test('hydrateEvents(): report pubkey and post // kind 1984 --- WITHOUT stats', async () => { - const db = new MockRelay(); + const relay = new MockRelay(); + await using db = await createTestDB(); const authorDictator = await eventFixture('kind-0-dictator'); const authorVictim = await eventFixture('kind-0-george-orwell'); @@ -115,14 +124,15 @@ Deno.test('hydrateEvents(): report pubkey and post // kind 1984 --- WITHOUT stat const event1 = await eventFixture('kind-1-author-george-orwell'); // Save events to database - await db.event(authorDictator); - await db.event(authorVictim); - await db.event(reportEvent); - await db.event(event1); + await relay.event(authorDictator); + await relay.event(authorVictim); + await relay.event(reportEvent); + await relay.event(event1); await hydrateEvents({ events: [reportEvent], - store: db, + store: relay, + kysely: db.kysely, }); const expectedEvent: DittoEvent = { diff --git a/src/storages/hydrate.ts b/src/storages/hydrate.ts index 3c264320..6fe8df6f 100644 --- a/src/storages/hydrate.ts +++ b/src/storages/hydrate.ts @@ -7,16 +7,18 @@ import { Conf } from '@/config.ts'; import { type DittoEvent } from '@/interfaces/DittoEvent.ts'; import { findQuoteTag } from '@/utils/tags.ts'; import { findQuoteInContent } from '@/utils/note.ts'; +import { Kysely } from 'kysely'; interface HydrateOpts { events: DittoEvent[]; store: NStore; signal?: AbortSignal; + kysely?: Kysely; } /** Hydrate events using the provided storage. */ async function hydrateEvents(opts: HydrateOpts): Promise { - const { events, store, signal } = opts; + const { events, store, signal, kysely = await DittoDB.getInstance() } = opts; if (!events.length) { return events; @@ -57,8 +59,8 @@ async function hydrateEvents(opts: HydrateOpts): Promise { } const stats = { - authors: await gatherAuthorStats(cache), - events: await gatherEventStats(cache), + authors: await gatherAuthorStats(cache, kysely), + events: await gatherEventStats(cache, kysely), }; // Dedupe events. @@ -276,7 +278,10 @@ function gatherReportedProfiles({ events, store, signal }: HydrateOpts): Promise } /** Collect author stats from the events. */ -async function gatherAuthorStats(events: DittoEvent[]): Promise { +async function gatherAuthorStats( + events: DittoEvent[], + kysely: Kysely, +): Promise { const pubkeys = new Set( events .filter((event) => event.kind === 0) @@ -287,8 +292,6 @@ async function gatherAuthorStats(events: DittoEvent[]): Promise { +async function gatherEventStats( + events: DittoEvent[], + kysely: Kysely, +): Promise { const ids = new Set( events .filter((event) => event.kind === 1) @@ -315,8 +321,6 @@ async function gatherEventStats(events: DittoEvent[]): Promise { @@ -63,6 +69,91 @@ export async function getTestDB() { }; } +/** Create an database for testing. */ +export const createTestDB = async (databaseUrl?: string) => { + databaseUrl ??= Deno.env.get('DATABASE_URL') ?? 'sqlite://:memory:'; + + let dialect: 'sqlite' | 'postgres' = (() => { + const protocol = databaseUrl.split(':')[0]; + switch (protocol) { + case 'sqlite': + return 'sqlite'; + case 'postgres': + return protocol; + case 'postgresql': + return 'postgres'; + default: + throw new Error(`Unsupported protocol: ${protocol}`); + } + })(); + + const allowToUseDATABASE_URL = Deno.env.get('ALLOW_TO_USE_DATABASE_URL')?.toLowerCase() ?? ''; + if (allowToUseDATABASE_URL !== 'true' && dialect === 'postgres') { + console.warn( + '%cRunning tests with sqlite, if you meant to use Postgres, run again with ALLOW_TO_USE_DATABASE_URL environment variable set to true', + 'color: yellow;', + ); + dialect = 'sqlite'; + } + + console.warn(`Using: ${dialect}`); + + let kysely: Kysely; + + if (dialect === 'sqlite') { + // migration 021_pgfts_index.ts calls 'Conf.db.dialect', + // and this calls the DATABASE_URL environment variable. + // The following line ensures to NOT use the DATABASE_URL that may exist in an .env file. + Deno.env.set('DATABASE_URL', 'sqlite://:memory:'); + + kysely = new Kysely({ + dialect: new DenoSqlite3Dialect({ + database: new Sqlite(':memory:'), + }), + }); + } else { + kysely = new Kysely({ + dialect: new PostgresJSDialect({ + postgres: postgres(Conf.databaseUrl, { + max: Conf.pg.poolSize, + }) as unknown as PostgresJSDialectConfig['postgres'], + }), + log: KyselyLogger, + }); + } + await DittoDB.migrate(kysely); + + const store = new EventsDB(kysely); + + return { + store, + kysely, + [Symbol.asyncDispose]: async () => { + if (dialect === 'postgres') { + for ( + const table of [ + 'author_stats', + 'event_stats', + 'event_zaps', + 'kysely_migration', + 'kysely_migration_lock', + 'nip46_tokens', + 'pubkey_domains', + 'unattached_media', + 'nostr_events', + 'nostr_tags', + 'nostr_pgfts', + 'event_zaps', + ] + ) { + await kysely.schema.dropTable(table).ifExists().cascade().execute(); + } + await kysely.destroy(); + } + }, + }; +}; + export function sleep(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } diff --git a/src/utils/stats.test.ts b/src/utils/stats.test.ts index c3e26595..69633ae3 100644 --- a/src/utils/stats.test.ts +++ b/src/utils/stats.test.ts @@ -1,11 +1,11 @@ import { assertEquals } from '@std/assert'; import { generateSecretKey, getPublicKey } from 'nostr-tools'; -import { genEvent, getTestDB } from '@/test.ts'; +import { createTestDB, genEvent } from '@/test.ts'; import { countAuthorStats, getAuthorStats, getEventStats, getFollowDiff, updateStats } from '@/utils/stats.ts'; Deno.test('updateStats with kind 1 increments notes count', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const sk = generateSecretKey(); const pubkey = getPublicKey(sk); @@ -18,7 +18,7 @@ Deno.test('updateStats with kind 1 increments notes count', async () => { }); Deno.test('updateStats with kind 1 increments replies count', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const sk = generateSecretKey(); @@ -36,7 +36,7 @@ Deno.test('updateStats with kind 1 increments replies count', async () => { }); Deno.test('updateStats with kind 5 decrements notes count', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const sk = generateSecretKey(); const pubkey = getPublicKey(sk); @@ -54,7 +54,7 @@ Deno.test('updateStats with kind 5 decrements notes count', async () => { }); Deno.test('updateStats with kind 3 increments followers count', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); await updateStats({ ...db, event: genEvent({ kind: 3, tags: [['p', 'alex']] }) }); await updateStats({ ...db, event: genEvent({ kind: 3, tags: [['p', 'alex']] }) }); @@ -66,7 +66,7 @@ Deno.test('updateStats with kind 3 increments followers count', async () => { }); Deno.test('updateStats with kind 3 decrements followers count', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const sk = generateSecretKey(); const follow = genEvent({ kind: 3, tags: [['p', 'alex']], created_at: 0 }, sk); @@ -92,7 +92,7 @@ Deno.test('getFollowDiff returns added and removed followers', () => { }); Deno.test('updateStats with kind 6 increments reposts count', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const note = genEvent({ kind: 1 }); await updateStats({ ...db, event: note }); @@ -108,7 +108,7 @@ Deno.test('updateStats with kind 6 increments reposts count', async () => { }); Deno.test('updateStats with kind 5 decrements reposts count', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const note = genEvent({ kind: 1 }); await updateStats({ ...db, event: note }); @@ -127,7 +127,7 @@ Deno.test('updateStats with kind 5 decrements reposts count', async () => { }); Deno.test('updateStats with kind 7 increments reactions count', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const note = genEvent({ kind: 1 }); await updateStats({ ...db, event: note }); @@ -143,7 +143,7 @@ Deno.test('updateStats with kind 7 increments reactions count', async () => { }); Deno.test('updateStats with kind 5 decrements reactions count', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const note = genEvent({ kind: 1 }); await updateStats({ ...db, event: note }); @@ -162,7 +162,7 @@ Deno.test('updateStats with kind 5 decrements reactions count', async () => { }); Deno.test('countAuthorStats counts author stats from the database', async () => { - await using db = await getTestDB(); + await using db = await createTestDB(); const sk = generateSecretKey(); const pubkey = getPublicKey(sk);