// src/lib/tours/mount-gate.test.ts — la dernière décision métier de la branche
// qui vivait encore dans un composant, et son branchement.
//
// « Aucun tour tant que la fenêtre de nom d'utilisateur est montée » est une
// interdiction de la spec, pas un détail d'affichage : cette popup n'est PAS
// fermable, et l'overlay de driver.js s'ouvrirait par-dessus sans que
// l'utilisateur puisse en sortir. Tant qu'elle vivait dans un ternaire du
// layout, la supprimer ne faisait rougir personne.
import { describe, expect, it } from "bun:test";
import { readFileSync } from "node:fs";
import { shouldMountTourRunner } from "./mount-gate";

describe("shouldMountTourRunner", () => {
  it("interdit tout tour tant que la fenêtre de nom d'utilisateur est montée", () => {
    expect(shouldMountTourRunner({ usernamePromptOpen: true })).toBe(false);
  });

  it("laisse passer les tours dès qu'elle ne l'est plus", () => {
    expect(shouldMountTourRunner({ usernamePromptOpen: false })).toBe(true);
  });
});

describe("branchement dans le layout (app)", () => {
  // Même technique que tour-runner.test.ts : on interroge la SOURCE. Déplacer
  // la décision dans un module pur ne sert à rien si le layout peut la
  // court-circuiter — un `{needsUsername ? null : <TourRunner …>}` réécrit à la
  // main serait de nouveau hors d'atteinte.
  const SOURCE = readFileSync(
    new URL("../../app/(app)/layout.tsx", import.meta.url),
    "utf8",
  );

  it("ne monte le runner qu'à travers la décision", () => {
    // `\s` et non `\b` : le commentaire du layout cite `<TourRunner>`, qui
    // n'est pas un montage.
    const montages = [...SOURCE.matchAll(/<TourRunner\s/g)];
    expect(montages).toHaveLength(1);

    const index = montages[0].index;
    const ligne = SOURCE.slice(SOURCE.lastIndexOf("\n", index) + 1, index);
    expect(ligne).toContain("mountTour ?");
  });

  it("prend la décision UNE fois, et l'interroge aussi pour la progression", () => {
    // Le `{}` passé quand la popup est montée n'est qu'une requête épargnée :
    // il ne protège de rien (une progression vide rend même un tour PLUS
    // probable). Il doit donc suivre la même décision, et non un second test
    // écrit à côté, qui pourrait diverger.
    expect(SOURCE).toContain("const mountTour = shouldMountTourRunner({");
    expect(SOURCE).toMatch(/const tourProgressMap = mountTour\b/);
  });
});
