diff --git a/core/api/test/unit/app/wind-down/is-account-in-wind-down-cohort.spec.ts b/core/api/test/unit/app/wind-down/is-account-in-wind-down-cohort.spec.ts index 0246215940..f22076682f 100644 --- a/core/api/test/unit/app/wind-down/is-account-in-wind-down-cohort.spec.ts +++ b/core/api/test/unit/app/wind-down/is-account-in-wind-down-cohort.spec.ts @@ -519,6 +519,23 @@ describe("evaluateWindDownCohortMatch with cohort flags on", () => { ) }) + it("does not skip past an unparsable newest deleted phone to an older affected one", async () => { + withUser(undefined, [MX_PHONE, "not-a-phone"]) + mockFindEarliestByAccountId.mockResolvedValue({ metadata: { isoCode: "GT" } }) + + const result = await evaluateWindDownCohortMatch({ account: makeAccount() }) + + expect(result).toEqual({ matched: false }) + expect(mockPersistAssessment).toHaveBeenCalledWith( + expect.objectContaining({ + matched: false, + assignedCountry: "GT", + rule: "hierarchy", + signals: expect.objectContaining({ creationIpCountry: "GT" }), + }), + ) + }) + it("bounds the lazy assessment's latest-IP evidence to the configured cutoff", async () => { withUser(MX_PHONE) const account = makeAccount() @@ -548,6 +565,23 @@ describe("evaluateWindDownCohortMatch with cohort flags on", () => { expect(mockPersistAssessment).toHaveBeenCalledTimes(1) }) + it("keeps a released account out even when its live signals turn affected", async () => { + mockFindAssessmentByAccountId.mockResolvedValue( + storedAssessment({ + matched: false, + assignedCountry: "GT" as CohortCountry, + rule: "exclusion-override" as WindDownCohortRule, + }), + ) + withUser(MX_PHONE) + + const result = await evaluateWindDownCohortMatch({ account: makeAccount() }) + + expect(result).toEqual({ matched: false }) + expect(mockFindById).not.toHaveBeenCalled() + expect(mockPersistAssessment).not.toHaveBeenCalled() + }) + it("trusts the concurrent winner's persisted verdict over its own computation", async () => { withUser(MX_PHONE) mockPersistAssessment.mockResolvedValue( diff --git a/core/api/test/unit/domain/wind-down/assess-cohort-residency.spec.ts b/core/api/test/unit/domain/wind-down/assess-cohort-residency.spec.ts index f58decca55..c24ecdb2b5 100644 --- a/core/api/test/unit/domain/wind-down/assess-cohort-residency.spec.ts +++ b/core/api/test/unit/domain/wind-down/assess-cohort-residency.spec.ts @@ -40,6 +40,15 @@ describe("assessCohortResidency", () => { ).toEqual({ matched: true, assignedCountry: "FJ", rule: "strict-list" }) }) + it("holds a strict AND affected phone against the same-country release pair", () => { + // the release would fire for this affected primary if the strict scan did not run first + expect( + assessCohortResidency( + args({ phoneCountry: "KE", creationIpCountry: "GT", latestIpCountry: "GT" }), + ), + ).toEqual({ matched: true, assignedCountry: "KE", rule: "strict-list" }) + }) + it("locks on a strict newest deleted phone regardless of IPs", () => { expect( assessCohortResidency(