import sitemap from "../app/sitemap"; import { buildBreadcrumbList, buildPersonJsonLd, buildProfilePageJsonLd, buildServiceJsonLd, buildWebSiteJsonLd, SEO_IDS, } from "./seo"; import { caseStudies, servicePages, siteName, siteUrl } from "./site-content"; const representativeService = servicePages[0]; if (!representativeService) throw new Error("Missing representative service"); it("uses one canonical identity across website, profile and service", () => { expect(SEO_IDS).toEqual({ website: `${siteUrl}/#website`, person: `${siteUrl}/#person`, profilePage: `${siteUrl}/curriculo#profile-page`, }); expect(buildWebSiteJsonLd().publisher).toEqual({ "@id": SEO_IDS.person }); expect(buildProfilePageJsonLd()).toMatchObject({ "@id": SEO_IDS.profilePage, isPartOf: { "@id": SEO_IDS.website }, mainEntity: { "@id": SEO_IDS.person }, }); expect(buildServiceJsonLd(representativeService).provider).toEqual({ "@id": SEO_IDS.person, }); }); it("keeps the root graph limited to verified website and person fields", () => { const website = buildWebSiteJsonLd(); const person = buildPersonJsonLd(); expect(Object.keys(website).sort()).toEqual( ["@id", "@type", "inLanguage", "name", "publisher", "url"].sort(), ); expect(Object.keys(person).sort()).toEqual( ["@id", "@type", "homeLocation", "image", "name", "sameAs", "url"].sort(), ); expect(website).toMatchObject({ "@type": "WebSite", "@id": SEO_IDS.website, url: siteUrl, name: siteName, }); expect(person).toMatchObject({ "@type": "Person", "@id": SEO_IDS.person, image: `${siteUrl}/edev.jpg`, homeLocation: { "@type": "Place", name: "Garuva, Santa Catarina, Brasil" }, sameAs: [ "https://github.com/evandrodevbr", "https://www.linkedin.com/in/evandro-fonseca-junior-0969aa1b0/", ], }); expect(JSON.stringify([website, person])).not.toMatch( /ProfessionalService|LocalBusiness|GeoCoordinates|PostalAddress|Instagram|telephone|address|geo|priceRange|OfferCatalog|hasOfferCatalog|offers/i, ); }); it("builds a canonical service with only the verified service area", () => { const service = representativeService; const pageUrl = `${siteUrl}/servicos/${service.slug}`; expect(buildServiceJsonLd(service)).toEqual({ "@type": "Service", "@id": `${pageUrl}#service`, url: pageUrl, name: service.navLabel, description: service.metaDescription, provider: { "@id": SEO_IDS.person }, areaServed: [ { "@type": "City", name: "Garuva" }, { "@type": "AdministrativeArea", name: "Norte de Santa Catarina" }, ], }); }); it("builds contiguous breadcrumbs from readonly tuples", () => { const pageUrl = `${siteUrl}/servicos/x`; const items = [ ["Início", siteUrl], ["Serviços", `${siteUrl}/servicos`], ["X", pageUrl], ] as const; const breadcrumb = buildBreadcrumbList(pageUrl, items); expect(breadcrumb["@id"]).toBe(`${pageUrl}#breadcrumb`); expect(breadcrumb.itemListElement).toEqual([ { "@type": "ListItem", position: 1, name: "Início", item: siteUrl }, { "@type": "ListItem", position: 2, name: "Serviços", item: `${siteUrl}/servicos`, }, { "@type": "ListItem", position: 3, name: "X", item: pageUrl }, ]); }); it("keeps profile data timeless and sitemap output deterministic", () => { expect(buildProfilePageJsonLd()).not.toHaveProperty("dateModified"); const expectedUrls = [ siteUrl, `${siteUrl}/curriculo`, `${siteUrl}/privacidade`, `${siteUrl}/servicos`, `${siteUrl}/cases`, ...servicePages.map(({ slug }) => `${siteUrl}/servicos/${slug}`), ...caseStudies.map(({ id }) => `${siteUrl}/cases/${id}`), ]; const first = sitemap(); const second = sitemap(); expect(first).toEqual(expectedUrls.map((url) => ({ url }))); expect(second).toEqual(first); expect(first).toHaveLength(17); expect( first.filter(({ url }) => url === `${siteUrl}/privacidade`), ).toHaveLength(1); });