dragonflight/services/editor/apps/image/src/app.test.ts
Zac b68f0c6aba feat(editor): integrate openreel-video as services/editor with MAM hooks
Vendored Augani/openreel-video (MIT) into services/editor and wired it to the MAM. Editor runs as its own container on port 47435. Library assets pull in via ?asset=<uuid>; render exports route back via POST /api/v1/upload/simple. Sidebar Editor link on every page; Edit button on every preview modal. See services/editor/INTEGRATION.md for the patch map.
2026-05-17 21:44:37 -04:00

184 lines
7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, it, expect } from 'vitest';
import { parseProject } from './services/project-schema';
import { migrateProject, CURRENT_VERSION } from './services/project-migration';
// ── App smoke tests ──────────────────────────────────────────────────────────
//
// These tests exercise the integration seam between the project schema,
// migration utilities, and the store to confirm the whole pipeline is wired up
// and importing correctly.
describe('OpenReel Image baseline smoke tests', () => {
// Schema is importable.
it('project schema module is importable', () => {
expect(typeof parseProject).toBe('function');
});
// Migration is importable and exposes the current version constant.
it('migration module exposes CURRENT_VERSION', () => {
expect(typeof CURRENT_VERSION).toBe('number');
expect(CURRENT_VERSION).toBeGreaterThanOrEqual(1);
});
// A minimal valid project document passes schema validation.
it('validates a minimal valid project', () => {
const baseLayer = {
id: 'l1',
name: 'Layer',
type: 'text' as const,
visible: true,
locked: false,
transform: {
x: 0, y: 0, width: 200, height: 50, rotation: 0,
scaleX: 1, scaleY: 1, skewX: 0, skewY: 0, opacity: 1,
},
blendMode: { mode: 'normal' as const },
shadow: { enabled: false, color: 'rgba(0,0,0,0.5)', blur: 10, offsetX: 0, offsetY: 4 },
innerShadow: { enabled: false, color: 'rgba(0,0,0,0.5)', blur: 10, offsetX: 2, offsetY: 2 },
stroke: { enabled: false, color: '#000000', width: 1, style: 'solid' as const },
glow: { enabled: false, color: '#ffffff', blur: 20, intensity: 1 },
filters: {
brightness: 100, contrast: 100, saturation: 100, hue: 0, exposure: 0,
vibrance: 0, highlights: 0, shadows: 0, clarity: 0, blur: 0,
blurType: 'gaussian' as const, blurAngle: 0, sharpen: 0, vignette: 0,
grain: 0, sepia: 0, invert: 0,
},
parentId: null,
flipHorizontal: false,
flipVertical: false,
mask: null,
clippingMask: false,
levels: {
enabled: false,
master: { inputBlack: 0, inputWhite: 255, gamma: 1, outputBlack: 0, outputWhite: 255 },
red: { inputBlack: 0, inputWhite: 255, gamma: 1, outputBlack: 0, outputWhite: 255 },
green: { inputBlack: 0, inputWhite: 255, gamma: 1, outputBlack: 0, outputWhite: 255 },
blue: { inputBlack: 0, inputWhite: 255, gamma: 1, outputBlack: 0, outputWhite: 255 },
},
curves: {
enabled: false,
master: { points: [{ input: 0, output: 0 }, { input: 255, output: 255 }] },
red: { points: [{ input: 0, output: 0 }, { input: 255, output: 255 }] },
green: { points: [{ input: 0, output: 0 }, { input: 255, output: 255 }] },
blue: { points: [{ input: 0, output: 0 }, { input: 255, output: 255 }] },
},
colorBalance: {
enabled: false,
shadows: { cyanRed: 0, magentaGreen: 0, yellowBlue: 0 },
midtones: { cyanRed: 0, magentaGreen: 0, yellowBlue: 0 },
highlights: { cyanRed: 0, magentaGreen: 0, yellowBlue: 0 },
preserveLuminosity: true,
},
selectiveColor: {
enabled: false, method: 'relative' as const,
reds: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
yellows: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
greens: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
cyans: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
blues: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
magentas: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
whites: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
neutrals: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
blacks: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
},
blackWhite: {
enabled: false, reds: 40, yellows: 60, greens: 40, cyans: 60, blues: 20,
magentas: 80, tintEnabled: false, tintHue: 35, tintSaturation: 25,
},
photoFilter: {
enabled: false, filter: 'warming-85' as const, color: '#ec8a00',
density: 25, preserveLuminosity: true,
},
channelMixer: {
enabled: false, monochrome: false,
red: { red: 100, green: 0, blue: 0, constant: 0 },
green: { red: 0, green: 100, blue: 0, constant: 0 },
blue: { red: 0, green: 0, blue: 100, constant: 0 },
},
gradientMap: {
enabled: false,
stops: [{ position: 0, color: '#000000' }, { position: 1, color: '#ffffff' }],
reverse: false, dither: false,
},
posterize: { enabled: false, levels: 4 },
threshold: { enabled: false, level: 128 },
content: 'Hello',
style: {
fontFamily: 'Inter', fontSize: 24, fontWeight: 400,
fontStyle: 'normal' as const, textDecoration: 'none' as const,
textAlign: 'left' as const, verticalAlign: 'top' as const,
lineHeight: 1.4, letterSpacing: 0, fillType: 'solid' as const,
color: '#ffffff', gradient: null, strokeColor: null, strokeWidth: 0,
backgroundColor: null, backgroundPadding: 8, backgroundRadius: 4,
textShadow: { enabled: false, color: 'rgba(0,0,0,0.5)', blur: 4, offsetX: 0, offsetY: 2 },
},
autoSize: true,
};
const validProject = {
id: 'p1',
name: 'Smoke Test',
createdAt: Date.now(),
updatedAt: Date.now(),
version: 1,
artboards: [
{
id: 'ab1',
name: 'Artboard 1',
size: { width: 1080, height: 1080 },
background: { type: 'color', color: '#ffffff' },
layerIds: ['l1'],
position: { x: 0, y: 0 },
},
],
layers: { l1: baseLayer },
assets: {},
activeArtboardId: 'ab1',
};
const result = parseProject(validProject);
expect(result.success).toBe(true);
});
// An invalid document is rejected.
it('rejects an invalid project document', () => {
const result = parseProject({ id: 42, broken: true });
expect(result.success).toBe(false);
});
// Migration promotes a v0 document to v1.
it('migrates a v0 project to v1', () => {
const v0 = {
id: 'old',
name: 'Legacy',
createdAt: 0,
updatedAt: 0,
artboards: [{ id: 'ab-old', name: 'Page 1' }],
layers: {},
assets: {},
};
const migrated = migrateProject(v0 as Record<string, unknown>);
expect(migrated.version).toBe(1);
expect(migrated.activeArtboardId).toBe('ab-old');
});
// A project that already has version 1 is returned unchanged.
it('does not re-migrate a current-version project', () => {
const v1 = {
id: 'current',
name: 'New',
createdAt: 0,
updatedAt: 0,
version: 1,
artboards: [],
layers: {},
assets: {},
activeArtboardId: null,
};
const migrated = migrateProject(v1 as Record<string, unknown>);
expect(migrated.version).toBe(1);
});
});