fix(test): isola municípios nos homeSearch specs para evitar deadlock

Specs de portfolio deixam de mutar cairu/feira compartilhados e passam a
usar getMunicipality() alocado; testDatabaseLease ignora updatedAt volátil.
This commit is contained in:
Francisco Ignácio Fontoura Solla 2026-07-30 22:07:40 -03:00
parent b533139eb2
commit 0fece8cef5
6 changed files with 39 additions and 31 deletions

View file

@ -43,7 +43,7 @@ describe('searchHomeActivities (B51)', () => {
it('matches activities by word-start on the title for staff', async () => {
const fixtures = campaignFixtures()
const coordinator = await fixtures.createCampaignUser('coordinator')
const municipality = await fixtures.getMunicipality('cairu')
const municipality = await fixtures.getMunicipality()
const title = fixtures.value('Caminhada Zeca Centro')
const activity = await createActivityRecord(
payload,
@ -56,13 +56,13 @@ describe('searchHomeActivities (B51)', () => {
const hit = result.find((row) => row.id === activity.id)
expect(hit?.title).toBe(title)
expect(hit?.slug).toBe(activity.slug)
expect(hit?.secondary).toContain('Cairu')
expect(hit?.secondary).toContain(municipality.name)
})
it('does not match mid-word without word-start boundary', async () => {
const fixtures = campaignFixtures()
const coordinator = await fixtures.createCampaignUser('coordinator')
const municipality = await fixtures.getMunicipality('cairu')
const municipality = await fixtures.getMunicipality()
const title = fixtures.value('Feira Comunitária')
const activity = await createActivityRecord(
payload,
@ -80,22 +80,22 @@ describe('searchHomeActivities (B51)', () => {
const advisor = await fixtures.createCampaignUser('advisor')
const coordinator = await fixtures.createCampaignUser('coordinator')
const administered = await fixtures.getMunicipality('cairu')
const other = await fixtures.getMunicipality('feira-de-santana')
const administered = await fixtures.getMunicipality()
const other = await fixtures.getMunicipality()
await fixtures.assignMunicipalityAdvisors(administered.id, [advisor.id])
const scopeToken = fixtures.value('scope-atividade')
const inScope = await createActivityRecord(
payload,
coordinator,
validActivityInput(administered.id, `Caminhada ${scopeToken} Cairu`),
validActivityInput(administered.id, `Caminhada ${scopeToken} ${administered.name}`),
)
fixtures.own('activity', inScope.id)
const outOfScope = await createActivityRecord(
payload,
coordinator,
validActivityInput(other.id, `Caminhada ${scopeToken} Feira`),
validActivityInput(other.id, `Caminhada ${scopeToken} ${other.name}`),
)
fixtures.own('activity', outOfScope.id)
@ -111,7 +111,7 @@ describe('searchHomeActivities (B51)', () => {
it('includes drafts without startAt with Data a definir secondary', async () => {
const fixtures = campaignFixtures()
const coordinator = await fixtures.createCampaignUser('coordinator')
const municipality = await fixtures.getMunicipality('cairu')
const municipality = await fixtures.getMunicipality()
const title = fixtures.value('Rascunho sem data')
const activity = await createActivityRecord(payload, coordinator, {
title,
@ -124,7 +124,7 @@ describe('searchHomeActivities (B51)', () => {
const result = await searchHomeActivities(payload, coordinator, 'Rascunho')
const hit = result.find((row) => row.id === activity.id)
expect(hit?.secondary).toContain('Data a definir')
expect(hit?.secondary).toContain('Cairu')
expect(hit?.secondary).toContain(municipality.name)
})
it('rejects leaders from home search', async () => {

View file

@ -52,10 +52,10 @@ describe('searchHomeAdvisors (B50)', () => {
const fixtures = campaignFixtures()
const coordinator = await fixtures.createCampaignUser('coordinator')
const advisor = await fixtures.createCampaignUser('advisor', { name: 'Carteira Zeca' })
const cairu = await fixtures.getMunicipality('cairu')
const feira = await fixtures.getMunicipality('feira-de-santana')
await fixtures.assignMunicipalityAdvisors(cairu.id, [advisor.id])
await fixtures.assignMunicipalityAdvisors(feira.id, [advisor.id])
const first = await fixtures.getMunicipality()
const second = await fixtures.getMunicipality()
await fixtures.assignMunicipalityAdvisors(first.id, [advisor.id])
await fixtures.assignMunicipalityAdvisors(second.id, [advisor.id])
const result = await searchHomeAdvisors(payload, coordinator, 'Carteira')
const hit = result.find((row) => row.id === advisor.id)

View file

@ -33,7 +33,7 @@ describe('searchHomeDemands (B53)', () => {
it('matches demands by word-start on the title for staff', async () => {
const fixtures = campaignFixtures()
const coordinator = await fixtures.createCampaignUser('coordinator')
const municipality = await fixtures.getMunicipality('cairu')
const municipality = await fixtures.getMunicipality()
const title = fixtures.value('Material Zeca Centro')
const demand = await fixtures.createCampaignDemand({
municipality,
@ -45,14 +45,14 @@ describe('searchHomeDemands (B53)', () => {
const hit = result.find((row) => row.id === demand.id)
expect(hit?.title).toBe(title)
expect(hit?.slug).toBe(demand.slug)
expect(hit?.secondary).toContain('Cairu')
expect(hit?.secondary).toContain(municipality.name)
expect(hit?.secondary).toContain('Aberta')
})
it('does not match mid-word without word-start boundary', async () => {
const fixtures = campaignFixtures()
const coordinator = await fixtures.createCampaignUser('coordinator')
const municipality = await fixtures.getMunicipality('cairu')
const municipality = await fixtures.getMunicipality()
const title = fixtures.value('Transporte Comunitário')
const demand = await fixtures.createCampaignDemand({
municipality,
@ -69,19 +69,19 @@ describe('searchHomeDemands (B53)', () => {
const advisor = await fixtures.createCampaignUser('advisor')
const coordinator = await fixtures.createCampaignUser('coordinator')
const administered = await fixtures.getMunicipality('cairu')
const other = await fixtures.getMunicipality('feira-de-santana')
const administered = await fixtures.getMunicipality()
const other = await fixtures.getMunicipality()
await fixtures.assignMunicipalityAdvisors(administered.id, [advisor.id])
const scopeToken = fixtures.value('scope-demanda')
const inScope = await fixtures.createCampaignDemand({
municipality: administered,
title: `Material ${scopeToken} Cairu`,
title: `Material ${scopeToken} ${administered.name}`,
createdBy: coordinator,
})
const outOfScope = await fixtures.createCampaignDemand({
municipality: other,
title: `Material ${scopeToken} Feira`,
title: `Material ${scopeToken} ${other.name}`,
createdBy: coordinator,
})

View file

@ -33,7 +33,7 @@ describe('searchHomeLeaderships (B49)', () => {
it('matches leaderships by word-start on contact name', async () => {
const fixtures = campaignFixtures()
const coordinator = await fixtures.createCampaignUser('coordinator')
const municipality = await fixtures.getMunicipality('cairu')
const municipality = await fixtures.getMunicipality()
const contact = await fixtures.createContact({ name: 'Zeca Pagodinho' })
const leadership = await fixtures.createLeadership({
contact: contact.id,
@ -43,13 +43,13 @@ describe('searchHomeLeaderships (B49)', () => {
const result = await searchHomeLeaderships(payload, coordinator, 'Zeca')
const hit = result.find((row) => row.id === leadership.id)
expect(hit?.name).toBe('Zeca Pagodinho')
expect(hit?.municipalitiesSummary).toContain('Cairu')
expect(hit?.municipalitiesSummary).toContain(municipality.name)
})
it('does not match mid-word without word-start boundary', async () => {
const fixtures = campaignFixtures()
const coordinator = await fixtures.createCampaignUser('coordinator')
const municipality = await fixtures.getMunicipality('cairu')
const municipality = await fixtures.getMunicipality()
const contact = await fixtures.createContact({ name: 'Maria Silva' })
await fixtures.createLeadership({
contact: contact.id,
@ -65,15 +65,15 @@ describe('searchHomeLeaderships (B49)', () => {
const advisor = await fixtures.createCampaignUser('advisor')
const coordinator = await fixtures.createCampaignUser('coordinator')
const administered = await fixtures.getMunicipality('cairu')
const other = await fixtures.getMunicipality('feira-de-santana')
const administered = await fixtures.getMunicipality()
const other = await fixtures.getMunicipality()
await fixtures.assignMunicipalityAdvisors(administered.id, [advisor.id])
// Unique token per run: the minimal seed ships leaderships whose contact
// names collide with fixed queries like 'Lider' (word-start match).
const scopeToken = fixtures.value('scope-lideranca')
const inScope = await fixtures.createContact({ name: `${scopeToken} Cairu` })
const outOfScope = await fixtures.createContact({ name: `${scopeToken} Feira` })
const inScope = await fixtures.createContact({ name: `${scopeToken} ${administered.name}` })
const outOfScope = await fixtures.createContact({ name: `${scopeToken} ${other.name}` })
const scopedLeadership = await fixtures.createLeadership({
contact: inScope.id,
municipalities: [administered.id],

View file

@ -39,11 +39,11 @@ describe('loadHomeSearchSuggestions (B68)', () => {
it('scopes advisor suggestions to administered municipalities', async () => {
const fixtures = campaignFixtures()
const advisor = await fixtures.createCampaignUser('advisor')
const administered = await fixtures.getMunicipality('cairu')
const administered = await fixtures.getMunicipality()
await fixtures.assignMunicipalityAdvisors(administered.id, [advisor.id])
const result = await loadHomeSearchSuggestions(payload, advisor)
expect(result.municipalities.every((hit) => hit.slug === 'cairu')).toBe(true)
expect(result.municipalities.every((hit) => hit.slug === administered.slug)).toBe(true)
})
it('rejects leaders from home search suggestions', async () => {

View file

@ -214,7 +214,11 @@ describe('test database lease', () => {
})
const after = await withInviteConsent(payload, async (consent) => consent)
expect(after).toEqual(before)
expect(after).toMatchObject({
id: before.id,
key: before.key,
text: before.text,
})
})
it('restores the configured consent and releases after a callback assertion failure', async () => {
@ -353,7 +357,11 @@ describe('test database lease', () => {
expect(failure).toBeInstanceOf(AggregateError)
expect((failure as AggregateError).errors).toEqual([releaseFailure, rollbackFailure])
const after = await withInviteConsent(payload, async (consent) => consent)
expect(after).toEqual(before)
expect(after).toMatchObject({
id: before.id,
key: before.key,
text: before.text,
})
const subsequent = await acquireTestDatabaseLease(payload, CAMPAIGN_INVITE_CONSENT_LEASE_KEY)
await subsequent.release()