修复证书操作失败后状态刷新及失败审计显示

This commit is contained in:
xuans 2026-09-25 02:33:06 +08:00
parent ddd1165125
commit feda065b45
2 changed files with 56 additions and 2 deletions

View File

@ -125,6 +125,7 @@ export function useDashboard() {
failed: "失败",
cancelled: "已取消",
};
taskStatusLabels.error = taskStatusLabels.failed;
const taskTypeLabels = {
management_renewal: "管理证书续期",
certificate_issue: "申请证书",
@ -687,9 +688,12 @@ export function useDashboard() {
const result = await response.json().catch(() => ({}));
if (!response.ok) throw new Error(result.error || "域名操作失败");
notice.value = successMessage;
await loadData();
} catch (err) {
error.value = err.message || "域名操作失败";
} finally {
const actionError = error.value;
await loadData();
if (actionError) error.value = actionError;
}
}
function issueDomain(item) {

View File

@ -515,4 +515,54 @@ test("sshKeyModal.compilesAndPreservesCredentialFields", async () => {
}
const css = await readFile(new URL("./SSHKeyModal.css", import.meta.url), "utf8");
assert.match(css, /\.ssh-key-modal\s*\{[^}]*overflow:\s*auto;/);
});
});test("domainAction.refreshesPersistedFailureWithoutLosingError", async (t) => {
let issued = false;
const { state } = await mountComposable(t, useDashboard, async (path) => {
if (path.endsWith("/issue")) {
issued = true;
return Response.json({ error: "test-issue-failure" }, { status: 502 });
}
if (path.startsWith("/api/v1/tasks?")) {
return Response.json({ items: issued ? [{ id: "task-1", status: "failed" }] : [] });
}
return Response.json({ items: [] });
});
await state.issueDomain({ id: "domain-1", name: "example.test" });
assert.equal(state.error.value, "test-issue-failure");
assert.equal(state.notice.value, "");
assert.deepEqual(state.tasks.value, [{ id: "task-1", status: "failed" }]);
assert.equal(state.displayLabel(state.taskStatusLabels, "error"), state.taskStatusLabels.failed);
});
test("domainAction.preservesOriginalErrorWhenRefreshAlsoFails", async (t) => {
let issued = false;
const { state } = await mountComposable(t, useDashboard, async (path) => {
if (path.endsWith("/issue")) {
issued = true;
return Response.json({ error: "test-original-failure" }, { status: 502 });
}
if (issued) return Response.json({ error: "test-refresh-failure" }, { status: 503 });
return Response.json({ items: [] });
});
await state.issueDomain({ id: "domain-1", name: "example.test" });
assert.equal(state.error.value, "test-original-failure");
assert.equal(state.loading.value, false);
});
test("domainAction.refreshesSuccessfulResultAndRetainsNotice", async (t) => {
let completed = false;
const { state } = await mountComposable(t, useDashboard, async (path) => {
if (path.endsWith("/certificate/validate")) {
completed = true;
return Response.json({ valid: true });
}
if (path.startsWith("/api/v1/tasks?")) {
return Response.json({ items: completed ? [{ id: "task-2", status: "success" }] : [] });
}
return Response.json({ items: [] });
});
await state.validateDomain({ id: "domain-1", name: "example.test" });
assert.equal(state.error.value, "");
assert.match(state.notice.value, /example\.test/);
assert.deepEqual(state.tasks.value, [{ id: "task-2", status: "success" }]);
});