test: create createTestDB function, supports both Sqlite and Postgres

This commit is contained in:
P. Reis 2024-07-05 17:26:27 -03:00
parent 12b2032d87
commit 2154cf011b

View file

@ -4,11 +4,23 @@ import path from 'node:path';
import { Database as Sqlite } from '@db/sqlite';
import { NDatabase, NostrEvent } from '@nostrify/nostrify';
import { DenoSqlite3Dialect } from '@soapbox/kysely-deno-sqlite';
import { FileMigrationProvider, Kysely, Migrator } from 'kysely';
import {
FileMigrationProvider,
Kysely,
Migrator,
PostgresAdapter,
PostgresIntrospector,
PostgresQueryCompiler,
} from 'kysely';
import { finalizeEvent, generateSecretKey } from 'nostr-tools';
import { DittoDB } from '@/db/DittoDB.ts';
import { DittoTables } from '@/db/DittoTables.ts';
import { purifyEvent } from '@/storages/hydrate.ts';
import { PostgreSQLDriver } from 'kysely_deno_postgres';
import { Pool } from 'postgres';
import { KyselyLogger } from '@/db/KyselyLogger.ts';
import { EventsDB } from '@/storages/EventsDB.ts';
/** Import an event fixture by name in tests. */
export async function eventFixture(name: string): Promise<NostrEvent> {
@ -62,3 +74,84 @@ export async function getTestDB() {
[Symbol.asyncDispose]: () => kysely.destroy(),
};
}
/** Create an database for testing. */
export const createTestDB = async (databaseUrl?: string) => {
databaseUrl ??= Deno.env.get('DATABASE_URL') ?? 'sqlite://:memory:';
const 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}`);
}
})();
let kysely: Kysely<DittoTables>;
if (dialect === 'sqlite') {
Deno.env.set('DATABASE_URL', 'sqlite://:memory:'); // hack, refactor all, 021 migration
kysely = new Kysely<DittoTables>({
dialect: new DenoSqlite3Dialect({
database: new Sqlite(':memory:'),
}),
});
} else {
//kysely = await DittoDB.getInstance();
kysely = new Kysely({
dialect: {
createAdapter() {
return new PostgresAdapter();
},
createDriver() {
return new PostgreSQLDriver(new Pool(databaseUrl, 10, true));
},
createIntrospector(db: Kysely<unknown>) {
return new PostgresIntrospector(db);
},
createQueryCompiler() {
return new PostgresQueryCompiler();
},
},
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();
}
},
};
};