import { describe, expect, it } from "vitest";
import { RpaError } from "@/modules/rpa/errors";
import { RPAContext, resolveRPAContext } from "@/workers/rpa/kernel/context";
import {
  assertRPAContext,
  ensureArray,
  isRPAContext,
  snapshotContextContract,
} from "@/workers/rpa/kernel/context-validator";

function mockPage(): object {
  return {
    locator: () => ({
      filter: () => ({ nth: () => ({}) }),
      first: () => ({}),
    }),
    waitForTimeout: async () => undefined,
    url: () => "https://example.com",
  };
}

describe("context-validator", () => {
  it("ensureArray：undefined → []", () => {
    expect(ensureArray(undefined)).toEqual([]);
    expect(ensureArray(null)).toEqual([]);
    expect(ensureArray([1])).toEqual([1]);
  });

  it("resolveRPAContext：已是 context 时不再包一层", () => {
    const page = mockPage();
    const ctx = new RPAContext(page as never);
    const resolved = resolveRPAContext(ctx);
    expect(resolved).toBe(ctx);
    expect(isRPAContext(resolved)).toBe(true);
  });

  it("fromSession 误传 context 不再导致 page.locator 断裂", () => {
    const page = mockPage();
    const ctx = new RPAContext(page as never);
    const wrapped = RPAContext.fromSession(ctx);
    expect(wrapped).toBe(ctx);
    expect(snapshotContextContract(wrapped).hasPage).toBe(true);
  });

  it("assertRPAContext：缺 state 时 fail-fast", () => {
    const page = mockPage();
    const broken = {
      page,
      selectors: {},
      exec: {},
      runtime: {},
      getWidgetScrollAt: () => 0,
      setWidgetScrollAt: () => undefined,
    };
    expect(() => assertRPAContext(broken)).toThrow(RpaError);
  });
});
