Inkling
@@ -103,7 +124,6 @@ export function App(): React.ReactElement {
[
{ key: 'inbox', label: 'Inbox', count: counts.active },
{ key: 'completed', label: '완료', count: counts.completed },
- { key: 'archived', label: '보관', count: counts.archived },
{ key: 'trash', label: '휴지통', count: counts.trashed }
] as const
).map((t) => (
@@ -153,7 +173,7 @@ export function App(): React.ReactElement {
⚙
-
+
{!showTrash && (
<>
{/* AI/만료/회상 배너는 active 노트 컨텍스트 — inbox 탭에서만 노출.
@@ -169,6 +189,7 @@ export function App(): React.ReactElement {
+
>
)}
{tagFilter !== null && (
@@ -237,8 +258,9 @@ export function App(): React.ReactElement {
)}
>
)}
-
+
- >
+
+
);
}
diff --git a/tests/unit/App.test.tsx b/tests/unit/App.test.tsx
index cc9bed1..1079965 100644
--- a/tests/unit/App.test.tsx
+++ b/tests/unit/App.test.tsx
@@ -4,6 +4,9 @@ import '@testing-library/jest-dom/vitest';
import { render, screen, fireEvent, cleanup, waitFor } from '@testing-library/react';
vi.mock('../../src/renderer/inbox/api.js', () => ({
+ notebookApi: {
+ list: vi.fn(async () => [])
+ },
inboxApi: {
listNotes: vi.fn(async () => []),
listByStatus: vi.fn(async () => []),
@@ -66,7 +69,11 @@ vi.mock('../../src/renderer/inbox/api.js', () => ({
// v0.3.1 Cut F — VisionSection 이 AiProviderSection 에 마운트되어 호출.
getVisionModels: vi.fn(async () => ({ models: [], at: null, selected: null })),
setVisionModel: vi.fn(async () => ({ ok: true as const })),
- refreshVisionCache: vi.fn(async () => ({ ok: true as const, models: [] }))
+ refreshVisionCache: vi.fn(async () => ({ ok: true as const, models: [] })),
+ // v0.4 Task 15 — loadPromotionCandidates 초기화 stub.
+ listPromotionCandidates: vi.fn(async () => []),
+ getPromotionDismissedTags: vi.fn(async () => []),
+ getPromotionSnoozeUntil: vi.fn(async () => 0)
}
}));
@@ -81,7 +88,8 @@ describe('App — settings view', () => {
view: 'inbox',
counts: { active: 0, completed: 0, archived: 0, trashed: 0 },
showSettings: false, showTrash: false,
- notes: [], trashNotes: [], trashCount: 0
+ notes: [], trashNotes: [], trashCount: 0,
+ sidebarVisible: false, notebooks: [], promotionCandidates: []
});
});
@@ -114,14 +122,15 @@ describe('App — settings view', () => {
});
});
-describe('App header — 4 tabs', () => {
+describe('App header — 3 tabs (v0.4)', () => {
beforeEach(() => {
cleanup();
useInbox.setState({
view: 'inbox',
counts: { active: 5, completed: 3, archived: 2, trashed: 1 },
notes: [], trashNotes: [], trashCount: 0,
- showTrash: false, showSettings: false
+ showTrash: false, showSettings: false,
+ sidebarVisible: false, notebooks: [], promotionCandidates: []
});
// loadInitial 이 비동기로 counts 를 덮어씀 — onboarding wizard async gate (Task 12) 도입
// 후 render 가 await 후 발생하므로 mock 의 countsByStatus 가 테스트 기대값을 반환하도록 갱신.
@@ -129,35 +138,48 @@ describe('App header — 4 tabs', () => {
vi.mocked(inboxApi.countsByStatus).mockResolvedValue({ active: 5, completed: 3, trashed: 1 });
});
- it('renders 4 tabs with counts', async () => {
+ it('renders 3 tabs (Inbox/완료/휴지통) with counts', async () => {
render(