|
1 | 1 | import { createTheme, CssBaseline, ThemeProvider } from '@mui/material'; |
2 | | -import { render, screen, within } from '@testing-library/react'; |
| 2 | +import { render, screen, waitFor, within } from '@testing-library/react'; |
3 | 3 | import userEvent, { UserEvent } from '@testing-library/user-event'; |
4 | 4 | import { SnackbarProvider } from 'notistack'; |
5 | 5 | import { ReactElement } from 'react'; |
@@ -363,52 +363,77 @@ describe('반복 일정 기능', () => { |
363 | 363 |
|
364 | 364 | describe('반복 일정 단일 삭제', () => { |
365 | 365 | it('반복 일정 중 하나를 삭제하면 해당 일정만 삭제된다', async () => { |
366 | | - vi.setSystemTime(new Date('2025-08-01')); // 테스트 기준 날짜 |
367 | | - // Given: 기존 이벤트가 존재 |
| 366 | + vi.setSystemTime(new Date('2025-10-01')); // 테스트 기준 날짜 |
| 367 | + |
| 368 | + // Given: 서로 다른 날짜의 반복 일정 2개가 존재 |
368 | 369 | setupMockHandlerRecurryingDeletion(); |
369 | 370 | const { user } = setup(<App />); |
370 | 371 |
|
371 | | - // When: 삭제할 이벤트 클릭 후 삭제 |
372 | | - await user.click(screen.getByText('삭제할 이벤트')); |
373 | | - await user.click(screen.getByRole('button', { name: /삭제/i })); |
| 372 | + // 초기 상태: 두 날짜의 이벤트가 모두 존재함을 확인 |
| 373 | + expect(await screen.findByText('2025-10-15')).toBeInTheDocument(); // 첫 번째 일정 |
| 374 | + expect(await screen.findByText('2025-10-22')).toBeInTheDocument(); // 두 번째 일정 |
374 | 375 |
|
375 | | - // Then: 선택한 이벤트만 삭제되고 화면에서 사라짐 |
376 | | - expect(screen.queryByText('삭제할 이벤트')).not.toBeInTheDocument(); |
| 376 | + // When: 첫 번째 이벤트 삭제 |
377 | 377 | const eventList = within(screen.getByTestId('event-list')); |
378 | | - expect(eventList.getAllByTestId('RepeatIcon')).toHaveLength(1); |
| 378 | + const deleteButtons = await eventList.findAllByTestId('DeleteIcon'); |
| 379 | + await user.click(deleteButtons[0]); |
| 380 | + |
| 381 | + // Then: 첫 번째 일정(2025-10-15)만 삭제되고, 두 번째 일정(2025-10-22)은 남아있음 |
| 382 | + await waitFor(() => { |
| 383 | + expect(eventList.queryByText('2025-10-15')).not.toBeInTheDocument(); // 삭제됨 |
| 384 | + expect(eventList.getByText('2025-10-22')).toBeInTheDocument(); // 남아있음 |
| 385 | + }); |
| 386 | + |
| 387 | + // 전체 이벤트 개수도 2개에서 1개로 감소 |
| 388 | + expect(eventList.queryAllByText('삭제할 이벤트')).toHaveLength(1); |
379 | 389 | }); |
380 | 390 |
|
381 | 391 | it('반복 일정 중 하나를 삭제해도 다른 반복 일정들은 영향받지 않는다', async () => { |
382 | | - vi.setSystemTime(new Date('2025-08-01')); // 테스트 기준 날짜 |
383 | | - // Given: 기존 이벤트 여러 개가 존재 |
| 392 | + vi.setSystemTime(new Date('2025-10-01')); // 테스트 기준 날짜 |
| 393 | + |
| 394 | + // Given: 기존 이벤트 2개가 존재 |
384 | 395 | setupMockHandlerRecurryingDeletion(); |
385 | 396 | const { user } = setup(<App />); |
386 | 397 |
|
| 398 | + const eventList = within(screen.getByTestId('event-list')); |
| 399 | + |
| 400 | + // 초기 상태: 2개의 반복 일정이 존재함을 확인 |
| 401 | + expect(await eventList.findAllByText('삭제할 이벤트')).toHaveLength(2); |
| 402 | + expect(await eventList.findAllByTestId('RepeatIcon')).toHaveLength(2); |
| 403 | + |
387 | 404 | // When: 첫 번째 이벤트 삭제 |
388 | | - await user.click(screen.getByText('삭제할 이벤트')); |
389 | | - await user.click(screen.getByRole('button', { name: /삭제/i })); |
| 405 | + const deleteButtons = await eventList.findAllByTestId('DeleteIcon'); |
| 406 | + await user.click(deleteButtons[0]); |
390 | 407 |
|
391 | | - // Then: 다른 이벤트는 그대로 존재 |
392 | | - expect(screen.getByText('남은 이벤트')).toBeInTheDocument(); |
393 | | - const eventList = within(screen.getByTestId('event-list')); |
394 | | - expect(eventList.getAllByTestId('RepeatIcon')).toHaveLength(1); |
| 408 | + // Then: 하나만 삭제되고 나머지 반복 일정은 그대로 존재 |
| 409 | + await waitFor(() => { |
| 410 | + expect(eventList.queryAllByText('삭제할 이벤트')).toHaveLength(1); |
| 411 | + expect(eventList.queryAllByTestId('RepeatIcon')).toHaveLength(1); |
| 412 | + }); |
395 | 413 | }); |
396 | 414 |
|
397 | 415 | it('단일 삭제된 일정은 캘린더뷰와 리스트뷰에 즉시 반영된다', async () => { |
398 | | - vi.setSystemTime(new Date('2025-08-01')); // 테스트 기준 날짜 |
| 416 | + vi.setSystemTime(new Date('2025-10-01')); // 테스트 기준 날짜 |
399 | 417 | // Given: 삭제할 이벤트 존재 |
400 | 418 | setupMockHandlerRecurryingDeletion(); |
401 | 419 | const { user } = setup(<App />); |
402 | 420 |
|
403 | 421 | // When: 삭제 버튼 클릭 |
404 | | - await user.click(screen.getByText('삭제할 이벤트')); |
405 | | - await user.click(screen.getByRole('button', { name: /삭제/i })); |
| 422 | + const eventList = within(screen.getByTestId('event-list')); |
| 423 | + const deleteButton = await eventList.findAllByTestId('DeleteIcon'); |
| 424 | + await user.click(deleteButton[0]); |
406 | 425 |
|
407 | 426 | // Then: 캘린더뷰와 리스트뷰에서 즉시 삭제 반영 |
408 | 427 | const calendarView = within(screen.getByTestId('month-view')); |
409 | 428 | const listView = within(screen.getByTestId('event-list')); |
410 | | - expect(calendarView.queryAllByRole('img', { name: /repeat-event-icon/i })).toHaveLength(1); |
411 | | - expect(listView.queryAllByRole('img', { name: /repeat-event-icon/i })).toHaveLength(1); |
| 429 | + await waitFor(() => { |
| 430 | + expect(listView.queryAllByText('삭제할 이벤트')).toHaveLength(1); |
| 431 | + }); |
| 432 | + |
| 433 | + // 캘린더뷰에서도 1개만 남아있는지 확인 |
| 434 | + await waitFor(() => { |
| 435 | + expect(calendarView.queryAllByText('삭제할 이벤트')).toHaveLength(1); |
| 436 | + }); |
412 | 437 | }); |
413 | 438 | }); |
414 | 439 | }); |
0 commit comments