Stop configuration snapshot request loop
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
/** @vitest-environment jsdom */
|
||||
|
||||
import { act, useState } from "react";
|
||||
import { createRoot, type Root } from "react-dom/client";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { ServerFileWorkspaceResponse, ServerInstanceResponse } from "../api/types";
|
||||
import type { OperationTracker } from "../stores/operations";
|
||||
import { ServerConfigEditor } from "./ServerConfigEditor";
|
||||
|
||||
const apiMocks = vi.hoisted(() => ({
|
||||
getServerFileReadSnapshot: vi.fn(),
|
||||
getServerFileWorkspace: vi.fn(),
|
||||
readServerFile: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock("../api/client", () => ({ platformApiClient: apiMocks }));
|
||||
|
||||
const instance = { id: "server-1", name: "SCUM Alpha" } as ServerInstanceResponse;
|
||||
const workspace = {
|
||||
serverInstanceId: "server-1",
|
||||
pluginId: "game.scum",
|
||||
defaultDirectoryKey: "scum-config",
|
||||
directories: [{ key: "scum-config", label: "服务器配置", scope: "config" }],
|
||||
files: [{ key: "scum-server-settings", directoryKey: "scum-config", label: "ServerSettings.ini", kind: "config", editable: true }],
|
||||
configFields: [],
|
||||
transfer: { channel: "run-file-transfer", uploadChunkSizeBytes: 1, downloadChunkSizeBytes: 1, maxInlineEditBytes: 64, maxBrowserUploadBytes: 64, notes: [] },
|
||||
declaredOnly: true
|
||||
} as ServerFileWorkspaceResponse;
|
||||
|
||||
let root: Root | null = null;
|
||||
let container: HTMLDivElement | null = null;
|
||||
|
||||
(globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
apiMocks.getServerFileWorkspace.mockResolvedValue(workspace);
|
||||
let snapshotCalls = 0;
|
||||
apiMocks.getServerFileReadSnapshot.mockImplementation(async () => {
|
||||
snapshotCalls += 1;
|
||||
return snapshotCalls === 1 ? { serverInstanceId: "server-1", pluginId: "game.scum", key: "scum-server-settings", state: "not-read" } : { serverInstanceId: "server-1", pluginId: "game.scum", key: "scum-server-settings", state: "ready", content: "[General]\nscum.MaxPlayers=63\n", version: 1, checksum: "sha256:test" };
|
||||
});
|
||||
apiMocks.readServerFile.mockResolvedValue({ status: "queued", serverInstanceId: "server-1", pluginId: "game.scum", operation: "read", key: "scum-server-settings", job: { id: "job-read", state: "queued" } });
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
if (root) await act(async () => root?.unmount());
|
||||
container?.remove();
|
||||
root = null;
|
||||
container = null;
|
||||
vi.clearAllMocks();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
describe("ServerConfigEditor", () => {
|
||||
it("does not restart the same snapshot request when operation state rerenders the parent", async () => {
|
||||
container = document.createElement("div");
|
||||
document.body.append(container);
|
||||
root = createRoot(container);
|
||||
|
||||
function Wrapper() {
|
||||
const [, rerender] = useState(0);
|
||||
const operations: OperationTracker = {
|
||||
operations: [],
|
||||
begin: () => { rerender((value) => value + 1); return "operation-read"; },
|
||||
update: () => undefined,
|
||||
succeed: () => undefined,
|
||||
fail: () => undefined,
|
||||
isPending: () => false
|
||||
};
|
||||
return <ServerConfigEditor instance={instance} operations={operations} requester="Operator" onClose={() => undefined} />;
|
||||
}
|
||||
|
||||
await act(async () => root?.render(<Wrapper />));
|
||||
await act(async () => { await Promise.resolve(); });
|
||||
await act(async () => { await vi.advanceTimersByTimeAsync(500); });
|
||||
await act(async () => { await Promise.resolve(); });
|
||||
|
||||
expect(apiMocks.readServerFile).toHaveBeenCalledTimes(1);
|
||||
expect(apiMocks.getServerFileReadSnapshot).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user