feat(ext/sw): get_vault_status handler + cached sync state (Plan C Phase 6)
Returns cached ahead/behind/lastSyncAt from the GitHost plus a live count of active (non-trashed) manifest items. No network call — sync is user-initiated; the sync handler records lastSyncAt (unix seconds). ahead/behind stay 0 in the extension (writes go straight to the host, no local commit graph) and exist for parity with relicario status. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
53
extension/src/service-worker/__tests__/vault-status.test.ts
Normal file
53
extension/src/service-worker/__tests__/vault-status.test.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { handleGetVaultStatus } from '../vault';
|
||||
import type { Manifest, ManifestEntry } from '../../shared/types';
|
||||
|
||||
// The handler only reads gitHost's three cache fields, so the test feeds a
|
||||
// minimal object — the handler's Pick-typed param makes full GitHost mocking
|
||||
// unnecessary.
|
||||
const cache = (lastSyncAt: number | null, ahead = 0, behind = 0) =>
|
||||
({ lastSyncAt, ahead, behind });
|
||||
|
||||
function manifestWith(activeCount: number, trashedCount = 0): Manifest {
|
||||
const items: Record<string, ManifestEntry> = {};
|
||||
for (let i = 0; i < activeCount; i++) {
|
||||
items[`a${i}`] = { trashed_at: undefined } as ManifestEntry;
|
||||
}
|
||||
for (let i = 0; i < trashedCount; i++) {
|
||||
items[`t${i}`] = { trashed_at: 1000 } as ManifestEntry;
|
||||
}
|
||||
return { items } as Manifest;
|
||||
}
|
||||
|
||||
describe('handleGetVaultStatus', () => {
|
||||
it('returns zeros when never synced and no manifest', () => {
|
||||
const resp = handleGetVaultStatus({ gitHost: cache(null), manifest: null });
|
||||
expect(resp).toEqual({
|
||||
ok: true,
|
||||
data: { ahead: 0, behind: 0, lastSyncAt: null, pendingItems: 0 },
|
||||
});
|
||||
});
|
||||
|
||||
it('reflects cached sync state + active (non-trashed) item count', () => {
|
||||
const resp = handleGetVaultStatus({
|
||||
gitHost: cache(1234567890, 3, 1),
|
||||
manifest: manifestWith(5, 2),
|
||||
});
|
||||
expect(resp.ok).toBe(true);
|
||||
if (resp.ok) {
|
||||
expect(resp.data).toEqual({
|
||||
ahead: 3, behind: 1, lastSyncAt: 1234567890, pendingItems: 5,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('returns vault_locked error when gitHost is null', () => {
|
||||
expect(handleGetVaultStatus({ gitHost: null, manifest: null }))
|
||||
.toEqual({ ok: false, error: 'vault_locked' });
|
||||
});
|
||||
|
||||
it('is synchronous — no network round-trip', () => {
|
||||
const resp = handleGetVaultStatus({ gitHost: cache(0), manifest: null });
|
||||
expect(resp).not.toBeInstanceOf(Promise);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user