TS174 linhas7.854 bytes
apps/worker/tests/premiacao-edicoes.ts
SHA-256
a53accea68aa533a0231ccea97f13ba9e7a93151cb9bfb629934c68c51d71ed9
Somente leiturafonte-0531042d9f3e
/**
* Testes das edições do prêmio, do certificado e do e-mail de entrega.
* Só funções puras: não abre banco, rede nem Chrome.
* pnpm --filter worker test:premiacao-edicoes
*/
import assert from 'node:assert/strict'
import {
definirEdicao,
edicoesPossiveis,
normalizarCodigo,
EdicaoInvalida,
} from '../src/services/premiacao-edicoes'
import type { Certificado, DadosCertificado } from '../src/services/premiacao-edicoes'
import { dataPorExtenso, justificativa, nomeArquivo } from '../src/services/certificado'
import { montarEmail } from '../src/services/premiacao-email'
import { REGUA_ANO, REGUA_LEGISLATURA } from '../src/services/premiacao'
let passou = 0
let total = 0
function teste(nome: string, fn: () => void) {
total++
try {
fn()
passou++
console.log(`ok ${nome}`)
} catch (err) {
console.log(`FALHA ${nome}\n ${(err as Error).message}`)
}
}
function dados(over: Partial<DadosCertificado> = {}): DadosCertificado {
return {
codigo: 'OS-L57-7K3M-Q9XA',
edicao: {
id: 'leg57', tipo: 'legislatura', titulo: '57ª Legislatura (2023–2027)',
subtitulo: 'Edição da Legislatura', periodo: { inicio: '2023-02-01', fim: '2027-01-31' },
apuracaoSha256: 'a'.repeat(64),
},
categoria: {
id: 'regional_ne', eixo: 'regional', titulo: 'Destaque Nordeste', descricao: '',
ambito: 'Região Nordeste', concorrentes: 23,
},
senador: { codigo: '1', nome: 'Fulana de Tal', tratamento: 'Senadora', partido: 'PXX', uf: 'BA' },
idsTotal: 78.4,
valor: 78.4,
indicador: { rotulo: 'Composição do IDS', valor: 78.4, unidade: 'de 100', detalhe: 'em 47 meses de exercício' },
houveDesempate: false,
emitidoEm: '2027-02-01',
...over,
}
}
function cert(d: DadosCertificado): Certificado {
return {
codigo: d.codigo, edicaoId: d.edicao.id, categoriaId: d.categoria.id, senadorCod: d.senador.codigo,
dados: d, pdfSha256: null, pdfGerado: false, emitidoEm: d.emitidoEm, email: null,
emailOficial: null, enviadoEm: null, envios: 0, envioErro: null, revogadoEm: null, motivoRevogacao: null,
}
}
teste('há uma edição da legislatura e uma por ano legislativo da Leg 57', () => {
assert.deepEqual(edicoesPossiveis().map((e) => e.id),
['leg57', 'leg57-2023', 'leg57-2024', 'leg57-2025', 'leg57-2026'])
})
teste('o ano de 2023 começa com a legislatura, não em 1º de janeiro', () => {
assert.deepEqual(definirEdicao('ano', 57, 2023).periodo, { inicio: '2023-02-01', fim: '2023-12-31' })
assert.deepEqual(definirEdicao('ano', 57, 2025).periodo, { inicio: '2025-01-01', fim: '2025-12-31' })
})
teste('sessão legislativa ordinal no subtítulo do ano', () => {
assert.equal(definirEdicao('ano', 57, 2025).subtitulo, '3ª Sessão Legislativa da 57ª Legislatura')
})
teste('edições anuais usam a régua de meio ano; a legislatura, a de meia legislatura', () => {
assert.equal(definirEdicao('ano', 57, 2024).regua, REGUA_ANO)
assert.equal(definirEdicao('legislatura', 57).regua, REGUA_LEGISLATURA)
assert.ok(REGUA_ANO.mesesMinVitoria <= 11, 'um ano tem no máximo 11 meses contáveis')
})
teste('legislatura não suportada e ano fora da Leg 57 são recusados', () => {
assert.throws(() => definirEdicao('legislatura', 58), EdicaoInvalida)
assert.throws(() => definirEdicao('ano', 57, 2027), EdicaoInvalida)
})
teste('código digitado com caixa, espaços e O/I/L trocados é normalizado', () => {
assert.equal(normalizarCodigo(' os-l57-7k3m-q9xa '), 'OS-L57-7K3M-Q9XA')
assert.equal(normalizarCodigo('OS-L57-O1IL-AB0C'), 'OS-L57-0111-AB0C')
assert.equal(normalizarCodigo('OS-A25-LLLL-OOOO'), 'OS-A25-1111-0000', 'o prefixo não é tocado')
})
teste('data por extenso usa ordinal no dia 1', () => {
assert.equal(dataPorExtenso('2027-02-01'), '1º de fevereiro de 2027')
assert.equal(dataPorExtenso('2026-10-29T10:00:00Z'), '29 de outubro de 2026')
})
teste('justificativa regional cita a nota, os concorrentes e a região', () => {
assert.equal(
justificativa(dados()),
'Maior Índice de Desempenho Senatorial de 78,4 em 100 entre 23 concorrentes da Região Nordeste, em 47 meses de exercício.',
)
})
teste('justificativa temática mostra o número contado, sem repetir a unidade', () => {
const t = justificativa(dados({
categoria: { id: 'fiscalizacao', eixo: 'tematico', titulo: 'Fiscalização e Relatoria',
descricao: 'Relatorias assumidas por mês.', ambito: 'Temático', concorrentes: 74 },
indicador: { rotulo: 'Relatorias', valor: 150, unidade: 'relatorias', detalhe: 'em 40 meses de exercício' },
}))
assert.equal(t, 'Relatorias assumidas por mês. Primeiro lugar entre 74 concorrentes, com 150 relatorias em 40 meses de exercício.')
})
teste('justificativa de presença e de CEAP formata % e R$', () => {
const pres = justificativa(dados({
categoria: { id: 'participacao', eixo: 'tematico', titulo: 'Presença', descricao: 'X.', ambito: 'Temático', concorrentes: 80 },
indicador: { rotulo: 'Presença em plenário', valor: 97.5, unidade: '%', detalhe: '390 de 400 votações em plenário' },
}))
assert.match(pres, /com 97,5% de presença em plenário \(390 de 400/)
const ceap = justificativa(dados({
categoria: { id: 'ceap', eixo: 'tematico', titulo: 'CEAP', descricao: 'X.', ambito: 'Temático', concorrentes: 80 },
indicador: { rotulo: 'Cota parlamentar', valor: 12345.6, unidade: 'R$/mês', detalhe: 'R$ 500.000 no total' },
}))
assert.match(ceap, /média de R\$ 12\.346 por mês na cota parlamentar/)
})
teste('saudação segue a forma oficial de tratamento', () => {
assert.match(montarEmail([cert(dados())]).texto, /^Excelentíssima Senhora Senadora Fulana de Tal,/)
const masc = dados({ senador: { ...dados().senador, tratamento: 'Senador', nome: 'Fulano' } })
assert.match(montarEmail([cert(masc)]).texto, /^Excelentíssimo Senhor Senador Fulano,/)
})
teste('sem tratamento oficial, a saudação é neutra', () => {
const d = dados({ senador: { ...dados().senador, tratamento: 'Senador(a)' } })
assert.match(montarEmail([cert(d)]).texto, /^Ao Gabinete de Senador\(a\) Fulana de Tal,/)
})
teste('o corpo do e-mail não depende de gênero', () => {
const texto = montarEmail([cert(dados())]).texto.split('\n').slice(1).join('\n')
assert.doesNotMatch(texto, /reconhecid[oa]\b|premiad[oa]\b|agraciad[oa]\b/)
})
teste('vários certificados: plural no assunto e uma linha por categoria', () => {
const a = cert(dados())
const b = cert(dados({ codigo: 'OS-L57-AAAA-BBBB', categoria: { ...dados().categoria, id: 'grande_premio', titulo: 'Grande Prêmio', eixo: 'grande_premio', ambito: 'Nacional' } }))
const e = montarEmail([a, b])
assert.match(e.assunto, /certificados de reconhecimento$/)
assert.match(e.texto, /em 2 categorias/)
assert.match(e.texto, /OS-L57-7K3M-Q9XA/)
assert.match(e.texto, /OS-L57-AAAA-BBBB/)
})
teste('teste e reenvio marcam o assunto', () => {
assert.match(montarEmail([cert(dados())], { teste: true }).assunto, /^\[TESTE\] /)
assert.match(montarEmail([cert(dados())], { reenvio: true }).assunto, /^Reenvio: /)
})
teste('assinatura do e-mail e do certificado é só institucional', () => {
const { texto, html } = montarEmail([cert(dados())], { mensagem: 'Divulgação em fevereiro.' })
assert.match(texto, /Respeitosamente,\nObservatório do Senado\n/)
assert.match(html, /Divulgação em fevereiro\./)
})
teste('mensagem do admin é escapada no HTML', () => {
const { html } = montarEmail([cert(dados())], { mensagem: '<script>x</script>' })
assert.doesNotMatch(html, /<script>x/)
})
teste('nome do arquivo sem acento nem espaço', () => {
assert.equal(nomeArquivo(dados()), 'certificado-leg57-destaque-nordeste-fulana-de-tal.pdf')
})
console.log(`\n${passou}/${total} testes passaram`)
if (passou !== total) process.exit(1)