Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions docs/devLog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## easy.useSearch.spec

1. new Date() 시스템 시간 값이 이상하다
지금 8월인데 10월로 나온다
이것때문에 dummy event 8월로 만들어두고 하루종일 테스트 통과 안되다가
설마하고 new Date() 콘솔에 찍어보니까 10월이라 열받는다.

```ts
beforeEach(() => {
expect.hasAssertions(); // ? Med: 이걸 왜 써야하는지 물어보자

vi.setSystemTime(new Date('2025-10-01')); // ? Med: 이걸 왜 써야하는지 물어보자
});
```

이것 때문이네!!

## easy.dateUtils.spec

1. getDaysInMonth

```ts
function getDaysInMonth(year: number, month: number): number {
return new Date(year, month, 0).getDate();
}
```

day에 0을 넣음으로써 monthIndex에 넣은 정수의 -1월을 계산한다.

> new Date(2025, 8, 0) -> 여기서 `8`은 `9월`,
> day가 `0`으로 `9월`에서 `-1`을 한 `8월`로 계산됨.
> month param에 `8`을 넣고 결과값도 `8월`로 계산됨.

monthIndex는 0~11로 월을 판단하는데, 우리가 쓰는 1~12월과는 -1씩 차이나기 때문에 moth parameter가 우리가 실사용하는 월로 계산될 수 있다.
함수 제대로 안 보고 막 작성했다가 꽤나 꼬였었음.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"react-dom": "19.1.0"
},
"devDependencies": {
"@eslint/js": "^9.33.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^14.5.2",
Expand All @@ -51,6 +52,7 @@
"eslint-plugin-vitest": "^0.5.4",
"globals": "16.3.0",
"jsdom": "^26.1.0",
"prettier": "^3.6.2",
"typescript": "^5.2.2",
"vite": "^7.0.2",
"vite-plugin-eslint": "^1.8.1",
Expand Down
34 changes: 23 additions & 11 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions src/__mocks__/handlersUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ export const setupMockHandlerUpdating = () => {
const updatedEvent = (await request.json()) as Event;
const index = mockEvents.findIndex((event) => event.id === id);

if (index === -1) {
return HttpResponse.json({ error: 'Event not found' }, { status: 404 });
}

mockEvents[index] = { ...mockEvents[index], ...updatedEvent };
return HttpResponse.json(mockEvents[index]);
})
Expand Down Expand Up @@ -92,3 +96,40 @@ export const setupMockHandlerDeletion = () => {
})
);
};

export const setupMockHandlerCreationFailure = () => {
server.use(
http.get('/api/events', () => {
return HttpResponse.json(null, { status: 500 });
}),
http.post('/api/events', async () => {
return HttpResponse.json(null, { status: 500 });
})
);
};

export const setupMockHandlerDeletionFailure = () => {
const mockEvents: Event[] = [
{
id: '1',
title: '삭제할 이벤트',
date: '2025-10-15',
startTime: '09:00',
endTime: '10:00',
description: '삭제할 이벤트입니다',
location: '어딘가',
category: '기타',
repeat: { type: 'none', interval: 0 },
notificationTime: 10,
},
];

server.use(
http.get('/api/events', () => {
return HttpResponse.json({ events: mockEvents });
}),
http.delete('/api/events/:id', () => {
return new HttpResponse(null, { status: 500 });
})
);
};
65 changes: 1 addition & 64 deletions src/__mocks__/response/realEvents.json
Original file line number Diff line number Diff line change
@@ -1,64 +1 @@
{
"events": [
{
"id": "2b7545a6-ebee-426c-b906-2329bc8d62bd",
"title": "팀 회의",
"date": "2025-08-20",
"startTime": "10:00",
"endTime": "11:00",
"description": "주간 팀 미팅",
"location": "회의실 A",
"category": "업무",
"repeat": { "type": "none", "interval": 0 },
"notificationTime": 1
},
{
"id": "09702fb3-a478-40b3-905e-9ab3c8849dcd",
"title": "점심 약속",
"date": "2025-08-21",
"startTime": "12:30",
"endTime": "13:30",
"description": "동료와 점심 식사",
"location": "회사 근처 식당",
"category": "개인",
"repeat": { "type": "none", "interval": 0 },
"notificationTime": 1
},
{
"id": "da3ca408-836a-4d98-b67a-ca389d07552b",
"title": "프로젝트 마감",
"date": "2025-08-25",
"startTime": "09:00",
"endTime": "18:00",
"description": "분기별 프로젝트 마감",
"location": "사무실",
"category": "업무",
"repeat": { "type": "none", "interval": 0 },
"notificationTime": 1
},
{
"id": "dac62941-69e5-4ec0-98cc-24c2a79a7f81",
"title": "생일 파티",
"date": "2025-08-28",
"startTime": "19:00",
"endTime": "22:00",
"description": "친구 생일 축하",
"location": "친구 집",
"category": "개인",
"repeat": { "type": "none", "interval": 0 },
"notificationTime": 1
},
{
"id": "80d85368-b4a4-47b3-b959-25171d49371f",
"title": "운동",
"date": "2025-08-22",
"startTime": "18:00",
"endTime": "19:00",
"description": "주간 운동",
"location": "헬스장",
"category": "개인",
"repeat": { "type": "none", "interval": 0 },
"notificationTime": 1
}
]
}
{"events":[{"id":"2b7545a6-ebee-426c-b906-2329bc8d62bd","title":"팀 회의","date":"2025-08-20","startTime":"10:00","endTime":"11:00","description":"주간 팀 미팅","location":"회의실 A","category":"업무","repeat":{"type":"none","interval":0},"notificationTime":1},{"id":"09702fb3-a478-40b3-905e-9ab3c8849dcd","title":"점심 약속","date":"2025-08-21","startTime":"12:30","endTime":"13:30","description":"동료와 점심 식사","location":"회사 근처 식당","category":"개인","repeat":{"type":"none","interval":0},"notificationTime":1},{"id":"da3ca408-836a-4d98-b67a-ca389d07552b","title":"프로젝트 마감","date":"2025-08-25","startTime":"09:00","endTime":"18:00","description":"분기별 프로젝트 마감","location":"사무실","category":"업무","repeat":{"type":"none","interval":0},"notificationTime":1},{"id":"dac62941-69e5-4ec0-98cc-24c2a79a7f81","title":"생일 파티","date":"2025-08-28","startTime":"19:00","endTime":"22:00","description":"친구 생일 축하","location":"친구 집","category":"개인","repeat":{"type":"none","interval":0},"notificationTime":1},{"id":"80d85368-b4a4-47b3-b959-25171d49371f","title":"운동","date":"2025-08-22","startTime":"18:00","endTime":"19:00","description":"주간 운동","location":"헬스장","category":"개인","repeat":{"type":"none","interval":0},"notificationTime":1},{"id":"b567e5b4-24dc-42e1-b644-9be03a4d738c","title":"123","date":"2025-08-20","startTime":"10:00","endTime":"11:00","description":"123","location":"123","category":"개인","repeat":{"type":"none","interval":1},"notificationTime":10}]}
86 changes: 76 additions & 10 deletions src/__tests__/hooks/easy.useCalendarView.spec.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,90 @@
import { act, renderHook } from '@testing-library/react';

import { useCalendarView } from '../../hooks/useCalendarView.ts';
import { assertDate } from '../utils.ts';

describe('초기 상태', () => {
it('view는 "month"이어야 한다', () => {});
it('view는 "month"이어야 한다', () => {
const { result } = renderHook(useCalendarView);
expect(result.current.view).toBe('month');
});

it('currentDate는 오늘 날짜인 "2025-10-01"이어야 한다', () => {});
it('currentDate는 오늘 날짜인 "2025-10-01"이어야 한다', () => {
const { result } = renderHook(useCalendarView);
expect(result.current.currentDate).toEqual(new Date('2025-10-01'));
});

it('holidays는 10월 휴일인 개천절, 한글날, 추석이 지정되어 있어야 한다', () => {});
it('holidays는 10월 휴일인 개천절, 한글날, 추석이 지정되어 있어야 한다', () => {
const { result } = renderHook(useCalendarView);
expect(result.current.holidays).toHaveProperty('2025-10-05', '추석');
expect(result.current.holidays).toHaveProperty('2025-10-03', '개천절');
expect(result.current.holidays).toHaveProperty('2025-10-09', '한글날');
});
});

it("view를 'week'으로 변경 시 적절하게 반영된다", () => {});
it("view를 'week'으로 변경 시 적절하게 반영된다", () => {
const { result } = renderHook(useCalendarView);

it("주간 뷰에서 다음으로 navigate시 7일 후 '2025-10-08' 날짜로 지정이 된다", () => {});
act(() => {
result.current.setView('week');
});

it("주간 뷰에서 이전으로 navigate시 7일 후 '2025-09-24' 날짜로 지정이 된다", () => {});
expect(result.current.view).toBe('week');
});

it("주간 뷰에서 다음으로 navigate시 7일 후 '2025-10-08' 날짜로 지정이 된다", () => {
const { result } = renderHook(useCalendarView);

act(() => {
result.current.setView('week');
});

act(() => {
result.current.navigate('next');
});

expect(result.current.currentDate).toEqual(new Date('2025-10-08'));
});

it("주간 뷰에서 이전으로 navigate시 7일 전 '2025-09-24' 날짜로 지정이 된다", () => {
const { result } = renderHook(useCalendarView);

act(() => {
result.current.setView('week');
});

act(() => {
result.current.navigate('prev');
});

expect(result.current.currentDate).toEqual(new Date('2025-09-24'));
});

it("월간 뷰에서 다음으로 navigate시 한 달 후 '2025-11-01' 날짜여야 한다", () => {
const { result } = renderHook(useCalendarView);

act(() => {
result.current.navigate('next');
});

expect(result.current.currentDate).toEqual(new Date('2025-11-01'));
});

it("월간 뷰에서 다음으로 navigate시 한 달 후 '2025-11-01' 날짜여야 한다", () => {});
it("월간 뷰에서 이전으로 navigate시 한 달 전 '2025-09-01' 날짜여야 한다", () => {
const { result } = renderHook(useCalendarView);

it("월간 뷰에서 이전으로 navigate시 한 달 전 '2025-09-01' 날짜여야 한다", () => {});
act(() => {
result.current.navigate('prev');
});

it("currentDate가 '2025-03-01' 변경되면 3월 휴일 '삼일절'로 업데이트되어야 한다", async () => {});
expect(result.current.currentDate).toEqual(new Date('2025-09-01'));
});

it("currentDate가 '2025-03-01' 변경되면 3월 휴일 '삼일절'로 업데이트되어야 한다", async () => {
const { result } = renderHook(useCalendarView);

act(() => {
result.current.setCurrentDate(new Date('2025-03-01'));
});

expect(result.current.holidays).toHaveProperty('2025-03-01', '삼일절');
});
Loading
Loading