Files
buzz-sheet/lib/guides/image-export.test.tsx
T

150 lines
6.0 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 { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it } from "vitest";
import {
GuideImageExport,
imageExportFileName,
} from "@/components/public/guide-image-export";
import { MaterialPoster } from "@/components/public/material-poster";
import { ConstellationImage } from "@/components/public/constellation-image";
import { WeaponComparisonImage } from "@/components/public/weapon-image-export";
import type { PublicGuide } from "@/lib/guides/queries";
describe("image export controls", () => {
it("omits the placeholder condition from weapon export images", () => {
const guide = {
character: { name: "Raiden", splashImageUrl: "/splash.png" },
coverUrl: "/cover.png",
} as PublicGuide;
const group = { rows: [], name: null, note: null } as unknown as PublicGuide["weaponGroups"][number];
const html = renderToStaticMarkup(
<WeaponComparisonImage
guide={guide}
group={group}
metric="overallPercent"
conditionLabel={group.name}
/>,
);
expect(html).not.toContain("Condition 1");
expect(html).not.toContain("เงื่อนไข 1");
});
it("shows one export trigger and keeps settings in its dialog", () => {
const html = renderToStaticMarkup(<GuideImageExport fileName="guide.png">No notes</GuideImageExport>);
expect(html).toContain("ส่งออกภาพ");
expect(html.match(/<button\b/gu)).toHaveLength(1);
});
it("shows only one export action when no-note export is disabled", () => {
const html = renderToStaticMarkup(<GuideImageExport fileName="guide.png" allowWithoutNotes={false}>Content</GuideImageExport>);
expect(html).toContain("ส่งออกภาพ");
expect(html.match(/<button\b/gu)).toHaveLength(1);
});
it("shows all settings inline with one export action inside an existing dialog", () => {
const html = renderToStaticMarkup(
<GuideImageExport fileName="guide.png" modeSelection="inline">
Content
</GuideImageExport>,
);
expect(html).toContain("รวมโน้ต");
expect(html).toContain("ไม่รวมโน้ต");
expect(html).toContain("ไทย");
expect(html).toContain("English");
expect(html.match(/>ส่งออกภาพ<\/button>/gu)).toHaveLength(1);
});
it("hides the persistent language chooser when language is prompted on export", () => {
const html = renderToStaticMarkup(
<GuideImageExport
fileName="guide.png"
allowWithoutNotes={false}
showLanguageSelector={false}
promptForLanguage
>
Content
</GuideImageExport>,
);
expect(html).not.toContain("ภาษาในภาพส่งออก");
expect(html).not.toContain("English");
expect(html.match(/<button\b/gu)).toHaveLength(1);
});
it("disables export when an export selection is empty", () => {
const html = renderToStaticMarkup(<GuideImageExport fileName="guide.png" disabled>No sections</GuideImageExport>);
expect(html.match(/\sdisabled=""/gu)).toHaveLength(1);
});
it.each(["English note", "โน้ตภาษาไทย"])("marks constellation notes for omission regardless of language: %s", (note) => {
const guide = { character: { name: "Raiden", splashImageUrl: "/splash.png" }, coverUrl: "/cover.png" } as PublicGuide;
const group = { rows: [], note } as unknown as PublicGuide["constellationGroups"][number];
const html = renderToStaticMarkup(createElement(ConstellationImage, { guide, group }));
expect(html).toContain("Raiden’s Constellations");
expect(html).not.toContain("กลุ่มดาวของ Raiden");
expect(html).toContain("Team Damage");
expect(html).toContain("ดาเมจทั้งทีม");
expect(html).toContain('data-export-note="true"');
expect(html).toContain(note);
});
});
describe("image export filenames", () => {
it("adds the selected language after the note variant", () => {
expect(imageExportFileName("Raiden.png", "th", false)).toBe("Raiden-th.png");
expect(imageExportFileName("Raiden.png", "en", true)).toBe("Raiden-without-notes-en.png");
});
it("can preserve English-only export filenames", () => {
expect(imageExportFileName("Raiden-materials.png", "th", false, false)).toBe("Raiden-materials.png");
});
});
describe("material poster text", () => {
const props = {
character: { name: "Raiden", nameCardImageUrl: null, baseStats: [], ascension: [], leveling: [] },
characterArtUrl: null,
artworkOffsetX: 0,
artworkOffsetY: 0,
artworkScale: 100,
artworkRotation: 0,
topColors: ["#000000", "#000000"] as [string, string],
bottomColors: ["#000000", "#000000"] as [string, string],
};
it("always uses English, including on the website", () => {
const html = renderToStaticMarkup(<MaterialPoster {...props} />);
expect(html).toContain("MATERIALS");
expect(html).toContain("LV.90");
expect(html).not.toContain("วัสดุ");
expect(html).not.toContain("เลเวล 90");
});
it("optimizes scale-aware character artwork and bleeding layers for export", () => {
const characterArtUrl = "https://buzz-cdn.astrxl.dev/posters/raiden.png";
const html = renderToStaticMarkup(
<MaterialPoster
{...props}
characterArtUrl={characterArtUrl}
artworkScale={200}
bleeding={[{ id: "bleed", imageUrl: characterArtUrl, amount: 50, blendMode: "screen" }]}
/>,
);
expect(html).toContain("/_next/image?url=https%3A%2F%2Fbuzz-cdn.astrxl.dev%2Fposters%2Fraiden.png");
expect(html).toContain("w=3840");
expect(html).toContain('sizes="3200px"');
expect(html).not.toContain(`src="${characterArtUrl}"`);
});
it("rotates the character artwork and bleeding layers together", () => {
const html = renderToStaticMarkup(
<MaterialPoster {...props} characterArtUrl="/raiden.png" artworkRotation={45} />,
);
expect(html).toContain("rotate(45deg)");
});
});