Files
pikasTech-HWLAB/web/hwlab-cloud-web/src/views/opencode/OpenCodeFrameView.test.ts
T

74 lines
2.8 KiB
TypeScript

// @vitest-environment jsdom
// SPEC: PJ2026-010405 云端控制台.
// Implementation reference: draft-2026-07-13-p0-cloud-console.
// Responsibility: 验证 OpenCode frame URL 换票完成后仍等待 iframe load,并提供失败、超时与重试状态。
import { flushPromises, mount } from "@vue/test-utils";
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
import OpenCodeFrameView from "./OpenCodeFrameView.vue";
vi.mock("@/config/runtime", () => ({
opencodeFrameUrl: () => "https://opencode.example.test"
}));
function successfulFrameUrlResponse(): Response {
return new Response(JSON.stringify({ url: "/opencode/proxy/?ticket=redacted" }), {
status: 200,
headers: { "content-type": "application/json" }
});
}
describe("OpenCodeFrameView", () => {
beforeEach(() => {
vi.stubGlobal("fetch", vi.fn(async () => successfulFrameUrlResponse()));
});
afterEach(() => {
vi.useRealTimers();
vi.unstubAllGlobals();
});
test("waits for iframe load before reporting ready", async () => {
const wrapper = mount(OpenCodeFrameView);
await flushPromises();
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("loading");
expect(wrapper.get("iframe").attributes("src")).toBe("/opencode/proxy/?ticket=redacted");
expect(wrapper.get("[role='status']").text()).toContain("OpenCode 加载中");
await wrapper.get("iframe").trigger("load");
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("ready");
expect(wrapper.find("[role='status']").exists()).toBe(false);
wrapper.unmount();
});
test("shows a retry after iframe error and starts a fresh bounded load", async () => {
const wrapper = mount(OpenCodeFrameView);
await flushPromises();
await wrapper.get("iframe").trigger("error");
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("error");
expect(wrapper.get("[role='status']").text()).toContain("iframe 加载失败");
expect(wrapper.find("iframe").exists()).toBe(false);
await wrapper.get("button").trigger("click");
await flushPromises();
expect(fetch).toHaveBeenCalledTimes(2);
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("loading");
expect(wrapper.find("iframe").exists()).toBe(true);
wrapper.unmount();
});
test("fails a frame that does not load within the bounded timeout", async () => {
vi.useFakeTimers();
const wrapper = mount(OpenCodeFrameView);
await flushPromises();
await vi.advanceTimersByTimeAsync(15_000);
expect(wrapper.get('[data-testid="opencode-load-state"]').text()).toBe("error");
expect(wrapper.get("[role='status']").text()).toContain("iframe 加载超时");
expect(wrapper.find("iframe").exists()).toBe(false);
wrapper.unmount();
});
});