mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 06:43:06 +00:00
Migration 20260823_161905_add_municipality_update_deliberation + access por mutationKind + ilha client nas 3 superfícies + specs unit/int/e2e.
81 lines
2.9 KiB
TypeScript
81 lines
2.9 KiB
TypeScript
// @vitest-environment node
|
|
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
import type { CampaignUser } from '@/payload-types'
|
|
import {
|
|
MUNICIPALITY_UPDATE_DELIBERATION_MUTATIONS,
|
|
resolveMunicipalityUpdateCapabilities,
|
|
} from '@/utilities/access/municipalityUpdates'
|
|
|
|
import { stub } from '../helpers/stub'
|
|
|
|
const campaignUser = (role: CampaignUser['role'], extra: Partial<CampaignUser> = {}) =>
|
|
stub<CampaignUser>({ collection: 'campaignUser', id: 1, role, ...extra })
|
|
|
|
/**
|
|
* C88 — the capability resolver is the pure mirror of the access predicates
|
|
* (assign/resolve = unrestricted, comment = create rule); the int spec pins
|
|
* the end-to-end gate. These pin the profile matrix the client card renders.
|
|
*/
|
|
describe('municipality update deliberation capabilities (C88)', () => {
|
|
it('grants everything to coordinator and candidate', () => {
|
|
expect(resolveMunicipalityUpdateCapabilities(campaignUser('coordinator'))).toEqual({
|
|
canAssign: true,
|
|
canComment: true,
|
|
canResolve: true,
|
|
})
|
|
expect(resolveMunicipalityUpdateCapabilities(campaignUser('candidate'))).toEqual({
|
|
canAssign: true,
|
|
canComment: true,
|
|
canResolve: true,
|
|
})
|
|
})
|
|
|
|
it('advisor may comment unless the Edição axis is somente_leitura, never assign or resolve', () => {
|
|
expect(
|
|
resolveMunicipalityUpdateCapabilities(campaignUser('advisor', { editing: 'carteira' })),
|
|
).toEqual({ canAssign: false, canComment: true, canResolve: false })
|
|
expect(
|
|
resolveMunicipalityUpdateCapabilities(
|
|
campaignUser('advisor', { visibility: 'tudo', editing: 'tudo' }),
|
|
),
|
|
).toEqual({ canAssign: false, canComment: true, canResolve: false })
|
|
// C141 coherence rule: Edição "Tudo" sem Visão "Tudo" resolve "none".
|
|
expect(
|
|
resolveMunicipalityUpdateCapabilities(campaignUser('advisor', { editing: 'tudo' })),
|
|
).toEqual({ canAssign: false, canComment: false, canResolve: false })
|
|
expect(
|
|
resolveMunicipalityUpdateCapabilities(
|
|
campaignUser('advisor', { editing: 'somente_leitura' }),
|
|
),
|
|
).toEqual({ canAssign: false, canComment: false, canResolve: false })
|
|
})
|
|
|
|
it('leader, unknown actors and anonymous get nothing', () => {
|
|
expect(resolveMunicipalityUpdateCapabilities(campaignUser('leader'))).toEqual({
|
|
canAssign: false,
|
|
canComment: false,
|
|
canResolve: false,
|
|
})
|
|
expect(resolveMunicipalityUpdateCapabilities(null)).toEqual({
|
|
canAssign: false,
|
|
canComment: false,
|
|
canResolve: false,
|
|
})
|
|
expect(resolveMunicipalityUpdateCapabilities(undefined)).toEqual({
|
|
canAssign: false,
|
|
canComment: false,
|
|
canResolve: false,
|
|
})
|
|
})
|
|
|
|
it('exposes exactly the four deliberative mutation kinds the hook allowlists', () => {
|
|
expect([...MUNICIPALITY_UPDATE_DELIBERATION_MUTATIONS]).toEqual([
|
|
'assignResponsible',
|
|
'appendComment',
|
|
'resolve',
|
|
'reopen',
|
|
])
|
|
})
|
|
})
|