Files
agentic-dev/packages/core-consent/src/migration.test.ts
Danijel Martinek b24f0666eb feat(core-consent): add extractAnonymousConsent and migrateAnonymousConsent helpers
Migration helpers let the auth signUp flow transfer anonymous cookie consent
to an authenticated user's record. extractAnonymousConsent parses the raw
Cookie header; migrateAnonymousConsent calls IConsent.grant with
method: "signup-migration" for each granted category, making the migration
traceable in the audit log. No-op when the consent cookie is absent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 12:59:53 +00:00

108 lines
3.5 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { RecordingConsent } from "@repo/core-testing/instrumentation";
import {
extractAnonymousConsent,
migrateAnonymousConsent,
CONSENT_COOKIE_NAME,
} from "@/migration";
describe("extractAnonymousConsent", () => {
it("returns null when no consent cookie is present", () => {
expect(extractAnonymousConsent("session=abc; other=xyz")).toBeNull();
});
it("returns null for an empty header", () => {
expect(extractAnonymousConsent("")).toBeNull();
});
it("extracts granted categories from the consent cookie", () => {
const result = extractAnonymousConsent(
`${CONSENT_COOKIE_NAME}=necessary,analytics; session=abc`,
);
expect(result).toEqual(["necessary", "analytics"]);
});
it("returns null when the consent cookie value is empty", () => {
expect(extractAnonymousConsent(`${CONSENT_COOKIE_NAME}=`)).toBeNull();
});
it("trims whitespace around category names", () => {
const result = extractAnonymousConsent(
`${CONSENT_COOKIE_NAME}= necessary , analytics `,
);
expect(result).toEqual(["necessary", "analytics"]);
});
it("returns a single category when only one is present", () => {
const result = extractAnonymousConsent(`${CONSENT_COOKIE_NAME}=marketing`);
expect(result).toEqual(["marketing"]);
});
it("returns null when cookie value contains only commas/whitespace", () => {
expect(extractAnonymousConsent(`${CONSENT_COOKIE_NAME}=,, ,`)).toBeNull();
});
});
describe("migrateAnonymousConsent", () => {
it("calls IConsent.grant with method signup-migration for each category", async () => {
const consent = new RecordingConsent();
await migrateAnonymousConsent({
consent,
cookieState: ["necessary", "analytics"],
bannerVersion: "v2",
policyVersion: "2026-01",
});
expect(consent.grants).toHaveLength(2);
expect(consent.grants[0]).toEqual({
category: "necessary",
meta: {
method: "signup-migration",
bannerVersion: "v2",
policyVersion: "2026-01",
},
});
expect(consent.grants[1]).toEqual({
category: "analytics",
meta: {
method: "signup-migration",
bannerVersion: "v2",
policyVersion: "2026-01",
},
});
});
it("is a no-op when cookieState is null (absent cookie)", async () => {
const consent = new RecordingConsent();
await migrateAnonymousConsent({ consent, cookieState: null });
expect(consent.grants).toHaveLength(0);
});
it("omits bannerVersion and policyVersion from meta when not provided", async () => {
const consent = new RecordingConsent();
await migrateAnonymousConsent({
consent,
cookieState: ["marketing"],
});
expect(consent.grants).toHaveLength(1);
expect(consent.grants[0]!.meta).toEqual({ method: "signup-migration" });
});
it("happy path: cookie header present → grant called with signup-migration on all categories", async () => {
const consent = new RecordingConsent();
const cookieState = extractAnonymousConsent(
`${CONSENT_COOKIE_NAME}=necessary,marketing`,
);
await migrateAnonymousConsent({
consent,
cookieState,
bannerVersion: "v1",
policyVersion: "2025-12",
});
expect(consent.grants).toHaveLength(2);
expect(consent.grants[0]!.meta?.method).toBe("signup-migration");
expect(consent.grants[1]!.meta?.method).toBe("signup-migration");
expect(consent.isGranted("necessary")).toBe(true);
expect(consent.isGranted("marketing")).toBe(true);
});
});