fix(web): 注入面板保存失败不再清空已加载实体并支持重试

This commit is contained in:
Yaojia Wang
2026-06-29 16:52:43 +02:00
parent ab3f9e17b1
commit 4afbbe0fe7
3 changed files with 166 additions and 40 deletions

View File

@@ -43,7 +43,8 @@ describe("useInjection", () => {
await waitFor(() => expect(result.current.loading).toBe(false));
expect(result.current.data).toEqual(body);
expect(result.current.error).toBeNull();
expect(result.current.loadError).toBeNull();
expect(result.current.saveError).toBeNull();
});
it("挂载后端返回 error给可读文案、data 置空", async () => {
@@ -52,7 +53,7 @@ describe("useInjection", () => {
const { result } = renderHook(() => useInjection("p1", 3));
await waitFor(() => expect(result.current.loading).toBe(false));
expect(result.current.error).toBe("注入信息暂不可用");
expect(result.current.loadError).toBe("注入信息暂不可用");
expect(result.current.data).toBeNull();
});
@@ -62,7 +63,7 @@ describe("useInjection", () => {
const { result } = renderHook(() => useInjection("p1", 3));
await waitFor(() => expect(result.current.loading).toBe(false));
expect(result.current.error).toBe("注入信息暂不可用");
expect(result.current.loadError).toBe("注入信息暂不可用");
expect(result.current.data).toBeNull();
});
@@ -81,7 +82,7 @@ describe("useInjection", () => {
expect(put).toHaveBeenCalledTimes(1);
expect(result.current.data).toEqual(updated);
expect(result.current.saving).toBe(false);
expect(result.current.error).toBeNull();
expect(result.current.saveError).toBeNull();
});
it("exclude / restore / setRecentN 各自经 PUT 提交覆盖", async () => {
@@ -121,7 +122,7 @@ describe("useInjection", () => {
await result.current.togglePin(CHAR);
});
expect(result.current.error).toBe("保存注入设置失败,请重试");
expect(result.current.saveError).toBe("保存注入设置失败,请重试");
expect(result.current.data).toEqual(loaded);
});
@@ -137,10 +138,60 @@ describe("useInjection", () => {
await result.current.togglePin(CHAR);
});
expect(result.current.error).toBe("保存注入设置失败,请重试");
expect(result.current.saveError).toBe("保存注入设置失败,请重试");
expect(result.current.data).toEqual(loaded);
});
it("保存失败不清空 data且 loadError 与 saveError 互不影响", async () => {
const loaded = makeResponse({ recent_n: 4 });
get.mockResolvedValue({ data: loaded, error: null });
put.mockResolvedValue({ data: null, error: { detail: "422" } });
const { result } = renderHook(() => useInjection("p1", 3));
await waitFor(() => expect(result.current.loading).toBe(false));
// 加载成功 → loadError 为空。
expect(result.current.loadError).toBeNull();
await act(async () => {
await result.current.togglePin(CHAR);
});
// 保存失败只设 saveErrordata 与 loadError 不受影响。
expect(result.current.saveError).toBe("保存注入设置失败,请重试");
expect(result.current.loadError).toBeNull();
expect(result.current.data).toEqual(loaded);
// clearSaveError 关闭悬浮提示data 仍在。
act(() => result.current.clearSaveError());
expect(result.current.saveError).toBeNull();
expect(result.current.data).toEqual(loaded);
});
it("retrySave 重放上一次失败的覆盖,成功后回放 data、清空 saveError", async () => {
const loaded = makeResponse({ recent_n: 4 });
get.mockResolvedValue({ data: loaded, error: null });
put.mockResolvedValueOnce({ data: null, error: { detail: "422" } });
const updated = makeResponse({ recent_n: 4, pinned: [{ ...CHAR }] });
put.mockResolvedValueOnce({ data: updated, error: null });
const { result } = renderHook(() => useInjection("p1", 3));
await waitFor(() => expect(result.current.loading).toBe(false));
await act(async () => {
await result.current.togglePin(CHAR);
});
expect(result.current.saveError).toBe("保存注入设置失败,请重试");
await act(async () => {
await result.current.retrySave();
});
expect(put).toHaveBeenCalledTimes(2);
expect(result.current.saveError).toBeNull();
expect(result.current.data).toEqual(updated);
});
it("data 未就绪时 mutate 早返回、不发 PUT", async () => {
get.mockResolvedValue({ data: null, error: { detail: "fail" } });