Add tests for db:export filters

This commit is contained in:
Siddharth Singh 2024-08-25 19:41:35 +05:30
parent fb199123be
commit 125dfb54f3
No known key found for this signature in database
2 changed files with 113 additions and 9 deletions

94
scripts/db-export.test.ts Normal file
View file

@ -0,0 +1,94 @@
import { assertEquals, assertThrows } from '@std/assert';
import { buildFilter } from './db-export.ts';
Deno.test('buildFilter should return an empty filter when no arguments are provided', () => {
const filter = buildFilter({});
assertEquals(Object.keys(filter).length, 0);
});
Deno.test('buildFilter should correctly handle valid authors', () => {
const filter = buildFilter({
authors: ['a'.repeat(64)],
});
assertEquals(filter.authors, ['a'.repeat(64)]);
});
Deno.test('buildFilter throws on invalid author pubkey', () => {
assertThrows(
() => {
buildFilter({
authors: ['invalid_pubkey'],
});
},
Error,
'ERROR: Invalid pubkey invalid_pubkey supplied.',
);
});
Deno.test('buildFilter should correctly handle valid ids', () => {
const filter = buildFilter({
ids: ['b'.repeat(64)],
});
assertEquals(filter.ids, ['b'.repeat(64)]);
});
Deno.test('buildFilter should throw on invalid event IDs', () => {
assertThrows(
() => {
buildFilter({
ids: ['invalid_id'],
});
},
Error,
'ERROR: Invalid event ID invalid_id supplied.',
);
});
Deno.test('buildFilter should correctly handle tag shortcuts', () => {
const filter = buildFilter({
d: 'value1',
e: 'a'.repeat(64),
p: 'b'.repeat(64),
});
assertEquals(filter['#d'], ['value1']);
assertEquals(filter['#e'], ['a'.repeat(64)]);
assertEquals(filter['#p'], ['b'.repeat(64)]);
});
Deno.test('buildFilter should correctly handle since and until args', () => {
const filter = buildFilter({
since: 1000,
until: 2000,
});
assertEquals(filter.since, 1000);
assertEquals(filter.until, 2000);
});
Deno.test('buildFilter should correctly handle search field', () => {
const filter = buildFilter({
search: 'search_term',
});
assertEquals(filter.search, 'search_term');
});
Deno.test('buildFilter should correctly handle tag k-v pairs', () => {
const filter = buildFilter({
tags: ['tag1=value1', 'tag2=value2'],
});
assertEquals(filter['#tag1'], ['value1']);
assertEquals(filter['#tag2'], ['value2']);
});
Deno.test('buildFilter should correctly handle limit specifier', () => {
const filter = buildFilter({
limit: 10,
});
assertEquals(filter.limit, 10);
});

View file

@ -2,8 +2,6 @@ import { Storages } from '@/storages.ts';
import { NostrFilter } from '@nostrify/nostrify'; import { NostrFilter } from '@nostrify/nostrify';
import { Command, InvalidOptionArgumentError } from 'commander'; import { Command, InvalidOptionArgumentError } from 'commander';
const store = await Storages.db();
interface ExportFilter { interface ExportFilter {
authors?: string[]; authors?: string[];
ids?: string[]; ids?: string[];
@ -47,11 +45,11 @@ function die(code: number, ...args: any[]) {
function tagFilterShortcut(name: 'd' | 'e' | 'p', value: string) { function tagFilterShortcut(name: 'd' | 'e' | 'p', value: string) {
const val = [value]; const val = [value];
if (findInvalid(val)) die(1, `ERROR: Invalid value supplied for ${name}-tag.`); if (findInvalid(val)) throw new Error(`ERROR: Invalid value supplied for ${name}-tag.`);
return val; return val;
} }
async function exportEvents(args: ExportFilter) { export function buildFilter(args: ExportFilter) {
const filter: NostrFilter = {}; const filter: NostrFilter = {};
const { authors, ids, kinds, d, e, limit, p, search, since, until, tags } = args; const { authors, ids, kinds, d, e, limit, p, search, since, until, tags } = args;
if (since) { if (since) {
@ -62,18 +60,19 @@ async function exportEvents(args: ExportFilter) {
} }
if (authors && authors.length) { if (authors && authors.length) {
const invalid = findInvalid(authors); const invalid = findInvalid(authors);
if (invalid) die(1, `ERROR: Invalid pubkey ${invalid} supplied.`); if (invalid) throw new Error(`ERROR: Invalid pubkey ${invalid} supplied.`);
filter.authors = authors; filter.authors = authors;
} }
if (ids) { if (ids) {
const invalid = findInvalid(ids); const invalid = findInvalid(ids);
if (invalid) die(1, `ERROR: Invalid event ID ${invalid} supplied.`); if (invalid) throw new Error(`ERROR: Invalid event ID ${invalid} supplied.`);
filter.ids = ids;
} }
if (kinds && kinds.length) { if (kinds && kinds.length) {
filter.kinds = kinds; filter.kinds = kinds;
} }
if (d) { if (d) {
filter['#d'] = tagFilterShortcut('d', d); filter['#d'] = [d];
} }
if (e) { if (e) {
filter['#e'] = tagFilterShortcut('e', e); filter['#e'] = tagFilterShortcut('e', e);
@ -94,6 +93,19 @@ async function exportEvents(args: ExportFilter) {
} }
} }
return filter;
}
async function exportEvents(args: ExportFilter) {
const store = await Storages.db();
let filter: NostrFilter = {};
try {
filter = buildFilter(args);
} catch (e) {
die(1, e.message || e.toString());
}
let count = 0; let count = 0;
for await (const msg of store.req([filter])) { for await (const msg of store.req([filter])) {
if (msg[0] === 'EOSE') { if (msg[0] === 'EOSE') {
@ -144,5 +156,3 @@ if (import.meta.main) {
await exporter.parseAsync(Deno.args, { from: 'user' }); await exporter.parseAsync(Deno.args, { from: 'user' });
} }
Deno.exit();