Três ofertas (site que traz pedidos pelo WhatsApp, sistema para tirar a operação da planilha, revisão de sistema existente) com miniatura e formulário com o tipo escolhido; botão principal do hero abre o WhatsApp; moldura da SEV no hero do celular; menu fecha ao navegar, Esc, foco preso incluindo a barra de cookies e espaço para ela; CinematicHome como componente de servidor com ilha cliente; /ia com H1 de oferta e cartão do que você recebe; botão flutuante em aside com transform; AVIF antes de WebP; copy sem repetir contato direto.
100 lines
3.2 KiB
TypeScript
100 lines
3.2 KiB
TypeScript
import type { ReactElement } from "react";
|
|
import { portfolio } from "@/lib/portfolio-data";
|
|
import { loadFeaturedProjects } from "@/lib/portfolio-data.server";
|
|
import { clientNames, testimonials } from "@/lib/proof";
|
|
import CinematicHome from "./components/cinematic/CinematicHome";
|
|
import Home from "./page";
|
|
|
|
/**
|
|
* Testes de caminhos-base de Home e de yearsOfExperience (que não é exportada, então passa por Home):
|
|
* os anos vêm do texto do portfólio, e a home mostra só projetos de cliente.
|
|
*/
|
|
|
|
jest.mock("./components/cinematic/CinematicHome", () => ({
|
|
__esModule: true,
|
|
default: jest.fn(() => null),
|
|
}));
|
|
jest.mock("@/lib/portfolio-data.server", () => ({
|
|
loadFeaturedProjects: jest.fn(),
|
|
}));
|
|
|
|
type HomeProps = React.ComponentProps<typeof CinematicHome>;
|
|
type Loaded = Awaited<ReturnType<typeof loadFeaturedProjects>>;
|
|
|
|
const originalSummary = portfolio.personal.summary;
|
|
|
|
function mockProjects(projects: Array<{ id: string; kind?: string }>) {
|
|
jest
|
|
.mocked(loadFeaturedProjects)
|
|
.mockResolvedValue(projects as unknown as Loaded);
|
|
}
|
|
|
|
async function renderHome() {
|
|
const element = (await Home()) as ReactElement<HomeProps>;
|
|
expect(element.type).toBe(CinematicHome);
|
|
return element.props;
|
|
}
|
|
|
|
beforeEach(() => {
|
|
mockProjects([]);
|
|
});
|
|
|
|
afterEach(() => {
|
|
portfolio.personal.summary = originalSummary;
|
|
});
|
|
|
|
describe("Home: anos de experiência", () => {
|
|
it("path: the summary says '5 anos de experiência' -> 5", async () => {
|
|
portfolio.personal.summary = "Desenvolvedor com 5 anos de experiência.";
|
|
|
|
expect((await renderHome()).heroStats).toEqual({ years: 5 });
|
|
});
|
|
|
|
it("path: more than one digit and different case -> the whole number", async () => {
|
|
portfolio.personal.summary = "Atuo há 12 ANOS DE EXPERIÊNCIA em web.";
|
|
|
|
expect((await renderHome()).heroStats).toEqual({ years: 12 });
|
|
});
|
|
|
|
it("path: the summary has no such stretch -> no number, the hero hides it", async () => {
|
|
portfolio.personal.summary = "Desenvolvedor de software em Garuva-SC.";
|
|
|
|
expect((await renderHome()).heroStats).toEqual({ years: undefined });
|
|
});
|
|
|
|
it("path: a number that is not followed by the experience wording -> ignored", async () => {
|
|
portfolio.personal.summary = "Formado há 5 anos, com 3 projetos entregues.";
|
|
|
|
expect((await renderHome()).heroStats?.years).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("Home: projetos e provas", () => {
|
|
it("path: client, laboratory and unlabelled projects -> only the client ones reach the page", async () => {
|
|
mockProjects([
|
|
{ id: "a", kind: "cliente" },
|
|
{ id: "b", kind: "laboratorio" },
|
|
{ id: "c" },
|
|
{ id: "d", kind: "cliente" },
|
|
]);
|
|
|
|
const props = await renderHome();
|
|
|
|
expect(props.projects.map(({ id }) => id)).toEqual(["a", "d"]);
|
|
});
|
|
|
|
it("path: no featured project at all -> an empty list, the page still renders", async () => {
|
|
mockProjects([]);
|
|
|
|
expect((await renderHome()).projects).toEqual([]);
|
|
});
|
|
|
|
it("path: the proof comes straight from its module, and the home no longer carries the service links (the offers do not list them)", async () => {
|
|
const props = await renderHome();
|
|
|
|
expect(props.clients).toBe(clientNames);
|
|
expect(props.testimonials).toBe(testimonials);
|
|
expect(props).not.toHaveProperty("serviceLinks");
|
|
});
|
|
});
|