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
3 changes: 2 additions & 1 deletion src/components/introduce/IntroduceHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const IntroduceHeaderWrapper = styled.div`
`;

const IntroduceHeader = ({
group, onApply, user, realTime, onApplyCancel, onChangeApplyFields, applyFields,
group, onApply, user, realTime, onApplyCancel, onChangeApplyFields, applyFields, clearForm,
}) => {
const [loginCheckModal, setLoginCheckModal] = useState(false);
const [applyCancelModal, setApplyCancelModal] = useState(false);
Expand Down Expand Up @@ -69,6 +69,7 @@ const IntroduceHeader = ({

const handleFormCancel = () => {
setModalForm(false);
clearForm();
};

return (
Expand Down
5 changes: 3 additions & 2 deletions src/components/introduce/IntroduceHeader.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import STUDY_GROUP from '../../../fixtures/study-group';
describe('IntroduceHeader', () => {
const handleApply = jest.fn();
const handleApplyCancel = jest.fn();
const handleClearForm = jest.fn();

beforeEach(() => {
jest.clearAllMocks();
Expand All @@ -18,10 +19,11 @@ describe('IntroduceHeader', () => {
<IntroduceHeader
user={user}
group={group}
applyFields={{ reason: '', wantToGet: '' }}
applyFields={{ reason: 'reason', wantToGet: 'reason' }}
realTime={time}
onApply={handleApply}
onApplyCancel={handleApplyCancel}
clearForm={handleClearForm}
/>
));

Expand Down Expand Up @@ -214,7 +216,6 @@ describe('IntroduceHeader', () => {

fireEvent.click(button);

// TODO: 이 부분은 추후 변경해야된다 현재 스터디 참여 신청서 모달창이 나타남.
fireEvent.click(getByText('확인'));

expect(handleApply).toBeCalled();
Expand Down
38 changes: 35 additions & 3 deletions src/components/introduce/modals/ApplicationFormModal.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';

import styled from '@emotion/styled';

Expand Down Expand Up @@ -96,6 +96,13 @@ const ContentTextareaWrapper = styled.textarea`
&:focus {
border: 2px solid ${palette.teal[5]};
}

${({ error }) => error && css`
&::placeholder {
color: ${palette.warn[1]};
}
border: 2px solid ${palette.warn[1]};
`};
`;

const StyledButton = styled(Button)`
Expand All @@ -107,14 +114,37 @@ const StyledButton = styled(Button)`
const ApplicationFormModal = ({
visible, onCancel, onConfirm, onChangeApply, fields,
}) => {
const [error, setError] = useState(null);

const { reason, wantToGet } = fields;

const handleChange = (e) => {
const { name, value } = e.target;

setError(null);
onChangeApply({ name, value });
};

const handleCancel = () => {
setError(null);
onCancel();
};

const handleConfirm = () => {
if (!reason.trim()) {
setError('reason');
return;
}

if (!wantToGet.trim()) {
setError('wantToGet');
return;
}

setError(null);
onConfirm();
};

if (!visible) {
return null;
}
Expand All @@ -126,6 +156,7 @@ const ApplicationFormModal = ({
<ContentBoxWrapper>
<label htmlFor="apply-reason">신청하게 된 이유</label>
<ContentTextareaWrapper
error={error && error === 'reason'}
rows="10"
id="apply-reason"
name="reason"
Expand All @@ -137,6 +168,7 @@ const ApplicationFormModal = ({
<ContentBoxWrapper>
<label htmlFor="study-want">스터디를 통해 얻고 싶은 것은 무엇인가요?</label>
<ContentTextareaWrapper
error={error && error === 'wantToGet'}
rows="10"
id="study-want"
name="wantToGet"
Expand All @@ -146,8 +178,8 @@ const ApplicationFormModal = ({
/>
</ContentBoxWrapper>
<div className="buttons">
<StyledButton onClick={onCancel}>취소</StyledButton>
<StyledButton success onClick={onConfirm}>확인</StyledButton>
<StyledButton onClick={handleCancel}>취소</StyledButton>
<StyledButton success onClick={handleConfirm}>확인</StyledButton>
</div>
</ModalBoxWrapper>
</ApplicationFormModalWrapper>
Expand Down
106 changes: 77 additions & 29 deletions src/components/introduce/modals/ApplicationFormModal.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ describe('ApplicationFormModal', () => {
const handleConfirm = jest.fn();
const handleChange = jest.fn();

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

const renderApplicationFormModal = ({ visible, fields }) => render((
<ApplicationFormModal
visible={visible}
Expand All @@ -20,50 +24,94 @@ describe('ApplicationFormModal', () => {
));

context('with visible', () => {
const modal = {
visible: true,
fields: {
reason: '',
wantToGet: '',
},
};
context('with applyFields value', () => {
const modal = {
visible: true,
fields: {
reason: 'reason',
wantToGet: 'wantToGet',
},
};

it('renders Modal text', () => {
const { container } = renderApplicationFormModal(modal);
it('renders Modal text', () => {
const { container } = renderApplicationFormModal(modal);

expect(container).toHaveTextContent('스터디 참여 신청서 📚');
expect(container).toHaveTextContent('신청하게 된 이유');
expect(container).toHaveTextContent('스터디를 통해 얻고 싶은 것은 무엇인가요?');
});
expect(container).toHaveTextContent('스터디 참여 신청서 📚');
expect(container).toHaveTextContent('신청하게 된 이유');
expect(container).toHaveTextContent('스터디를 통해 얻고 싶은 것은 무엇인가요?');
});

it('calls confirm event action', () => {
const { getByText } = renderApplicationFormModal(modal);
it('calls confirm event action', () => {
const { getByText } = renderApplicationFormModal(modal);

const button = getByText('확인');
const button = getByText('확인');

fireEvent.click(button);
fireEvent.click(button);

expect(handleConfirm).toBeCalled();
});
expect(handleConfirm).toBeCalled();
});

it('calls cancel event action', () => {
const { getByText } = renderApplicationFormModal(modal);

it('calls cancel event action', () => {
const { getByText } = renderApplicationFormModal(modal);
const button = getByText('취소');

const button = getByText('취소');
fireEvent.click(button);

fireEvent.click(button);
expect(handleCancel).toBeCalled();
});

expect(handleCancel).toBeCalled();
it('change apply form fields', () => {
const { getByLabelText } = renderApplicationFormModal(modal);

const input = getByLabelText('신청하게 된 이유');

fireEvent.change(input, { target: { name: 'reason', value: '내용' } });

expect(handleChange).toBeCalled();
});
});

it('change apply form fields', () => {
const { getByLabelText } = renderApplicationFormModal(modal);
context('without applyFields value', () => {
it("doesn't reason value", () => {
const modal = {
visible: true,
fields: {
reason: '',
wantToGet: 'wantToGet',
},
};

const { getByText, getByLabelText } = renderApplicationFormModal(modal);

const button = getByText('확인');

fireEvent.click(button);

expect(handleConfirm).not.toBeCalled();

expect(getByLabelText('신청하게 된 이유')).toHaveStyle('border: 2px solid #ff8787;');
});

it("doesn't wantToGet value", () => {
const modal = {
visible: true,
fields: {
reason: 'reason',
wantToGet: '',
},
};

const { getByText, getByLabelText } = renderApplicationFormModal(modal);

const button = getByText('확인');

const input = getByLabelText('신청하게 된 이유');
fireEvent.click(button);

fireEvent.change(input, { target: { name: 'reason', value: '내용' } });
expect(handleConfirm).not.toBeCalled();

expect(handleChange).toBeCalled();
expect(getByLabelText('스터디를 통해 얻고 싶은 것은 무엇인가요?')).toHaveStyle('border: 2px solid #ff8787;');
});
});
});

Expand Down
7 changes: 6 additions & 1 deletion src/containers/introduce/IntroduceContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useDispatch, useSelector } from 'react-redux';

import { getAuth, getGroup } from '../../util/utils';
import {
changeApplyFields, deleteParticipant, loadStudyGroup, updateParticipant,
changeApplyFields, clearApplyFields, deleteParticipant, loadStudyGroup, updateParticipant,
} from '../../reducers/groupSlice';

import StudyIntroduceForm from '../../components/introduce/StudyIntroduceForm';
Expand Down Expand Up @@ -41,6 +41,10 @@ const IntroduceContainer = ({ groupId }) => {
dispatch(changeApplyFields({ name, value }));
}, [dispatch]);

const clearApplyForm = useCallback(() => {
dispatch(clearApplyFields());
}, [dispatch]);

if (!group) {
return (
<GroupContentLoader />
Expand All @@ -56,6 +60,7 @@ const IntroduceContainer = ({ groupId }) => {
applyFields={applyFields}
onApply={onApplyStudy}
onApplyCancel={onApplyCancel}
clearForm={clearApplyForm}
onChangeApplyFields={onChangeApplyFields}
/>
<StudyIntroduceForm
Expand Down
5 changes: 2 additions & 3 deletions src/containers/introduce/IntroduceContainer.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ describe('IntroduceContainer', () => {
given('group', () => (STUDY_GROUP));
given('user', () => ('user'));
given('applyFields', () => ({
reason: '',
wantToGet: '',
reason: 'reason',
wantToGet: 'wantToGet',
}));

it('click event dispatches action call updateParticipant', () => {
Expand All @@ -101,7 +101,6 @@ describe('IntroduceContainer', () => {

fireEvent.click(button);

// TODO: 이 부분은 추후 수정해야된다. 현재 스터디 참여 신청서 모달창으로 인해 테스트 fail되기 때문에 변경해놈
fireEvent.click(getByText('확인'));

expect(dispatch).toBeCalledTimes(2);
Expand Down
9 changes: 9 additions & 0 deletions src/reducers/groupSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ const { actions, reducer } = createSlice({
draft.applyFields[name] = value;
});
},

clearApplyFields(state) {
return {
...state,
applyFields: applyInitialState,
};
},
},
});

Expand All @@ -86,6 +93,7 @@ export const {
clearWriteFields,
successWrite,
changeApplyFields,
clearApplyFields,
} = actions;

export const loadStudyGroups = (tag) => async (dispatch) => {
Expand Down Expand Up @@ -142,6 +150,7 @@ export const updateParticipant = ({ reason, wantToGet }) => async (dispatch, get
});

dispatch(setStudyGroup(newGroup));
dispatch(clearApplyFields());
};

export const deleteParticipant = () => async (dispatch, getState) => {
Expand Down
22 changes: 21 additions & 1 deletion src/reducers/groupSlice.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import reducer, {
updateParticipant,
deleteParticipant,
changeApplyFields,
clearApplyFields,
} from './groupSlice';

import STUDY_GROUPS from '../../fixtures/study-groups';
Expand Down Expand Up @@ -151,6 +152,24 @@ describe('reducer', () => {
expect(state.applyFields.reason).toBe('참여합니다.');
});
});

describe('clearApplyFields', () => {
const initialState = {
applyFields: {
reason: '타이틀',
wantToGet: '내용',
},
};

it('clears fields of application', () => {
const state = reducer(initialState, clearApplyFields());

const { applyFields: { reason, wantToGet } } = state;

expect(reason).toBe('');
expect(wantToGet).toBe('');
});
});
});

describe('async actions', () => {
Expand Down Expand Up @@ -237,7 +256,7 @@ describe('async actions', () => {
wantToGet: '원하는 것',
};

it('dispatches setStudyGroup', async () => {
it('dispatches setStudyGroup and clearApplyFields', async () => {
await store.dispatch(updateParticipant(applyFields));

const actions = store.getActions();
Expand All @@ -250,6 +269,7 @@ describe('async actions', () => {
confirm: false,
}],
}));
expect(actions[1]).toEqual(clearApplyFields());
});
});

Expand Down