feat(home): seção Sobre com prova por ponto, contato por oferta e hero com a Lavação 047 na tela larga
This commit is contained in:
1 parent
d356c364e0
commit
9fd1570426
33 files changed
+1128
-369
No files matched your search
@@ -1,10 +1,12 @@
|
||||
import { render } from "@testing-library/react";
|
||||
import { SEO_IDS } from "@/lib/seo";
|
||||
import { serviceOffers, siteUrl } from "@/lib/site-content";
|
||||
import CinematicHome from "./CinematicHome";
|
||||
|
||||
/**
|
||||
* Dados estruturados da home: um único script `application/ld+json` com o negócio (ProfessionalService). O WebSite e
|
||||
* a Person já saem do layout (app/layout.tsx), e repeti-los aqui duplicaria os dados.
|
||||
* Dados estruturados da home: um único script `application/ld+json` com as três ofertas (nós Service ligados à
|
||||
* Person). O WebSite e a Person já saem do layout (app/layout.tsx), e repeti-los aqui duplicaria os dados. Sem
|
||||
* ProfessionalService nem LocalBusiness: a política de docs/seo-geo-operations.md os exclui.
|
||||
*/
|
||||
|
||||
jest.mock("../Hero", () => ({ __esModule: true, default: () => null }));
|
||||
@@ -39,15 +41,32 @@ describe("CinematicHome: dados estruturados", () => {
|
||||
expect(container.firstElementChild).toBe(scripts[0]);
|
||||
});
|
||||
|
||||
it("describes only the business as a ProfessionalService, without repeating what the layout emits", () => {
|
||||
it("describes only the three offers as Service nodes tied to the person, without repeating what the layout emits", () => {
|
||||
const [data] = structuredData();
|
||||
|
||||
expect(data["@context"]).toBe("https://schema.org");
|
||||
expect(data["@graph"]).toHaveLength(1);
|
||||
const [business] = data["@graph"];
|
||||
expect(business["@type"]).toBe("ProfessionalService");
|
||||
expect(business["@id"]).toBe(SEO_IDS.professionalService);
|
||||
expect(business.founder).toEqual({ "@id": SEO_IDS.person });
|
||||
expect(data["@graph"]).toHaveLength(3);
|
||||
for (const offer of data["@graph"]) {
|
||||
expect(offer["@type"]).toBe("Service");
|
||||
expect(offer.provider).toEqual({ "@id": SEO_IDS.person });
|
||||
expect(
|
||||
offer.areaServed.map(({ name }: { name: string }) => name),
|
||||
).toEqual(["Garuva", "Joinville", "Santa Catarina", "Brasil"]);
|
||||
}
|
||||
expect(data["@graph"].map(({ name }: { name: string }) => name)).toEqual(
|
||||
serviceOffers.map(({ name }) => name),
|
||||
);
|
||||
expect(data["@graph"].map(({ url }: { url: string }) => url)).toEqual(
|
||||
serviceOffers.map(({ href }) => `${siteUrl}${href}`),
|
||||
);
|
||||
expect(JSON.stringify(data)).not.toMatch(/"@type":"(WebSite|Person)"/);
|
||||
});
|
||||
|
||||
it("never emits ProfessionalService, LocalBusiness or an offer catalog (docs/seo-geo-operations.md)", () => {
|
||||
const [data] = structuredData();
|
||||
|
||||
expect(JSON.stringify(data)).not.toMatch(
|
||||
/ProfessionalService|LocalBusiness|OfferCatalog/,
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -76,24 +76,24 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
describe("CinematicHome: endereço do trabalho em destaque", () => {
|
||||
it("path: the featured project (SEV) is in the list with its own domain -> that domain goes to the hero", () => {
|
||||
it("path: the featured project (Lavação 047) is in the list with its own domain -> that domain goes to the hero", () => {
|
||||
render(
|
||||
<CinematicHome
|
||||
projects={[
|
||||
project("lavacao-047", "https://www.landing-lavacao.example.com/"),
|
||||
project("sev-modaintima", "https://sevmodaintima.com.br"),
|
||||
project("lavacao-047", "https://www.lavacao047.com.br/"),
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(lastHeroProps().workUrl).toEqual({
|
||||
text: "sevmodaintima.com.br",
|
||||
text: "lavacao047.com.br",
|
||||
secure: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("path: the featured project is in the list but has no site -> no address", () => {
|
||||
render(<CinematicHome projects={[project("sev-modaintima", null)]} />);
|
||||
render(<CinematicHome projects={[project("lavacao-047", null)]} />);
|
||||
|
||||
expect(lastHeroProps().workUrl).toBeNull();
|
||||
});
|
||||
@@ -101,7 +101,7 @@ describe("CinematicHome: endereço do trabalho em destaque", () => {
|
||||
it("path: the featured project is not in the list -> no address", () => {
|
||||
render(
|
||||
<CinematicHome
|
||||
projects={[project("lavacao-047", "https://lavacao.example.com")]}
|
||||
projects={[project("sev-modaintima", "https://sevmodaintima.com.br")]}
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -112,7 +112,7 @@ describe("CinematicHome: endereço do trabalho em destaque", () => {
|
||||
render(
|
||||
<CinematicHome
|
||||
projects={[
|
||||
project("sev-modaintima", "https://sev-moda-intima.vercel.app/"),
|
||||
project("lavacao-047", "https://landing-page-lavacao047.vercel.app"),
|
||||
]}
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { safeJsonLd } from "@/lib/jsonld";
|
||||
import type { PortfolioProjectView } from "@/lib/portfolio-data";
|
||||
import type { Testimonial } from "@/lib/proof";
|
||||
import { buildProfessionalServiceJsonLd } from "@/lib/seo";
|
||||
import { buildOfferServicesJsonLd } from "@/lib/seo";
|
||||
import About from "../About";
|
||||
import type { ClientLink } from "../ClientStrip";
|
||||
import Contact from "../Contact";
|
||||
@@ -13,17 +13,17 @@ import Testimonials from "../Testimonials";
|
||||
import { WorkModalities } from "../WorkModalities";
|
||||
import CinematicMain from "./CinematicMain";
|
||||
|
||||
/** Projeto cujo endereço aparece na barra do navegador de HeroWork (a SEV Moda Íntima, com domínio próprio). */
|
||||
const HERO_WORK_PROJECT = "sev-modaintima";
|
||||
/** Projeto do navegador de HeroWork (a Lavação 047), cujo endereço, se for domínio próprio, aparece na barra. */
|
||||
const HERO_WORK_PROJECT = "lavacao-047";
|
||||
|
||||
/**
|
||||
* Dados estruturados da home: o negócio como ProfessionalService (área de atendimento e as três ofertas). Só ele: o
|
||||
* WebSite e a Person já saem do layout, e repeti-los aqui duplicaria os dados. O script fica aqui, e não em
|
||||
* app/page.tsx, para a página continuar devolvendo só a home.
|
||||
* Dados estruturados da home: as três ofertas como nós Service (provider ligado à pessoa e área de atendimento). Só elas:
|
||||
* o WebSite e a Person já saem do layout, e repeti-los aqui duplicaria os dados. Sem ProfessionalService nem LocalBusiness
|
||||
* (docs/seo-geo-operations.md). O script fica aqui, e não em app/page.tsx, para a página continuar devolvendo só a home.
|
||||
*/
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [buildProfessionalServiceJsonLd()],
|
||||
"@graph": buildOfferServicesJsonLd(),
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user