teqo-backup/tests/unit/speechHighlight.unit.spec.ts
Francisco Solla 3e062749fa feat(C154): vertical de comunicação — papel communicator e acervo pesquisável
Papel communicator com nav própria e gate speechCatalog; acervo em
/campanha/comunicacao/acervo com busca normalizada (destaque no trecho),
filtros de ano/tema/alcance/fase/município/duração em URL canônica e
paginação por discurso via speech.searchText (GIN trgm + backfill).
Detalhe com player nativo no trecho, transcrição clicável, baixar/abrir
fonte e fallback sem VOD. Resolve o débito do C153 (Sollinha fora da
vertical) e corrige o parser de keywords oficiais no dono.

Closes #956
2026-09-13 13:46:58 -03:00

76 lines
2.8 KiB
TypeScript

// @vitest-environment node
import { describe, expect, it } from 'vitest'
import {
buildHighlightedExcerpt,
findHighlightRanges,
matchesSearchTerms,
splitHighlightedParts,
} from '@/lib/speechHighlight'
const highlighted = (text: string, query: string): string[] =>
splitHighlightedParts(text, query)
.filter((part) => part.highlighted)
.map((part) => part.text)
describe('findHighlightRanges', () => {
it('maps an accent-free query back to the accented original spelling', () => {
const text = 'A defesa do SUS e da saúde pública'
expect(findHighlightRanges(text, 'saude')).toEqual([{ start: 21, end: 26 }])
expect(highlighted(text, 'saude')).toEqual(['saúde'])
})
it('finds every term of a multi-word query, accent-insensitively', () => {
const text = 'O Governo retomou a Farmácia Popular na Bahia'
expect(highlighted(text, 'farmacia popular')).toEqual(['Farmácia', 'Popular'])
expect(highlighted(text, 'FARMÁCIA')).toEqual(['Farmácia'])
})
it('merges overlapping occurrences', () => {
expect(findHighlightRanges('banana', 'ana')).toEqual([{ start: 1, end: 6 }])
})
it('handles whitespace and punctuation around the match', () => {
const text = ' saúde,\n educação '
expect(highlighted(text, 'saude educacao')).toEqual(['saúde', 'educação'])
})
it('returns nothing for an empty query or a miss', () => {
expect(findHighlightRanges('texto', '')).toEqual([])
expect(findHighlightRanges('texto', 'inexistente')).toEqual([])
})
})
describe('matchesSearchTerms', () => {
it('requires every term, in any order', () => {
expect(matchesSearchTerms('A defesa do SUS e da saúde', 'saude sus')).toBe(true)
expect(matchesSearchTerms('A defesa do SUS', 'saude educacao')).toBe(false)
expect(matchesSearchTerms('A defesa do SUS', '')).toBe(false)
})
})
describe('buildHighlightedExcerpt', () => {
it('windows around the first match and flags truncation', () => {
const text = `${'a'.repeat(300)} saúde ${'b'.repeat(300)}`
const excerpt = buildHighlightedExcerpt(text, 'saude', { radius: 20 })
expect(excerpt.truncatedStart).toBe(true)
expect(excerpt.truncatedEnd).toBe(true)
const parts = excerpt.parts
expect(parts.some((part) => part.highlighted && part.text === 'saúde')).toBe(true)
})
it('falls back to the text start without highlights when nothing matches', () => {
const excerpt = buildHighlightedExcerpt('Uma fala sem o termo buscado', 'inexistente', {
radius: 10,
})
expect(excerpt.parts.every((part) => !part.highlighted)).toBe(true)
expect(excerpt.truncatedStart).toBe(false)
expect(excerpt.truncatedEnd).toBe(true)
})
it('returns empty parts for empty text', () => {
expect(buildHighlightedExcerpt(' ', 'saude').parts).toEqual([])
})
})