Newer
Older
smart-home-server / webclient / src / components / script / __tests__ / ScriptRunModal.spec.js
import { describe, it, expect, beforeEach, vi } from "vitest";
import { mount } from "@vue/test-utils";
import ScriptRunModal from "../ScriptRunModal.vue";

vi.mock("gnexus-ui-kit/vue", async () => {
  const actual = await vi.importActual("gnexus-ui-kit/vue");
  return {
    ...actual,
    useToast: () => ({ success: vi.fn(), error: vi.fn() }),
  };
});

describe("ScriptRunModal", () => {
  const script = {
    alias: "dim_lights",
    name: "Диммер",
    params_schema: {
      level: { type: "range", label: "Яркость", min: 0, max: 100, step: 5, default: 50 },
      room: { type: "select", label: "Комната", options: { kitchen: "Кухня", hall: "Зал" }, default: "hall" },
      instant: { type: "toggle", label: "Мгновенно", default: false },
      note: { type: "textarea", label: "Примечание" },
    },
  };

  function createWrapper(props = {}) {
    return mount(ScriptRunModal, {
      props: {
        open: true,
        script,
        ...props,
      },
    });
  }

  it("renders modal when open", () => {
    const wrapper = createWrapper();
    expect(wrapper.findComponent({ name: "GnModal" }).exists()).toBe(true);
  });

  it("initializes form values with defaults", () => {
    const wrapper = createWrapper();
    expect(wrapper.vm.formValues).toEqual({
      level: 50,
      room: "hall",
      instant: false,
      note: "",
    });
  });

  it("emits run event with params on submit", async () => {
    const wrapper = createWrapper();
    wrapper.vm.formValues = {
      level: 80,
      room: "kitchen",
      instant: true,
      note: "test",
    };

    wrapper.vm.submit();

    expect(wrapper.emitted("run")).toBeTruthy();
    expect(wrapper.emitted("run")[0]).toEqual([
      { alias: "dim_lights", params: { level: 80, room: "kitchen", instant: true, note: "test" } },
    ]);
  });

  it("closes modal on run", async () => {
    const wrapper = createWrapper();
    wrapper.vm.formValues = { level: 80, room: "kitchen", instant: false, note: "" };
    wrapper.vm.submit();
    expect(wrapper.emitted("update:open")?.[0]).toEqual([false]);
  });

  it("disables submit when required field is empty", async () => {
    const requiredScript = {
      alias: "test",
      name: "Test",
      params_schema: {
        name: { type: "text", label: "Name", required: true },
      },
    };
    const wrapper = mount(ScriptRunModal, {
      props: { open: true, script: requiredScript },
    });

    wrapper.vm.formValues.name = "";
    await wrapper.vm.$nextTick();
    expect(wrapper.vm.canSubmit).toBe(false);
  });
});