teqo-backup/tests/unit/campaignHome.unit.spec.tsx
Francisco Solla 8e0366d3ba feat(S14): cards personalizados — ajustes de fidelidade e experiência
A home abre o mesmo compositor do /cards ali mesmo (dialog no desktop,
drawer no mobile) e perde o CTA: os três modelos viram botões e nada
navega. A seção sobe para imediatamente antes da captura de novidades.
O nome no card e no tile alinha à esquerda com o SOU (x=213) via leftX
+ drawCardName extraído; o tile passa a desenhar SEU NOME com o próprio
pipeline real (canvas transparente sobre a base). Modal sem o vão
interno (p-0 sm:p-0) e ajuda legível no tema campaign-site
(--muted-foreground). Remove a variante link e o cardModelHref sem call
site. Unit atualizado (+ drawCardName) e e2e com alinhamento por pixel;
sem migration, sem PII em rede.
2026-09-12 21:01:15 -03:00

87 lines
3.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { cleanup, render, screen } from '@testing-library/react'
import { afterEach, describe, expect, it, vi } from 'vitest'
import HomePage from '@/app/(frontend)/(home)/page'
type MockImageProps = React.ImgHTMLAttributes<HTMLImageElement> & {
fill?: boolean
priority?: boolean
}
vi.mock('next/image', () => ({
default: ({ alt, fill: _fill, priority: _priority, ...props }: MockImageProps) => (
// eslint-disable-next-line @next/next/no-img-element
<img alt={alt} {...props} />
),
}))
// The content section is an async server component that reads posts through
// the Payload DB; the unit env has no database and an async child suspends the
// whole tree under testing-library. Its empty/full behavior is covered by e2e
// (frontend.e2e.spec.ts), so the home skeleton tests render it away.
vi.mock('@/components/CampaignContentSection', () => ({
CampaignContentSection: () => null,
}))
// The S9 capture form is a client component (radix comboboxes/checkbox) whose
// interactions are e2e-covered; the unit skeleton only pins the section shell.
vi.mock('@/components/CampaignNewsletterForm', () => ({
CampaignNewsletterCapture: () => null,
}))
// S10 — the section reads the site-settings global (server-only, Payload DB);
// the unit env has no database, and the pixel behavior is e2e-covered.
vi.mock('@/utilities/campaignHomeTracking', () => ({
getCampaignHomeMetaPixelId: async () => null,
}))
// S14 — the card section renders the client studio island (next/font local
// face + matchMedia + canvas); its behavior is e2e-covered, so the unit
// skeleton mocks both the face module and the island.
vi.mock('@/app/(frontend)/fonts', () => ({
brexterBold: { variable: 'font-brexter-mock', style: { fontFamily: 'Brexter' } },
}))
vi.mock('@/components/cards/CardsStudio', () => ({
CardsStudio: () => null,
}))
afterEach(cleanup)
describe('Campaign home', () => {
it('monta as cinco seções previstas e o rodapé eleitoral', async () => {
render(await HomePage())
expect(screen.getByRole('heading', { level: 1, name: 'MAIS SAÚDE MAIS FUTURO' })).toBeTruthy()
expect(screen.getByText('3.333')).toBeTruthy()
expect(screen.getByText('1.031')).toBeTruthy()
expect(screen.getByText('3º')).toBeTruthy()
expect(screen.getByRole('heading', { name: /Eleger deputado é coisa séria/i })).toBeTruthy()
expect(
screen.getByRole('heading', {
name: /Junto com o trabalhador e do lado de quem mais precisa, sempre/i,
}),
).toBeTruthy()
expect(screen.getByRole('heading', { name: /Mostre que você está com Solla/i })).toBeTruthy()
expect(screen.getByRole('heading', { name: /Receba as novidades da campanha/i })).toBeTruthy()
expect(screen.getByText(/CNPJ: 68\.430\.467\/0001-05/)).toBeTruthy()
})
it('usa exatamente as seis bandeiras aprovadas', async () => {
render(await HomePage())
// S6: cada bandeira aparece em duas renderizações irmãs (grade desktop e
// carrossel mobile); o teste garante que as duas seguem a mesma copy.
const expectedTitles = [
'Defender o SUS e valorizar quem cuida',
'Fim da escala 6×1 e jornada de 40h',
'Educação em tempo integral e federais no interior',
'Recomprar a Refinaria de Mataripe',
'Salário mínimo forte, emprego e moradia',
'Defesa intransigente da democracia',
]
for (const title of expectedTitles) {
expect(screen.getAllByText(title)).toHaveLength(2)
}
})
})