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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"draft-js": "^0.11.7",
"draftjs-to-html": "^0.9.1",
"firebase": "^8.1.1",
"html-to-draftjs": "^1.5.0",
"immer": "^8.0.0",
"moment": "^2.29.1",
"moment-timezone": "^0.5.32",
Expand Down
9 changes: 7 additions & 2 deletions src/components/introduce/IntroduceActionButtons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const ActionButton = styled.button`
`};
`;

const IntroduceActionButtons = ({ onRemove }) => {
const IntroduceActionButtons = ({ onRemove, onEdit }) => {
const [modal, setModal] = useState(false);

const handleConfirm = () => {
Expand All @@ -58,7 +58,12 @@ const IntroduceActionButtons = ({ onRemove }) => {
return (
<>
<IntroduceActionButtonsWrapper>
<ActionButton revise>수정</ActionButton>
<ActionButton
revise
onClick={onEdit}
>
수정
</ActionButton>
<ActionButton
remove
onClick={handleRemove}
Expand Down
3 changes: 2 additions & 1 deletion src/components/introduce/IntroduceForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const IntroduceFooter = styled.div`
`;

const IntroduceForm = ({
user, group, realTime, onRemove,
user, group, realTime, onRemove, onEdit,
}) => {
const {
contents, tags, moderatorId, personnel, participants, applyEndDate, createDate, id,
Expand Down Expand Up @@ -128,6 +128,7 @@ const IntroduceForm = ({
<Tags tags={tags} />
{isCheckOwnGroupPost && (
<IntroduceActionButtons
onEdit={onEdit}
onRemove={() => onRemove(id)}
/>
)}
Expand Down
6 changes: 4 additions & 2 deletions src/components/write/WriteButtons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ const isCheckApplyEndDate = (applyDate) => Date.now() - applyDate >= 0;
const removeHtml = (body) => sanitize(body, { allowedTags: [] }).trim();
const isCheckPersonnel = (personnel) => !Number.isInteger(personnel) || personnel < 1;

const WriteButtons = ({ fields, onSubmit, onCancel }) => {
const WriteButtons = ({
fields, onSubmit, onCancel, isEdit,
}) => {
const [error, setError] = useState(null);

const {
Expand Down Expand Up @@ -109,7 +111,7 @@ const WriteButtons = ({ fields, onSubmit, onCancel }) => {
type="button"
onClick={handleSubmit}
>
등록하기
{isEdit ? '수정하기' : '등록하기'}
</SubmitButton>
<CancelButton
warn
Expand Down
186 changes: 100 additions & 86 deletions src/components/write/WriteButtons.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,153 +14,167 @@ describe('WriteButtons', () => {
jest.clearAllMocks();
});

const renderWriteButtons = (fields) => render((
const renderWriteButtons = ({ fields, originalArticleId = false }) => render((
<WriteButtons
fields={fields}
isEdit={originalArticleId}
onSubmit={handleSubmit}
onCancel={handleCancel}
/>
));

it('render Write buttons', () => {
const { container } = renderWriteButtons(WRITE_FROM);
const { container } = renderWriteButtons({ fields: WRITE_FROM });

expect(container).toHaveTextContent('등록하기');
expect(container).toHaveTextContent('취소');
});

context('with input value', () => {
it('call event submit action', () => {
const { getByText } = renderWriteButtons(WRITE_FROM);
context('without originalArticleId', () => {
context('with input value', () => {
it('call event submit action', () => {
const { getByText } = renderWriteButtons({ fields: WRITE_FROM });

const button = getByText('등록하기');
const button = getByText('등록하기');

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

expect(handleSubmit).toBeCalled();
});
expect(handleSubmit).toBeCalled();
});

it('call event cancel action', () => {
const { getByText } = renderWriteButtons(WRITE_FROM);
it('call event cancel action', () => {
const { getByText } = renderWriteButtons({ fields: WRITE_FROM });

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

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

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

context('with input value null', () => {
describe('When the title is blank', () => {
const fields = {
...WRITE_FROM,
title: '',
};
context('with input value null', () => {
describe('When the title is blank', () => {
const fields = {
...WRITE_FROM,
title: '',
};

it('renders error message "Please enter the subject."', () => {
const { container, getByText } = renderWriteButtons(fields);
it('renders error message "Please enter the subject."', () => {
const { container, getByText } = renderWriteButtons({ fields });

fireEvent.click(getByText('등록하기'));
fireEvent.click(getByText('등록하기'));

expect(container).toHaveTextContent('제목을 입력해주세요.');
expect(container).toHaveTextContent('제목을 입력해주세요.');
});
});
});

describe('When the applyEndDate is blank', () => {
const fields = {
...WRITE_FROM,
applyEndDate: '',
};
describe('When the applyEndDate is blank', () => {
const fields = {
...WRITE_FROM,
applyEndDate: '',
};

it('renders error message "Please enter the application deadline."', () => {
const { container, getByText } = renderWriteButtons(fields);
it('renders error message "Please enter the application deadline."', () => {
const { container, getByText } = renderWriteButtons({ fields });

fireEvent.click(getByText('등록하기'));
fireEvent.click(getByText('등록하기'));

expect(container).toHaveTextContent('모집 마감 일자를 입력해주세요.');
expect(container).toHaveTextContent('모집 마감 일자를 입력해주세요.');
});
});
});

describe('when personnel error', () => {
const ERROR_PERSONNEL = '참여 인원 수를 입력하지 않았거나, 잘못된 값을 입력하였습니다.';
describe('when personnel error', () => {
const ERROR_PERSONNEL = '참여 인원 수를 입력하지 않았거나, 잘못된 값을 입력하였습니다.';

describe("When the personnel isn't number", () => {
const fields = {
...WRITE_FROM,
personnel: 'e',
};
describe("When the personnel isn't number", () => {
const fields = {
...WRITE_FROM,
personnel: 'e',
};

it(`renders error message "You did not enter the number of participants,
or you entered an incorrect value."`, () => {
const { container, getByText } = renderWriteButtons(fields);
it(`renders error message "You did not enter the number of participants,
or you entered an incorrect value."`, () => {
const { container, getByText } = renderWriteButtons({ fields });

fireEvent.click(getByText('등록하기'));
fireEvent.click(getByText('등록하기'));

expect(container).toHaveTextContent(ERROR_PERSONNEL);
});
});

describe('When personnel is less than 1', () => {
const fields = {
...WRITE_FROM,
personnel: '-1',
};

it(`renders error message "You did not enter the number of participants,
or you entered an incorrect value."`, () => {
const { container, getByText } = renderWriteButtons({ fields });

expect(container).toHaveTextContent(ERROR_PERSONNEL);
fireEvent.click(getByText('등록하기'));

expect(container).toHaveTextContent(ERROR_PERSONNEL);
});
});
});

describe('When personnel is less than 1', () => {
describe('When there is no content', () => {
const fields = {
...WRITE_FROM,
personnel: '-1',
contents: '',
};

it(`renders error message "You did not enter the number of participants,
or you entered an incorrect value."`, () => {
const { container, getByText } = renderWriteButtons(fields);
it('renders error message "Please enter your details."', () => {
const { container, getByText } = renderWriteButtons({ fields });

fireEvent.click(getByText('등록하기'));

expect(container).toHaveTextContent(ERROR_PERSONNEL);
expect(container).toHaveTextContent('내용을 입력해주세요.');
});
});
});

describe('When there is no content', () => {
const fields = {
...WRITE_FROM,
contents: '',
};
describe('When the length of tags is 0', () => {
const fields = {
...WRITE_FROM,
tags: [],
};

it('renders error message "Please enter your details."', () => {
const { container, getByText } = renderWriteButtons(fields);
it('renders error message "Please enter a tag."', () => {
const { container, getByText } = renderWriteButtons({ fields });

fireEvent.click(getByText('등록하기'));
fireEvent.click(getByText('등록하기'));

expect(container).toHaveTextContent('내용을 입력해주세요.');
expect(container).toHaveTextContent('태그를 입력하세요.');
});
});
});

describe('When the length of tags is 0', () => {
const fields = {
...WRITE_FROM,
tags: [],
};
describe('When the application deadline is earlier than the current time', () => {
const fields = {
...WRITE_FROM,
applyEndDate: '2020-10-01',
};

it('renders error message "Please enter a tag."', () => {
const { container, getByText } = renderWriteButtons(fields);
it('renders error message "The application deadline is earlier than the current time."', () => {
const { container, getByText } = renderWriteButtons({ fields });

fireEvent.click(getByText('등록하기'));
fireEvent.click(getByText('등록하기'));

expect(container).toHaveTextContent('태그를 입력하세요.');
expect(container).toHaveTextContent('접수 마감날짜가 현재 시간보다 빠릅니다.');
});
});
});
});

describe('When the application deadline is earlier than the current time', () => {
const fields = {
...WRITE_FROM,
applyEndDate: '2020-10-01',
};

it('renders error message "The application deadline is earlier than the current time."', () => {
const { container, getByText } = renderWriteButtons(fields);

fireEvent.click(getByText('등록하기'));

expect(container).toHaveTextContent('접수 마감날짜가 현재 시간보다 빠릅니다.');
context('with originalArticleId', () => {
it('renders Edit buttons', () => {
const { container } = renderWriteButtons({
fields: WRITE_FROM,
originalArticleId: true,
});

expect(container).toHaveTextContent('수정하기');
});
});
});
64 changes: 25 additions & 39 deletions src/components/write/WriteEditor.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import React, { useState } from 'react';
import React from 'react';

import styled from '@emotion/styled';

import draftToHtml from 'draftjs-to-html';
import { Editor } from 'react-draft-wysiwyg';
import { EditorState, convertToRaw } from 'draft-js';

import palette from '../../styles/palette';

Expand Down Expand Up @@ -32,41 +30,29 @@ const SpaceBlock = styled.div`
background: ${palette.gray[3]};
`;

const WriteEditor = ({ onChange }) => {
const [editorState, setEditorState] = useState(EditorState.createEmpty());

const handleChangeEditor = (state) => {
setEditorState(state);
onChange({
name: 'contents',
value: draftToHtml(convertToRaw(state.getCurrentContent())),
});
};

return (
<>
<WriteEditorWrapper>
<Editor
editorState={editorState}
onEditorStateChange={handleChangeEditor}
ariaLabel="contents"
placeholder="내용을 작성해주세요."
toolbarClassName="toolbar"
editorClassName="editor"
localization={{
locale: 'ko',
}}
toolbar={{
list: { inDropdown: true },
textAlign: { inDropdown: true },
link: { inDropdown: true },
history: { inDropdown: true },
}}
/>
</WriteEditorWrapper>
<SpaceBlock />
</>
);
};
const WriteEditor = ({ editorState, onChange }) => (
<>
<WriteEditorWrapper>
<Editor
editorState={editorState}
onEditorStateChange={onChange}
ariaLabel="contents"
placeholder="내용을 작성해주세요."
toolbarClassName="toolbar"
editorClassName="editor"
localization={{
locale: 'ko',
}}
toolbar={{
list: { inDropdown: true },
textAlign: { inDropdown: true },
link: { inDropdown: true },
history: { inDropdown: true },
}}
/>
</WriteEditorWrapper>
<SpaceBlock />
</>
);

export default WriteEditor;
Loading