73 lines
4.5 KiB
JavaScript
73 lines
4.5 KiB
JavaScript
import { rmSync, mkdirSync, existsSync, unlinkSync } from 'fs';
|
|
import { resolve } from 'path';
|
|
import sharp from 'sharp';
|
|
|
|
const root = resolve('.');
|
|
const dbPath = resolve(root, 'db', 'vendoo.db');
|
|
const uploadRoot = resolve(root, 'uploads');
|
|
rmSync(dbPath, { force: true });
|
|
rmSync(`${dbPath}-wal`, { force: true });
|
|
rmSync(`${dbPath}-shm`, { force: true });
|
|
rmSync(uploadRoot, { recursive: true, force: true });
|
|
mkdirSync(resolve(uploadRoot, 'test'), { recursive: true });
|
|
await sharp({ create: { width: 900, height: 1200, channels: 3, background: '#d8c1a7' } }).png().toFile(resolve(uploadRoot, 'test', 'produkt.png'));
|
|
|
|
const batch = await import('../lib/image-batch-jobs.mjs');
|
|
const { db } = await import('../lib/db.mjs');
|
|
const profiles = batch.listImageBatchProfiles();
|
|
if (profiles.length < 8) throw new Error(`Nur ${profiles.length} integrierte Profile gefunden.`);
|
|
const custom = batch.createImageBatchProfile({
|
|
name: 'Test WebP', description: 'Verifikation', filename_pattern: '{name}-test-{index}',
|
|
operations: { resize: { width: 640, height: 640, fit: 'contain', background: '#ffffff' }, format: 'webp', quality: 82 },
|
|
});
|
|
if (!custom?.id || custom.is_builtin) throw new Error('Eigenes Profil wurde nicht korrekt angelegt.');
|
|
|
|
const job = batch.createImageBatchJob({ source_paths: ['test/produkt.png'], profile_ids: [custom.id], name: 'Batch-Verifikation' });
|
|
batch.startImageBatchJobLoop();
|
|
const waitFor = async (id, accepted, timeout = 15000) => {
|
|
const started = Date.now();
|
|
while (Date.now() - started < timeout) {
|
|
const current = batch.getImageBatchJob(id);
|
|
if (accepted.includes(current?.status)) return current;
|
|
await new Promise(resolveWait => setTimeout(resolveWait, 100));
|
|
}
|
|
throw new Error(`Timeout für Auftrag ${id}`);
|
|
};
|
|
const completed = await waitFor(job.id, ['completed','partial','failed']);
|
|
if (completed.status !== 'completed') throw new Error(`Batch-Auftrag endete mit ${completed.status}: ${completed.items?.[0]?.error_message || ''}`);
|
|
const output = completed.items[0]?.output_path;
|
|
if (!output || !existsSync(resolve(uploadRoot, output))) throw new Error('Batch-Ausgabedatei fehlt.');
|
|
const meta = await sharp(resolve(uploadRoot, output)).metadata();
|
|
if (meta.width !== 640 || meta.height !== 640 || meta.format !== 'webp') throw new Error(`Falsche Ausgabe: ${meta.width}x${meta.height} ${meta.format}`);
|
|
const version = db.prepare("SELECT * FROM image_edit_versions WHERE output_path = ? AND context = 'batch'").get(output);
|
|
if (!version) throw new Error('Nicht destruktive Batch-Version fehlt in image_edit_versions.');
|
|
|
|
await sharp({ create: { width: 700, height: 500, channels: 3, background: '#eeeeee' } }).jpeg().toFile(resolve(uploadRoot, 'test', 'pause.jpg'));
|
|
const pausedJob = batch.createImageBatchJob({ source_paths: ['test/pause.jpg'], profile_ids: [profiles[0].id], name: 'Pause-Verifikation' });
|
|
batch.pauseImageBatchJob(pausedJob.id);
|
|
await new Promise(resolveWait => setTimeout(resolveWait, 300));
|
|
if (batch.getImageBatchJob(pausedJob.id).status !== 'paused') throw new Error('Pause wurde nicht persistiert.');
|
|
batch.resumeImageBatchJob(pausedJob.id);
|
|
const resumed = await waitFor(pausedJob.id, ['completed','partial','failed']);
|
|
if (resumed.status !== 'completed') throw new Error('Fortgesetzter Auftrag wurde nicht fertig.');
|
|
|
|
await sharp({ create: { width: 400, height: 400, channels: 3, background: '#ffffff' } }).png().toFile(resolve(uploadRoot, 'test', 'fail.png'));
|
|
const retryJob = batch.createImageBatchJob({ source_paths: ['test/fail.png'], profile_ids: [custom.id], name: 'Retry-Verifikation' });
|
|
unlinkSync(resolve(uploadRoot, 'test', 'fail.png'));
|
|
const failed = await waitFor(retryJob.id, ['failed','partial']);
|
|
if (failed.status !== 'failed') throw new Error('Fehlersimulation wurde nicht als fehlgeschlagen erkannt.');
|
|
await sharp({ create: { width: 400, height: 400, channels: 3, background: '#ffffff' } }).png().toFile(resolve(uploadRoot, 'test', 'fail.png'));
|
|
batch.retryImageBatchJob(retryJob.id);
|
|
const retried = await waitFor(retryJob.id, ['completed','partial','failed']);
|
|
if (retried.status !== 'completed') throw new Error('Wiederholung war nicht erfolgreich.');
|
|
|
|
const outputs = batch.getImageBatchOutputPaths(job.id);
|
|
if (outputs.length !== 1) throw new Error('ZIP-Ausgabeliste ist inkorrekt.');
|
|
console.log(JSON.stringify({ ok: true, profiles: profiles.length, output, dimensions: `${meta.width}x${meta.height}`, pause_resume: true, retry: true }, null, 2));
|
|
|
|
db.close();
|
|
rmSync(dbPath, { force: true });
|
|
rmSync(`${dbPath}-wal`, { force: true });
|
|
rmSync(`${dbPath}-shm`, { force: true });
|
|
rmSync(uploadRoot, { recursive: true, force: true });
|