mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-28 06:17:06 +00:00
160 lines
5.7 KiB
TypeScript
160 lines
5.7 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import type { CompatibilityPause } from "@/common/databaseCompatibility.ts";
|
|
import { REVIEW_HARNESS_STATE_KEY } from "@/features/ReviewHarness/reviewHarnessController.ts";
|
|
import { useReviewHarness } from "./useReviewHarness.ts";
|
|
|
|
const VIEW_TYPE_REVIEW_HARNESS = "self-hosted-livesync-review-harness";
|
|
|
|
vi.mock("@/features/ReviewHarness/ReviewHarnessView", () => ({
|
|
VIEW_TYPE_REVIEW_HARNESS: "self-hosted-livesync-review-harness",
|
|
ReviewHarnessView: class {},
|
|
}));
|
|
|
|
function compatibilityPause(): CompatibilityPause {
|
|
return {
|
|
resumable: true,
|
|
reasons: [
|
|
{
|
|
source: "settings-schema",
|
|
sourceVersion: 9,
|
|
currentVersion: 10,
|
|
isFromFutureSchema: false,
|
|
resumable: true,
|
|
reviewReasons: [],
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
function createFixture(options: { enableDebugTools?: boolean; continuation?: string } = {}) {
|
|
const settingLoadedHandlers: Array<() => Promise<boolean>> = [];
|
|
const layoutReadyHandlers: Array<() => Promise<boolean>> = [];
|
|
const local = new Map<string, string>();
|
|
if (options.continuation) local.set(REVIEW_HARNESS_STATE_KEY, options.continuation);
|
|
const settings = {
|
|
enableDebugTools: options.enableDebugTools ?? true,
|
|
liveSync: false,
|
|
syncOnSave: false,
|
|
syncOnEditorSave: true,
|
|
syncOnStart: false,
|
|
syncOnFileOpen: true,
|
|
syncAfterMerge: false,
|
|
periodicReplication: true,
|
|
};
|
|
const services = {} as Record<string, unknown>;
|
|
const replicator = { env: { services } };
|
|
const api = {
|
|
registerWindow: vi.fn(),
|
|
addCommand: vi.fn(),
|
|
showWindow: vi.fn().mockResolvedValue(undefined),
|
|
addLog: vi.fn(),
|
|
getPluginVersion: () => "1.0.0-rc.0",
|
|
getAppVersion: () => "1.12.7",
|
|
getPlatform: () => "desktop",
|
|
};
|
|
Object.assign(services, {
|
|
setting: {
|
|
currentSettings: () => settings,
|
|
getSettingsMigrationState: () => ({
|
|
sourceVersion: 9,
|
|
targetVersion: 10,
|
|
isNewVault: false,
|
|
isFromFutureSchema: false,
|
|
changed: true,
|
|
requiresSyncReview: true,
|
|
reviewReasons: [],
|
|
}),
|
|
getSmallConfig: (key: string) => local.get(key) ?? "",
|
|
setSmallConfig: (key: string, value: string) => local.set(key, value),
|
|
deleteSmallConfig: (key: string) => local.delete(key),
|
|
},
|
|
appLifecycle: {
|
|
onSettingLoaded: {
|
|
addHandler: vi.fn((handler: () => Promise<boolean>) => settingLoadedHandlers.push(handler)),
|
|
},
|
|
onLayoutReady: {
|
|
addHandler: vi.fn((handler: () => Promise<boolean>) => layoutReadyHandlers.push(handler)),
|
|
},
|
|
performRestart: vi.fn(),
|
|
},
|
|
API: api,
|
|
UI: {
|
|
confirm: { askYesNoDialog: vi.fn().mockResolvedValue("no") },
|
|
},
|
|
});
|
|
let pause: CompatibilityPause | undefined = compatibilityPause();
|
|
const compatibilityReview = {
|
|
initialised: true,
|
|
get pendingPause() {
|
|
return pause;
|
|
},
|
|
openReview: vi.fn(async () => {
|
|
pause = undefined;
|
|
}),
|
|
};
|
|
const core = { services };
|
|
const plugin = {
|
|
core,
|
|
app: {
|
|
vault: {},
|
|
fileManager: {},
|
|
},
|
|
};
|
|
|
|
const controller = useReviewHarness(core as never, plugin as never, { replicator } as never, compatibilityReview as never);
|
|
return {
|
|
controller,
|
|
api,
|
|
settings,
|
|
local,
|
|
settingLoadedHandlers,
|
|
layoutReadyHandlers,
|
|
compatibilityReview,
|
|
};
|
|
}
|
|
|
|
describe("Review Harness composition", () => {
|
|
it("does not register the command or view when developer debug tools are disabled", async () => {
|
|
const fixture = createFixture({ enableDebugTools: false });
|
|
|
|
await fixture.settingLoadedHandlers[0]();
|
|
|
|
expect(fixture.api.registerWindow).not.toHaveBeenCalled();
|
|
expect(fixture.api.addCommand).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("removes a one-shot continuation before reopening the Harness after layout", async () => {
|
|
const requestedAt = "2026-07-18T11:59:00.000Z";
|
|
const continuation = JSON.stringify({
|
|
formatVersion: 1,
|
|
requestId: `compatibility-review-${requestedAt}`,
|
|
scenarioId: "compatibility-review",
|
|
stage: "awaiting-restart",
|
|
requestedAt,
|
|
});
|
|
const fixture = createFixture({ continuation });
|
|
|
|
await fixture.settingLoadedHandlers[0]();
|
|
|
|
expect(fixture.local.has(REVIEW_HARNESS_STATE_KEY)).toBe(false);
|
|
expect(fixture.controller.snapshot().resumedRequestId).toBe(`compatibility-review-${requestedAt}`);
|
|
expect(fixture.api.registerWindow).toHaveBeenCalledWith(VIEW_TYPE_REVIEW_HARNESS, expect.any(Function));
|
|
|
|
await fixture.layoutReadyHandlers[0]();
|
|
|
|
expect(fixture.api.showWindow).toHaveBeenCalledWith(VIEW_TYPE_REVIEW_HARNESS);
|
|
});
|
|
|
|
it("uses the actual compatibility controller as the guided review boundary", async () => {
|
|
const fixture = createFixture();
|
|
|
|
await fixture.controller.runScenario("compatibility-review");
|
|
expect(fixture.controller.snapshot().results["compatibility-review"].status).toBe("waiting-for-user");
|
|
|
|
await fixture.controller.openCompatibilityReview();
|
|
|
|
expect(fixture.compatibilityReview.openReview).toHaveBeenCalledOnce();
|
|
expect(fixture.controller.snapshot().results["compatibility-review"].status).toBe("passed");
|
|
});
|
|
});
|