mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-30 15:27:06 +00:00
138 lines
4.9 KiB
TypeScript
138 lines
4.9 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { collectPeers, createPeerConnectionStatsPayload, parseTimeoutSeconds, syncWithPeer } from "./p2p";
|
|
|
|
function createCore() {
|
|
const settings = { P2P_Enabled: true, P2P_AppID: "app-id", P2P_IsHeadless: false };
|
|
return {
|
|
services: {
|
|
setting: { currentSettings: () => settings },
|
|
replicator: { getNewReplicator: vi.fn(() => Promise.reject(new Error("must not be called"))) },
|
|
},
|
|
} as never;
|
|
}
|
|
|
|
function createP2PService() {
|
|
const connect = vi.fn(async () => undefined);
|
|
const disconnect = vi.fn(async () => undefined);
|
|
const pullFromPeer = vi.fn(async () => ({ ok: true }));
|
|
const requestPushToPeer = vi.fn(async () => ({ ok: true }));
|
|
return {
|
|
service: {
|
|
transportLifecycle: { isConnected: false, connect, disconnect },
|
|
peerDirectory: {
|
|
getPeers: () => [{ peerId: "peer-a", name: "Peer A", platform: "test" }],
|
|
},
|
|
targetedTransfer: {
|
|
pullFromPeer,
|
|
requestPushToPeer,
|
|
synchroniseWithPeer: vi.fn(),
|
|
},
|
|
diagnostics: { requestStatus: vi.fn(), getPeerConnectionMetrics: vi.fn() },
|
|
},
|
|
connect,
|
|
disconnect,
|
|
pullFromPeer,
|
|
requestPushToPeer,
|
|
};
|
|
}
|
|
|
|
describe("p2p command helpers", () => {
|
|
it("accepts non-negative timeout", () => {
|
|
expect(parseTimeoutSeconds("0", "p2p-peers")).toBe(0);
|
|
expect(parseTimeoutSeconds("2.5", "p2p-sync")).toBe(2.5);
|
|
});
|
|
|
|
it("rejects invalid timeout values", () => {
|
|
expect(() => parseTimeoutSeconds("-1", "p2p-peers")).toThrow(
|
|
"p2p-peers requires a non-negative timeout in seconds"
|
|
);
|
|
expect(() => parseTimeoutSeconds("abc", "p2p-sync")).toThrow(
|
|
"p2p-sync requires a non-negative timeout in seconds"
|
|
);
|
|
});
|
|
|
|
it("collects peers through service views without acquiring a concrete replicator", async () => {
|
|
const { service, connect, disconnect } = createP2PService();
|
|
|
|
await expect(collectPeers(createCore(), service as never, 0)).resolves.toEqual([
|
|
{ peerId: "peer-a", name: "Peer A" },
|
|
]);
|
|
expect(connect).toHaveBeenCalledOnce();
|
|
expect(disconnect).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it("synchronises through the targeted-transfer view", async () => {
|
|
const { service, pullFromPeer, requestPushToPeer } = createP2PService();
|
|
|
|
await expect(syncWithPeer(createCore(), service as never, "peer-a", 0)).resolves.toEqual({
|
|
peerId: "peer-a",
|
|
name: "Peer A",
|
|
});
|
|
expect(pullFromPeer).toHaveBeenCalledWith("peer-a", { showNotice: false });
|
|
expect(requestPushToPeer).toHaveBeenCalledWith("peer-a");
|
|
});
|
|
|
|
it("preserves the benchmark diagnostics JSONL contract", () => {
|
|
expect(
|
|
createPeerConnectionStatsPayload(
|
|
{ peerId: "peer-a", name: "Peer A" },
|
|
{
|
|
selectedPairPresent: true,
|
|
selectedPairId: "pair-1",
|
|
state: "succeeded",
|
|
currentRoundTripTime: 0.01,
|
|
totalRoundTripTime: 0.1,
|
|
requestsSent: 3,
|
|
responsesReceived: 3,
|
|
packetsDiscardedOnSend: 0,
|
|
bytesSent: 100,
|
|
bytesReceived: 200,
|
|
localCandidate: {
|
|
id: "local-1",
|
|
candidateType: "host",
|
|
protocol: "udp",
|
|
relayProtocol: "unknown",
|
|
},
|
|
remoteCandidate: {
|
|
id: "remote-1",
|
|
candidateType: "relay",
|
|
protocol: "udp",
|
|
relayProtocol: "udp",
|
|
},
|
|
},
|
|
"2026-08-27T00:00:00.000Z"
|
|
)
|
|
).toEqual({
|
|
generatedAt: "2026-08-27T00:00:00.000Z",
|
|
command: "p2p-sync",
|
|
peerId: "peer-a",
|
|
peerName: "Peer A",
|
|
candidatePathCollected: true,
|
|
selectedPath: "host<->relay",
|
|
selectedPair: {
|
|
id: "pair-1",
|
|
state: "succeeded",
|
|
currentRoundTripTime: 0.01,
|
|
totalRoundTripTime: 0.1,
|
|
requestsSent: 3,
|
|
responsesReceived: 3,
|
|
packetsDiscardedOnSend: 0,
|
|
bytesSent: 100,
|
|
bytesReceived: 200,
|
|
},
|
|
localCandidate: {
|
|
id: "local-1",
|
|
candidateType: "host",
|
|
protocol: "udp",
|
|
relayProtocol: "unknown",
|
|
},
|
|
remoteCandidate: {
|
|
id: "remote-1",
|
|
candidateType: "relay",
|
|
protocol: "udp",
|
|
relayProtocol: "udp",
|
|
},
|
|
});
|
|
});
|
|
});
|