mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-11 17:26:45 +02:00
Montage (étape 3) : - Nouvelle composition ReelVideo : sous-titres animés mot à mot (3 styles : Impact, Surligné, Épuré), logo, effet de fin et fondu, en React - Le service Python prépare l'image (recadrage, HDR, stabilisation, dernière image figée) et la piste son finale (/prepare-reel) ; Remotion compose - Reels d'images sur les mêmes composants, avec le vrai minutage de la voix - Police Montserrat embarquée (plus de dépendance à Google Fonts) - REEL_RENDERER=ffmpeg conserve le rendu FFmpeg, plus rapide, en secours - Script de pré-bundle réparé (échouait en silence : require en ESM) Interface (étape 4) : - Aperçu en direct avec @remotion/player, identique au rendu final ; la voix testée cale les sous-titres, sinon minutage estimé - Choix du style de sous-titres sur les 4 pages Reel - Vraie progression : étape réelle du rendu, échecs visibles 24 h avec leur cause ; fin de la barre simulée et du faux « publié avec succès » Outillage (étape 5) : - Tests vitest (minutage identique à Python, validation, sécurité) et pytest ; CI GitHub Actions (tsc, tests, build, ruff) - Captures d'écran, out.mp4 et scripts de test retirés de la racine Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Ze4bs7tpF1KGWUk6ZZSZ4
36 lines
1.4 KiB
TypeScript
36 lines
1.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { imagesReelParamsSchema, ttsPreviewSchema, videoReelParamsSchema } from "./reel";
|
|
|
|
describe("videoReelParamsSchema", () => {
|
|
it("exige une vidéo et une page, avec des messages lisibles", () => {
|
|
const result = videoReelParamsSchema.safeParse({ pageIds: [] });
|
|
expect(result.success).toBe(false);
|
|
expect(result.error?.issues.map((i) => i.message)).toContain("Vidéo requise");
|
|
});
|
|
|
|
it("applique les valeurs par défaut", () => {
|
|
const params = videoReelParamsSchema.parse({ videoMediaId: "v", pageIds: ["p"] });
|
|
expect(params).toMatchObject({ captionStyle: "bold", stabilize: false, drawText: true, musicVolume: 0.25 });
|
|
});
|
|
|
|
it("accepte les anciens paramètres encore stockés dans des jobs", () => {
|
|
expect(videoReelParamsSchema.safeParse({ videoMediaId: "v", pageIds: ["p"], wordDuration: 0.6 }).success).toBe(true);
|
|
});
|
|
|
|
it("refuse un moteur de voix inconnu", () => {
|
|
expect(videoReelParamsSchema.safeParse({ videoMediaId: "v", pageIds: ["p"], ttsEngine: "autre" }).success).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("imagesReelParamsSchema", () => {
|
|
it("limite à 4 images", () => {
|
|
expect(imagesReelParamsSchema.safeParse({ imageUrls: ["a", "b", "c", "d", "e"] }).success).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("ttsPreviewSchema", () => {
|
|
it("refuse un texte vide", () => {
|
|
expect(ttsPreviewSchema.safeParse({ text: " " }).success).toBe(false);
|
|
});
|
|
});
|