diff --git a/src/App.test.jsx b/src/App.test.jsx
index 3d85f28..e15f2d3 100644
--- a/src/App.test.jsx
+++ b/src/App.test.jsx
@@ -34,6 +34,10 @@ describe('App', () => {
reason: '',
wantToGet: '',
},
+ studyReviewFields: {
+ rating: 3,
+ review: '',
+ },
},
authReducer: {
register: {
diff --git a/src/components/introduce/StudyReviewForm.jsx b/src/components/introduce/StudyReviewForm.jsx
index 39cb278..77d77f2 100644
--- a/src/components/introduce/StudyReviewForm.jsx
+++ b/src/components/introduce/StudyReviewForm.jsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React from 'react';
import styled from '@emotion/styled';
@@ -44,11 +44,15 @@ const StudyReviewFormButton = styled(Button)`
const isValidateUserInfo = (user) => (participants) => !!participants
.find(({ id, confirm }) => id === user && confirm && confirm === true);
-const StudyReviewForm = ({ group, user, time }) => {
+const StudyReviewForm = ({
+ group, user, time, fields, onChangeReview,
+}) => {
const {
participants, personnel, applyEndDate,
} = group;
+ const { rating, review } = fields;
+
const applyEndTime = changeDateToTime(applyEndDate);
const valid = {
@@ -59,10 +63,20 @@ const StudyReviewForm = ({ group, user, time }) => {
return null;
}
- const [rating, setRating] = useState(0);
+ const handleChangeRating = (newRating, name) => {
+ onChangeReview({
+ name,
+ value: newRating,
+ });
+ };
+
+ const handleChangeReview = (event) => {
+ const { name, value } = event.target;
- const changeRating = (newRating) => {
- setRating(newRating);
+ onChangeReview({
+ name,
+ value,
+ });
};
return (
@@ -76,7 +90,7 @@ const StudyReviewForm = ({ group, user, time }) => {
starDimension="35px"
starSpacing="0"
starHoverColor="#ffc816"
- changeRating={changeRating}
+ changeRating={handleChangeRating}
name="rating"
/>
@@ -84,7 +98,10 @@ const StudyReviewForm = ({ group, user, time }) => {
후기 등록하기
diff --git a/src/components/introduce/StudyReviewForm.test.jsx b/src/components/introduce/StudyReviewForm.test.jsx
index d68672c..dda62cb 100644
--- a/src/components/introduce/StudyReviewForm.test.jsx
+++ b/src/components/introduce/StudyReviewForm.test.jsx
@@ -1,6 +1,6 @@
import React from 'react';
-import { render } from '@testing-library/react';
+import { render, fireEvent } from '@testing-library/react';
import StudyReviewForm from './StudyReviewForm';
@@ -8,11 +8,19 @@ import { yesterday } from '../../util/utils';
import STUDY_GROUP from '../../../fixtures/study-group';
describe('StudyReviewForm', () => {
- const renderStudyReviewForm = ({ group, time, user }) => render((
+ const handleChange = jest.fn();
+
+ const reviewForm = { rating: 3, review: '' };
+
+ const renderStudyReviewForm = ({
+ group, time, user, fields = reviewForm,
+ }) => render((
));
@@ -33,9 +41,25 @@ describe('StudyReviewForm', () => {
participants: [{ id: 'user1', confirm: true }],
user: 'user1',
}));
-
expect(container).toHaveTextContent('스터디 후기를 작성해주세요!');
});
+ it('call event change review form', () => {
+ const { getByPlaceholderText } = renderStudyReviewForm(userStatusSetting({
+ participants: [{ id: 'user1', confirm: true }],
+ user: 'user1',
+ }));
+
+ const textarea = getByPlaceholderText('후기를 입력해주세요!');
+
+ fireEvent.change(textarea, {
+ target: {
+ name: 'review',
+ value: 'test',
+ },
+ });
+
+ expect(handleChange).toBeCalled();
+ });
});
describe('When the user is not approved applicant', () => {
diff --git a/src/containers/introduce/StudyReviewContainer.jsx b/src/containers/introduce/StudyReviewContainer.jsx
index 244aa4c..8b3f478 100644
--- a/src/containers/introduce/StudyReviewContainer.jsx
+++ b/src/containers/introduce/StudyReviewContainer.jsx
@@ -1,22 +1,30 @@
-import React, { useState } from 'react';
+import React, { useState, useCallback } from 'react';
-import { useSelector } from 'react-redux';
+import { useSelector, useDispatch } from 'react-redux';
import { useInterval } from 'react-use';
import { getAuth, getGroup } from '../../util/utils';
import StudyReviewForm from '../../components/introduce/StudyReviewForm';
+import { changeStudyReviewFields } from '../../reducers/groupSlice';
const StudyReviewContainer = () => {
const [realTime, setRealTime] = useState(Date.now());
- const group = useSelector(getGroup('group'));
+ const dispatch = useDispatch();
+
const user = useSelector(getAuth('user'));
+ const group = useSelector(getGroup('group'));
+ const studyReviewFields = useSelector(getGroup('studyReviewFields'));
useInterval(() => {
setRealTime(Date.now());
}, 1000);
+ const onChangeReviewFields = useCallback(({ name, value }) => {
+ dispatch(changeStudyReviewFields({ name, value }));
+ }, [dispatch]);
+
if (!group) {
return null;
}
@@ -26,6 +34,8 @@ const StudyReviewContainer = () => {
user={user}
group={group}
time={realTime}
+ fields={studyReviewFields}
+ onChangeReview={onChangeReviewFields}
/>
);
};
diff --git a/src/containers/introduce/StudyReviewContainer.test.jsx b/src/containers/introduce/StudyReviewContainer.test.jsx
index a828b20..d3643d3 100644
--- a/src/containers/introduce/StudyReviewContainer.test.jsx
+++ b/src/containers/introduce/StudyReviewContainer.test.jsx
@@ -1,8 +1,8 @@
import React from 'react';
-import { useSelector } from 'react-redux';
+import { useSelector, useDispatch } from 'react-redux';
-import { render } from '@testing-library/react';
+import { render, fireEvent } from '@testing-library/react';
import StudyReviewContainer from './StudyReviewContainer';
@@ -10,10 +10,20 @@ import STUDY_GROUP from '../../../fixtures/study-group';
import { yesterday } from '../../util/utils';
describe('StudyReviewContainer', () => {
+ const dispatch = jest.fn();
+
beforeEach(() => {
+ dispatch.mockClear();
+
+ useDispatch.mockImplementation(() => dispatch);
+
useSelector.mockImplementation((state) => state({
groupReducer: {
group: given.group,
+ studyReviewFields: {
+ rating: 3,
+ review: '',
+ },
},
authReducer: {
user: given.user,
@@ -43,6 +53,24 @@ describe('StudyReviewContainer', () => {
expect(container).toHaveTextContent('스터디 후기를 작성해주세요!');
});
});
+
+ it('dispatch actions call changeStudyReviewFields', () => {
+ const form = {
+ name: 'review',
+ value: '후기입니다.',
+ };
+
+ const { getByPlaceholderText } = renderStudyReviewContainer();
+
+ const textarea = getByPlaceholderText('후기를 입력해주세요!');
+
+ fireEvent.change(textarea, { target: form });
+
+ expect(dispatch).toBeCalledWith({
+ type: 'group/changeStudyReviewFields',
+ payload: form,
+ });
+ });
});
context('without login and group', () => {
diff --git a/src/pages/IntroducePage.test.jsx b/src/pages/IntroducePage.test.jsx
index 9eb380c..4a39c34 100644
--- a/src/pages/IntroducePage.test.jsx
+++ b/src/pages/IntroducePage.test.jsx
@@ -34,6 +34,10 @@ describe('IntroducePage', () => {
reason: '',
wantToGet: '',
},
+ studyReviewFields: {
+ rating: 3,
+ review: '',
+ },
},
authReducer: {},
}));
diff --git a/src/reducers/groupSlice.js b/src/reducers/groupSlice.js
index e47ce96..bd42bf2 100644
--- a/src/reducers/groupSlice.js
+++ b/src/reducers/groupSlice.js
@@ -28,6 +28,11 @@ const applyInitialState = {
wantToGet: '',
};
+const studyReviewInitialState = {
+ rating: 3,
+ review: '',
+};
+
const { actions, reducer } = createSlice({
name: 'group',
initialState: {
@@ -38,6 +43,7 @@ const { actions, reducer } = createSlice({
originalArticleId: null,
writeField: writeInitialState,
applyFields: applyInitialState,
+ studyReviewFields: studyReviewInitialState,
},
reducers: {
@@ -115,6 +121,12 @@ const { actions, reducer } = createSlice({
},
};
},
+
+ changeStudyReviewFields(state, { payload: { name, value } }) {
+ return produce(state, (draft) => {
+ draft.studyReviewFields[name] = value;
+ });
+ },
},
});
@@ -128,6 +140,7 @@ export const {
changeApplyFields,
clearApplyFields,
setOriginalArticle,
+ changeStudyReviewFields,
} = actions;
export const loadStudyGroups = (tag) => async (dispatch) => {
diff --git a/src/reducers/groupSlice.test.js b/src/reducers/groupSlice.test.js
index aa6bf04..6cbf373 100644
--- a/src/reducers/groupSlice.test.js
+++ b/src/reducers/groupSlice.test.js
@@ -21,6 +21,7 @@ import reducer, {
setOriginalArticle,
editStudyGroup,
setGroupError,
+ changeStudyReviewFields,
} from './groupSlice';
import STUDY_GROUPS from '../../fixtures/study-groups';
@@ -54,6 +55,10 @@ describe('reducer', () => {
reason: '',
wantToGet: '',
},
+ studyReviewFields: {
+ rating: 3,
+ review: '',
+ },
};
it('returns initialState', () => {
@@ -221,6 +226,24 @@ describe('reducer', () => {
expect(writeField.title).toBe('title');
});
});
+
+ describe('changeStudyReviewFields', () => {
+ it('changes a field of study review form', () => {
+ const initialState = {
+ studyReviewFields: {
+ rating: 3,
+ review: '',
+ },
+ };
+
+ const state = reducer(
+ initialState,
+ changeStudyReviewFields({ name: 'rating', value: 5 }),
+ );
+
+ expect(state.studyReviewFields.rating).toBe(5);
+ });
+ });
});
describe('async actions', () => {