Files
buzz-sheet/lib/guides/image-export.test.tsx
T
gunshiz 7c10b2c995
CI / Verify (push) Successful in 1m46s
CI / Build immutable images and deploy (push) Successful in 2m3s
feat : able to rotate img for mat card
2026-09-19 20:20:02 +07:00

151 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 action when both note modes are available", () => {
const html = renderToStaticMarkup(<GuideImageExport fileName="guide.png">No notes</GuideImageExport>);
expect(html).toContain("ส่งออกภาพ");
expect(html).toContain("ไทย");
expect(html).toContain("English");
expect(html).toContain('data-language-flag="th"');
expect(html).toContain('data-language-flag="en"');
expect(html.match(/<button\b/gu)).toHaveLength(3);
});
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(3);
});
it("can show note modes inline inside an existing dialog", () => {
const html = renderToStaticMarkup(
<GuideImageExport fileName="guide.png" modeSelection="inline">
Content
</GuideImageExport>,
);
expect(html).toContain("ส่งออกภาพโดยไม่รวมโน้ต");
expect(html.match(/<button\b/gu)).toHaveLength(4);
});
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)");
});
});