test: cover publishing, authentication and storage persistence

This commit is contained in:
2026-09-15 21:48:15 +03:30
parent ee9f49e4b7
commit c17b4b57b2
11 changed files with 294 additions and 23 deletions

58
tests/content.test.ts Normal file
View File

@@ -0,0 +1,58 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { openDatabase, migrateDatabase } from '../src/server/db';
import { seedDatabase } from '../src/server/seed';
import { readContent, saveContent, resolvePublicRoute, deleteContent } from '../src/server/content';
import { importLegacy } from '../src/server/legacy-import';
function setup(t: { after: (fn: () => void) => void }) {
const directory = mkdtempSync(path.join(tmpdir(), 'portfolio-test-'));
const connection = openDatabase(directory);
migrateDatabase(connection); seedDatabase(connection);
t.after(() => { connection.sqlite.close(); rmSync(directory, { recursive: true, force: true }); });
return connection;
}
test('seed is idempotent and content saves are validated and immediately readable', t => {
const connection = setup(t); const original = readContent(connection);
const hero = original.sections.find(section => section.key === 'hero')!;
hero.translations.en.name = 'Test owner';
saveContent(connection, 'sections', hero);
seedDatabase(connection);
assert.equal(resolvePublicRoute(readContent(connection)).portfolio.messages.hero.name, 'Test owner');
assert.throws(() => saveContent(connection, 'sections', { ...hero, translations: { en: { name: '' } } }));
assert.equal(resolvePublicRoute(readContent(connection)).portfolio.messages.hero.name, 'Test owner');
assert.throws(() => importLegacy(connection), /before content has been edited/);
saveContent(connection, 'sections', { ...hero, visible: false });
assert.ok(!JSON.stringify(resolvePublicRoute(readContent(connection)).portfolio).includes('Test owner'));
});
test('runtime projects and arbitrary locales resolve, hidden and missing URLs do not', t => {
const connection = setup(t);
saveContent(connection, 'languages', { code: 'ar', name: 'العربية', direction: 'rtl', enabled: true, messages: { 'projects.viewCaseStudy': 'دراسة الحالة' } });
assert.equal(resolvePublicRoute(readContent(connection), ['ar']).portfolio.direction, 'rtl');
assert.equal(resolvePublicRoute(readContent(connection), ['ar']).portfolio.messages.projects.viewCaseStudy, 'دراسة الحالة');
const project = readContent(connection).entries.find(entry => entry.kind === 'projects')!;
saveContent(connection, 'entries', { ...project, id: 'new-project' });
assert.equal(resolvePublicRoute(readContent(connection), ['ar','projects','new-project']).project?.id, 'new-project');
saveContent(connection, 'entries', { ...project, id: 'new-project', visible: false });
assert.throws(() => resolvePublicRoute(readContent(connection), ['projects','new-project']), /not found/);
deleteContent(connection, 'entries', project.id);
assert.throws(() => resolvePublicRoute(readContent(connection), ['projects',project.id]), /not found/);
for (const parts of [['en'], ['unknown'], ['ar','bad'], ['admin']]) assert.throws(() => resolvePublicRoute(readContent(connection), parts));
assert.throws(() => saveContent(connection, 'languages', { code: 'en', name: 'English', direction: 'ltr', enabled: false, messages: {} }));
});
test('legacy import preserves English and Persian projects and only runs once', t => {
const connection = setup(t); importLegacy(connection);
const snapshot = readContent(connection);
assert.equal(resolvePublicRoute(snapshot, ['projects','qlockify']).project?.title, 'Qlockify');
assert.equal(resolvePublicRoute(snapshot, ['fa']).portfolio.direction, 'rtl');
assert.ok(snapshot.entries.length > 5);
assert.throws(() => importLegacy(connection));
});
test('startup rejects a database migrated by an incompatible application image', t => {
const connection = setup(t);
connection.sqlite.prepare('INSERT INTO __drizzle_migrations (hash, created_at) VALUES (?, ?)').run('future-migration', Date.now() + 100000);
assert.throws(() => migrateDatabase(connection), /do not match/);
});