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
12 changes: 8 additions & 4 deletions src/components/common/ModalWindow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import styled from '@emotion/styled';

import { css } from '@emotion/react';
import Button from '../../styles/Button';
import palette from '../../styles/palette';

const ModalWindowWrapper = styled.div`
position: fixed;
Expand Down Expand Up @@ -57,10 +58,13 @@ const ModalBoxWrapper = styled.div`
`;

const StyledButton = styled(Button)`
height: 2rem;
& + & {
margin-left: 0.75rem;
&:last-of-type {
margin-left: .7rem;
}

${(props) => props.cancel && css`
border: 2px solid ${palette.gray[7]};
`}
`;

const ModalWindow = ({
Expand All @@ -82,7 +86,7 @@ const ModalWindow = ({
<h2>{title}</h2>
<p>{description}</p>
<div className="buttons">
<StyledButton warn onClick={onCancel}>{cancelText}</StyledButton>
<StyledButton cancel onClick={onCancel}>{cancelText}</StyledButton>
{onConfirm && (
<StyledButton success onClick={onConfirm}>{confirmText}</StyledButton>
)}
Expand Down
35 changes: 27 additions & 8 deletions src/components/introduce/IntroduceHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { changeDateToTime, isCheckedTimeStatus } from '../../util/utils';

import ApplyStatusButton from './ApplyStatusButton';
import AskLoginModal from './modals/AskLoginModal';
import AskApplyCancelModal from './modals/AskApplyCancelModal';

const IntroduceHeaderWrapper = styled.div`
border-bottom: 2px solid ${palette.gray[4]};
Expand All @@ -24,25 +25,35 @@ const IntroduceHeaderWrapper = styled.div`
const IntroduceHeader = ({
group, onApply, user, realTime, onApplyCancel,
}) => {
const [modal, setModal] = useState(false);
const [loginCheckModal, setLoginCheckModal] = useState(false);
const [applyCancelModal, setApplyCancelModal] = useState(false);

const {
title, moderatorId, participants, applyEndDate,
} = group;

const applyEndTime = changeDateToTime(applyEndDate);

const onApplyClick = () => {
setModal(true);
const handleApplyCancelConfirmClick = () => {
setApplyCancelModal(true);
};

const handleCancel = () => {
setModal(false);
const handleLoginCheckCancel = () => {
setLoginCheckModal(false);
};

const handleApplyCancel = () => {
setApplyCancelModal(false);
};

const handleApplyCancelConfirm = () => {
setApplyCancelModal(false);
onApplyCancel();
};

const handleApply = () => {
if (!user) {
onApplyClick();
setLoginCheckModal(true);
return;
}

Expand All @@ -56,12 +67,20 @@ const IntroduceHeader = ({
<>
<ApplyStatusButton
user={user}
onCancel={onApplyCancel}
onApply={handleApply}
onCancel={handleApplyCancelConfirmClick}
applyStatus={participants.includes(user)}
timeStatus={isCheckedTimeStatus({ ...group, time: realTime, applyEndTime })}
/>
<AskLoginModal visible={modal} onCancel={handleCancel} />
<AskLoginModal
visible={loginCheckModal}
onCancel={handleLoginCheckCancel}
/>
<AskApplyCancelModal
visible={applyCancelModal}
onCancel={handleApplyCancel}
onConfirm={handleApplyCancelConfirm}
/>
</>
)}
</IntroduceHeaderWrapper>
Expand Down
32 changes: 26 additions & 6 deletions src/components/introduce/IntroduceHeader.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,36 @@ describe('IntroduceHeader', () => {
personnel: 3,
};

it('Call the cancel application button.', () => {
const { getByText } = renderIntroduceHeader({ group, user: 'user', time });
context('click confirm', () => {
it('Call the cancel application button.', () => {
const { getByText } = renderIntroduceHeader({ group, user: 'user', time });

const button = getByText('신청 취소');
const button = getByText('신청 취소');

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

fireEvent.click(button);

fireEvent.click(getByText('확인'));

expect(handleApplyCancel).toBeCalled();
});
});

fireEvent.click(button);
context('click cancel', () => {
it("doesn't call the cancel application button.", () => {
const { getByText } = renderIntroduceHeader({ group, user: 'user', time });

expect(handleApplyCancel).toBeCalled();
const button = getByText('신청 취소');

expect(button).not.toBeNull();

fireEvent.click(button);

fireEvent.click(getByText('취소'));

expect(handleApplyCancel).not.toBeCalled();
});
});
});

Expand Down
15 changes: 15 additions & 0 deletions src/components/introduce/modals/AskApplyCancelModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

import ModalWindow from '../../common/ModalWindow';

const AskApplyCancelModal = ({ visible, onCancel, onConfirm }) => (
<ModalWindow
title="신청 취소"
description="스터디 그룹 신청을 취소하시겠습니까?"
visible={visible}
onConfirm={onConfirm}
onCancel={onCancel}
/>
);

export default AskApplyCancelModal;
63 changes: 63 additions & 0 deletions src/components/introduce/modals/AskApplyCancelModal.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';

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

import AskApplyCancelModal from './AskApplyCancelModal';

describe('AskApplyCancelModal', () => {
const handleCancel = jest.fn();
const handleConfirm = jest.fn();

const renderAskApplyCancelModal = ({ visible }) => render((
<AskApplyCancelModal
visible={visible}
onConfirm={handleConfirm}
onCancel={handleCancel}
/>
));

context('with visible', () => {
const modal = {
visible: true,
};

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

expect(container).toHaveTextContent('신청 취소');
expect(container).toHaveTextContent('스터디 그룹 신청을 취소하시겠습니까?');
});

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

const button = getByText('확인');

fireEvent.click(button);

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

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

const button = getByText('취소');

fireEvent.click(button);

expect(handleCancel).toBeCalled();
});
});

context('without visible', () => {
const modal = {
visible: false,
};

it("doesn't renders Modal text", () => {
const { container } = renderAskApplyCancelModal(modal);

expect(container).toBeEmptyDOMElement();
});
});
});
36 changes: 29 additions & 7 deletions src/containers/introduce/IntroduceContainer.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,40 @@ describe('IntroduceContainer', () => {
given('group', () => (group));
given('user', () => ('user'));

it('click event dispatches action call deleteParticipant', () => {
const { getByText } = renderIntroduceContainer(1);
context('click confirm', () => {
it('click event dispatches action call deleteParticipant', () => {
const { getByText } = renderIntroduceContainer(1);

expect(dispatch).toBeCalledTimes(1);
expect(dispatch).toBeCalledTimes(1);

const button = getByText('신청 취소');
const button = getByText('신청 취소');

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

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

expect(dispatch).toBeCalledTimes(2);
fireEvent.click(getByText('확인'));

expect(dispatch).toBeCalledTimes(2);
});
});

context('click cancel', () => {
it("doesn't click event dispatches action call deleteParticipant", () => {
const { getByText } = renderIntroduceContainer(1);

expect(dispatch).toBeCalledTimes(1);

const button = getByText('신청 취소');

expect(button).not.toBeNull();

fireEvent.click(button);

fireEvent.click(getByText('취소'));

expect(dispatch).toBeCalledTimes(1);
});
});
});
});