Files
mintel.me/apps/video/src/content/videos.spec.ts
T
mmintelandClaude Opus 5.5 4bfbcbcacd feat: video films for social media, with the skill to make more
Adds apps/video, a standalone Remotion package (not part of the pnpm
workspace, so it never reaches the web build or the Docker image). It
renders six looping films, one per service, in German and English, as
4:5 for LinkedIn and 16:9 for YouTube and ads, together with the text
to post and an overview page.

Each film is one continuous shot: close on something abstract, the
camera pulls back to show what it really is, the form changes, and the
picture folds back into its opening. The slide deck code from the
earlier attempts is still in the package and no longer used.

Also adds the Google Ads concept, brings the relaunch concept in line
with the site as built, and a project skill that describes how to make
further films.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 21:23:01 +02:00

52 lines
1.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { COPY, LANGS, VIDEO_IDS, translate } from "./videos";
const MAX_LINES = 2;
/** Longer lines get too small to read on a phone. */
const MAX_LINE_LENGTH = 24;
describe("video copy", () => {
it.each(VIDEO_IDS)("%s has the same slides in every language", (id) => {
const [first, ...others] = LANGS.map((lang) => Object.keys(COPY[id][lang].slides).sort());
for (const slides of others) expect(slides).toEqual(first);
});
it.each(VIDEO_IDS)("%s keeps every headline to two short lines", (id) => {
for (const lang of LANGS) {
for (const [slide, lines] of Object.entries(COPY[id][lang].slides)) {
expect(lines.length, `${id} ${lang} ${slide}`).toBeGreaterThan(0);
expect(lines.length, `${id} ${lang} ${slide}`).toBeLessThanOrEqual(MAX_LINES);
for (const line of lines) {
expect(line.length, `${id} ${lang} ${slide}: "${line}"`).toBeLessThanOrEqual(MAX_LINE_LENGTH);
}
}
}
});
it.each(VIDEO_IDS)("%s ends with a call to action slide", (id) => {
for (const lang of LANGS) expect(COPY[id][lang].slides).toHaveProperty("cta");
});
it.each(VIDEO_IDS)("%s has a post that names the website and never an email address", (id) => {
for (const lang of LANGS) {
const { post } = COPY[id][lang];
expect(post).toContain("www.mintel.me");
expect(post).not.toContain("@");
}
});
});
describe("translate", () => {
it("leaves English labels as they are", () => {
expect(translate("en", "Invoice")).toBe("Invoice");
});
it("returns the German label when there is one", () => {
expect(translate("de", "Invoice")).toBe("Rechnung");
});
it("falls back to the given text when there is no German label", () => {
expect(translate("de", "Shop")).toBe("Shop");
});
});