/**
 * Parity-tests с backend `tests/test_rbac.py::test_is_path_allowed_*`.
 *
 * Если кто-то меняет глоб-семантику backend'а — должен синхронно поменять JS
 * порт здесь, иначе UI начнёт врать про доступы (показывать ссылки, которые
 * backend заблокирует, или наоборот скрывать разрешённые).
 *
 * Pairs мирорят `auth/roles.yaml` (обновлено 2026-05-26 — pilot scope сужен
 * до /trade-in/** only):
 *   admin:  paths=["/**"]                                deny=[]
 *   pilot:  paths=["/trade-in/**", "/trade-in/api/v1/**"]
 *           deny=["/admin/**", "/api/v1/admin/**", "/trade-in/api/v1/admin/**"]
 */
import { isPathAllowed } from "../isPathAllowed";

const ADMIN_PATHS = ["/**"] as const;
const ADMIN_DENY = [] as const;

const PILOT_PATHS = ["/trade-in/**", "/trade-in/api/v1/**"] as const;
const PILOT_DENY = [
  "/admin/**",
  "/api/v1/admin/**",
  "/trade-in/api/v1/admin/**",
] as const;

describe("isPathAllowed — admin everywhere", () => {
  const cases: string[] = [
    "/",
    "/admin",
    "/admin/scrape/runs",
    "/api/v1/admin/scrape/status",
    "/trade-in/api/v1/admin/scrape",
    "/concept/123",
    "/analytics/dashboard",
  ];
  it.each(cases)("allows %s", (path) => {
    expect(isPathAllowed(ADMIN_PATHS, ADMIN_DENY, path)).toBe(true);
  });
});

describe("isPathAllowed — pilot allowed paths (только trade-in)", () => {
  const allowed: string[] = [
    "/trade-in",
    "/trade-in/",
    // canonical prod-маршрут (TopNav nav-item href, обслуживается tradein-frontend)
    "/trade-in/v2",
    "/trade-in/123",
    "/trade-in/api/v1/search",
    "/trade-in/api/v1/me",
  ];
  it.each(allowed)("allows %s", (path) => {
    expect(isPathAllowed(PILOT_PATHS, PILOT_DENY, path)).toBe(true);
  });
});

describe("isPathAllowed — pilot denied paths (landing + admin + остальное)", () => {
  const denied: string[] = [
    // Landing + non-tradein разделы — теперь denied (decision 2026-05-26)
    "/",
    "/analytics/dashboard",
    "/site-finder/123",
    "/concept/abc",
    "/api/v1/parcels/123",
    "/api/v1/analytics/dashboard",
    // Admin paths (explicit deny + not in allowed)
    "/admin",
    "/admin/jobs",
    "/admin/scrape/runs/42",
    "/api/v1/admin/scrape/status",
    "/api/v1/admin/jobs",
    "/trade-in/api/v1/admin/scrape",
  ];
  it.each(denied)("denies %s", (path) => {
    expect(isPathAllowed(PILOT_PATHS, PILOT_DENY, path)).toBe(false);
  });
});

describe("isPathAllowed — edge cases", () => {
  it("denies path not matching any rule", () => {
    expect(isPathAllowed(PILOT_PATHS, PILOT_DENY, "/unknown")).toBe(false);
  });
  it("matches bare /trade-in via /trade-in/** glob (no trailing /)", () => {
    // Backend glob `/foo/**` после подстановки `(?:/.*)?` матчит и bare `/foo`.
    expect(isPathAllowed(PILOT_PATHS, PILOT_DENY, "/trade-in")).toBe(true);
  });
});
