test(ext/vault): handler→renderer status integration + indicator CSS (Plan C Phase 6)
Pins the 6.1↔6.2 contract: handleGetVaultStatus output feeds straight into renderStatusIndicator. Adds minimal self-contained .vault-status CSS. Stays out of vault-sidebar.ts — the footer wiring (Task 6.3) is Dev-B's boundary. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
65
extension/src/vault/__tests__/status-integration.test.ts
Normal file
65
extension/src/vault/__tests__/status-integration.test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { handleGetVaultStatus } from '../../service-worker/vault';
|
||||
import { renderStatusIndicator } from '../vault-status';
|
||||
import type { Manifest, ManifestEntry } from '../../shared/types';
|
||||
|
||||
// Integration seam: the get_vault_status SW handler (Phase 6 Task 6.1) produces
|
||||
// the exact data shape the sidebar renderer (Task 6.2) consumes. This pins the
|
||||
// contract between the two so a future change to either side can't silently
|
||||
// drift the keys apart. It does NOT touch vault-sidebar.ts — the wiring layer
|
||||
// (Task 6.3) is Dev-B's boundary and lands separately.
|
||||
|
||||
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('vault status: handler → renderer integration', () => {
|
||||
it('renders "in sync" from a freshly-synced, no-pending handler response', () => {
|
||||
const resp = handleGetVaultStatus({ gitHost: cache(1700000000), manifest: manifestWith(0) });
|
||||
expect(resp.ok).toBe(true);
|
||||
if (!resp.ok) return;
|
||||
const el = document.createElement('div');
|
||||
renderStatusIndicator(el, resp.data);
|
||||
expect(el.textContent).toMatch(/in sync/i);
|
||||
expect(el.textContent).toMatch(/last sync/i);
|
||||
});
|
||||
|
||||
it('surfaces the handler\'s active-item count as "N pending" in the DOM', () => {
|
||||
const resp = handleGetVaultStatus({ gitHost: cache(1700000000), manifest: manifestWith(7, 3) });
|
||||
expect(resp.ok).toBe(true);
|
||||
if (!resp.ok) return;
|
||||
expect(resp.data.pendingItems).toBe(7);
|
||||
const el = document.createElement('div');
|
||||
renderStatusIndicator(el, resp.data);
|
||||
expect(el.textContent).toMatch(/7 pending/i);
|
||||
});
|
||||
|
||||
it('surfaces cached ahead/behind from the handler in the DOM', () => {
|
||||
const resp = handleGetVaultStatus({ gitHost: cache(1700000000, 2, 1), manifest: manifestWith(0) });
|
||||
expect(resp.ok).toBe(true);
|
||||
if (!resp.ok) return;
|
||||
const el = document.createElement('div');
|
||||
renderStatusIndicator(el, resp.data);
|
||||
expect(el.textContent).toMatch(/2 ahead/i);
|
||||
expect(el.textContent).toMatch(/1 behind/i);
|
||||
});
|
||||
|
||||
it('renders "never synced" when the handler reports a null lastSyncAt', () => {
|
||||
const resp = handleGetVaultStatus({ gitHost: cache(null), manifest: manifestWith(0) });
|
||||
expect(resp.ok).toBe(true);
|
||||
if (!resp.ok) return;
|
||||
const el = document.createElement('div');
|
||||
renderStatusIndicator(el, resp.data);
|
||||
expect(el.textContent).toMatch(/never synced/i);
|
||||
});
|
||||
});
|
||||
@@ -2113,3 +2113,15 @@ textarea {
|
||||
.history-index-row__info { flex: 1; display: flex; flex-direction: column; }
|
||||
.history-index-row__title { color: var(--text); }
|
||||
.history-index-row__meta { font-size: 11px; }
|
||||
|
||||
/* Sidebar-footer vault status indicator (Plan C Phase 6, vault-status.ts).
|
||||
The footer slot + refresh button are wired by vault-sidebar.ts in Task 6.3. */
|
||||
.vault-status {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
font-size: 11px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.vault-status__state { color: var(--text-dim); }
|
||||
.vault-status__ts { color: var(--text-muted); }
|
||||
|
||||
Reference in New Issue
Block a user