mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-12 22:13:05 +00:00
* feat(ops): auto-promote stage→main e merge em stage sem exigir head Substitui o promote manual por workflow disparado no ci-stage green, relaxa strict na proteção de stage (script configure:branch-protection) e documenta o novo paradigma em AGENT-OPS e work-issue. * style: format AGENT-OPS and configure-branch-protection for ci-pr * feat(ops): pnpm push com ensure-repo-deps determinístico Bootstrap install + Husky antes de todo push (pnpm push e pre-push). Documenta fluxo canônico em work-issue, agent-pr-workflow e AGENT-OPS. * fix(ops): pnpm push roda gate no script, sem depender do Husky Cloud environment.json chama prepare explicitamente após install. * test(int): isolate advisor portfolio search from shared cairu slug Parallel int specs were stomping municipality.advisors on the fixed cairu row; allocate per-test municipalities instead.
74 lines
2.8 KiB
TypeScript
74 lines
2.8 KiB
TypeScript
// @vitest-environment node
|
|
|
|
import type { Payload } from 'payload'
|
|
import { getPayload } from 'payload'
|
|
import { beforeAll, describe, expect, it } from 'vitest'
|
|
|
|
import { getMunicipalityCatalogEntry } from '@/lib/municipalityCatalog'
|
|
import config from '@/payload.config'
|
|
import { searchStaffMunicipalityHits } from '@/utilities/homeSearch/searchStaffMunicipalityHits'
|
|
|
|
import { installCampaignFixtures } from '../helpers/campaignFixtures'
|
|
|
|
let payload: Payload
|
|
const campaignFixtures = installCampaignFixtures({
|
|
getPayload: () => payload,
|
|
setPayload: (nextPayload) => {
|
|
payload = nextPayload
|
|
},
|
|
})
|
|
|
|
describe('searchStaffMunicipalityHits (B60)', () => {
|
|
beforeAll(async () => {
|
|
payload = await getPayload({ config: await config })
|
|
})
|
|
|
|
it('returns empty hits when query is shorter than the minimum', async () => {
|
|
const fixtures = campaignFixtures()
|
|
const coordinator = await fixtures.createCampaignUser('coordinator')
|
|
|
|
const result = await searchStaffMunicipalityHits(payload, coordinator, 'a')
|
|
expect(result).toEqual([])
|
|
})
|
|
|
|
it('matches municipalities by word-start on the name', async () => {
|
|
const fixtures = campaignFixtures()
|
|
const coordinator = await fixtures.createCampaignUser('coordinator')
|
|
const cairu = getMunicipalityCatalogEntry('cairu')
|
|
expect(cairu).toBeDefined()
|
|
|
|
const result = await searchStaffMunicipalityHits(payload, coordinator, 'Cai')
|
|
expect(result.some((hit) => hit.slug === 'cairu')).toBe(true)
|
|
})
|
|
|
|
it('scopes municipality hits to the advisor portfolio', async () => {
|
|
const fixtures = campaignFixtures()
|
|
const advisor = await fixtures.createCampaignUser('advisor')
|
|
const coordinator = await fixtures.createCampaignUser('coordinator')
|
|
|
|
const administered = await fixtures.getMunicipality()
|
|
const other = await fixtures.getMunicipality()
|
|
await fixtures.assignMunicipalityAdvisors(administered.id, [advisor.id])
|
|
|
|
const otherQuery = other.name.split(/\s+/)[0]!
|
|
const administeredQuery = administered.name.split(/\s+/)[0]!
|
|
|
|
const advisorResult = await searchStaffMunicipalityHits(payload, advisor, otherQuery)
|
|
expect(advisorResult.map((hit) => hit.slug)).toEqual([])
|
|
|
|
const coordinatorResult = await searchStaffMunicipalityHits(payload, coordinator, otherQuery)
|
|
expect(coordinatorResult.some((hit) => hit.slug === other.slug)).toBe(true)
|
|
|
|
const advisorAdmin = await searchStaffMunicipalityHits(payload, advisor, administeredQuery)
|
|
expect(advisorAdmin.map((hit) => hit.slug)).toEqual([administered.slug])
|
|
})
|
|
|
|
it('rejects leaders from wizard municipality search', async () => {
|
|
const fixtures = campaignFixtures()
|
|
const leader = await fixtures.createCampaignUser('leader')
|
|
|
|
await expect(searchStaffMunicipalityHits(payload, leader, 'Cairu')).rejects.toThrow(
|
|
/equipe de campanha/i,
|
|
)
|
|
})
|
|
})
|