F1 — a tolerancia de simplificacao e os digitos de quantizacao viraram politica em unidades de solo em scripts/lib/topology.mjs, consumida pelos dois scripts de geometria. Os quantis 0.35 copiados cortavam as 19 ZE de Salvador a ~0.6 m2 e os 417 municipios a ~1.78 km2; com tolerancia absoluta e a grade de ~103 m do estado, a malha das zonas caiu de 480 para 30.2 pontos/feature. bahia-municipalities segue byte-identico e o tripwire de bytes deu lugar a pontos/feature. F2 — featureMapKey passou a ser asserido sobre features reais das tres malhas comprometidas (417 codarea, 27 code, 19 slug), e o comentario de MAP_KEY_PROPERTIES agora diz o que o codigo faz: as propriedades sao mutuamente exclusivas, nao ordenadas por especificidade. F3 — a malha das zonas e um detalhe sobre o mapa, nao o mapa: se o chunk falha, Salvador cai no poligono municipal que ja esta desenhado embaixo e o resto da Bahia continua funcionando, com o motivo logado. A ressalva de aproximacao saiu do gate de comparacao e passou a depender de bundle.hasZoneMunicipalities, derivado no servidor de municipality.kind. F4 — orfaos deletados: os dois acessores sem chamador, isZoneMapKey (o servidor ja sabe a regra), o wrapper simplifyTopology e o helper polygonCount com um branch inalcancavel. MunicipalityMapNavigation colapsou em string | undefined e MunicipalitiesByMapKey em Record<string, string>.
97 lines
4 KiB
TypeScript
97 lines
4 KiB
TypeScript
// @vitest-environment node
|
|
|
|
import type { Payload } from 'payload'
|
|
import { getPayload } from 'payload'
|
|
import { beforeAll, describe, expect, it } from 'vitest'
|
|
|
|
import { municipalityCatalog } from '@/lib/municipalityCatalog'
|
|
import config from '@/payload.config'
|
|
import { loadMunicipalityMapBundle } from '@/utilities/municipalityMapData'
|
|
|
|
import { installCampaignFixtures } from '../helpers/campaignFixtures'
|
|
|
|
const zoneMunicipalities = municipalityCatalog.filter((entry) => entry.kind === 'zona')
|
|
const ZONE_MUNICIPALITY_COUNT = zoneMunicipalities.length
|
|
const ZONE_MUNICIPALITY_SLUGS = new Set(zoneMunicipalities.map((entry) => entry.slug))
|
|
const ZONE_MUNICIPALITY_CODES = new Set(zoneMunicipalities.map((entry) => entry.ibgeCode))
|
|
|
|
let payload: Payload
|
|
const campaignFixtures = installCampaignFixtures({
|
|
getPayload: () => payload,
|
|
setPayload: (nextPayload) => {
|
|
payload = nextPayload
|
|
},
|
|
})
|
|
|
|
describe('loadMunicipalityMapBundle — list URL filters', () => {
|
|
beforeAll(async () => {
|
|
payload = await getPayload({ config: await config })
|
|
})
|
|
|
|
it('paints each zone under its own map key, never pooled under the city code', async () => {
|
|
const coordinator = await campaignFixtures().createCampaignUser('coordinator')
|
|
|
|
const bundle = await loadMunicipalityMapBundle(payload, coordinator, { kind: 'zona' })
|
|
|
|
expect(bundle).not.toBeNull()
|
|
expect(bundle!.zoneBreakdown).toHaveLength(ZONE_MUNICIPALITY_COUNT)
|
|
expect(bundle!.hasZoneMunicipalities).toBe(true)
|
|
|
|
const mapKeys = Object.keys(bundle!.valuesByYear['2022'] ?? {})
|
|
expect(mapKeys.length).toBeGreaterThan(0)
|
|
for (const key of mapKeys) {
|
|
expect(ZONE_MUNICIPALITY_SLUGS.has(key), key).toBe(true)
|
|
expect(ZONE_MUNICIPALITY_CODES.has(key), key).toBe(false)
|
|
}
|
|
expect(Object.keys(bundle!.municipalitiesByMapKey).sort()).toEqual([...mapKeys].sort())
|
|
|
|
// The zones share the city's TSE rank — the artifact ranks by codarea only.
|
|
const ranks = bundle!.competitiveRankByYear['2022'] ?? {}
|
|
const positions = new Set(mapKeys.map((key) => ranks[key]?.rank))
|
|
expect(positions.size).toBe(1)
|
|
})
|
|
|
|
it('returns null when the filtered municipality set is empty', async () => {
|
|
const coordinator = await campaignFixtures().createCampaignUser('coordinator')
|
|
|
|
const bundle = await loadMunicipalityMapBundle(payload, coordinator, { q: 'zzznomatch' })
|
|
|
|
expect(bundle).toBeNull()
|
|
})
|
|
|
|
it('keeps advisor access and applies URL filters on top', async () => {
|
|
const fixtures = campaignFixtures()
|
|
const advisor = await fixtures.createCampaignUser('advisor')
|
|
const administered = await fixtures.getMunicipality()
|
|
await fixtures.assignMunicipalityAdvisors(administered.id, [advisor.id])
|
|
|
|
const included = await loadMunicipalityMapBundle(payload, advisor, { q: administered.name })
|
|
expect(included).not.toBeNull()
|
|
expect(included!.zoneBreakdown.some((row) => row.slug === administered.slug)).toBe(
|
|
administered.kind === 'zona',
|
|
)
|
|
// The map's provenance caveat follows the actor's scope, not the list below it.
|
|
expect(included!.hasZoneMunicipalities).toBe(administered.kind === 'zona')
|
|
expect(Object.keys(included!.valuesByYear['2022'] ?? {})).toEqual([
|
|
administered.kind === 'zona' ? administered.slug : administered.ibgeCode,
|
|
])
|
|
|
|
const excluded =
|
|
administered.kind === 'zona'
|
|
? await loadMunicipalityMapBundle(payload, advisor, { kind: 'municipio' })
|
|
: await loadMunicipalityMapBundle(payload, advisor, { kind: 'zona' })
|
|
expect(excluded).toBeNull()
|
|
})
|
|
|
|
it('includes validVotesByYear for TSE years and reuses 2022 for 2026', async () => {
|
|
const coordinator = await campaignFixtures().createCampaignUser('coordinator')
|
|
|
|
const bundle = await loadMunicipalityMapBundle(payload, coordinator, {})
|
|
|
|
expect(bundle).not.toBeNull()
|
|
expect(bundle!.validVotesByYear['2014']).toBeDefined()
|
|
expect(bundle!.validVotesByYear['2018']).toBeDefined()
|
|
expect(bundle!.validVotesByYear['2022']).toBeDefined()
|
|
expect(bundle!.validVotesByYear['2026']).toBe(bundle!.validVotesByYear['2022'])
|
|
})
|
|
})
|