Skip to content

Commit 5ef9f72

Browse files
authored
Merge pull request #118 from saseungmin/delete-introduce-study-group
[Feature] Study introduction is deleted by clicking the delete button.
2 parents 14e692d + 535ae7d commit 5ef9f72

File tree

9 files changed

+128
-11
lines changed

9 files changed

+128
-11
lines changed

src/components/introduce/IntroduceActionButtons.jsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,15 @@ const ActionButton = styled.button`
3737
`};
3838
`;
3939

40-
const IntroduceActionButtons = () => (
40+
const IntroduceActionButtons = ({ onRemove }) => (
4141
<IntroduceActionButtonsWrapper>
4242
<ActionButton revise>수정</ActionButton>
43-
<ActionButton remove>삭제</ActionButton>
43+
<ActionButton
44+
remove
45+
onClick={onRemove}
46+
>
47+
삭제
48+
</ActionButton>
4449
</IntroduceActionButtonsWrapper>
4550
);
4651

src/components/introduce/IntroduceForm.jsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,14 @@ const IntroduceFooter = styled.div`
8686
`;
8787

8888
const IntroduceForm = ({
89-
group, realTime,
89+
user, group, realTime, onRemove,
9090
}) => {
9191
const {
92-
contents, tags, moderatorId, personnel, participants, applyEndDate, createDate,
92+
contents, tags, moderatorId, personnel, participants, applyEndDate, createDate, id,
9393
} = group;
9494

9595
const applyEndTime = changeDateToTime(applyEndDate);
96+
const isCheckOwnGroupPost = (user && user) === moderatorId;
9697

9798
return (
9899
<>
@@ -125,7 +126,11 @@ const IntroduceForm = ({
125126
<IntroduceContent dangerouslySetInnerHTML={{ __html: contents }} />
126127
<IntroduceFooter>
127128
<Tags tags={tags} />
128-
<IntroduceActionButtons />
129+
{isCheckOwnGroupPost && (
130+
<IntroduceActionButtons
131+
onRemove={() => onRemove(id)}
132+
/>
133+
)}
129134
</IntroduceFooter>
130135
</>
131136
);

src/components/introduce/IntroduceForm.test.jsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,22 @@ import React from 'react';
22

33
import { MemoryRouter } from 'react-router-dom';
44

5-
import { render } from '@testing-library/react';
5+
import { fireEvent, render } from '@testing-library/react';
66

77
import IntroduceForm from './IntroduceForm';
88

99
import STUDY_GROUP from '../../../fixtures/study-group';
1010

1111
describe('IntroduceForm', () => {
12-
const renderIntroduceForm = ({ group, time }) => render((
12+
const handleRemove = jest.fn();
13+
14+
const renderIntroduceForm = ({ group, time, user = 'user2' }) => render((
1315
<MemoryRouter>
1416
<IntroduceForm
17+
user={user}
1518
group={group}
1619
realTime={time}
20+
onRemove={handleRemove}
1721
/>
1822
</MemoryRouter>
1923
));
@@ -30,4 +34,30 @@ describe('IntroduceForm', () => {
3034

3135
expect(container.innerHTML).toContain('<a ');
3236
});
37+
38+
context('with moderator', () => {
39+
it('renders delete button and revise button', () => {
40+
const { container } = renderIntroduceForm({ group: STUDY_GROUP });
41+
42+
expect(container).toHaveTextContent('수정');
43+
expect(container).toHaveTextContent('삭제');
44+
});
45+
46+
it('click to delete button call event', () => {
47+
const { getByText } = renderIntroduceForm({ group: STUDY_GROUP });
48+
49+
fireEvent.click(getByText('삭제'));
50+
51+
expect(handleRemove).toBeCalled();
52+
});
53+
});
54+
55+
context('without moderator', () => {
56+
it("doesn't renders delete button and revise button", () => {
57+
const { container } = renderIntroduceForm({ group: STUDY_GROUP, user: 'user' });
58+
59+
expect(container).not.toHaveTextContent('수정');
60+
expect(container).not.toHaveTextContent('삭제');
61+
});
62+
});
3363
});

src/containers/introduce/IntroduceFormContainer.jsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,43 @@
11
import React, { useState } from 'react';
22

33
import { useInterval } from 'react-use';
4-
import { useSelector } from 'react-redux';
4+
import { useHistory } from 'react-router-dom';
5+
import { useDispatch, useSelector } from 'react-redux';
56

6-
import { getGroup } from '../../util/utils';
7+
import { getAuth, getGroup } from '../../util/utils';
78

89
import IntroduceForm from '../../components/introduce/IntroduceForm';
10+
import { deleteGroup } from '../../reducers/groupSlice';
911

1012
const IntroduceFormContainer = () => {
1113
const [realTime, setRealTime] = useState(Date.now());
1214

15+
const history = useHistory();
16+
const dispatch = useDispatch();
17+
1318
const group = useSelector(getGroup('group'));
19+
const user = useSelector(getAuth('user'));
1420

1521
useInterval(() => {
1622
setRealTime(Date.now());
1723
}, 1000);
1824

25+
const onRemove = (id) => {
26+
dispatch(deleteGroup(id));
27+
28+
history.push('/');
29+
};
30+
1931
if (!group) {
2032
return null;
2133
}
2234

2335
return (
2436
<IntroduceForm
37+
user={user}
2538
group={group}
2639
realTime={realTime}
40+
onRemove={onRemove}
2741
/>
2842
);
2943
};

src/containers/introduce/IntroduceFormContainer.test.jsx

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
import React from 'react';
22

3-
import { useSelector } from 'react-redux';
3+
import { useDispatch, useSelector } from 'react-redux';
44

5-
import { render } from '@testing-library/react';
5+
import { fireEvent, render } from '@testing-library/react';
66

77
import { MemoryRouter } from 'react-router-dom';
88

99
import IntroduceFormContainer from './IntroduceFormContainer';
1010

11+
const mockPush = jest.fn();
12+
13+
jest.mock('react-router-dom', () => ({
14+
...jest.requireActual('react-router-dom'),
15+
useHistory() {
16+
return { push: mockPush };
17+
},
18+
}));
19+
1120
describe('IntroduceFormContainer', () => {
21+
const dispatch = jest.fn();
22+
1223
beforeEach(() => {
24+
dispatch.mockClear();
25+
mockPush.mockClear();
26+
27+
useDispatch.mockImplementation(() => dispatch);
28+
1329
useSelector.mockImplementation((state) => state({
1430
groupReducer: {
1531
group: given.group,
1632
applyFields: given.applyFields,
1733
},
34+
authReducer: {
35+
user: 'user1',
36+
},
1837
}));
1938
});
2039

@@ -44,6 +63,20 @@ describe('IntroduceFormContainer', () => {
4463

4564
expect(container).toHaveTextContent('우리는 이것저것 합니다.1');
4665
});
66+
67+
it('click delete button call dispatch action', () => {
68+
const { getByText } = renderIntroduceContainer(1);
69+
70+
const button = getByText('삭제');
71+
72+
expect(button).not.toBeNull();
73+
74+
fireEvent.click(button);
75+
76+
expect(dispatch).toBeCalled();
77+
78+
expect(mockPush).toBeCalledWith('/');
79+
});
4780
});
4881

4982
context('without group ', () => {

src/reducers/groupSlice.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
updatePostParticipant,
1010
deletePostParticipant,
1111
updateConfirmPostParticipant,
12+
deletePostGroup,
1213
} from '../services/api';
1314

1415
const writeInitialState = {
@@ -204,4 +205,8 @@ export const updateConfirmParticipant = (userEmail) => async (dispatch, getState
204205
}));
205206
};
206207

208+
export const deleteGroup = (groupId) => async () => {
209+
await deletePostGroup(groupId);
210+
};
211+
207212
export default reducer;

src/reducers/groupSlice.test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import reducer, {
1717
changeApplyFields,
1818
clearApplyFields,
1919
updateConfirmParticipant,
20+
deleteGroup,
2021
} from './groupSlice';
2122

2223
import STUDY_GROUPS from '../../fixtures/study-groups';
@@ -368,4 +369,20 @@ describe('async actions', () => {
368369
});
369370
});
370371
});
372+
373+
describe('deleteGroup', () => {
374+
beforeEach(() => {
375+
store = mockStore({});
376+
});
377+
378+
it('dispatches setStudyGroup', async () => {
379+
const groupId = '1';
380+
381+
await store.dispatch(deleteGroup(groupId));
382+
383+
const actions = store.getActions();
384+
385+
expect(actions[0]).toEqual();
386+
});
387+
});
371388
});

src/services/__mocks__/api.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ export const updatePostParticipant = jest.fn();
1515
export const deletePostParticipant = jest.fn();
1616

1717
export const updateConfirmPostParticipant = jest.fn();
18+
19+
export const deletePostGroup = jest.fn();

src/services/api.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ export const deletePostParticipant = async ({ id, participants }) => {
7979
});
8080
};
8181

82+
export const deletePostGroup = async (id) => {
83+
const groups = db.collection('groups').doc(id);
84+
85+
await groups.delete();
86+
};
87+
8288
export const updateConfirmPostParticipant = async ({ id, participants }) => {
8389
const groups = db.collection('groups').doc(id);
8490

0 commit comments

Comments
 (0)