mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-16 22:32:40 +00:00
Route interactive P2P UI through focused views
This commit is contained in:
@@ -6,20 +6,20 @@ import type { P2PServiceViews } from "@vrtmrz/livesync-commonlib/p2p";
|
|||||||
import { P2POpenReplicationModal } from "./P2POpenReplicationModal";
|
import { P2POpenReplicationModal } from "./P2POpenReplicationModal";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an openReplicationUI factory for Obsidian environments.
|
* Create the Obsidian-owned interactive P2P entry for stable service views.
|
||||||
* Returns a per-replicator closure that opens the P2P Replication modal
|
*
|
||||||
* and performs bidirectional sync (pull then push on success) through the
|
* Peer selection belongs to the host UI rather than the concrete compatibility
|
||||||
* stable targeted-transfer view. The compatibility Replicator argument is
|
* Replicator. The returned operation opens the modal and performs bidirectional
|
||||||
* intentionally unused here and remains available only to the rebuild factory.
|
* synchronisation, pulling before pushing, through the targeted-transfer view.
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
* const factory = createOpenReplicationUI(app);
|
* const createInteractiveReplication = createOpenReplicationUI(app);
|
||||||
* useP2PReplicatorFeature(core, factory);
|
* const openInteractiveReplication = createInteractiveReplication(p2p);
|
||||||
*/
|
*/
|
||||||
export function createOpenReplicationUI(
|
export function createOpenReplicationUI(
|
||||||
app: App
|
app: App
|
||||||
): (replicator: LiveSyncTrysteroReplicator, p2p: P2PServiceViews) => (showResult: boolean) => Promise<boolean | void> {
|
): (p2p: P2PServiceViews) => (showResult: boolean) => Promise<boolean | void> {
|
||||||
return (_replicator: LiveSyncTrysteroReplicator, p2p: P2PServiceViews) =>
|
return (p2p: P2PServiceViews) =>
|
||||||
(showResult: boolean): Promise<boolean | void> => {
|
(showResult: boolean): Promise<boolean | void> => {
|
||||||
const logLevel = showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO;
|
const logLevel = showResult ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO;
|
||||||
return new Promise<boolean | void>((resolve) => {
|
return new Promise<boolean | void>((resolve) => {
|
||||||
@@ -89,7 +89,7 @@ export function createOpenReplicationUI(
|
|||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
* const factory = createOpenRebuildUI(app);
|
* const factory = createOpenRebuildUI(app);
|
||||||
* useP2PReplicatorFeature(core, createOpenReplicationUI(app), factory);
|
* useP2PReplicatorFeature(core, openReplicationUIFactory, factory);
|
||||||
*/
|
*/
|
||||||
export function createOpenRebuildUI(
|
export function createOpenRebuildUI(
|
||||||
app: App
|
app: App
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ describe("createOpenReplicationUI", () => {
|
|||||||
|
|
||||||
it("settles a cancelled peer-selection session when the modal closes", async () => {
|
it("settles a cancelled peer-selection session when the modal closes", async () => {
|
||||||
const p2p = createP2PServiceViews();
|
const p2p = createP2PServiceViews();
|
||||||
const session = createOpenReplicationUI({} as any)(createReplicator(), p2p)(true);
|
const session = createOpenReplicationUI({} as any)(p2p)(true);
|
||||||
const modal = modalState.instances[0];
|
const modal = modalState.instances[0];
|
||||||
|
|
||||||
expect(modal.p2p).toBe(p2p);
|
expect(modal.p2p).toBe(p2p);
|
||||||
@@ -80,9 +80,8 @@ describe("createOpenReplicationUI", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("keeps repeated synchronisation inside the session boundary until the modal closes", async () => {
|
it("keeps repeated synchronisation inside the session boundary until the modal closes", async () => {
|
||||||
const replicator = createReplicator();
|
|
||||||
const p2p = createP2PServiceViews();
|
const p2p = createP2PServiceViews();
|
||||||
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
|
const session = createOpenReplicationUI({} as any)(p2p)(true);
|
||||||
const modal = modalState.instances[0];
|
const modal = modalState.instances[0];
|
||||||
let settled = false;
|
let settled = false;
|
||||||
void session.finally(() => {
|
void session.finally(() => {
|
||||||
@@ -102,9 +101,8 @@ describe("createOpenReplicationUI", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("routes ordinary peer transfer through the stable targeted-transfer view", async () => {
|
it("routes ordinary peer transfer through the stable targeted-transfer view", async () => {
|
||||||
const replicator = createReplicator();
|
|
||||||
const p2p = createP2PServiceViews();
|
const p2p = createP2PServiceViews();
|
||||||
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
|
const session = createOpenReplicationUI({} as any)(p2p)(true);
|
||||||
const modal = modalState.instances[0];
|
const modal = modalState.instances[0];
|
||||||
|
|
||||||
await modal.callback.onSync("peer-a");
|
await modal.callback.onSync("peer-a");
|
||||||
@@ -113,13 +111,10 @@ describe("createOpenReplicationUI", () => {
|
|||||||
|
|
||||||
expect(p2p.targetedTransfer.pullFromPeer).toHaveBeenCalledWith("peer-a", { showNotice: true });
|
expect(p2p.targetedTransfer.pullFromPeer).toHaveBeenCalledWith("peer-a", { showNotice: true });
|
||||||
expect(p2p.targetedTransfer.requestPushToPeer).toHaveBeenCalledWith("peer-a");
|
expect(p2p.targetedTransfer.requestPushToPeer).toHaveBeenCalledWith("peer-a");
|
||||||
expect(replicator.replicateFrom).not.toHaveBeenCalled();
|
|
||||||
expect(replicator.requestSynchroniseToPeer).not.toHaveBeenCalled();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("waits for an in-flight synchronisation when the modal closes", async () => {
|
it("waits for an in-flight synchronisation when the modal closes", async () => {
|
||||||
let finishPull!: (value: { status: "completed"; ok: true }) => void;
|
let finishPull!: (value: { status: "completed"; ok: true }) => void;
|
||||||
const replicator = createReplicator();
|
|
||||||
const p2p = createP2PServiceViews();
|
const p2p = createP2PServiceViews();
|
||||||
p2p.targetedTransfer.pullFromPeer.mockImplementation(
|
p2p.targetedTransfer.pullFromPeer.mockImplementation(
|
||||||
async () =>
|
async () =>
|
||||||
@@ -127,7 +122,7 @@ describe("createOpenReplicationUI", () => {
|
|||||||
finishPull = resolve;
|
finishPull = resolve;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
|
const session = createOpenReplicationUI({} as any)(p2p)(true);
|
||||||
const modal = modalState.instances[0];
|
const modal = modalState.instances[0];
|
||||||
let settled = false;
|
let settled = false;
|
||||||
void session.finally(() => {
|
void session.finally(() => {
|
||||||
@@ -146,15 +141,13 @@ describe("createOpenReplicationUI", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("closes the P2P connection after a successful sync-and-close action", async () => {
|
it("closes the P2P connection after a successful sync-and-close action", async () => {
|
||||||
const replicator = createReplicator();
|
|
||||||
const p2p = createP2PServiceViews();
|
const p2p = createP2PServiceViews();
|
||||||
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
|
const session = createOpenReplicationUI({} as any)(p2p)(true);
|
||||||
const modal = modalState.instances[0];
|
const modal = modalState.instances[0];
|
||||||
|
|
||||||
await modal.callback.onSyncAndClose("peer-a");
|
await modal.callback.onSyncAndClose("peer-a");
|
||||||
|
|
||||||
expect(p2p.transportLifecycle.disconnect).toHaveBeenCalledOnce();
|
expect(p2p.transportLifecycle.disconnect).toHaveBeenCalledOnce();
|
||||||
expect(replicator.close).not.toHaveBeenCalled();
|
|
||||||
let settled = false;
|
let settled = false;
|
||||||
void session.finally(() => {
|
void session.finally(() => {
|
||||||
settled = true;
|
settled = true;
|
||||||
@@ -167,10 +160,9 @@ describe("createOpenReplicationUI", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("returns a cancelled peer push as non-success to the presentation boundary", async () => {
|
it("returns a cancelled peer push as non-success to the presentation boundary", async () => {
|
||||||
const replicator = createReplicator();
|
|
||||||
const p2p = createP2PServiceViews();
|
const p2p = createP2PServiceViews();
|
||||||
p2p.targetedTransfer.requestPushToPeer.mockResolvedValue({ status: "cancelled" } as never);
|
p2p.targetedTransfer.requestPushToPeer.mockResolvedValue({ status: "cancelled" } as never);
|
||||||
const session = createOpenReplicationUI({} as any)(replicator, p2p)(true);
|
const session = createOpenReplicationUI({} as any)(p2p)(true);
|
||||||
const modal = modalState.instances[0];
|
const modal = modalState.instances[0];
|
||||||
|
|
||||||
const actionResult = await modal.callback.onSync("peer-a");
|
const actionResult = await modal.callback.onSync("peer-a");
|
||||||
|
|||||||
+3
-2
@@ -178,14 +178,15 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
const curriedFeature = () => featuresInitialiser(core);
|
const curriedFeature = () => featuresInitialiser(core);
|
||||||
core.services.appLifecycle.onLayoutReady.addHandler(curriedFeature);
|
core.services.appLifecycle.onLayoutReady.addHandler(curriedFeature);
|
||||||
const setupManager = core.getModule(SetupManager);
|
const setupManager = core.getModule(SetupManager);
|
||||||
|
const createInteractiveP2PReplication = createOpenReplicationUI(this.app);
|
||||||
const replicator = useP2PReplicatorFeature(
|
const replicator = useP2PReplicatorFeature(
|
||||||
core,
|
core,
|
||||||
createOpenReplicationUI(this.app),
|
(_compatibilityReplicator, p2p) => createInteractiveP2PReplication(p2p),
|
||||||
createOpenRebuildUI(this.app)
|
createOpenRebuildUI(this.app)
|
||||||
);
|
);
|
||||||
setupManager.registerP2PSetupConnectionProbe(replicator.connectionProbe);
|
setupManager.registerP2PSetupConnectionProbe(replicator.connectionProbe);
|
||||||
useP2PReplicatorCommands(core, replicator);
|
useP2PReplicatorCommands(core, replicator);
|
||||||
useP2PReplicatorUI(core, core, replicator);
|
useP2PReplicatorUI(core, core, replicator, createInteractiveP2PReplication(replicator));
|
||||||
useRemoteConfiguration(core);
|
useRemoteConfiguration(core);
|
||||||
|
|
||||||
useSetupProtocolFeature(core, setupManager);
|
useSetupProtocolFeature(core, setupManager);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { eventHub, EVENT_REQUEST_OPEN_P2P } from "@/common/events";
|
import { eventHub, EVENT_REQUEST_OPEN_P2P } from "@/common/events";
|
||||||
import { reactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
|
|
||||||
import type { NecessaryServices } from "@vrtmrz/livesync-commonlib/compat/interfaces/ServiceModule";
|
import type { NecessaryServices } from "@vrtmrz/livesync-commonlib/compat/interfaces/ServiceModule";
|
||||||
import { type UseP2PReplicatorResult } from "@vrtmrz/livesync-commonlib/compat/replication/trystero/UseP2PReplicatorResult";
|
import { type UseP2PReplicatorResult } from "@vrtmrz/livesync-commonlib/compat/replication/trystero/UseP2PReplicatorResult";
|
||||||
import { P2PLogCollector } from "@vrtmrz/livesync-commonlib/compat/replication/trystero/P2PLogCollector";
|
|
||||||
import {
|
import {
|
||||||
P2PServerStatusPaneView,
|
P2PServerStatusPaneView,
|
||||||
VIEW_TYPE_P2P_SERVER_STATUS,
|
VIEW_TYPE_P2P_SERVER_STATUS,
|
||||||
@@ -21,6 +19,9 @@ class LegacyP2PStatusPaneView extends P2PServerStatusPaneView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Host-owned peer-selection entry used by the two adjunct P2P commands. */
|
||||||
|
export type OpenInteractiveP2PReplication = (showResult: boolean) => Promise<boolean | void>;
|
||||||
|
|
||||||
export function hasP2PConfiguration(settings: Partial<ObsidianLiveSyncSettings>): boolean {
|
export function hasP2PConfiguration(settings: Partial<ObsidianLiveSyncSettings>): boolean {
|
||||||
if (
|
if (
|
||||||
settings.remoteType === REMOTE_P2P ||
|
settings.remoteType === REMOTE_P2P ||
|
||||||
@@ -61,7 +62,8 @@ export function useP2PReplicatorUI(
|
|||||||
never
|
never
|
||||||
>,
|
>,
|
||||||
core: LiveSyncCore,
|
core: LiveSyncCore,
|
||||||
replicator: UseP2PReplicatorResult
|
replicator: UseP2PReplicatorResult,
|
||||||
|
openInteractiveReplication: OpenInteractiveP2PReplication
|
||||||
) {
|
) {
|
||||||
const api = host.services.API as {
|
const api = host.services.API as {
|
||||||
showWindow: (type: string) => Promise<void>;
|
showWindow: (type: string) => Promise<void>;
|
||||||
@@ -80,21 +82,6 @@ export function useP2PReplicatorUI(
|
|||||||
) => { addClass?: (name: string) => unknown; remove?: () => void } | undefined;
|
) => { addClass?: (name: string) => unknown; remove?: () => void } | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
// const env: LiveSyncTrysteroReplicatorEnv = { services: host.services as any };
|
|
||||||
const getReplicator = () => replicator.replicator;
|
|
||||||
const p2pLogCollector = new P2PLogCollector(host.services.context.events);
|
|
||||||
const storeP2PStatusLine = reactiveSource("");
|
|
||||||
p2pLogCollector.p2pReplicationLine.onChanged((line) => {
|
|
||||||
storeP2PStatusLine.value = line.value;
|
|
||||||
});
|
|
||||||
const p2pParams = {
|
|
||||||
get replicator() {
|
|
||||||
return getReplicator();
|
|
||||||
},
|
|
||||||
p2pLogCollector,
|
|
||||||
storeP2PStatusLine,
|
|
||||||
};
|
|
||||||
|
|
||||||
const statusFactory = (leaf: WorkspaceLeaf) => {
|
const statusFactory = (leaf: WorkspaceLeaf) => {
|
||||||
return new P2PServerStatusPaneView(leaf, core, replicator);
|
return new P2PServerStatusPaneView(leaf, core, replicator);
|
||||||
};
|
};
|
||||||
@@ -108,15 +95,11 @@ export function useP2PReplicatorUI(
|
|||||||
return api.showWindow(VIEW_TYPE_P2P_SERVER_STATUS);
|
return api.showWindow(VIEW_TYPE_P2P_SERVER_STATUS);
|
||||||
};
|
};
|
||||||
const runOpenReplication = () => {
|
const runOpenReplication = () => {
|
||||||
const activeReplicator = replicator.replicator;
|
// Peer selection is a host UI concern. The injected operation opens
|
||||||
if (!activeReplicator) return;
|
// the dialogue, while its transfer callbacks use focused P2P views.
|
||||||
const settings = host.services.setting.currentSettings();
|
void host.services.replicator.runFiniteReplicationActivity(() => openInteractiveReplication(true), {
|
||||||
// The deprecated compatibility result only opens the ordinary UI; the
|
label: "replication",
|
||||||
// actual transfer runs through the stable targeted-transfer view.
|
});
|
||||||
void host.services.replicator.runFiniteReplicationActivity(
|
|
||||||
() => activeReplicator.openReplication(settings, false, true, false),
|
|
||||||
{ label: "replication" }
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
// Keep the retired view type registered only long enough to restore an
|
// Keep the retired view type registered only long enough to restore an
|
||||||
// existing workspace leaf with the current status UI. Layout-ready
|
// existing workspace leaf with the current status UI. Layout-ready
|
||||||
@@ -244,5 +227,4 @@ export function useP2PReplicatorUI(
|
|||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
return p2pParams;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ vi.mock("@/features/P2PSync/P2PReplicator/P2PServerStatusPaneView", () => ({
|
|||||||
|
|
||||||
import { useP2PReplicatorUI } from "./useP2PReplicatorUI";
|
import { useP2PReplicatorUI } from "./useP2PReplicatorUI";
|
||||||
|
|
||||||
|
const noopOpenInteractiveReplication = () => Promise.resolve(false);
|
||||||
|
|
||||||
describe("useP2PReplicatorUI commands", () => {
|
describe("useP2PReplicatorUI commands", () => {
|
||||||
it("waits for settings to load before deciding whether to show the P2P ribbon", async () => {
|
it("waits for settings to load before deciding whether to show the P2P ribbon", async () => {
|
||||||
let initialise: (() => Promise<unknown>) | undefined;
|
let initialise: (() => Promise<unknown>) | undefined;
|
||||||
@@ -49,7 +51,7 @@ describe("useP2PReplicatorUI commands", () => {
|
|||||||
},
|
},
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
useP2PReplicatorUI(host, {} as any, { replicator: undefined } as any);
|
useP2PReplicatorUI(host, {} as any, {} as any, noopOpenInteractiveReplication);
|
||||||
|
|
||||||
await expect(initialise?.()).resolves.toBe(true);
|
await expect(initialise?.()).resolves.toBe(true);
|
||||||
expect(currentSettings).not.toHaveBeenCalled();
|
expect(currentSettings).not.toHaveBeenCalled();
|
||||||
@@ -64,7 +66,7 @@ describe("useP2PReplicatorUI commands", () => {
|
|||||||
it("exposes a direct modal P2P replication command as finite replication activity", async () => {
|
it("exposes a direct modal P2P replication command as finite replication activity", async () => {
|
||||||
const commands: Array<{ id: string; checkCallback?: (isChecking: boolean) => unknown }> = [];
|
const commands: Array<{ id: string; checkCallback?: (isChecking: boolean) => unknown }> = [];
|
||||||
let initialise: (() => Promise<unknown>) | undefined;
|
let initialise: (() => Promise<unknown>) | undefined;
|
||||||
const openReplication = vi.fn(async () => true);
|
const openInteractiveReplication = vi.fn(async () => true);
|
||||||
const runFiniteReplicationActivity = vi.fn(async (task: () => unknown) => await task());
|
const runFiniteReplicationActivity = vi.fn(async (task: () => unknown) => await task());
|
||||||
const host = {
|
const host = {
|
||||||
services: {
|
services: {
|
||||||
@@ -96,58 +98,18 @@ describe("useP2PReplicatorUI commands", () => {
|
|||||||
} as any;
|
} as any;
|
||||||
const p2p = {
|
const p2p = {
|
||||||
transportLifecycle: { isConnected: true },
|
transportLifecycle: { isConnected: true },
|
||||||
replicator: {
|
|
||||||
server: { isServing: true },
|
|
||||||
openReplication,
|
|
||||||
replicateFromCommand: vi.fn(),
|
|
||||||
},
|
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
useP2PReplicatorUI(host, {} as any, p2p);
|
useP2PReplicatorUI(host, {} as any, p2p, openInteractiveReplication);
|
||||||
await initialise?.();
|
await initialise?.();
|
||||||
commands.find((command) => command.id === "replicate-now-by-p2p")?.checkCallback?.(false);
|
commands.find((command) => command.id === "replicate-now-by-p2p")?.checkCallback?.(false);
|
||||||
|
|
||||||
await vi.waitFor(() => expect(openReplication).toHaveBeenCalledOnce());
|
await vi.waitFor(() => expect(openInteractiveReplication).toHaveBeenCalledWith(true));
|
||||||
expect(runFiniteReplicationActivity).toHaveBeenCalledWith(expect.any(Function), {
|
expect(runFiniteReplicationActivity).toHaveBeenCalledWith(expect.any(Function), {
|
||||||
label: "replication",
|
label: "replication",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("keeps the current replicator in the pane parameters after replacement", () => {
|
|
||||||
const first = { id: "first" };
|
|
||||||
const second = { id: "second" };
|
|
||||||
let current = first;
|
|
||||||
const p2p = {
|
|
||||||
get replicator() {
|
|
||||||
return current;
|
|
||||||
},
|
|
||||||
} as any;
|
|
||||||
const host = {
|
|
||||||
services: {
|
|
||||||
context: createServiceContext(),
|
|
||||||
API: {
|
|
||||||
showWindow: vi.fn(async () => undefined),
|
|
||||||
registerWindow: vi.fn(),
|
|
||||||
addCommand: vi.fn(),
|
|
||||||
addRibbonIcon: vi.fn(),
|
|
||||||
getPlatform: vi.fn(() => "obsidian"),
|
|
||||||
},
|
|
||||||
appLifecycle: {
|
|
||||||
onInitialise: { addHandler: vi.fn() },
|
|
||||||
onSettingLoaded: { addHandler: vi.fn() },
|
|
||||||
onLayoutReady: { addHandler: vi.fn() },
|
|
||||||
},
|
|
||||||
setting: { currentSettings: vi.fn(() => ({ remoteType: "COUCHDB" })) },
|
|
||||||
replicator: { runFiniteReplicationActivity: vi.fn() },
|
|
||||||
},
|
|
||||||
} as any;
|
|
||||||
|
|
||||||
const paneParams = useP2PReplicatorUI(host, {} as any, p2p);
|
|
||||||
current = second;
|
|
||||||
|
|
||||||
expect(paneParams.replicator).toBe(second);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("retains only the current P2P status command and routes existing open requests to it", async () => {
|
it("retains only the current P2P status command and routes existing open requests to it", async () => {
|
||||||
const commands: Array<{
|
const commands: Array<{
|
||||||
id: string;
|
id: string;
|
||||||
@@ -186,9 +148,9 @@ describe("useP2PReplicatorUI commands", () => {
|
|||||||
replicator: { runFiniteReplicationActivity: vi.fn() },
|
replicator: { runFiniteReplicationActivity: vi.fn() },
|
||||||
},
|
},
|
||||||
} as any;
|
} as any;
|
||||||
const p2p = { replicator: undefined } as any;
|
const p2p = {} as any;
|
||||||
|
|
||||||
useP2PReplicatorUI(host, {} as any, p2p);
|
useP2PReplicatorUI(host, {} as any, p2p, noopOpenInteractiveReplication);
|
||||||
await initialise?.();
|
await initialise?.();
|
||||||
|
|
||||||
expect(commands.map((command) => command.id)).not.toContain("open-p2p-replicator");
|
expect(commands.map((command) => command.id)).not.toContain("open-p2p-replicator");
|
||||||
@@ -237,19 +199,13 @@ describe("useP2PReplicatorUI commands", () => {
|
|||||||
replicator: { runFiniteReplicationActivity },
|
replicator: { runFiniteReplicationActivity },
|
||||||
},
|
},
|
||||||
} as any;
|
} as any;
|
||||||
const replicateFromCommand = vi.fn();
|
|
||||||
const synchroniseConfiguredTargets = vi.fn(async () => ({ status: "completed" }));
|
const synchroniseConfiguredTargets = vi.fn(async () => ({ status: "completed" }));
|
||||||
const p2p = {
|
const p2p = {
|
||||||
transportLifecycle: { isConnected: true },
|
transportLifecycle: { isConnected: true },
|
||||||
targetedTransfer: { synchroniseConfiguredTargets },
|
targetedTransfer: { synchroniseConfiguredTargets },
|
||||||
replicator: {
|
|
||||||
server: { isServing: true },
|
|
||||||
openReplication: vi.fn(),
|
|
||||||
replicateFromCommand,
|
|
||||||
},
|
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
useP2PReplicatorUI(host, {} as any, p2p);
|
useP2PReplicatorUI(host, {} as any, p2p, noopOpenInteractiveReplication);
|
||||||
await initialise?.();
|
await initialise?.();
|
||||||
|
|
||||||
for (const commandId of [
|
for (const commandId of [
|
||||||
@@ -283,7 +239,6 @@ describe("useP2PReplicatorUI commands", () => {
|
|||||||
|
|
||||||
commands.find(({ id }) => id === "p2p-sync-targets")?.checkCallback?.(false);
|
commands.find(({ id }) => id === "p2p-sync-targets")?.checkCallback?.(false);
|
||||||
await vi.waitFor(() => expect(synchroniseConfiguredTargets).toHaveBeenCalledOnce());
|
await vi.waitFor(() => expect(synchroniseConfiguredTargets).toHaveBeenCalledOnce());
|
||||||
expect(replicateFromCommand).not.toHaveBeenCalled();
|
|
||||||
expect(runFiniteReplicationActivity).toHaveBeenCalledWith(expect.any(Function), {
|
expect(runFiniteReplicationActivity).toHaveBeenCalledWith(expect.any(Function), {
|
||||||
label: "replication",
|
label: "replication",
|
||||||
});
|
});
|
||||||
@@ -323,7 +278,7 @@ describe("useP2PReplicatorUI commands", () => {
|
|||||||
},
|
},
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
useP2PReplicatorUI(host, {} as any, { replicator: undefined } as any);
|
useP2PReplicatorUI(host, {} as any, {} as any, noopOpenInteractiveReplication);
|
||||||
await layoutReady?.();
|
await layoutReady?.();
|
||||||
|
|
||||||
expect(showWindow).not.toHaveBeenCalled();
|
expect(showWindow).not.toHaveBeenCalled();
|
||||||
@@ -379,7 +334,7 @@ describe("useP2PReplicatorUI commands", () => {
|
|||||||
},
|
},
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
useP2PReplicatorUI(host, {} as any, { replicator: undefined } as any);
|
useP2PReplicatorUI(host, {} as any, {} as any, noopOpenInteractiveReplication);
|
||||||
await initialise?.();
|
await initialise?.();
|
||||||
await settingLoaded?.();
|
await settingLoaded?.();
|
||||||
expect(addRibbonIcon).not.toHaveBeenCalled();
|
expect(addRibbonIcon).not.toHaveBeenCalled();
|
||||||
@@ -453,7 +408,7 @@ describe("useP2PReplicatorUI commands", () => {
|
|||||||
},
|
},
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
useP2PReplicatorUI(host, {} as any, { replicator: undefined } as any);
|
useP2PReplicatorUI(host, {} as any, {} as any, noopOpenInteractiveReplication);
|
||||||
await layoutReady?.();
|
await layoutReady?.();
|
||||||
|
|
||||||
expect(legacyLeaf.setViewState).toHaveBeenCalledWith({
|
expect(legacyLeaf.setViewState).toHaveBeenCalledWith({
|
||||||
|
|||||||
Reference in New Issue
Block a user