/servicos abre com as 3 ofertas e depois outros serviços; H1 de criação de sites e de engenharia com o nome da oferta; capa de cada serviço pelo assunto (SEV fora do próprio case cai de ~11 para 2 imagens); diagrama de fluxo em SVG nos serviços sem case; cases com o que o cliente passou a poder fazer e contato logo depois de Como ficou; FAQ num componente só; lastmod por rota; ProfessionalService com areaServed.
91 lines
3.1 KiB
TypeScript
91 lines
3.1 KiB
TypeScript
import { render, screen, within } from "@testing-library/react";
|
|
import { Faq } from "./Faq";
|
|
import HomeFaq from "./HomeFaq";
|
|
|
|
const items = [
|
|
{ question: "Primeira pergunta?", answer: "Primeira resposta." },
|
|
{
|
|
question: "Segunda pergunta?",
|
|
answer: "Segunda resposta.",
|
|
link: { href: "/ia", label: "Ver a revisão" },
|
|
},
|
|
{ question: "Sem resposta ainda?", answer: " " },
|
|
];
|
|
|
|
describe("Faq", () => {
|
|
it("path: answered questions -> one closed accordion item per question, under a level 2 heading", () => {
|
|
const { container } = render(<Faq items={items} />);
|
|
|
|
expect(
|
|
screen.getByRole("heading", { level: 2, name: "Perguntas frequentes" }),
|
|
).toBeInTheDocument();
|
|
const summaries = Array.from(container.querySelectorAll("summary")).map(
|
|
(summary) => summary.textContent?.replace("+", "").trim(),
|
|
);
|
|
expect(summaries).toEqual(["Primeira pergunta?", "Segunda pergunta?"]);
|
|
for (const details of container.querySelectorAll("details")) {
|
|
expect(details.open).toBe(false);
|
|
}
|
|
});
|
|
|
|
it("path: a question with no answer -> stays out of the page, like on the home", () => {
|
|
render(<Faq items={items} />);
|
|
|
|
expect(screen.queryByText("Sem resposta ainda?")).toBeNull();
|
|
});
|
|
|
|
it("path: a question with a link -> the link sits inside its answer", () => {
|
|
render(<Faq items={items} />);
|
|
|
|
const details = screen
|
|
.getByText("Segunda pergunta?")
|
|
.closest("details") as HTMLElement;
|
|
expect(within(details).getByText("Segunda resposta.")).toBeInTheDocument();
|
|
expect(
|
|
within(details).getByRole("link", { name: "Ver a revisão" }),
|
|
).toHaveAttribute("href", "/ia");
|
|
});
|
|
|
|
it("path: custom title and anchor -> the heading and the section follow them", () => {
|
|
const { container } = render(
|
|
<Faq items={items} id="antes" title="Antes de contratar" />,
|
|
);
|
|
|
|
const heading = screen.getByRole("heading", { name: "Antes de contratar" });
|
|
expect(heading).toHaveAttribute("id", "antes-title");
|
|
expect(container.querySelector("section")).toHaveAttribute("id", "antes");
|
|
expect(container.querySelector("section")).toHaveAttribute(
|
|
"aria-labelledby",
|
|
"antes-title",
|
|
);
|
|
});
|
|
|
|
it("path: no items, or none with an answer -> renders nothing, not even the heading", () => {
|
|
const empty = render(<Faq />);
|
|
expect(empty.container).toBeEmptyDOMElement();
|
|
empty.unmount();
|
|
|
|
const unanswered = render(
|
|
<Faq items={[{ question: "Pergunta?", answer: "" }]} />,
|
|
);
|
|
expect(unanswered.container).toBeEmptyDOMElement();
|
|
});
|
|
|
|
it("path: same pattern as the home FAQ -> same summary and details classes", () => {
|
|
const shared = render(<Faq items={items} />);
|
|
const home = render(
|
|
<HomeFaq
|
|
items={[{ question: "Primeira pergunta?", answer: "Resposta." }]}
|
|
/>,
|
|
);
|
|
|
|
const classOf = (container: HTMLElement, selector: string) =>
|
|
container.querySelector(selector)?.className;
|
|
for (const selector of ["details", "summary", "summary > span"]) {
|
|
expect(classOf(shared.container, selector)).toBe(
|
|
classOf(home.container, selector),
|
|
);
|
|
}
|
|
});
|
|
});
|