diff --git a/src/components/introduce/IntroduceActionButtons.jsx b/src/components/introduce/IntroduceActionButtons.jsx
index ab2809d..8057157 100644
--- a/src/components/introduce/IntroduceActionButtons.jsx
+++ b/src/components/introduce/IntroduceActionButtons.jsx
@@ -37,10 +37,15 @@ const ActionButton = styled.button`
`};
`;
-const IntroduceActionButtons = () => (
+const IntroduceActionButtons = ({ onRemove }) => (
수정
- 삭제
+
+ 삭제
+
);
diff --git a/src/components/introduce/IntroduceForm.jsx b/src/components/introduce/IntroduceForm.jsx
index bfca9d2..4bc074f 100644
--- a/src/components/introduce/IntroduceForm.jsx
+++ b/src/components/introduce/IntroduceForm.jsx
@@ -86,13 +86,14 @@ const IntroduceFooter = styled.div`
`;
const IntroduceForm = ({
- group, realTime,
+ user, group, realTime, onRemove,
}) => {
const {
- contents, tags, moderatorId, personnel, participants, applyEndDate, createDate,
+ contents, tags, moderatorId, personnel, participants, applyEndDate, createDate, id,
} = group;
const applyEndTime = changeDateToTime(applyEndDate);
+ const isCheckOwnGroupPost = (user && user) === moderatorId;
return (
<>
@@ -125,7 +126,11 @@ const IntroduceForm = ({
-
+ {isCheckOwnGroupPost && (
+ onRemove(id)}
+ />
+ )}
>
);
diff --git a/src/components/introduce/IntroduceForm.test.jsx b/src/components/introduce/IntroduceForm.test.jsx
index 0c9618c..c3e5dbf 100644
--- a/src/components/introduce/IntroduceForm.test.jsx
+++ b/src/components/introduce/IntroduceForm.test.jsx
@@ -2,18 +2,22 @@ import React from 'react';
import { MemoryRouter } from 'react-router-dom';
-import { render } from '@testing-library/react';
+import { fireEvent, render } from '@testing-library/react';
import IntroduceForm from './IntroduceForm';
import STUDY_GROUP from '../../../fixtures/study-group';
describe('IntroduceForm', () => {
- const renderIntroduceForm = ({ group, time }) => render((
+ const handleRemove = jest.fn();
+
+ const renderIntroduceForm = ({ group, time, user = 'user2' }) => render((
));
@@ -30,4 +34,30 @@ describe('IntroduceForm', () => {
expect(container.innerHTML).toContain(' {
+ it('renders delete button and revise button', () => {
+ const { container } = renderIntroduceForm({ group: STUDY_GROUP });
+
+ expect(container).toHaveTextContent('수정');
+ expect(container).toHaveTextContent('삭제');
+ });
+
+ it('click to delete button call event', () => {
+ const { getByText } = renderIntroduceForm({ group: STUDY_GROUP });
+
+ fireEvent.click(getByText('삭제'));
+
+ expect(handleRemove).toBeCalled();
+ });
+ });
+
+ context('without moderator', () => {
+ it("doesn't renders delete button and revise button", () => {
+ const { container } = renderIntroduceForm({ group: STUDY_GROUP, user: 'user' });
+
+ expect(container).not.toHaveTextContent('수정');
+ expect(container).not.toHaveTextContent('삭제');
+ });
+ });
});
diff --git a/src/containers/introduce/IntroduceFormContainer.jsx b/src/containers/introduce/IntroduceFormContainer.jsx
index 6babdd5..84b8b62 100644
--- a/src/containers/introduce/IntroduceFormContainer.jsx
+++ b/src/containers/introduce/IntroduceFormContainer.jsx
@@ -1,29 +1,43 @@
import React, { useState } from 'react';
import { useInterval } from 'react-use';
-import { useSelector } from 'react-redux';
+import { useHistory } from 'react-router-dom';
+import { useDispatch, useSelector } from 'react-redux';
-import { getGroup } from '../../util/utils';
+import { getAuth, getGroup } from '../../util/utils';
import IntroduceForm from '../../components/introduce/IntroduceForm';
+import { deleteGroup } from '../../reducers/groupSlice';
const IntroduceFormContainer = () => {
const [realTime, setRealTime] = useState(Date.now());
+ const history = useHistory();
+ const dispatch = useDispatch();
+
const group = useSelector(getGroup('group'));
+ const user = useSelector(getAuth('user'));
useInterval(() => {
setRealTime(Date.now());
}, 1000);
+ const onRemove = (id) => {
+ dispatch(deleteGroup(id));
+
+ history.push('/');
+ };
+
if (!group) {
return null;
}
return (
);
};
diff --git a/src/containers/introduce/IntroduceFormContainer.test.jsx b/src/containers/introduce/IntroduceFormContainer.test.jsx
index 507fbcc..6f38994 100644
--- a/src/containers/introduce/IntroduceFormContainer.test.jsx
+++ b/src/containers/introduce/IntroduceFormContainer.test.jsx
@@ -1,20 +1,39 @@
import React from 'react';
-import { useSelector } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
-import { render } from '@testing-library/react';
+import { fireEvent, render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import IntroduceFormContainer from './IntroduceFormContainer';
+const mockPush = jest.fn();
+
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
+ useHistory() {
+ return { push: mockPush };
+ },
+}));
+
describe('IntroduceFormContainer', () => {
+ const dispatch = jest.fn();
+
beforeEach(() => {
+ dispatch.mockClear();
+ mockPush.mockClear();
+
+ useDispatch.mockImplementation(() => dispatch);
+
useSelector.mockImplementation((state) => state({
groupReducer: {
group: given.group,
applyFields: given.applyFields,
},
+ authReducer: {
+ user: 'user1',
+ },
}));
});
@@ -44,6 +63,20 @@ describe('IntroduceFormContainer', () => {
expect(container).toHaveTextContent('우리는 이것저것 합니다.1');
});
+
+ it('click delete button call dispatch action', () => {
+ const { getByText } = renderIntroduceContainer(1);
+
+ const button = getByText('삭제');
+
+ expect(button).not.toBeNull();
+
+ fireEvent.click(button);
+
+ expect(dispatch).toBeCalled();
+
+ expect(mockPush).toBeCalledWith('/');
+ });
});
context('without group ', () => {
diff --git a/src/reducers/groupSlice.js b/src/reducers/groupSlice.js
index 0667055..23ddd28 100644
--- a/src/reducers/groupSlice.js
+++ b/src/reducers/groupSlice.js
@@ -9,6 +9,7 @@ import {
updatePostParticipant,
deletePostParticipant,
updateConfirmPostParticipant,
+ deletePostGroup,
} from '../services/api';
const writeInitialState = {
@@ -204,4 +205,8 @@ export const updateConfirmParticipant = (userEmail) => async (dispatch, getState
}));
};
+export const deleteGroup = (groupId) => async () => {
+ await deletePostGroup(groupId);
+};
+
export default reducer;
diff --git a/src/reducers/groupSlice.test.js b/src/reducers/groupSlice.test.js
index f663f60..f19681b 100644
--- a/src/reducers/groupSlice.test.js
+++ b/src/reducers/groupSlice.test.js
@@ -17,6 +17,7 @@ import reducer, {
changeApplyFields,
clearApplyFields,
updateConfirmParticipant,
+ deleteGroup,
} from './groupSlice';
import STUDY_GROUPS from '../../fixtures/study-groups';
@@ -368,4 +369,20 @@ describe('async actions', () => {
});
});
});
+
+ describe('deleteGroup', () => {
+ beforeEach(() => {
+ store = mockStore({});
+ });
+
+ it('dispatches setStudyGroup', async () => {
+ const groupId = '1';
+
+ await store.dispatch(deleteGroup(groupId));
+
+ const actions = store.getActions();
+
+ expect(actions[0]).toEqual();
+ });
+ });
});
diff --git a/src/services/__mocks__/api.js b/src/services/__mocks__/api.js
index d554f20..506fc3d 100644
--- a/src/services/__mocks__/api.js
+++ b/src/services/__mocks__/api.js
@@ -15,3 +15,5 @@ export const updatePostParticipant = jest.fn();
export const deletePostParticipant = jest.fn();
export const updateConfirmPostParticipant = jest.fn();
+
+export const deletePostGroup = jest.fn();
diff --git a/src/services/api.js b/src/services/api.js
index 0b70dc9..6dba732 100644
--- a/src/services/api.js
+++ b/src/services/api.js
@@ -79,6 +79,12 @@ export const deletePostParticipant = async ({ id, participants }) => {
});
};
+export const deletePostGroup = async (id) => {
+ const groups = db.collection('groups').doc(id);
+
+ await groups.delete();
+};
+
export const updateConfirmPostParticipant = async ({ id, participants }) => {
const groups = db.collection('groups').doc(id);