// The Lucia project.
// Copyright 2026-2026 DSP, inc.  All rights reserved.
// Authors:
//   imacat.yang@dsp.im (imacat), 2026/03/05

import { describe, it, expect, beforeEach, vi } from "vitest";
import {
  getCookie,
  setCookie,
  setCookieWithoutExpiration,
  deleteCookie,
} from "@/utils/cookieUtil.js";

describe("cookieUtil", () => {
  let cookieSetter;

  beforeEach(() => {
    // Clear all cookies before each test
    document.cookie.split(";").forEach((c) => {
      const name = c.split("=")[0].trim();
      if (name) {
        document.cookie = name + "=; Max-Age=-99999999; path=/";
      }
    });
    // Spy on document.cookie setter to capture the raw string
    // (jsdom silently drops Secure cookies on http://)
    cookieSetter = vi.spyOn(document, "cookie", "set");
  });

  describe("getCookie", () => {
    it("returns null when cookie does not exist", () => {
      expect(getCookie("nonexistent")).toBeNull();
    });

    it("returns value of an existing cookie", () => {
      document.cookie = "testKey=testValue";
      expect(getCookie("testKey")).toBe("testValue");
    });

    it("returns correct value when multiple cookies exist", () => {
      document.cookie = "first=aaa";
      document.cookie = "second=bbb";
      document.cookie = "third=ccc";
      expect(getCookie("second")).toBe("bbb");
    });

    it("does not match partial cookie names", () => {
      document.cookie = "testKey=value";
      expect(getCookie("test")).toBeNull();
    });
  });

  describe("setCookie", () => {
    it("sets cookie with Secure and SameSite=Lax flags", () => {
      setCookie("myKey", "myValue");

      const written = cookieSetter.mock.calls.find((c) =>
        c[0].startsWith("myKey="),
      );
      expect(written).toBeDefined();
      const str = written[0];
      expect(str).toContain("myKey=myValue");
      expect(str).toContain("expires=");
      expect(str).toContain("path=/");
      expect(str).toContain("Secure");
      expect(str).toContain("SameSite=Lax");
    });
  });

  describe("setCookieWithoutExpiration", () => {
    it("sets session cookie with Secure and SameSite=Lax flags", () => {
      setCookieWithoutExpiration("sessionKey", "sessionVal");

      const written = cookieSetter.mock.calls.find((c) =>
        c[0].startsWith("sessionKey="),
      );
      expect(written).toBeDefined();
      const str = written[0];
      expect(str).toContain("sessionKey=sessionVal");
      expect(str).toContain("Secure");
      expect(str).toContain("SameSite=Lax");
    });

    it("sets cookie with path=/", () => {
      setCookieWithoutExpiration("pathKey", "pathVal");

      const written = cookieSetter.mock.calls.find((c) =>
        c[0].startsWith("pathKey="),
      );
      expect(written[0]).toContain("path=/");
    });
  });

  describe("deleteCookie", () => {
    it("sets Max-Age=-99999999 with Secure and SameSite=Lax flags", () => {
      deleteCookie("toDelete");

      const written = cookieSetter.mock.calls.find((c) =>
        c[0].startsWith("toDelete="),
      );
      expect(written).toBeDefined();
      const str = written[0];
      expect(str).toContain("Max-Age=-99999999");
      expect(str).toContain("Secure");
      expect(str).toContain("SameSite=Lax");
    });
  });
});
