Ask before applying maintenance prerequisite settings

Local database maintenance actions require local chunk revisions and fully replicated chunks, but previously failed with a notice when those settings were not already configured.

This adds a small prerequisite confirmation helper for the maintenance commands. When required settings are missing, the user can apply them and continue from the action they already started, or cancel without changing settings.

Covers both required maintenance settings:
- Compute revisions for chunks enabled
- Fetch chunks on demand disabled

Fixes #980
This commit is contained in:
Ouyang Xingyuan
2026-06-25 14:41:14 +08:00
parent 2d5b5da904
commit 7e59010824
3 changed files with 163 additions and 18 deletions
@@ -0,0 +1,89 @@
import { describe, expect, it, vi } from "vitest";
import { DEFAULT_SETTINGS } from "@lib/common/types";
import { ensureLocalDatabaseMaintenancePrerequisites } from "./maintenancePrerequisites";
function createPrerequisites(settingsOverride: Partial<typeof DEFAULT_SETTINGS> = {}) {
const askSelectStringDialogue = vi.fn<() => Promise<"Apply and continue" | "Cancel" | false | undefined>>(
async () => "Apply and continue"
);
const applyPartial = vi.fn(async () => undefined);
const settings = {
...DEFAULT_SETTINGS,
doNotUseFixedRevisionForChunks: false,
readChunksOnline: true,
...settingsOverride,
};
return { settings, askSelectStringDialogue, applyPartial };
}
describe("LocalDatabaseMaintenance prerequisites", () => {
it("asks to apply missing prerequisite settings before maintenance actions", async () => {
const { settings, askSelectStringDialogue, applyPartial } = createPrerequisites();
const result = await ensureLocalDatabaseMaintenancePrerequisites({
operationName: "Garbage Collection",
settings: {
doNotUseFixedRevisionForChunks: settings.doNotUseFixedRevisionForChunks,
readChunksOnline: settings.readChunksOnline,
},
askSelectStringDialogue,
applyPartial,
});
expect(result).toBe(true);
expect(askSelectStringDialogue).toHaveBeenCalledWith(
expect.stringContaining("Garbage Collection requires the following settings"),
["Apply and continue", "Cancel"],
{
title: "Garbage Collection prerequisites",
defaultAction: "Cancel",
}
);
expect(applyPartial).toHaveBeenCalledWith(
{
doNotUseFixedRevisionForChunks: true,
readChunksOnline: false,
},
true
);
});
it("cancels maintenance actions when prerequisite changes are rejected", async () => {
const { settings, askSelectStringDialogue, applyPartial } = createPrerequisites();
askSelectStringDialogue.mockResolvedValueOnce("Cancel");
const result = await ensureLocalDatabaseMaintenancePrerequisites({
operationName: "Garbage Collection",
settings: {
doNotUseFixedRevisionForChunks: settings.doNotUseFixedRevisionForChunks,
readChunksOnline: settings.readChunksOnline,
},
askSelectStringDialogue,
applyPartial,
});
expect(result).toBe(false);
expect(applyPartial).not.toHaveBeenCalled();
});
it("continues without asking when prerequisite settings already match", async () => {
const { settings, askSelectStringDialogue, applyPartial } = createPrerequisites({
doNotUseFixedRevisionForChunks: true,
readChunksOnline: false,
});
const result = await ensureLocalDatabaseMaintenancePrerequisites({
operationName: "Garbage Collection",
settings: {
doNotUseFixedRevisionForChunks: settings.doNotUseFixedRevisionForChunks,
readChunksOnline: settings.readChunksOnline,
},
askSelectStringDialogue,
applyPartial,
});
expect(askSelectStringDialogue).not.toHaveBeenCalled();
expect(applyPartial).not.toHaveBeenCalled();
});
});