Refresh owned Security Seed observations

This commit is contained in:
vorotamoroz
2026-08-30 16:15:55 +00:00
parent 69cd6250d2
commit 704e141fd9
4 changed files with 60 additions and 4 deletions
+2 -2
View File
@@ -224,8 +224,8 @@ describe("replicator probe factories", () => {
objectSettings.endpoint = "https://changed.example.test";
await expect(couchResource.read()).resolves.toBe(couchSeed);
await expect(objectResource.read()).resolves.toBe(objectSeed);
expect(couchReplicator.getReplicationPBKDF2Salt).toHaveBeenCalledWith(couchSnapshot);
expect(objectReplicator.getReplicationPBKDF2Salt).toHaveBeenCalledWith(objectSnapshot);
expect(couchReplicator.getReplicationPBKDF2Salt).toHaveBeenCalledWith(couchSnapshot, true);
expect(objectReplicator.getReplicationPBKDF2Salt).toHaveBeenCalledWith(objectSnapshot, true);
await Promise.all([couchResource.dispose(), objectResource.dispose()]);
expect(couchReplicator.closeReplication).toHaveBeenCalledOnce();
@@ -22,7 +22,7 @@ function createSecuritySeedResourceFactory(
const snapshot = snapshotRemoteSettings(setting);
const replicator = createReplicator();
return Promise.resolve({
read: () => replicator.getReplicationPBKDF2Salt(snapshot),
read: () => replicator.getReplicationPBKDF2Salt(snapshot, true),
dispose: createReplicatorDisposer(replicator),
});
};
@@ -1,5 +1,6 @@
import { describe, expect, it, vi } from "vitest";
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 {
CENTRAL_COMPATIBILITY_REJECTION_REASONS,
NO_INTERACTION,
@@ -21,6 +22,40 @@ import { LiveSyncCouchDBReplicator } from "@vrtmrz/livesync-commonlib/compat/rep
import { createCentralCompatibilityRecovery } from "./centralCompatibilityRecovery";
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 () => {
const askResolvingMismatched = vi.fn(async (..._arguments: unknown[]) => undefined);
const failedSetPreferred = vi.fn(async (_setting: unknown) => undefined);
@@ -1,5 +1,5 @@
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 {
createReplicationSchedulingContext,
@@ -22,6 +22,7 @@ function createDeferred<T>() {
function createControllerHarness(
overrides: Partial<{
remoteType: typeof DEFAULT_SETTINGS.remoteType;
liveSync: boolean;
syncOnStart: boolean;
periodicReplication: boolean;
@@ -111,6 +112,26 @@ describe("replication scheduling context", () => {
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 () => {
const { context, replicateUnattended, startContinuous } = createControllerHarness({ liveSync: true });