mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-30 23:37:08 +00:00
Refresh owned Security Seed observations
This commit is contained in:
@@ -224,8 +224,8 @@ describe("replicator probe factories", () => {
|
|||||||
objectSettings.endpoint = "https://changed.example.test";
|
objectSettings.endpoint = "https://changed.example.test";
|
||||||
await expect(couchResource.read()).resolves.toBe(couchSeed);
|
await expect(couchResource.read()).resolves.toBe(couchSeed);
|
||||||
await expect(objectResource.read()).resolves.toBe(objectSeed);
|
await expect(objectResource.read()).resolves.toBe(objectSeed);
|
||||||
expect(couchReplicator.getReplicationPBKDF2Salt).toHaveBeenCalledWith(couchSnapshot);
|
expect(couchReplicator.getReplicationPBKDF2Salt).toHaveBeenCalledWith(couchSnapshot, true);
|
||||||
expect(objectReplicator.getReplicationPBKDF2Salt).toHaveBeenCalledWith(objectSnapshot);
|
expect(objectReplicator.getReplicationPBKDF2Salt).toHaveBeenCalledWith(objectSnapshot, true);
|
||||||
|
|
||||||
await Promise.all([couchResource.dispose(), objectResource.dispose()]);
|
await Promise.all([couchResource.dispose(), objectResource.dispose()]);
|
||||||
expect(couchReplicator.closeReplication).toHaveBeenCalledOnce();
|
expect(couchReplicator.closeReplication).toHaveBeenCalledOnce();
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ function createSecuritySeedResourceFactory(
|
|||||||
const snapshot = snapshotRemoteSettings(setting);
|
const snapshot = snapshotRemoteSettings(setting);
|
||||||
const replicator = createReplicator();
|
const replicator = createReplicator();
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
read: () => replicator.getReplicationPBKDF2Salt(snapshot),
|
read: () => replicator.getReplicationPBKDF2Salt(snapshot, true),
|
||||||
dispose: createReplicatorDisposer(replicator),
|
dispose: createReplicatorDisposer(replicator),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import type { ObsidianLiveSyncSettings } from "@vrtmrz/livesync-commonlib/compat/common/types";
|
import type { ObsidianLiveSyncSettings } from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||||
|
import { defaultLogger, LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, setGlobalLogFunction } from "octagonal-wheels/common/logger";
|
||||||
import {
|
import {
|
||||||
CENTRAL_COMPATIBILITY_REJECTION_REASONS,
|
CENTRAL_COMPATIBILITY_REJECTION_REASONS,
|
||||||
NO_INTERACTION,
|
NO_INTERACTION,
|
||||||
@@ -21,6 +22,40 @@ import { LiveSyncCouchDBReplicator } from "@vrtmrz/livesync-commonlib/compat/rep
|
|||||||
import { createCentralCompatibilityRecovery } from "./centralCompatibilityRecovery";
|
import { createCentralCompatibilityRecovery } from "./centralCompatibilityRecovery";
|
||||||
|
|
||||||
describe("central compatibility recovery", () => {
|
describe("central compatibility recovery", () => {
|
||||||
|
it("characterises unattended central failure handling as one INFO log without a NOTICE", async () => {
|
||||||
|
const log = vi.fn((_message: unknown, _level?: number, _key?: string) => undefined);
|
||||||
|
setGlobalLogFunction(log);
|
||||||
|
try {
|
||||||
|
const recovery = createCentralCompatibilityRecovery({
|
||||||
|
confirm: {},
|
||||||
|
localDatabase: {},
|
||||||
|
rebuilder: {},
|
||||||
|
services: {
|
||||||
|
appLifecycle: {},
|
||||||
|
API: {},
|
||||||
|
replicator: {},
|
||||||
|
tweakValue: {},
|
||||||
|
},
|
||||||
|
} as never);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
recovery.handleReplicationFailure({
|
||||||
|
context: { provider: {}, replicator: {} },
|
||||||
|
setting: {},
|
||||||
|
outcome: replicationFailed(new Error("provider failed")),
|
||||||
|
showMessage: false,
|
||||||
|
interaction: NO_INTERACTION,
|
||||||
|
} as never)
|
||||||
|
).resolves.toBe(false);
|
||||||
|
|
||||||
|
expect(log).toHaveBeenCalledOnce();
|
||||||
|
expect(log).toHaveBeenCalledWith("Replication failed on an unattended path.", LOG_LEVEL_INFO, undefined);
|
||||||
|
expect(log.mock.calls.map(([, level]) => level)).not.toContain(LOG_LEVEL_NOTICE);
|
||||||
|
} finally {
|
||||||
|
setGlobalLogFunction(defaultLogger);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it("uses the exact failed outcome and permits dialogue only with recovery authority", async () => {
|
it("uses the exact failed outcome and permits dialogue only with recovery authority", async () => {
|
||||||
const askResolvingMismatched = vi.fn(async (..._arguments: unknown[]) => undefined);
|
const askResolvingMismatched = vi.fn(async (..._arguments: unknown[]) => undefined);
|
||||||
const failedSetPreferred = vi.fn(async (_setting: unknown) => undefined);
|
const failedSetPreferred = vi.fn(async (_setting: unknown) => undefined);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import { DEFAULT_SETTINGS } from "@vrtmrz/livesync-commonlib/compat/common/types";
|
import { DEFAULT_SETTINGS, REMOTE_MINIO } from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||||
import { NO_INTERACTION, type ReplicationOutcome } from "@vrtmrz/livesync-commonlib/replication";
|
import { NO_INTERACTION, type ReplicationOutcome } from "@vrtmrz/livesync-commonlib/replication";
|
||||||
import {
|
import {
|
||||||
createReplicationSchedulingContext,
|
createReplicationSchedulingContext,
|
||||||
@@ -22,6 +22,7 @@ function createDeferred<T>() {
|
|||||||
|
|
||||||
function createControllerHarness(
|
function createControllerHarness(
|
||||||
overrides: Partial<{
|
overrides: Partial<{
|
||||||
|
remoteType: typeof DEFAULT_SETTINGS.remoteType;
|
||||||
liveSync: boolean;
|
liveSync: boolean;
|
||||||
syncOnStart: boolean;
|
syncOnStart: boolean;
|
||||||
periodicReplication: boolean;
|
periodicReplication: boolean;
|
||||||
@@ -111,6 +112,26 @@ describe("replication scheduling context", () => {
|
|||||||
expect(timer.enable).toHaveBeenCalledWith(45_000);
|
expect(timer.enable).toHaveBeenCalledWith(45_000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("schedules migrated Object Storage syncOnStart through unattended OneShot", async () => {
|
||||||
|
const { context, replicateUnattended, startContinuous } = createControllerHarness({
|
||||||
|
remoteType: REMOTE_MINIO,
|
||||||
|
liveSync: true,
|
||||||
|
syncOnStart: true,
|
||||||
|
});
|
||||||
|
startContinuous.mockResolvedValue({
|
||||||
|
status: "blocked",
|
||||||
|
reason: "capability-not-applicable",
|
||||||
|
});
|
||||||
|
|
||||||
|
resumeReplicationScheduling(context);
|
||||||
|
|
||||||
|
await vi.waitFor(() => expect(replicateUnattended).toHaveBeenCalledOnce());
|
||||||
|
expect(replicateUnattended).toHaveBeenCalledWith({
|
||||||
|
trigger: "resume",
|
||||||
|
interaction: NO_INTERACTION,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("does not run a finite fallback after Continuous starts successfully", async () => {
|
it("does not run a finite fallback after Continuous starts successfully", async () => {
|
||||||
const { context, replicateUnattended, startContinuous } = createControllerHarness({ liveSync: true });
|
const { context, replicateUnattended, startContinuous } = createControllerHarness({ liveSync: true });
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user