mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 15:13:07 +00:00
Substitui o modelo de MunicipalityUpdate (kind/semanal/urgente/nota/sinal + signalType) por um modelo unificado: body obrigatório + polarity (boa/neutra/ruim) + urgent + adversarySignal. - Schema: polarity enum obrigatório, urgent boolean default false, adversarySignal boolean - Wizard: novo WizardUpdateBodyStep com campo de texto + polaridade + urgente - Lista: controle unificado de atualização com polaridade inline - Feed: exibe polaridade como badge colorido + indicador de urgência - V2 status strip: atualização rápida de polaridade - E11: queries atualizadas para polarity + adversarySignal - Migração: 20260807_030000_unify_municipality_update (backfill polarity=neutra, urgent de kind, adversarySignal de kind+signalType) - Testes: 18/18 integração C87, 593/593 total, 1399/1399 unitários - Fix: testes de state deputy usavam nomes fixos que colidiam entre execuções
77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
buildMunicipalityV2StatusAggregate,
|
|
MUNICIPALITY_V2_SIGNAL_COLD_VALUE,
|
|
resolveMunicipalityV2UpdateState,
|
|
} from '@/utilities/municipality/municipalityV2StatusView'
|
|
|
|
describe('municipalityV2StatusView', () => {
|
|
it('uses cold sentinel when there is no recent signal', () => {
|
|
const state = resolveMunicipalityV2UpdateState(
|
|
{ polarity: null, lastSignalAt: null },
|
|
new Date('2026-08-02T12:00:00.000Z'),
|
|
)
|
|
expect(state.value).toBe(MUNICIPALITY_V2_SIGNAL_COLD_VALUE)
|
|
expect(state.isCold).toBe(true)
|
|
expect(state.label).toContain('Sem sinal')
|
|
})
|
|
|
|
it('does not claim frio when frescor is warm but typeless', () => {
|
|
const state = resolveMunicipalityV2UpdateState(
|
|
{
|
|
polarity: null,
|
|
lastSignalAt: '2026-08-01T12:00:00.000Z',
|
|
},
|
|
new Date('2026-08-02T12:00:00.000Z'),
|
|
)
|
|
expect(state.value).toBe(MUNICIPALITY_V2_SIGNAL_COLD_VALUE)
|
|
expect(state.isCold).toBe(false)
|
|
expect(state.label).toBe('Sem polaridade')
|
|
})
|
|
|
|
it('keeps the typed polarity when still warm', () => {
|
|
const state = resolveMunicipalityV2UpdateState(
|
|
{
|
|
polarity: 'ruim',
|
|
lastSignalAt: '2026-08-01T12:00:00.000Z',
|
|
},
|
|
new Date('2026-08-02T12:00:00.000Z'),
|
|
)
|
|
expect(state.value).toBe('ruim')
|
|
expect(state.isCold).toBe(false)
|
|
expect(state.label).toBe('Ruim')
|
|
})
|
|
|
|
it('builds the aggregate from the three note axes', () => {
|
|
const aggregate = buildMunicipalityV2StatusAggregate(
|
|
{
|
|
engagementLevel: 'n2',
|
|
levelNote: 'Subiu o nível',
|
|
trendNote: 'Tendência melhor',
|
|
updatePolarity: 'ruim',
|
|
updateBody: 'Rede parou',
|
|
lastSignalAt: '2026-08-01T12:00:00.000Z',
|
|
},
|
|
new Date('2026-08-02T12:00:00.000Z'),
|
|
)
|
|
expect(aggregate).toBe('Subiu o nível · Tendência melhor · Rede parou')
|
|
})
|
|
|
|
it('names absences when notes are empty', () => {
|
|
const aggregate = buildMunicipalityV2StatusAggregate(
|
|
{
|
|
engagementLevel: 'n1',
|
|
levelNote: null,
|
|
trendNote: null,
|
|
updatePolarity: null,
|
|
updateBody: null,
|
|
lastSignalAt: null,
|
|
},
|
|
new Date('2026-08-02T12:00:00.000Z'),
|
|
)
|
|
expect(aggregate).toContain('sem motivo')
|
|
expect(aggregate).toContain('Tendência sem nota')
|
|
expect(aggregate).toContain('Sem sinal')
|
|
})
|
|
})
|