import { execFileSync } from 'node:child_process'; import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import path from 'node:path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { closeDatabase } from './database.js'; import { createTool, listTools, updateTool } from './tools.js'; let directory: string; beforeEach(() => { directory = mkdtempSync(path.join(tmpdir(), 'sendewerk-tools-test-')); process.env.SENDEWERK_DB_PATH = path.join(directory, 'test.sqlite'); process.env.SENDEWERK_UPLOAD_DIR = path.join(directory, 'uploads'); execFileSync(process.execPath, ['scripts/migrate.mjs'], { cwd: process.cwd(), env: process.env }); execFileSync(process.execPath, ['scripts/seed.mjs'], { cwd: process.cwd(), env: process.env }); }); afterEach(() => { closeDatabase(); delete process.env.SENDEWERK_DB_PATH; delete process.env.SENDEWERK_UPLOAD_DIR; rmSync(directory, { recursive: true, force: true }); }); describe('tool catalog', () => { it('validates, classifies and deactivates tools without deleting them', () => { const id = createTool({ name: 'Tierlist', startUrl: 'https://example.com/tierlist', description: 'Gemeinsames Ranking', iconName: 'ranking-star', isActive: true, formatIds: ['format-quiz'] }); expect(listTools()).toEqual([ { id, name: 'Tierlist', startUrl: 'https://example.com/tierlist', description: 'Gemeinsames Ranking', iconName: 'ranking-star', isActive: true, formatIds: ['format-quiz'] } ]); updateTool(id, { name: 'Tierlist', startUrl: '', description: '', iconName: 'list-ol', isActive: false, formatIds: [] }); expect(listTools()).toEqual([]); expect(listTools(true)[0]).toMatchObject({ id, iconName: 'list-ol', isActive: false }); expect(() => createTool({ name: 'Unsicher', startUrl: 'javascript:alert(1)', description: '', iconName: 'wrench', isActive: true, formatIds: [] }) ).toThrow('INVALID_TOOL_URL'); expect(() => createTool({ name: 'Unbekanntes Icon', startUrl: '', description: '', iconName: 'kein-font-awesome-icon', isActive: true, formatIds: [] }) ).toThrow('INVALID_ICON'); }); });