Files

141 lines
5.0 KiB
TypeScript

import { getCaseMedia } from "@/app/cases/_components/case-media";
import { getShowcaseAssets } from "@/lib/project-showcase";
import { getServicePage, type ServicePageContent } from "@/lib/site-content";
import { resolveServiceHero, splitServiceCases } from "./service-page";
/**
* Caminhos-base de resolveServiceHero (CC 6) e splitServiceCases (CC 3) que service-page.test.ts não separa, todos com um
* serviço montado à mão, porque nenhum serviço real reúne essas combinações:
* - capa e esquema ao mesmo tempo: a capa vale e o esquema some; sem captura da capa, o esquema entra no lugar;
* - os cases do bloco menor não contam para o botão "Ver projetos parecidos" (ele leva a "Onde já apliquei isso");
* - todos os cases no bloco menor: nenhum cartão, e o bloco leva todos, na ordem de `relatedCaseIds`.
* A existência das capturas em disco é simulada em getCaseMedia.
*/
jest.mock("@/app/cases/_components/case-media", () => ({
getCaseMedia: jest.fn(),
}));
const mockedGetCaseMedia = jest.mocked(getCaseMedia);
function service(overrides: Partial<ServicePageContent>): ServicePageContent {
const base = getServicePage("consultoria-nextjs");
if (!base) throw new Error("Missing service consultoria-nextjs");
return {
...base,
heroCase: undefined,
diagram: undefined,
alsoCases: undefined,
...overrides,
};
}
/** Só as capturas listadas existem no disco. */
function capturesOnDisk(captures: readonly (readonly [string, string])[]) {
mockedGetCaseMedia.mockImplementation((id, device) =>
captures.some(
([knownId, knownDevice]) => knownId === id && knownDevice === device,
)
? getShowcaseAssets(id, device)
: undefined,
);
}
afterEach(() => {
mockedGetCaseMedia.mockReset();
});
describe("resolveServiceHero: combinações que os serviços reais não têm", () => {
it("path: a cover with its capture AND a diagram -> the cover wins and the diagram is dropped", () => {
capturesOnDisk([["lavacao-047", "desktop"]]);
const hero = resolveServiceHero(
service({
relatedCaseIds: ["lavacao-047"],
heroCase: { id: "lavacao-047", device: "desktop" },
diagram: "iot",
}),
);
expect(hero.heroCase?.id).toBe("lavacao-047");
expect(hero.diagram).toBeUndefined();
expect(hero.hasHeroSide).toBe(true);
});
it("path: a cover WITHOUT its capture and a diagram -> the diagram takes the side column", () => {
capturesOnDisk([]);
const hero = resolveServiceHero(
service({
relatedCaseIds: ["lavacao-047"],
heroCase: { id: "lavacao-047", device: "desktop" },
diagram: "iot",
}),
);
expect(hero.heroCase).toBeUndefined();
expect(hero.diagram).toBe("iot");
expect(hero.hasHeroSide).toBe(true);
// a capa não valeu, então o case não está citado em legenda nenhuma: ele ganha o cartão
expect(hero.hasCaseCards).toBe(true);
});
it("path: the only card left after the smaller block is the cover -> no 'Ver projetos parecidos' target, even with related cases in the block", () => {
capturesOnDisk([["lavacao-047", "desktop"]]);
const hero = resolveServiceHero(
service({
relatedCaseIds: ["lavacao-047", "sc-plus", "as-servicos"],
heroCase: { id: "lavacao-047", device: "desktop" },
alsoCases: { title: "Também", caseIds: ["sc-plus", "as-servicos"] },
}),
);
expect(hero.heroCase?.id).toBe("lavacao-047");
expect(hero.hasCaseCards).toBe(false);
});
it("path: a cover in the smaller block as well -> it is not a card, and the cover stays", () => {
capturesOnDisk([["lavacao-047", "desktop"]]);
const hero = resolveServiceHero(
service({
relatedCaseIds: ["lavacao-047"],
heroCase: { id: "lavacao-047", device: "desktop" },
alsoCases: { title: "Também", caseIds: ["lavacao-047"] },
}),
);
expect(hero.heroCase?.id).toBe("lavacao-047");
expect(hero.hasCaseCards).toBe(false);
});
});
describe("splitServiceCases: o bloco leva todos os cases", () => {
it("path: every related case in the smaller block -> no card at all, and the block keeps the order of relatedCaseIds", () => {
const { cards, also } = splitServiceCases(
service({
relatedCaseIds: ["sc-plus", "as-servicos"],
// fora de ordem de propósito: quem manda é a ordem de `relatedCaseIds`
alsoCases: { title: "Também", caseIds: ["as-servicos", "sc-plus"] },
}),
);
expect(cards).toEqual([]);
expect(also?.title).toBe("Também");
expect(also?.cases.map(({ id }) => id)).toEqual(["sc-plus", "as-servicos"]);
});
it("path: a smaller block with an empty list of ids -> null, and every related case stays a card", () => {
const { cards, also } = splitServiceCases(
service({
relatedCaseIds: ["sc-plus", "lavacao-047"],
alsoCases: { title: "Também", caseIds: [] },
}),
);
expect(also).toBeNull();
expect(cards.map(({ id }) => id)).toEqual(["sc-plus", "lavacao-047"]);
});
});