/**
 * 文件路径安全单测(Metis 安全红线:穿越/.git/分隔符/深度)。
 */
import { describe, expect, it } from "vitest";
import { validateFilePath, FILE_PATH_MAX_DEPTH, FILE_PATH_MAX_LENGTH } from "../../src/database/filelib/fileService.js";
import { FileLibError } from "../../src/database/filelib/model.js";

describe("validateFilePath · 路径安全", () => {
  it("正常相对路径通过(含 CJK 与多级)", () => {
    expect(validateFilePath("a.md")).toBe("a.md");
    expect(validateFilePath("docs/讲义/第一课.md")).toBe("docs/讲义/第一课.md");
    expect(validateFilePath("a/b/c/d.txt")).toBe("a/b/c/d.txt");
  });

  it("拒绝穿越:.. 段、绝对路径", () => {
    expect(() => validateFilePath("../x")).toThrowError(FileLibError);
    expect(() => validateFilePath("a/../../x")).toThrowError(FileLibError);
    expect(() => validateFilePath("/etc/passwd")).toThrowError(FileLibError);
  });

  it("拒绝 .git 段与点段", () => {
    expect(() => validateFilePath(".git")).toThrowError(FileLibError);
    expect(() => validateFilePath("a/.git/config")).toThrowError(FileLibError);
    expect(() => validateFilePath("./a.md")).toThrowError(FileLibError);
  });

  it("拒绝反斜杠、控制字符、空段(双斜杠/尾斜杠)", () => {
    expect(() => validateFilePath("a\\b.md")).toThrowError(FileLibError);
    expect(() => validateFilePath("a\nb.md")).toThrowError(FileLibError);
    expect(() => validateFilePath("a//b.md")).toThrowError(FileLibError);
    expect(() => validateFilePath("a/b/")).toThrowError(FileLibError);
  });

  it("拒绝空路径、超长、超深", () => {
    expect(() => validateFilePath("")).toThrowError(FileLibError);
    expect(() => validateFilePath("a".repeat(FILE_PATH_MAX_LENGTH + 1))).toThrowError(FileLibError);
    expect(() => validateFilePath(Array(FILE_PATH_MAX_DEPTH + 1).fill("d").join("/"))).toThrowError(FileLibError);
    expect(validateFilePath(Array(FILE_PATH_MAX_DEPTH).fill("d").join("/"))).toContain("d/");
  });
});
