teqo/tests/unit/accessShared.unit.spec.ts
Francisco Ignácio Fontoura Solla 4806c417c8 Engineering Pass 3: consolidate patterns and lock them with guards.
Fold duplicated campanha access, loaders, list/filter/form shells, and scripts into shared modules; reorganize utilities by domain; stabilize e2e; and document prevention-first audit workflow so the same smells cannot creep back in.
2026-07-29 06:11:29 -03:00

84 lines
3.2 KiB
TypeScript

// @vitest-environment node
import type { Payload, PayloadRequest } from 'payload'
import { describe, expect, it, vi } from 'vitest'
import type { CampaignUser, User } from '@/payload-types'
import {
advisorMunicipalityScopeWhere,
resolveAccessibleIds,
resolveActorScopedRead,
} from '@/utilities/access/shared'
import { stub } from '../helpers/stub'
const advisorUser = stub<CampaignUser>({
collection: 'campaignUser',
id: 7,
role: 'advisor',
})
/**
* P3-D pin: one spec per consolidated predicate form — the scope fragment, the
* scoped-read prologue, and the memoized accessible-ids engine. The int access
* matrix pins behavior end-to-end; these pin the single spellings the guard in
* `codebaseConventions.unit.spec.ts` makes the only writable ones.
*/
describe('access shared policies (P3-D)', () => {
it('spells the advisor scope fragment exactly once per field', () => {
expect(advisorMunicipalityScopeWhere('municipality', [1, 2])).toEqual({
municipality: { in: [1, 2] },
})
expect(advisorMunicipalityScopeWhere('municipalities', null)).toEqual({
municipalities: { in: [] },
})
})
it('resolveActorScopedRead: admin → all, anon → nothing, advisor → scope', async () => {
const adminReq = stub<PayloadRequest>({
user: stub<User>({ collection: 'users', roles: ['admin'] }),
})
await expect(resolveActorScopedRead(adminReq, 'municipality', vi.fn())).resolves.toBe(true)
const anonReq = stub<PayloadRequest>({ user: null })
await expect(resolveActorScopedRead(anonReq, 'municipality', vi.fn())).resolves.toBe(false)
const loadAccessibleIds = vi.fn().mockResolvedValue([42])
// The prologue reloads the actor fresh (getFreshCampaignUser), so the stub
// request needs a payload answering findByID with the same advisor.
const advisorReq = stub<PayloadRequest>({
user: advisorUser,
payload: stub<Payload>({ findByID: vi.fn().mockResolvedValue(advisorUser) }),
})
await expect(
resolveActorScopedRead(advisorReq, 'municipality', loadAccessibleIds),
).resolves.toEqual({ municipality: { in: [42] } })
})
it('resolveAccessibleIds: unrestricted → null, non-campaign → [], memoizes per request', async () => {
const coordinator = stub<CampaignUser>({
collection: 'campaignUser',
id: 1,
role: 'coordinator',
})
const unrestrictedReq = stub<PayloadRequest>({
user: coordinator,
payload: stub<Payload>({ findByID: vi.fn().mockResolvedValue(coordinator) }),
})
await expect(resolveAccessibleIds(unrestrictedReq, undefined, 'k', vi.fn())).resolves.toBeNull()
const foreignReq = stub<PayloadRequest>({
user: stub<User>({ collection: 'users', roles: ['editor'] }),
})
await expect(resolveAccessibleIds(foreignReq, undefined, 'k', vi.fn())).resolves.toEqual([])
const compute = vi.fn().mockResolvedValue([5])
const req = stub<PayloadRequest>({
user: advisorUser,
payload: stub<Payload>({ findByID: vi.fn().mockResolvedValue(advisorUser) }),
})
await expect(resolveAccessibleIds(req, undefined, 'k', compute)).resolves.toEqual([5])
await expect(resolveAccessibleIds(req, undefined, 'k', compute)).resolves.toEqual([5])
expect(compute).toHaveBeenCalledTimes(1)
})
})