Extract dashboard InboxPanel component (#62)
* review: harden readonly git checks and lint verification * test: satisfy readonly reviewer sandbox typing * test: fix readonly reviewer sandbox assertions * test: remove impossible readonly sandbox guards * test: relax readonly sandbox assertions * test: cast readonly sandbox expectation shape * test: cast readonly sandbox expectation through unknown * Phase 0 — STEP_DONE/TASK_DONE split + owner-follow-up integration smoke * Add STEP_DONE guards, verdict storage, and stale delivery suppression * style: format paired stepdone telemetry files * Route STEP_DONE through reviewer * Add structured Discord attachments * style: format structured attachment test * Fix room thread bot output parity * Remove duplicate work item attachment migration from owner branch * Remove legacy dashboard rooms renderer * Extract dashboard parsed body renderer * Extract dashboard redaction helpers * Extract dashboard RoomCardV2 component * Include RoomCardV2 test in vitest suite * Extract dashboard RoomBoardV2 component * Extract dashboard EmptyState component * Extract dashboard InboxPanel component * Split dashboard InboxPanel card renderer
This commit is contained in:
82
apps/dashboard/src/InboxPanel.test.ts
Normal file
82
apps/dashboard/src/InboxPanel.test.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { createElement } from 'react';
|
||||
import { renderToStaticMarkup } from 'react-dom/server';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import type { DashboardOverview } from './api';
|
||||
import { InboxPanel, type InboxPanelProps } from './InboxPanel';
|
||||
import { messages } from './i18n';
|
||||
|
||||
const t = messages.en;
|
||||
|
||||
function overview(inbox: DashboardOverview['inbox']): DashboardOverview {
|
||||
return {
|
||||
generatedAt: '2026-04-28T04:00:00.000Z',
|
||||
inbox,
|
||||
operations: { serviceRestarts: [] },
|
||||
rooms: { active: 0, inactive: 0, total: 0, waiting: 0 },
|
||||
services: [],
|
||||
tasks: {
|
||||
active: 0,
|
||||
completed: 0,
|
||||
paused: 0,
|
||||
total: 0,
|
||||
watchers: { active: 0, completed: 0, paused: 0 },
|
||||
},
|
||||
usage: { fetchedAt: null, rows: [] },
|
||||
};
|
||||
}
|
||||
|
||||
const inboxItem: DashboardOverview['inbox'][number] = {
|
||||
createdAt: '2026-04-28T03:55:00.000Z',
|
||||
groupFolder: 'eyejokerdb',
|
||||
groupKey: 'paired:room-1',
|
||||
id: 'inbox-1',
|
||||
kind: 'reviewer-request',
|
||||
lastOccurredAt: '2026-04-28T03:59:00.000Z',
|
||||
occurrences: 2,
|
||||
occurredAt: '2026-04-28T03:58:00.000Z',
|
||||
roomJid: 'room-1',
|
||||
roomName: 'eyejokerdb-main',
|
||||
severity: 'warn',
|
||||
source: 'paired-task',
|
||||
summary: '<internal>hidden</internal>Reviewer needs action',
|
||||
title: '<internal>hidden</internal>Review requested',
|
||||
};
|
||||
|
||||
const baseProps: InboxPanelProps = {
|
||||
inboxActionKey: null,
|
||||
locale: 'en',
|
||||
onInboxAction: () => {},
|
||||
onTaskAction: () => {},
|
||||
overview: overview([inboxItem]),
|
||||
taskActionKey: null,
|
||||
tasks: [],
|
||||
t,
|
||||
};
|
||||
|
||||
describe('InboxPanel', () => {
|
||||
it('renders inbox summary, filters, and paired task actions', () => {
|
||||
const html = renderToStaticMarkup(
|
||||
createElement(InboxPanel, { ...baseProps }),
|
||||
);
|
||||
|
||||
expect(html).toContain(t.inbox.summary);
|
||||
expect(html).toContain('Review requested');
|
||||
expect(html).toContain('Reviewer needs action');
|
||||
expect(html).toContain(t.inbox.actions.runReview);
|
||||
expect(html).toContain(t.inbox.actions.decline);
|
||||
expect(html).toContain(t.inbox.actions.dismiss);
|
||||
expect(html).not.toContain('internal');
|
||||
});
|
||||
|
||||
it('renders empty state when no inbox items exist', () => {
|
||||
const html = renderToStaticMarkup(
|
||||
createElement(InboxPanel, {
|
||||
...baseProps,
|
||||
overview: overview([]),
|
||||
}),
|
||||
);
|
||||
|
||||
expect(html).toContain(t.inbox.empty);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user