teqo/tests/int/municipalityMapData.int.spec.ts
Francisco Ignácio Fontoura Solla e2724c10da Remodel the campaign vertical from Praça to Município
Rename the operational unit "Praça"/"Núcleo" to "Município" (code identifier
`municipality`) and land the 2026-07-23 course changes:

- New `candidate` role with unrestricted visibility (`isCampaignStaff` now
  includes it) alongside coordinator/advisor; leader is locked down to the
  supporter contact tool only.
- Demandas become staff-only; dobradinhas modeled via a `stateDeputy` entity.
- Camaçari consolidated to a single município (ZE 170/171 aggregated);
  Salvador keeps its 19 zone municípios.
- Map moves to the staff dashboard; `/campanha/municipios` is list/overview.
- Vote pledges keep the declared vs estimated (scenario) asymmetry; leaders
  never see estimates.

Destructive migration for the campaign vertical (drops nucleus/plaza-era
tables, wipes campaign rows, seeds 435 municípios). Public-site data untouched.

Includes the post-delivery /simplify cleanups: shared reloadStaffActor /
reloadCoordinatorActor helpers, req.context cache for getFreshCampaignUser,
parallelized dashboard loads, candidate dashboard-copy fix, and dead
leader-dashboard / roleKind code removal.
2026-07-23 21:36:20 -03:00

87 lines
3.3 KiB
TypeScript

// @vitest-environment node
import type { Payload } from 'payload'
import { getPayload } from 'payload'
import { beforeAll, describe, expect, it } from 'vitest'
import config from '@/payload.config'
import { municipalityCatalog } from '@/lib/municipalityCatalog'
import { loadMunicipalityMapBundle } from '@/utilities/municipalityMapData'
import { installCampaignFixtures } from '../helpers/campaignFixtures'
const ZONE_PLAZA_COUNT = municipalityCatalog.filter((entry) => entry.kind === 'zona').length
const ZONE_MUNICIPALITY_CODES = new Set(
municipalityCatalog.filter((entry) => entry.kind === 'zona').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('scopes the map to zone municipalities when kind=zona is in the URL', async () => {
const coordinator = await campaignFixtures().createCampaignUser('coordinator')
const bundle = await loadMunicipalityMapBundle(payload, coordinator, { kind: 'zona' })
expect(bundle).not.toBeNull()
expect(bundle!.zoneBreakdown).toHaveLength(ZONE_PLAZA_COUNT)
const ibgeCodes = Object.keys(bundle!.valuesByYear['2022'] ?? {})
expect(ibgeCodes.length).toBeGreaterThan(0)
for (const code of ibgeCodes) {
expect(ZONE_MUNICIPALITY_CODES.has(code)).toBe(true)
}
})
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',
)
if (administered.kind !== 'zona') {
expect(Object.keys(included!.valuesByYear['2022'] ?? {})).toEqual([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'])
})
})