import { describe, expect, it } from "vitest";
import {
  assertLocalDwatchDatabaseUrl,
  isLocalDwatchDatabaseUrl,
} from "@/lib/db/local-guard";

describe("isLocalDwatchDatabaseUrl", () => {
  it("localhost の dwatch_local は true", () => {
    expect(isLocalDwatchDatabaseUrl("mysql://root@localhost:3306/dwatch_local")).toBe(
      true
    );
  });

  it("127.0.0.1 の dwatch_local も true", () => {
    expect(
      isLocalDwatchDatabaseUrl("mysql://root@127.0.0.1:3306/dwatch_local")
    ).toBe(true);
  });

  it("ホストが違えば false（TeamWorks側への誤接続を防ぐ。URL・認証情報はすべて架空 CLAUDE.md §9.3）", () => {
    expect(
      isLocalDwatchDatabaseUrl(
        "mysql://testuser:pw@example.com:3306/dwatch_local"
      )
    ).toBe(false);
  });

  it("DB名が違えば false（dwatch_ddl は参照専用）", () => {
    expect(
      isLocalDwatchDatabaseUrl("mysql://root@localhost:3306/dwatch_ddl")
    ).toBe(false);
  });

  it("DB名が違えば false（TeamWorks側の clean_watch）", () => {
    expect(
      isLocalDwatchDatabaseUrl("mysql://root@localhost:3306/clean_watch")
    ).toBe(false);
  });

  it("不正なURL文字列は例外を投げず false", () => {
    expect(isLocalDwatchDatabaseUrl("not a url")).toBe(false);
  });
});

describe("assertLocalDwatchDatabaseUrl", () => {
  it("ローカルなら例外を投げない", () => {
    expect(() =>
      assertLocalDwatchDatabaseUrl("mysql://root@localhost:3306/dwatch_local")
    ).not.toThrow();
  });

  it("ローカルでなければ例外を投げる（メッセージにURLを含めない）", () => {
    const url = "mysql://testuser:s3cret@example.com:3306/clean_watch";
    try {
      assertLocalDwatchDatabaseUrl(url);
      throw new Error("例外が投げられるべき");
    } catch (e) {
      expect(e).toBeInstanceOf(Error);
      expect((e as Error).message).not.toContain("s3cret");
      expect((e as Error).message).not.toContain(url);
    }
  });
});
