Skip to content
Merged
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
5 changes: 4 additions & 1 deletion src/components/auth/AuthForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const FORM_TYPE = {
};

const AuthForm = ({
type, fields, onChange, onSubmit,
type, fields, onChange, onSubmit, error,
}) => {
const formType = FORM_TYPE[type];

Expand Down Expand Up @@ -60,6 +60,9 @@ const AuthForm = ({
onChange={handleChange}
/>
)}
{error && (
<div>{error}</div>
)}
<button
data-testid="auth-button"
type="submit"
Expand Down
34 changes: 27 additions & 7 deletions src/containers/auth/RegisterFormContainer.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import React, { useCallback, useEffect } from 'react';
import React, { useCallback, useEffect, useState } from 'react';

import { useUnmount } from 'react-use';
import { useHistory } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';

import { get } from '../../util/utils';
import { ERROR_MESSAGE, FIREBASE_AUTH_ERROR_MESSAGE } from '../../util/messages';
import { get, isCheckValidate } from '../../util/utils';
import {
changeAuthField, clearAuth, clearAuthFields, requestRegister,
} from '../../reducers/slice';

import AuthForm from '../../components/auth/AuthForm';

const { NO_INPUT, NOT_MATCH_PASSWORD, FAILURE_REGISTER } = ERROR_MESSAGE;

const RegisterFormContainer = () => {
const [error, setError] = useState(null);

const dispatch = useDispatch();
const history = useHistory();

Expand All @@ -30,11 +35,23 @@ const RegisterFormContainer = () => {
);
}, [dispatch]);

const onSubmit = useCallback(() => {
// TODO: 회원가입 validation 체크 로직 추가
const onSubmit = () => {
const { userEmail, password, passwordConfirm } = register;

if (isCheckValidate([userEmail, password, passwordConfirm])) {
setError(NO_INPUT);
return;
}

if (password !== passwordConfirm) {
setError(NOT_MATCH_PASSWORD);
dispatch(changeAuthField({ form: 'register', name: 'password', value: '' }));
dispatch(changeAuthField({ form: 'register', name: 'passwordConfirm', value: '' }));
return;
}

dispatch(requestRegister());
}, [dispatch]);
};

useEffect(() => {
if (user) {
Expand All @@ -48,8 +65,10 @@ const RegisterFormContainer = () => {
}

if (authError) {
// TODO: error 처리 추가
console.error(authError);
setError(
FIREBASE_AUTH_ERROR_MESSAGE[authError]
|| FAILURE_REGISTER,
);
}
}, [auth, authError]);

Expand All @@ -61,6 +80,7 @@ const RegisterFormContainer = () => {
return (
<AuthForm
type="register"
error={error}
fields={register}
onChange={onChangeRegisterField}
onSubmit={onSubmit}
Expand Down
110 changes: 98 additions & 12 deletions src/containers/auth/RegisterFormContainer.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ describe('RegisterFormContainer', () => {
user: given.user,
auth: given.auth,
authError: given.authError,
register: {
userEmail: '',
password: '',
passwordConfirm: '',
},
register: given.register,
}));
});

Expand All @@ -44,6 +40,12 @@ describe('RegisterFormContainer', () => {
));

it('renders register form text', () => {
given('register', () => ({
userEmail: '',
password: '',
passwordConfirm: '',
}));

const { container, getByPlaceholderText } = renderRegisterFormContainer();

expect(container).toHaveTextContent('회원가입');
Expand All @@ -54,6 +56,12 @@ describe('RegisterFormContainer', () => {

describe('action dispatch in register page', () => {
it('change event calls dispatch', () => {
given('register', () => ({
userEmail: '',
password: '',
passwordConfirm: '',
}));

const { getByPlaceholderText } = renderRegisterFormContainer();

const inputs = [
Expand All @@ -80,20 +88,87 @@ describe('RegisterFormContainer', () => {
});
});

it('submit event calls dispatch', () => {
const { getByTestId } = renderRegisterFormContainer();
context('without validation error', () => {
given('register', () => ({
userEmail: 'seungmin@example.com',
password: '123456',
passwordConfirm: '123456',
}));

it('submit event calls dispatch', () => {
const { getByTestId } = renderRegisterFormContainer();

const button = getByTestId('auth-button');
const button = getByTestId('auth-button');

expect(button).not.toBeNull();
expect(button).not.toBeNull();

fireEvent.submit(button);
fireEvent.submit(button);

expect(dispatch).toBeCalled();
expect(dispatch).toBeCalled();
});
});

context('with validation check error', () => {
describe('When there is something that has not been entered', () => {
given('register', () => ({
userEmail: '',
password: '',
passwordConfirm: '',
}));

it('renders error message "There are some items that have not been entered."', () => {
const { getByTestId, container } = renderRegisterFormContainer();

const button = getByTestId('auth-button');

expect(button).not.toBeNull();

fireEvent.submit(button);

expect(dispatch).not.toBeCalled();

expect(container).toHaveTextContent('입력이 안된 사항이 있습니다.');
});
});

describe('When the password and password confirmation value are different', () => {
given('register', () => ({
userEmail: 'seungmin@example.com',
password: '1234561',
passwordConfirm: '1232456',
}));

it('renders error message "The password is different."', () => {
const { getByTestId, container } = renderRegisterFormContainer();

const button = getByTestId('auth-button');

expect(button).not.toBeNull();

fireEvent.submit(button);

expect(dispatch).toBeCalledWith({
payload: {
form: 'register',
name: 'password',
value: '',
},
type: 'application/changeAuthField',
});

expect(container).toHaveTextContent('비밀번호가 일치하지 않습니다.');
});
});
});
});

describe('actions after signing up', () => {
given('register', () => ({
userEmail: '',
password: '',
passwordConfirm: '',
}));

context('when success auth to register', () => {
given('auth', () => ({
auth: 'seungmin@naver.com',
Expand All @@ -106,15 +181,26 @@ describe('RegisterFormContainer', () => {
});
});

// TODO: 현재 authError는 콘솔 출력
context('when failure auth to register', () => {
given('authError', () => ({
authError: 'error',
}));

it('renders error message', () => {
const { container } = renderRegisterFormContainer();

expect(container).toHaveTextContent('회원가입에 실패하였습니다.');
});
});
});

describe('action after login', () => {
given('register', () => ({
userEmail: '',
password: '',
passwordConfirm: '',
}));

given('user', () => ({
user: 'seungmin@naver.com',
}));
Expand Down
15 changes: 8 additions & 7 deletions src/containers/write/WriteButtonsContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import React, { useEffect, useCallback, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';

import { get } from '../../util/utils';
import { ERROR_MESSAGE } from '../../util/messages';
import { get, isCheckValidate } from '../../util/utils';
import { writeStudyGroup } from '../../reducers/slice';

import WriteButtons from '../../components/write/WriteButtons';

const checkTrim = (value) => value.trim();
const isCheckApplyEndDate = (applyDate) => Date.now() - applyDate >= 0;

const isCheckValidate = (values) => values.map(checkTrim).includes('');
const { NO_INPUT, NO_TAG, FAST_APPLY_DEADLINE } = ERROR_MESSAGE;

const WriteButtonsContainer = () => {
const [error, setError] = useState(null);
Expand All @@ -29,17 +30,17 @@ const WriteButtonsContainer = () => {

const onSubmit = () => {
if (isCheckValidate([title, applyEndDate, personnel])) {
setError('입력이 안된 사항이 있습니다.');
setError(NO_INPUT);
return;
}

if (!tags.length) {
setError('태그를 입력하세요.');
setError(NO_TAG);
return;
}

if (Date.now() - applyEndTime >= 0) {
setError('접수 마감날짜가 현재 시간보다 빠릅니다.');
if (isCheckApplyEndDate(applyEndTime)) {
setError(FAST_APPLY_DEADLINE);
return;
}

Expand Down
13 changes: 13 additions & 0 deletions src/util/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const ERROR_MESSAGE = {
NO_INPUT: '입력이 안된 사항이 있습니다.',
NOT_MATCH_PASSWORD: '비밀번호가 일치하지 않습니다.',
NO_TAG: '태그를 입력하세요.',
FAST_APPLY_DEADLINE: '접수 마감날짜가 현재 시간보다 빠릅니다.',
FAILURE_REGISTER: '회원가입에 실패하였습니다.',
};

export const FIREBASE_AUTH_ERROR_MESSAGE = {
'auth/email-already-in-use': '이미 가입된 사용자입니다.',
'auth/weak-password': '6자리 이상의 비밀번호를 입력하세요.',
'auth/too-many-requests': '잠시 후 다시 시도해 주세요.',
};
4 changes: 4 additions & 0 deletions src/util/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ export function equal(key, value) {
export const isCheckedTimeStatus = ({
time, applyEndTime, participants, personnel,
}) => (!!((time - applyEndTime >= 0 || participants.length === parseInt(personnel, 10))));

const checkTrim = (value) => value.trim();

export const isCheckValidate = (values) => values.map(checkTrim).includes('');