Skip to content

Commit

Permalink
Merge pull request kakao-tech-campus-2nd-step3#150 from KimJi-An/test/k…
Browse files Browse the repository at this point in the history
…akao-tech-campus-2nd-step3#148

Test/kakao-tech-campus-2nd-step3#148 외국인 등록 번호 및 비자 발급 일자 등록 폼, Header 테스트 코드 구현
  • Loading branch information
YIMSEBIN authored Nov 14, 2024
2 parents 07f5dd2 + d287a20 commit 7d40dc6
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 8 deletions.
1 change: 1 addition & 0 deletions package-lock.json

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

10 changes: 5 additions & 5 deletions src/assets/translator/RegisterVisa/registerVisaData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Languages } from '../Languages';

export const registerVisaData = {
[Languages.KO]: {
title: '외국인 번호 및 비자 발급 일자 등록',
title: '외국인 등록 번호 및 비자 발급 일자 등록',
labels: {
foreigner_number: '외국인 번호',
foreigner_number: '외국인 등록 번호',
visa_generate_date: '비자 발급 일자',
},
error_message: '올바른 형식으로 입력해주세요. (형식: 000000-0000000)',
Expand All @@ -13,10 +13,10 @@ export const registerVisaData = {
button: '확인',
},
[Languages.VE]: {
title: 'Đăng ký số người nước ngoài và ngày cấp thị thực',
title: 'Đăng ký số đăng ký người nước ngoài và ngày cấp visa',
labels: {
foreigner_number: 'Số người nước ngoài',
visa_generate_date: 'Ngày cấp thị thực',
foreigner_number: 'số đăng ký người nước ngoài',
visa_generate_date: 'ngày cấp visa',
},
error_message: 'Vui lòng nhập đúng định dạng. (định dạng: 000000-0000000)',
submit: 'Đăng ký',
Expand Down
68 changes: 68 additions & 0 deletions src/features/layout/Header/__test__/Header.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { renderWithProviders } from '@/__test__/test-utils';
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
import Header from '..';
import { fireEvent, screen } from '@testing-library/react';
import { server } from '@/mocks/server';
import { useNavigate } from 'react-router-dom';
import ROUTE_PATH from '@/routes/path';
import { userLocalStorage } from '@/utils/storage';
import { UserData } from '@/types';

const mockEmployeeUser = { type: 'employee', profileImage: 'userProfileImage', name: 'userName' } as UserData;
const mockEmployerUser = { type: 'employer', profileImage: 'employerProfileImage', name: 'employerName' } as UserData;

vi.mock('react-router-dom', async () => {
const actual = await vi.importActual('react-router-dom');
return {
...actual,
useNavigate: vi.fn(),
};
});

describe('Header 테스트', () => {
const mockNavigate = vi.fn();

beforeAll(() => {
server.listen();
vi.mocked(useNavigate).mockImplementation(() => mockNavigate);
});
afterEach(() => {
server.resetHandlers();
vi.clearAllMocks();
});
afterAll(() => server.close());

beforeEach(() => {
vi.clearAllMocks();
});

it('로고 클릭 시 홈페이지로 이동한다', () => {
renderWithProviders(<Header />);
const logo = document.querySelector('.logo');
expect(logo).not.toBeNull();
fireEvent.click(logo!);
expect(mockNavigate).toHaveBeenCalledWith(ROUTE_PATH.HOME);
});

it('로컬 스토리지에 저장된 사용자의 타입이 employee이면 근로자 마이페이지로 이동한다', () => {
vi.spyOn(userLocalStorage, 'getUser').mockReturnValue(mockEmployeeUser);

renderWithProviders(<Header />);

const profileImage = screen.getByTestId('profile');
fireEvent.click(profileImage);

expect(mockNavigate).toHaveBeenCalledWith(ROUTE_PATH.EMPLOYEE.EMPLOYEE_PAGE);
});

it('로컬 스토리지에 저장된 사용자의 타입이 employer이면 고용주 마이페이지로 이동한다', () => {
vi.spyOn(userLocalStorage, 'getUser').mockReturnValue(mockEmployerUser);

renderWithProviders(<Header />);

const profileImage = screen.getByTestId('profile');
fireEvent.click(profileImage);

expect(mockNavigate).toHaveBeenCalledWith(ROUTE_PATH.MY_PAGE.EMPLOYER);
});
});
13 changes: 10 additions & 3 deletions src/features/layout/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ export default function Header() {
userLocalStorage.removeToken();
userLocalStorage.removeUser();
setUser(undefined);
navigate(ROUTE_PATH.HOME);
startTransition(() => {
navigate(ROUTE_PATH.HOME);
});
};

const goToMyPage = () => {
Expand All @@ -46,7 +48,7 @@ export default function Header() {
return (
<HeaderContainer>
<Flex justifyContent="space-between" alignItems="center" css={flexStyle}>
<LogoImg onClick={goToHome} />
<LogoImg className="logo" onClick={goToHome} />
<Flex justifyContent="flex-end" css={menuIconStyle} onClick={toggleMenu}>
{menuOpen ? <CloseIcon /> : <MenuIcon />}
</Flex>
Expand All @@ -59,7 +61,12 @@ export default function Header() {
) : (
<>
<Flex justifyContent="center" alignItems="center" onClick={goToMyPage}>
<Image url={user.profileImage} size={{ width: '40px', height: '40px' }} css={imageStyle} />
<Image
data-testid="profile"
url={user.profileImage}
size={{ width: '40px', height: '40px' }}
css={imageStyle}
/>
</Flex>
<Button style={customButtonStyle} onClick={logout}>
{t('header.logout')}
Expand Down
2 changes: 2 additions & 0 deletions src/features/registerVisa/VisaRegistrationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export default function VisaRegistrationForm() {
<Form onSubmit={handleSubmit}>
<Flex direction="column" gap={{ y: '10px' }}>
<Input
aria-label={t('registerVisa.labels.foreigner_number')}
label={t('registerVisa.labels.foreigner_number')}
type="text"
value={foreignerIdNumber}
Expand All @@ -66,6 +67,7 @@ export default function VisaRegistrationForm() {
</Flex>
<Flex direction="column" gap={{ y: '10px' }}>
<Input
aria-label={t('registerVisa.labels.visa_generate_date')}
label={t('registerVisa.labels.visa_generate_date')}
type="date"
value={visaGenerateDate}
Expand Down
56 changes: 56 additions & 0 deletions src/features/registerVisa/__test__/VisaRegistrationForm.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { renderWithProviders } from '@/__test__/test-utils';
import { server } from '@/mocks/server';
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
import VisaRegistrationForm from '../VisaRegistrationForm';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { fireEvent, screen, waitFor } from '@testing-library/react';

const queryClient = new QueryClient();

describe('VisaRegistrationForm 테스트', () => {
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

beforeEach(() => {
vi.clearAllMocks();
});

const renderVisaRegistrationForm = () => {
return renderWithProviders(
<QueryClientProvider client={queryClient}>
<VisaRegistrationForm />
</QueryClientProvider>,
);
};

it('외국인 등록 번호와 비자 발급 일자를 올바르게 입력하고 폼을 제출한다', async () => {
const { getByLabelText, getByRole } = renderVisaRegistrationForm();

const foreignerNumberInput = getByLabelText('registerVisa.labels.foreigner_number');
const visaDateInput = getByLabelText('registerVisa.labels.visa_generate_date');

fireEvent.change(foreignerNumberInput, { target: { value: '123456-1234567' } });
fireEvent.change(visaDateInput, { target: { value: '2024-01-01' } });
fireEvent.submit(getByRole('button', { name: 'registerVisa.submit' }));

const completeMessage = await screen.findByText('registerVisa.complete_message');
expect(completeMessage).toBeInTheDocument();
});

it('잘못된 외국인 등록 번호를 입력하면 에러 메시지를 표시하고 버튼이 비활성화된다', async () => {
const { getByLabelText, getByRole } = renderVisaRegistrationForm();
const foreignerNumberInput = getByLabelText('registerVisa.labels.foreigner_number');
const submitButton = getByRole('button', { name: 'registerVisa.submit' });

fireEvent.change(foreignerNumberInput, { target: { value: 'wrong-format' } });
fireEvent.submit(submitButton);

const errorMessage = await screen.findByText('registerVisa.error_message');
expect(errorMessage).toBeInTheDocument();

await waitFor(() => {
expect(submitButton).toBeDisabled();
});
});
});

0 comments on commit 7d40dc6

Please sign in to comment.