teqo/tests/unit/voteGoals.unit.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

54 lines
1.9 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { municipalityStrategyUpdateSchema } from '@/lib/schemas/municipality'
import {
aggregateVoteGoals,
countHighPriorityEntries,
getVoteGoalsOrderViolation,
sumVoteGoals,
voteGoalProgressPercent,
} from '@/utilities/voteGoals'
describe('vote goals schema and aggregates', () => {
it('accepts vote goals and priority on the municipality strategy schema', () => {
const parsed = municipalityStrategyUpdateSchema.parse({
municipality: 1,
voteGoals: { good: 1000, regular: 800, minimum: 500 },
priority: 'alta',
})
expect(parsed.voteGoals).toEqual({ good: 1000, regular: 800, minimum: 500 })
expect(parsed.priority).toBe('alta')
})
it('aggregates vote goals and counts high-priority municipalities', () => {
const municipalities = [
{
voteGoals: { good: 1000, regular: 800, minimum: 500 },
priority: 'alta' as const,
},
{
voteGoals: { good: 200, regular: 150, minimum: 100 },
priority: 'normal' as const,
},
]
expect(aggregateVoteGoals(municipalities)).toEqual({
good: 1200,
regular: 950,
minimum: 600,
highPriorityCount: 1,
})
expect(sumVoteGoals(municipalities)).toEqual({ good: 1200, regular: 950, minimum: 600 })
expect(countHighPriorityEntries(municipalities)).toBe(1)
expect(voteGoalProgressPercent(400, 800)).toBe(50)
expect(voteGoalProgressPercent(null, 800)).toBeNull()
})
it('flags vote goal order violations on sparse inputs', () => {
expect(getVoteGoalsOrderViolation({ good: 100, regular: 200 })).toBe('regular')
expect(getVoteGoalsOrderViolation({ regular: 50, minimum: 100 })).toBe('minimum')
expect(getVoteGoalsOrderViolation({ good: 100, minimum: 200 })).toBe('minimum')
expect(getVoteGoalsOrderViolation({ good: 100, regular: 80 })).toBeNull()
})
})