65 lines
2.8 KiB
TypeScript
65 lines
2.8 KiB
TypeScript
// @vitest-environment jsdom
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import '@testing-library/jest-dom/vitest';
|
|
import { render, screen, fireEvent, cleanup, waitFor } from '@testing-library/react';
|
|
|
|
const createNotebook = vi.fn(async (): Promise<{ ok: boolean; reason?: string }> => ({ ok: true }));
|
|
|
|
vi.mock('../../src/renderer/inbox/store.js', () => ({
|
|
useInbox: (selector?: (s: { createNotebook: typeof createNotebook }) => unknown) => {
|
|
const state = { createNotebook };
|
|
return selector ? selector(state) : state;
|
|
}
|
|
}));
|
|
|
|
import { NotebookCreateModal } from '../../src/renderer/inbox/components/NotebookCreateModal';
|
|
|
|
describe('NotebookCreateModal', () => {
|
|
beforeEach(() => {
|
|
cleanup();
|
|
createNotebook.mockClear();
|
|
});
|
|
|
|
it('이름 빈 상태에서 "만들기" disabled', () => {
|
|
render(<NotebookCreateModal onClose={() => {}} />);
|
|
const btn = screen.getByRole('button', { name: '만들기' });
|
|
expect(btn).toBeDisabled();
|
|
});
|
|
|
|
it('이름 입력 후 만들기 클릭 → createNotebook 호출 + onClose', async () => {
|
|
const onClose = vi.fn();
|
|
createNotebook.mockResolvedValueOnce({ ok: true });
|
|
render(<NotebookCreateModal onClose={onClose} />);
|
|
fireEvent.change(screen.getByLabelText('노트북 이름'), { target: { value: '회사' } });
|
|
fireEvent.click(screen.getByRole('button', { name: '만들기' }));
|
|
await waitFor(() => expect(createNotebook).toHaveBeenCalledWith('회사', expect.any(String)));
|
|
await waitFor(() => expect(onClose).toHaveBeenCalled());
|
|
});
|
|
|
|
it('duplicate_name reason 시 에러 표시 + onClose 안 됨', async () => {
|
|
const onClose = vi.fn();
|
|
createNotebook.mockResolvedValueOnce({ ok: false, reason: 'duplicate_name' });
|
|
render(<NotebookCreateModal onClose={onClose} />);
|
|
fireEvent.change(screen.getByLabelText('노트북 이름'), { target: { value: '기본' } });
|
|
fireEvent.click(screen.getByRole('button', { name: '만들기' }));
|
|
await waitFor(() => expect(screen.getByText(/이미 있어요/)).toBeInTheDocument());
|
|
expect(onClose).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('overlay 클릭 → onClose', () => {
|
|
const onClose = vi.fn();
|
|
const { container } = render(<NotebookCreateModal onClose={onClose} />);
|
|
fireEvent.click(container.firstChild as HTMLElement);
|
|
expect(onClose).toHaveBeenCalled();
|
|
});
|
|
|
|
it('color palette 클릭 시 선택 색 변경 (border 확인)', () => {
|
|
render(<NotebookCreateModal onClose={() => {}} />);
|
|
const colorBtns = screen.getAllByRole('button').filter((b) => b.getAttribute('aria-label')?.startsWith('색 '));
|
|
expect(colorBtns).toHaveLength(6);
|
|
fireEvent.click(colorBtns[2]!);
|
|
// 선택 색의 border 가 '2px solid #333' 인지 확인
|
|
expect(colorBtns[2]!.style.border).toContain('2px');
|
|
});
|
|
});
|