// src/lib/onboarding/activation/actions.test.ts — dismissal persistence
// against REAL data in Postgres (gated on DB_TESTS=1, test DB only) + garde
// de surface d'endpoint sur actions.ts ("use server").
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";

mock.module("server-only", () => ({}));

const RUN_DB = process.env.DB_TESTS === "1";
const NOW = new Date();
const ORG = "act-dismiss-org";
const USER = "act-dismiss-user";

describe.skipIf(!RUN_DB)("activation dismissal (postgres)", () => {
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let db: any;
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let authSchema: any;
  // biome-ignore lint/suspicious/noExplicitAny: imports dynamiques de test
  let dismiss: any;

  async function cleanup() {
    const { inArray } = await import("drizzle-orm");
    await db
      .delete(authSchema.organization)
      .where(inArray(authSchema.organization.id, [ORG]));
    await db.delete(authSchema.user).where(inArray(authSchema.user.id, [USER]));
  }

  beforeEach(async () => {
    ({ db } = await import("@/lib/db/client"));
    authSchema = await import("@/lib/db/auth-schema");
    dismiss = await import("./dismiss");
    const { assertTestDb } = await import("@/lib/db/assert-test-db");
    await assertTestDb();
    await cleanup();
    await db.insert(authSchema.user).values({
      id: USER,
      name: USER,
      email: `${USER}@test.dev`,
      emailVerified: true,
      createdAt: NOW,
      updatedAt: NOW,
    });
    await db.insert(authSchema.organization).values({
      id: ORG,
      name: ORG,
      slug: ORG,
      createdAt: NOW,
    });
  });

  afterAll(async () => {
    if (!RUN_DB) return;
    await cleanup();
  });

  test("dismiss → isDismissed true ; idempotent ; restore → false", async () => {
    expect(await dismiss.isActivationDismissed(USER, ORG)).toBe(false);
    await dismiss.dismissActivation(USER, ORG);
    expect(await dismiss.isActivationDismissed(USER, ORG)).toBe(true);
    await dismiss.dismissActivation(USER, ORG); // pas d'erreur de PK
    await dismiss.restoreActivation(USER, ORG);
    expect(await dismiss.isActivationDismissed(USER, ORG)).toBe(false);
  });

  test("scoping : dismiss (user, orgA) ne masque pas (user, orgB)", async () => {
    await dismiss.dismissActivation(USER, ORG);
    expect(await dismiss.isActivationDismissed(USER, "act-dismiss-other")).toBe(
      false,
    );
  });
});

// Garde de surface d'endpoint : tout export d'un module "use server" est un
// endpoint POST atteignable, donc la liste des exports EST la surface d'attaque.
// actions.ts ne doit exposer QUE les 2 écritures auth-guardées — la lecture est
// passée dans ./snapshot.ts, appelée par les RSC.
test("actions.ts n'exporte que les 2 actions publiques", async () => {
  const mod = await import("./actions");
  expect(Object.keys(mod).sort()).toEqual([
    "dismissActivationAction",
    "restoreActivationAction",
  ]);
});
