teqo-backup/tests/unit/projectionSheetParse.unit.spec.ts

270 lines
9.4 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import {
mapSheetPriority,
parseExpectationCell,
parseSheetNumber,
parseSituationCell,
splitNameCell,
} from '@/lib/projectionSheetParse'
describe('parseSheetNumber', () => {
it('parses Brazilian thousand separators', () => {
expect(parseSheetNumber('10.000')).toBe(10000)
expect(parseSheetNumber('1.400')).toBe(1400)
expect(parseSheetNumber(350)).toBe(350)
})
it('returns null for empty or non-numeric', () => {
expect(parseSheetNumber('')).toBeNull()
expect(parseSheetNumber(null)).toBeNull()
expect(parseSheetNumber('n/a')).toBeNull()
})
})
describe('parseExpectationCell', () => {
it('maps Bom/Regular/Mínimo onto optimistic/central/pessimistic', () => {
expect(parseExpectationCell('Bom:200 | Regular: 150 | Minimo: 100')).toEqual({
optimistic: 200,
central: 150,
pessimistic: 100,
})
expect(parseExpectationCell('Bom: 300 | Regular: 200 | Minimo: 100')).toEqual({
optimistic: 300,
central: 200,
pessimistic: 100,
})
expect(parseExpectationCell('Bom: 200| Regular: 150| Minimo: 100')).toEqual({
optimistic: 200,
central: 150,
pessimistic: 100,
})
})
it('parses thousand separators inside labeled cells', () => {
expect(parseExpectationCell('Bom: 2.000 | Regular: 1.500 | Minimo: 1.000')).toEqual({
optimistic: 2000,
central: 1500,
pessimistic: 1000,
})
expect(parseExpectationCell('Bom: 10.000 | Regular: 8.000 | Minimo: 6.000')).toEqual({
optimistic: 10000,
central: 8000,
pessimistic: 6000,
})
})
it('accepts Mínimo with accent', () => {
expect(parseExpectationCell('Bom: 100 | Regular: 80 | Mínimo: 50')).toEqual({
optimistic: 100,
central: 80,
pessimistic: 50,
})
})
it('parses slash format', () => {
expect(parseExpectationCell('800/500/400')).toEqual({
optimistic: 800,
central: 500,
pessimistic: 400,
})
expect(parseExpectationCell('300 /200 /100')).toEqual({
optimistic: 300,
central: 200,
pessimistic: 100,
})
})
it('tolerates backslash separators from sheet export glitches', () => {
expect(parseExpectationCell('Bom:300 \\Regular:150\\ mínimo: 50')).toEqual({
optimistic: 300,
central: 150,
pessimistic: 50,
})
})
it('returns null for empty or unrecognized cells', () => {
expect(parseExpectationCell(null)).toBeNull()
expect(parseExpectationCell('')).toBeNull()
expect(parseExpectationCell('Bom: 50 / regular: 30 / otmo: 100')).toBeNull()
})
})
describe('mapSheetPriority', () => {
it('maps alta to alta regardless of case', () => {
expect(mapSheetPriority('alta')).toBe('alta')
expect(mapSheetPriority('Alta')).toBe('alta')
expect(mapSheetPriority(' ALTA ')).toBe('alta')
})
it('maps Baixa, empty, and unknown to normal', () => {
expect(mapSheetPriority('Baixa')).toBe('normal')
expect(mapSheetPriority('')).toBe('normal')
expect(mapSheetPriority(null)).toBe('normal')
expect(mapSheetPriority('média')).toBe('normal')
})
})
describe('parseSituationCell', () => {
it('maps the long MAPA GERAL labels with emoji', () => {
expect(parseSituationCell('🔴 QUEDA DE VOTOS — Requer ação imediata')).toBe('desfavoravel')
expect(parseSituationCell('🟡 MANTÉM VOTAÇÃO — Acompanhar de perto')).toBe('neutra')
expect(parseSituationCell('🟢 AUMENTO DE VOTOS — Consolidar e ampliar')).toBe('favoravel')
})
it('maps the bare PRIORITÁRIAS labels', () => {
expect(parseSituationCell('QUEDA')).toBe('desfavoravel')
expect(parseSituationCell('MANTÉM')).toBe('neutra')
expect(parseSituationCell('AUMENTO')).toBe('favoravel')
})
it('returns null for undefined situations and footers', () => {
expect(parseSituationCell('NÃO DEFINIDA')).toBeNull()
expect(parseSituationCell('TOTAL GERAL')).toBeNull()
expect(parseSituationCell('')).toBeNull()
expect(parseSituationCell(null)).toBeNull()
})
})
describe('splitNameCell', () => {
it('splits on commas, slashes, and " e "', () => {
expect(splitNameCell('Mário, Romilson, Diquinha e Jamile')).toEqual({
names: ['Mário', 'Romilson', 'Diquinha', 'Jamile'],
skipped: [],
})
expect(splitNameCell('Júlio-').names).toEqual(['Júlio'])
expect(splitNameCell('Roberto/Oseas e Ademário')).toEqual({
names: ['Roberto', 'Oseas', 'Ademário'],
skipped: [],
})
expect(splitNameCell('Radiovaldo e Júlio e Ludimila')).toEqual({
names: ['Radiovaldo', 'Júlio', 'Ludimila'],
skipped: [],
})
})
it('keeps honorifics and descriptors as part of the name', () => {
expect(splitNameCell('Pedro Melo, Vera, Dr. Paulo e Yago').names).toEqual([
'Pedro Melo',
'Vera',
'Dr. Paulo',
'Yago',
])
expect(splitNameCell('Emiran, Amilton do PT e Moça de KK')).toEqual({
names: ['Emiran', 'Amilton do PT'],
skipped: ['Moça de KK'],
})
expect(splitNameCell('Markão, Sandrinho, Prefeito e Eleni Sec Saúde')).toEqual({
names: ['Markão', 'Sandrinho', 'Eleni Sec Saúde'],
skipped: ['Prefeito'],
})
})
it('extracts parentheticals before splitting', () => {
expect(splitNameCell('Cintia/Fernando/ (shaulin e davi terra ) e Silvio')).toEqual({
names: ['Cintia', 'Fernando', 'Silvio'],
skipped: ['(shaulin e davi terra )'],
})
expect(splitNameCell('Lucy, Edizio e Marianna (com Jamile)')).toEqual({
names: ['Lucy', 'Edizio', 'Marianna'],
skipped: ['(com Jamile)'],
})
})
it('drops uncertainty markers and placeholder dashes', () => {
expect(splitNameCell('Alex? e Júlio')).toEqual({ names: ['Júlio'], skipped: ['Alex?'] })
expect(splitNameCell('Panfile, Eliomar, vice?')).toEqual({
names: ['Panfile', 'Eliomar'],
skipped: ['vice?'],
})
expect(splitNameCell('-')).toEqual({ names: [], skipped: ['-'] })
expect(splitNameCell('?')).toEqual({ names: [], skipped: ['?'] })
expect(splitNameCell(null)).toEqual({ names: [], skipped: [] })
})
it('drops action phrases and collectives', () => {
expect(splitNameCell('VER COM VILMA').names).toEqual([])
expect(splitNameCell('CONFIRMAR COM JÚLIO').names).toEqual([])
expect(splitNameCell('AGUARDAR DEFINIÇÃO DE CIBELE').names).toEqual([])
expect(splitNameCell('SOLLA VAI INFORMAR').names).toEqual([])
expect(splitNameCell('Solla vai ver').names).toEqual([])
expect(splitNameCell('Construindo pra trocar Galo por Julio ou Rosemberg').names).toEqual([])
expect(splitNameCell('Júlio e Estadual do Prefeito')).toEqual({
names: ['Júlio'],
skipped: ['Estadual do Prefeito'],
})
expect(splitNameCell('A definir').names).toEqual([])
expect(splitNameCell('candidato do Prefeito').names).toEqual([])
expect(splitNameCell('Chico e vereador')).toEqual({
names: ['Chico'],
skipped: ['vereador'],
})
expect(splitNameCell('TRATAR COM ADEMAR DELGADO').names).toEqual([])
expect(splitNameCell('Burica | DEFINIR ALYSON')).toEqual({
names: ['Burica'],
skipped: ['DEFINIR ALYSON'],
})
expect(splitNameCell('Diego Pita - COBRAR IONÁ').names).toEqual([])
expect(splitNameCell('Ex-vice prefeito').names).toEqual([])
expect(splitNameCell('o Prefeito').names).toEqual([])
expect(splitNameCell('Assessor de Fatima Nunes').names).toEqual([])
expect(splitNameCell('Presidente do PT e Netinho presidente do PT')).toEqual({
names: ['Netinho presidente do PT'],
skipped: ['Presidente do PT'],
})
expect(splitNameCell('Meiriane ex prefeita').names).toEqual(['Meiriane ex prefeita'])
expect(splitNameCell('Rogério e grupo de ACS, Rodrigo ')).toEqual({
names: ['Rogério', 'Rodrigo'],
skipped: ['grupo de ACS'],
})
expect(splitNameCell('Dr. Ruy e pesoal do PT e Alfredo Boasorte')).toEqual({
names: ['Dr. Ruy', 'Alfredo Boasorte'],
skipped: ['pesoal do PT'],
})
expect(splitNameCell('Sec. Saúde, Rosival Presidente do PT, Associação de mulheres')).toEqual({
names: ['Rosival Presidente do PT'],
skipped: ['Sec. Saúde', 'Associação de mulheres'],
})
expect(
splitNameCell('Adiel e irmã de Nagib, pessoal do Circo (Oseas) e Pessoal do Roque'),
).toEqual({
names: ['Adiel'],
skipped: ['(Oseas)', 'irmã de Nagib', 'pessoal do Circo', 'Pessoal do Roque'],
})
})
it('splits sentence periods while keeping honorific abbreviations intact', () => {
expect(splitNameCell('Lucy. Falar com Fabio e com Goiano')).toEqual({
names: ['Lucy'],
skipped: ['Falar com Fabio', 'com Goiano'],
})
expect(splitNameCell('Telma, Breno e Nem do Caipe, Luis campineira.').names).toEqual([
'Telma',
'Breno',
'Nem do Caipe',
'Luis campineira',
])
})
it('keeps compound entries with embedded descriptors', () => {
expect(
splitNameCell(
'David Terra, Geysa e Ana Fraga, Adalicio - Sindicato dos Trabalhadores Rurais e sogro de Matheus, Fernando de Cairu, Jaci Perninha',
),
).toEqual({
names: [
'David Terra',
'Geysa',
'Ana Fraga',
'Adalicio - Sindicato dos Trabalhadores Rurais',
'Fernando de Cairu',
'Jaci Perninha',
],
skipped: ['sogro de Matheus'],
})
expect(splitNameCell('Getúlio e vereadores')).toEqual({
names: ['Getúlio'],
skipped: ['vereadores'],
})
})
})