Add db seed and integration, update scripts in package.json
This commit is contained in:
1 parent
d505320c50
commit
45ca4de0ad
4 files changed
+112
-1
No files matched your search
+1
-1
@@ -4,7 +4,7 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "tsx run-tests.ts",
|
||||
"test": "node --import tsx --test \"src/**/*.test.ts\"",
|
||||
"db:migrate": "dotenv dbmate up"
|
||||
},
|
||||
"keywords": [],
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { describe, it, before, after } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { Pool } from 'pg';
|
||||
import { CategoryRepository } from './category.repository.ts';
|
||||
import { seedCategoryTable, clearCategoryTable } from './test-seed.ts';
|
||||
import { join } from 'node:path';
|
||||
import process from 'node:process';
|
||||
|
||||
// load the local .env file
|
||||
try {
|
||||
process.loadEnvFile(join(process.cwd(), '.env'));
|
||||
} catch (e) {
|
||||
console.warn('⚠️ Warning: No local .env file found. Falling back to default system environment tokens.');
|
||||
}
|
||||
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL || process.env.INTERNAL_PROD_DB_URL
|
||||
});
|
||||
|
||||
describe('CategoryRepository - Live Database Integration Tests', () => {
|
||||
const repository = new CategoryRepository(pool);
|
||||
|
||||
// Setup: Seed the database before executing integration items
|
||||
before(async () => {
|
||||
await seedCategoryTable(pool);
|
||||
});
|
||||
|
||||
// Teardown: Clean out the database after tests wrap up
|
||||
after(async () => {
|
||||
await clearCategoryTable(pool);
|
||||
await pool.end();
|
||||
});
|
||||
|
||||
it('should fetch all deep descendants using the <@ ltree operator', async () => {
|
||||
const results = await repository.findAllDescendants('Top.Science');
|
||||
|
||||
// Should return Science, Astronomy, and Astrophysics (3 nodes)
|
||||
assert.equal(results.length, 3);
|
||||
assert.equal(results[0].name, 'Science');
|
||||
assert.equal(results[1].name, 'Astronomy');
|
||||
assert.equal(results[2].name, 'Astrophysics');
|
||||
});
|
||||
|
||||
it('should isolate only immediate structural child links via findDirectChildren()', async () => {
|
||||
const results = await repository.findDirectChildren('Top');
|
||||
|
||||
// Top has two immediate children: Science and Hobbies
|
||||
assert.equal(results.length, 2);
|
||||
|
||||
const names = results.map(r => r.name);
|
||||
assert.ok(names.includes('Science'));
|
||||
assert.ok(names.includes('Hobbies'));
|
||||
assert.ok(!names.includes('Astronomy')); // Deeper descendant, should be skipped
|
||||
});
|
||||
|
||||
it('should resolve breadcrumb history using the @> ltree operator', async () => {
|
||||
const results = await repository.findAncestors('Top.Science.Astronomy');
|
||||
|
||||
// Should trace: Root (Top) -> Science -> Astronomy
|
||||
assert.equal(results.length, 3);
|
||||
assert.equal(results[0].path, 'Top');
|
||||
assert.equal(results[1].path, 'Top.Science');
|
||||
assert.equal(results[2].path, 'Top.Science.Astronomy');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Pool } from 'pg';
|
||||
import { seedCategoryTable } from './test-seed.ts';
|
||||
import 'dotenv/config'; // Requires npm install dotenv if you want to parse local .env assets
|
||||
|
||||
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
||||
|
||||
async function run() {
|
||||
console.log('🌱 Seeding target database connection schema...');
|
||||
try {
|
||||
await seedCategoryTable(pool);
|
||||
console.log('✅ Database hierarchy seed operations completed successfully.');
|
||||
} catch (error) {
|
||||
console.error('❌ Database seed operations failed:', error);
|
||||
} finally {
|
||||
await pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Pool } from 'pg';
|
||||
|
||||
export async function seedCategoryTable(pool: Pool): Promise<void> {
|
||||
// 1. Wipe old records to ensure clean execution states
|
||||
await pool.query('TRUNCATE TABLE categories RESTART IDENTITY CASCADE;');
|
||||
|
||||
// 2. Insert standard ltree seed records
|
||||
const seedQueries = [
|
||||
{ name: 'Root', path: 'Top' },
|
||||
{ name: 'Science', path: 'Top.Science' },
|
||||
{ name: 'Astronomy', path: 'Top.Science.Astronomy' },
|
||||
{ name: 'Astrophysics', path: 'Top.Science.Astronomy.Astrophysics' },
|
||||
{ name: 'Hobbies', path: 'Top.Hobbies' },
|
||||
{ name: 'Gardening', path: 'Top.Hobbies.Gardening' },
|
||||
];
|
||||
|
||||
for (const record of seedQueries) {
|
||||
await pool.query(
|
||||
'INSERT INTO categories (name, path) VALUES ($1, $2::ltree);',
|
||||
[record.name, record.path]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function clearCategoryTable(pool: Pool): Promise<void> {
|
||||
await pool.query('TRUNCATE TABLE categories RESTART IDENTITY CASCADE;');
|
||||
}
|
||||
Reference in new issue
Block a user