// src/lib/tours/mark-tour.test.ts — asservit le CORPS de l'écriture publique.
//
// Aucun mock.module ici : `markTour` reçoit ses dépendances en paramètre, donc
// les deux comportements qui comptent s'observent directement, sans lire le
// texte source et sans simulacre de module (qui fuirait sur progress.test.ts,
// dans le même process).
import { describe, expect, it } from "bun:test";
import { type MarkTourDeps, markTour } from "./mark-tour";

type Write = { userId: string; tourId: string; status: string };

function harness(overrides: Partial<MarkTourDeps> = {}) {
  const writes: Write[] = [];
  const deps: MarkTourDeps = {
    isImpersonating: async () => false,
    getUserId: async () => "user-de-session",
    setProgress: async (userId, tourId, status) => {
      writes.push({ userId, tourId, status });
    },
    ...overrides,
  };
  return { deps, writes };
}

describe("markTour", () => {
  it("écrit avec l'identité de la session, jamais une identité fournie", async () => {
    const { deps, writes } = harness();
    await markTour(deps, "reservoir", "completed");
    expect(writes).toEqual([
      { userId: "user-de-session", tourId: "reservoir", status: "completed" },
    ]);
  });

  // LE test de la garde d'usurpation : supprimer `isImpersonating` de
  // `markTour` doit rendre ce cas rouge. Un opérateur du support qui parcourt
  // le compte d'un client ne doit pas lui brûler ses tours.
  it("n'écrit RIEN quand la session est une usurpation", async () => {
    const { deps, writes } = harness({ isImpersonating: async () => true });
    await markTour(deps, "reservoir", "completed");
    expect(writes).toEqual([]);
  });

  it("ignore un tourId absent du catalogue", async () => {
    const { deps, writes } = harness();
    await markTour(deps, "tour-inexistant", "completed");
    expect(writes).toEqual([]);
  });

  it("ignore un statut hors des deux valeurs admises", async () => {
    const { deps, writes } = harness();
    // Le paramètre vient d'un endpoint POST : son typage ne le contraint pas.
    await markTour(deps, "reservoir", "pouet" as "completed");
    expect(writes).toEqual([]);
  });

  it("accepte chaque tour du catalogue et les deux statuts", async () => {
    const { deps, writes } = harness();
    await markTour(deps, "recherche", "dismissed");
    await markTour(deps, "planning", "completed");
    expect(writes.map((w) => w.tourId)).toEqual(["recherche", "planning"]);
  });
});
