Files
buzz/desktop/src/shared/api/tauriTeams.snapshotImport.test.mjs
2026-07-15 17:19:03 +00:00

238 lines
7.5 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import {
deriveImportPhase,
getProfileSyncFailures,
deriveImportToast,
} from "../../features/agents/ui/teamSnapshotImport.lib.ts";
// Behavior tests for the team snapshot import dialog flow. These import and
// exercise the actual production functions used by TeamSnapshotImportDialog
// and useTeamActions.
// ── Factories ────────────────────────────────────────────────────────────────
function makeMemberResult(overrides = {}) {
return {
displayName: "Agent A",
pubkey: "aabb".repeat(16),
personaId: "persona-uuid-1",
memoryWritten: 0,
memoryTotal: 0,
memoryErrors: [],
profileSyncError: null,
...overrides,
};
}
function makeImportResult(overrides = {}) {
const { members: memberOverrides, team: teamOverrides, ...rest } = overrides;
return {
team: {
id: "team-uuid",
name: "Test Team",
description: "A test team",
personaIds: ["persona-uuid-1"],
instructions: "Be helpful",
isBuiltin: false,
sourceDir: null,
isSymlink: false,
symlinkTarget: null,
version: null,
createdAt: new Date().toISOString(),
...teamOverrides,
},
personaIds: ["persona-uuid-1"],
members: [makeMemberResult()],
...rest,
...(memberOverrides !== undefined ? { members: memberOverrides } : {}),
};
}
// ── deriveImportPhase ────────────────────────────────────────────────────────
test("deriveImportPhase_returns_result_when_result_present", () => {
const result = makeImportResult();
assert.equal(deriveImportPhase(result, false), "result");
});
test("deriveImportPhase_returns_result_even_when_confirming", () => {
// result takes precedence over isConfirming
const result = makeImportResult();
assert.equal(deriveImportPhase(result, true), "result");
});
test("deriveImportPhase_returns_confirming_when_inflight", () => {
assert.equal(deriveImportPhase(null, true), "confirming");
});
test("deriveImportPhase_returns_preview_when_idle", () => {
assert.equal(deriveImportPhase(null, false), "preview");
});
test("deriveImportPhase_confirm_failure_returns_to_preview", () => {
// When confirm throws, result stays null and isConfirming resets to false
assert.equal(deriveImportPhase(null, false), "preview");
});
// ── getProfileSyncFailures ───────────────────────────────────────────────────
test("getProfileSyncFailures_returns_members_with_errors", () => {
const members = [
makeMemberResult({ displayName: "A", profileSyncError: "relay timeout" }),
makeMemberResult({
displayName: "B",
pubkey: "ccdd".repeat(16),
profileSyncError: null,
}),
];
const failures = getProfileSyncFailures(members);
assert.equal(failures.length, 1);
assert.equal(failures[0].displayName, "A");
assert.equal(failures[0].profileSyncError, "relay timeout");
});
test("getProfileSyncFailures_returns_empty_when_all_ok", () => {
const members = [
makeMemberResult({ profileSyncError: null }),
makeMemberResult({
displayName: "B",
pubkey: "ccdd".repeat(16),
profileSyncError: null,
}),
];
assert.equal(getProfileSyncFailures(members).length, 0);
});
test("getProfileSyncFailures_returns_all_when_all_failed", () => {
const members = [
makeMemberResult({ displayName: "A", profileSyncError: "relay rejected" }),
makeMemberResult({
displayName: "B",
pubkey: "ccdd".repeat(16),
profileSyncError: "network error",
}),
];
assert.equal(getProfileSyncFailures(members).length, 2);
});
// ── deriveImportToast ────────────────────────────────────────────────────────
test("deriveImportToast_success_when_no_failures", () => {
const result = makeImportResult();
const toast = deriveImportToast(result);
assert.equal(toast.type, "notice");
assert.match(toast.message, /Imported Test Team with 1 member\./);
});
test("deriveImportToast_error_when_profile_sync_fails", () => {
const result = makeImportResult({
members: [makeMemberResult({ profileSyncError: "relay timeout" })],
});
const toast = deriveImportToast(result);
assert.equal(toast.type, "error");
assert.match(toast.message, /Test Team imported, but/);
assert.match(toast.message, /failed to sync profile/);
});
test("deriveImportToast_error_when_memory_errors_only", () => {
const result = makeImportResult({
members: [
makeMemberResult({
memoryTotal: 2,
memoryWritten: 0,
memoryErrors: ["err1", "err2"],
profileSyncError: null,
}),
],
});
const toast = deriveImportToast(result);
assert.equal(toast.type, "error");
assert.match(toast.message, /2 memory entr/);
assert.doesNotMatch(toast.message, /sync profile/);
});
test("deriveImportToast_error_composes_both_failure_types", () => {
const result = makeImportResult({
members: [
makeMemberResult({
memoryTotal: 3,
memoryWritten: 1,
memoryErrors: ["slug err 1", "slug err 2"],
profileSyncError: "relay timeout",
}),
],
});
const toast = deriveImportToast(result);
assert.equal(toast.type, "error");
assert.match(toast.message, /2 memory entr/);
assert.match(toast.message, /failed to sync profile/);
assert.match(toast.message, / and /);
});
test("deriveImportToast_plural_members", () => {
const result = makeImportResult({
members: [
makeMemberResult(),
makeMemberResult({
displayName: "Agent B",
pubkey: "ccdd".repeat(16),
personaId: "persona-uuid-2",
}),
],
});
const toast = deriveImportToast(result);
assert.equal(toast.type, "notice");
assert.match(toast.message, /with 2 members\./);
});
test("deriveImportToast_singular_member", () => {
const result = makeImportResult();
const toast = deriveImportToast(result);
assert.match(toast.message, /with 1 member\./);
});
// ── Mixed success/failure across members ─────────────────────────────────────
test("mixed_member_outcomes_memory_errors_and_profile_sync", () => {
const result = makeImportResult({
members: [
makeMemberResult({
displayName: "Agent A",
memoryWritten: 3,
memoryTotal: 3,
memoryErrors: [],
profileSyncError: "relay timeout",
}),
makeMemberResult({
displayName: "Agent B",
pubkey: "ccdd".repeat(16),
personaId: "persona-uuid-2",
memoryWritten: 0,
memoryTotal: 2,
memoryErrors: ["err1", "err2"],
profileSyncError: null,
}),
makeMemberResult({
displayName: "Agent C",
pubkey: "eeff".repeat(16),
personaId: "persona-uuid-3",
memoryWritten: 1,
memoryTotal: 1,
memoryErrors: [],
profileSyncError: null,
}),
],
});
const failures = getProfileSyncFailures(result.members);
assert.equal(failures.length, 1);
assert.equal(failures[0].displayName, "Agent A");
const toast = deriveImportToast(result);
assert.equal(toast.type, "error");
assert.match(toast.message, /2 memory entr/);
assert.match(toast.message, /1 member failed to sync profile/);
});