teqo-backup/tests/unit/contentPieceShare.unit.spec.ts
Francisco Solla dda55adc27 feat(S27): Central de Conteúdos pública — Peça voto pra Solla 1313
/conteudos + /conteudos/<slug>: catálogo filtrável (Tipo · Cidade · Região ·
Tema · Instituição + termo na URL canônica), play sob demanda (Vídeo/Áudio só
carregam no toque; Foto com preview leve), Baixar e Compartilhar do próprio
card com a mensagem de voto por tipo (wa.me sem destinatário, editável; "A
mídia" usa a folha nativa e cai em download onde o aparelho não suportar) e o
card personalizado como peça sintética do catálogo → /cards.

- leitura pública nova (contentPieceReads) cacheada na tag contentPieces com o
  gate where status=publicado + contentPieceIsPublic; a rota GET
  /conteudos/<slug>/midia reusa buildPrivateMediaResponse (range, disposition,
  private no-store, 404 uniforme) com download jorge-solla-1313-<slug>.<ext> e
  a allowlist inline do dono estendida (webp/gif/avif + áudios das peças)
- contrato público puro do catálogo (filtros/VM/download) + mensagens de voto
  (contentPieceShare); OG com fallback do global; conteudos entra nos slugs
  reservados; kill switch por peça vale na hora (lista, página, rodapé/selo);
  descoberta condicional no CampaignFooter e no header local
- UI portada classe-a-classe do design aprovado (cenas 01–08, com as cenas
  06–08 estendidas no trigger a); sem migration, sem Consent e sem access novo;
  contentMedia segue privada (sem segunda cópia de mídia)
- testes: 2 unit specs novos, 18 casos int (leitura pública + rota de mídia) e
  e2e frontendConteudos (5 casos); manifest e curado atualizados
- follow-up de engenharia: #1276 (docs/plans/escala-dry-pos-s27.md)

Closes #1255
2026-09-23 11:13:57 -03:00

69 lines
2.5 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.

// @vitest-environment node
import { describe, expect, it } from 'vitest'
import {
buildContentPieceWhatsAppUrl,
contentPieceShareLink,
contentPieceVoteMessage,
} from '@/lib/contentPieceShare'
const ORIGIN = 'https://jorgesolla1313.com.br'
const LINK = 'https://jorgesolla1313.com.br/conteudos/fim-da-escala-6x1'
describe('content piece vote message (S27)', () => {
it('uses the video literal with title and link', () => {
expect(contentPieceVoteMessage('video', 'Fim da escala 6×1 é saúde', LINK)).toBe(
`Estamos na reta final e o Jorge Solla 1313 precisa do seu voto. Olha esse vídeo: Fim da escala 6×1 é saúde — ${LINK}. Peça voto pra Solla 1313 pra quem você conhece.`,
)
})
it('uses the audio literal', () => {
expect(contentPieceVoteMessage('audio', 'Mensagem para o grupo', LINK)).toBe(
`Ouça e mande pro grupo: Mensagem para o grupo — ${LINK}. Peça voto pra Solla 1313.`,
)
})
it('uses the material literal for foto, texto and card', () => {
const expected = `Fiz/achei esse material do Solla 1313: Card do giro — ${LINK}. Peça voto pra Solla 1313 também.`
expect(contentPieceVoteMessage('foto', 'Card do giro', LINK)).toBe(expected)
expect(contentPieceVoteMessage('texto', 'Card do giro', LINK)).toBe(expected)
expect(contentPieceVoteMessage('card', 'Card do giro', LINK)).toBe(expected)
})
})
describe('content piece share link (S27)', () => {
it('shares the public page for an archived piece', () => {
expect(
contentPieceShareLink({ slug: 'fim-da-escala-6x1', isLink: false, sourceUrl: null }, ORIGIN),
).toBe(LINK)
})
it('shares the canonical platform URL for a link piece (never a second copy)', () => {
expect(
contentPieceShareLink(
{
slug: 'post-instagram',
isLink: true,
sourceUrl: 'https://www.instagram.com/reel/ABC/',
},
ORIGIN,
),
).toBe('https://www.instagram.com/reel/ABC/')
})
it('degrades to the relative path without an origin', () => {
expect(contentPieceShareLink({ slug: 'x', isLink: false, sourceUrl: null }, '')).toBe(
'/conteudos/x',
)
})
})
describe('content piece WhatsApp url (S27)', () => {
it('prefills the sender text with no recipient and no automatic send', () => {
const url = new URL(buildContentPieceWhatsAppUrl('Peça voto pra Solla 1313'))
expect(url.origin).toBe('https://wa.me')
expect(url.pathname).toBe('/')
expect(url.searchParams.get('text')).toBe('Peça voto pra Solla 1313')
})
})