feat(search): scope 토글 — 이 노트북 / 모든 노트북
SearchBox 에 scope dropdown 추가. 기본 'current' (현재 notebook ID 전달), 'all' 선택 시 notebookId=undefined 로 전체 검색. store.searchNotes opts 인자 추가.
This commit is contained in:
@@ -9,10 +9,13 @@ const { mockSearchNotes, mockClearSearch } = vi.hoisted(() => ({
|
||||
mockClearSearch: vi.fn()
|
||||
}));
|
||||
|
||||
// selectedNotebookId 를 테스트 간 변경할 수 있도록 ref 로 관리.
|
||||
let mockSelectedNotebookId: string | null = 'nb-1';
|
||||
|
||||
vi.mock('../../src/renderer/inbox/store.js', () => ({
|
||||
useInbox: Object.assign(
|
||||
(selector?: (s: { searchQuery: string }) => unknown) => {
|
||||
const state = { searchQuery: '' };
|
||||
(selector?: (s: { searchQuery: string; selectedNotebookId: string | null }) => unknown) => {
|
||||
const state = { searchQuery: '', selectedNotebookId: mockSelectedNotebookId };
|
||||
return selector ? selector(state) : state;
|
||||
},
|
||||
{ getState: () => ({ searchNotes: mockSearchNotes, clearSearch: mockClearSearch }) }
|
||||
@@ -26,6 +29,7 @@ describe('SearchBox', () => {
|
||||
vi.clearAllMocks();
|
||||
cleanup();
|
||||
vi.useFakeTimers();
|
||||
mockSelectedNotebookId = 'nb-1';
|
||||
});
|
||||
|
||||
it('타이핑 → 200ms debounce 후 searchNotes 호출', () => {
|
||||
@@ -34,7 +38,7 @@ describe('SearchBox', () => {
|
||||
fireEvent.change(input, { target: { value: '회의' } });
|
||||
expect(mockSearchNotes).not.toHaveBeenCalled();
|
||||
vi.advanceTimersByTime(200);
|
||||
expect(mockSearchNotes).toHaveBeenCalledWith('회의');
|
||||
expect(mockSearchNotes).toHaveBeenCalledWith('회의', { notebookId: 'nb-1' });
|
||||
});
|
||||
|
||||
it('빈 값 → clearSearch 호출', () => {
|
||||
@@ -44,4 +48,32 @@ describe('SearchBox', () => {
|
||||
vi.advanceTimersByTime(200);
|
||||
expect(mockClearSearch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('기본 scope=current — searchNotes 에 selectedNotebookId 전달', () => {
|
||||
render(<SearchBox />);
|
||||
const input = screen.getByRole('searchbox');
|
||||
fireEvent.change(input, { target: { value: '노트' } });
|
||||
vi.advanceTimersByTime(200);
|
||||
expect(mockSearchNotes).toHaveBeenCalledWith('노트', { notebookId: 'nb-1' });
|
||||
});
|
||||
|
||||
it('scope=all 변경 시 다음 검색에서 notebookId 미전달 (undefined)', () => {
|
||||
render(<SearchBox />);
|
||||
const input = screen.getByRole('searchbox');
|
||||
const scopeSelect = screen.getByRole('combobox', { name: '검색 범위' });
|
||||
|
||||
fireEvent.change(scopeSelect, { target: { value: 'all' } });
|
||||
fireEvent.change(input, { target: { value: '리뷰' } });
|
||||
vi.advanceTimersByTime(200);
|
||||
expect(mockSearchNotes).toHaveBeenCalledWith('리뷰', { notebookId: undefined });
|
||||
});
|
||||
|
||||
it('selectedNotebookId=null 이면 scope=current 에서 notebookId=undefined 전달', () => {
|
||||
mockSelectedNotebookId = null;
|
||||
render(<SearchBox />);
|
||||
const input = screen.getByRole('searchbox');
|
||||
fireEvent.change(input, { target: { value: '테스트' } });
|
||||
vi.advanceTimersByTime(200);
|
||||
expect(mockSearchNotes).toHaveBeenCalledWith('테스트', { notebookId: undefined });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user