feat(v029): 헤더 4탭 (Inbox/완료/보관/휴지통) + count badge
- App.tsx: 기존 2탭 (Inbox/휴지통) → 4탭. setView/counts 사용.
- onNavigate 도 setView 로 위임 (mirror state 동기 갱신).
- App.test: 4탭 렌더 + 클릭 → setView('completed') + aria-pressed (3 cases).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,8 @@ import { render, screen, fireEvent, cleanup, waitFor } from '@testing-library/re
|
||||
vi.mock('../../src/renderer/inbox/api.js', () => ({
|
||||
inboxApi: {
|
||||
listNotes: vi.fn(async () => []),
|
||||
listByStatus: vi.fn(async () => []),
|
||||
countsByStatus: vi.fn(async () => ({ active: 0, completed: 0, archived: 0, trashed: 0 })),
|
||||
getContinuity: vi.fn(async () => ({
|
||||
weekStart: '', weekCount: 0, weekTarget: 7,
|
||||
consecutiveCompleteWeeks: 0, showRecoveryToast: false, lastNoteAt: null
|
||||
@@ -58,7 +60,12 @@ import { inboxApi } from '../../src/renderer/inbox/api.js';
|
||||
describe('App — settings view', () => {
|
||||
beforeEach(() => {
|
||||
cleanup();
|
||||
useInbox.setState({ showSettings: false, notes: [], trashNotes: [], trashCount: 0 });
|
||||
useInbox.setState({
|
||||
view: 'inbox',
|
||||
counts: { active: 0, completed: 0, archived: 0, trashed: 0 },
|
||||
showSettings: false, showTrash: false,
|
||||
notes: [], trashNotes: [], trashCount: 0
|
||||
});
|
||||
});
|
||||
|
||||
it('renders SettingsPage when showSettings=true', async () => {
|
||||
@@ -89,3 +96,38 @@ describe('App — settings view', () => {
|
||||
await waitFor(() => expect(useInbox.getState().showSettings).toBe(true));
|
||||
});
|
||||
});
|
||||
|
||||
describe('App header — 4 tabs', () => {
|
||||
beforeEach(() => {
|
||||
cleanup();
|
||||
useInbox.setState({
|
||||
view: 'inbox',
|
||||
counts: { active: 5, completed: 3, archived: 2, trashed: 1 },
|
||||
notes: [], trashNotes: [], trashCount: 0,
|
||||
showTrash: false, showSettings: false
|
||||
});
|
||||
});
|
||||
|
||||
it('renders 4 tabs with counts', () => {
|
||||
render(<App />);
|
||||
expect(screen.getByRole('button', { name: /Inbox\(5\)/ })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /완료\(3\)/ })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /보관\(2\)/ })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: /휴지통\(1\)/ })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('clicking 완료 tab sets view=completed', () => {
|
||||
render(<App />);
|
||||
fireEvent.click(screen.getByRole('button', { name: /완료/ }));
|
||||
expect(useInbox.getState().view).toBe('completed');
|
||||
});
|
||||
|
||||
it('aria-pressed reflects current view', () => {
|
||||
useInbox.setState({ view: 'archived' });
|
||||
render(<App />);
|
||||
const archivedBtn = screen.getByRole('button', { name: /보관/ });
|
||||
expect(archivedBtn.getAttribute('aria-pressed')).toBe('true');
|
||||
const inboxBtn = screen.getByRole('button', { name: /Inbox/ });
|
||||
expect(inboxBtn.getAttribute('aria-pressed')).toBe('false');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user