Skip to content

Commit

Permalink
[FE][관리자 페이지] 프로젝트 생성 공백 문자 입력 예외 처리 (#186) (#240)
Browse files Browse the repository at this point in the history
* chore: jest 환경 설정

* feat: 공백 제거 유틸함수 추가 및 테스트코드 작성

* fix: 프로젝트 명 공백 입력 오류 수정

- autoFocus추가

* refactor: ol 태그 외부에있는 p 태그 제거

* refactor: 함수명과 내부 동작 불일치된 부분 수정

* refactor: 어색한 코드 라인 수정 및 프로젝트 이름 중복체크 기능 추가
  • Loading branch information
zereight authored Jul 21, 2021
1 parent c345aa3 commit 3269692
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 63 deletions.
10 changes: 10 additions & 0 deletions frontend/manage/jest.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"preset": "ts-jest",
"moduleDirectories": ["node_modules", "src"],
"transform": {
"node_modules/variables/.+\\.(j|t)sx?$": "ts-jest",
".+\\.(svg|css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
},
"coveragePathIgnorePatterns": ["/node_modules/", "/jest"],
"testEnvironment": "jsdom"
}
6 changes: 6 additions & 0 deletions frontend/manage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
"@storybook/addon-links": "^6.3.2",
"@storybook/react": "^6.3.2",
"@testing-library/dom": "^8.1.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@types/jest": "^26.0.24",
"@types/react": "^17.0.13",
"@types/react-dom": "^17.0.8",
"@types/react-router-dom": "^5.1.7",
Expand All @@ -31,8 +33,11 @@
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.3.2",
"jest": "^27.0.6",
"jest-transform-stub": "^2.0.0",
"jsdom": "^16.6.0",
"prettier": "^2.3.2",
"react-refresh": "^0.10.0",
"ts-jest": "^27.0.3",
"type-fest": "^1.2.2",
"typescript": "^4.3.5",
"url-loader": "^4.1.1",
Expand All @@ -53,6 +58,7 @@
"scripts": {
"start": "webpack server",
"build": "webpack",
"test": "jest",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
}
Expand Down
32 changes: 32 additions & 0 deletions frontend/manage/src/__test__/unit/isEmptyString.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { isEmptyString } from "../../utils/validation";

describe("isEmptyString", () => {
test("문자열을 인자로 넣을 시, 해당 문자열이 공백 또는 개행으로만 이루어져 있는지 여부를 반환한다.", () => {
const fixture = [
{
input: " ",
expectedOutput: true
},
{
input: " \n \n \n ",
expectedOutput: true
},
{
input: "a",
expectedOutput: false
},
{
input: " a a a \na a \nna\n ",
expectedOutput: false
},
{
input: "\n\n\n\n\n\n ",
expectedOutput: true
}
];

fixture.forEach(({ input, expectedOutput }) => {
expect(isEmptyString(input)).toEqual(expectedOutput);
});
});
});
19 changes: 3 additions & 16 deletions frontend/manage/src/components/pages/NewProjectPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
import { FormEvent } from "react";
import { useHistory } from "react-router-dom";
import { ROUTE } from "../../../constants";
import { useCreateProject, useInput } from "../../../hooks";
import { useGetAllProjects } from "../../../hooks";
import NewProject from "../../templates/NewProject";

const NewProjectPage = () => {
const history = useHistory();
const { createProject } = useCreateProject();
const { value: projectName, onChange: onChangeProjectName } = useInput("");
const { projects } = useGetAllProjects();

const onSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();

const project = await createProject(projectName);

history.push(ROUTE.GET_SCRIPT_PUBLISHING(project.id));
};

return <NewProject onSubmit={onSubmit} projectName={projectName} onChangeProjectName={onChangeProjectName} />;
return <NewProject projects={projects} />;
};

export default NewProjectPage;
35 changes: 30 additions & 5 deletions frontend/manage/src/components/templates/NewProject/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,47 @@
import { ChangeEvent, FormEvent } from "react";
import { useCreateProject, useInput } from "../../../hooks";
import { PALETTE } from "../../../styles/palette";
import ScreenContainer from "../../../styles/ScreenContainer";
import { Container, Form, Input, Label, SubmitButton, Title } from "./styles";
import { useHistory } from "react-router-dom";
import { isEmptyString } from "../../../utils/validation";
import { ROUTE } from "../../../constants";
import { Project } from "../../../types/project";

export interface Props {
projectName: string;
onChangeProjectName: (event: ChangeEvent<HTMLInputElement>) => void;
onSubmit: (event: FormEvent<HTMLFormElement>) => void;
projects: Project[] | undefined;
}

const NewProject = ({ onSubmit, projectName, onChangeProjectName }: Props) => {
const NewProject = ({ projects }: Props) => {
const history = useHistory();
const { createProject } = useCreateProject();
const { value: projectName, onChange: onChangeProjectName } = useInput("");

const onSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();

try {
const isDuplicatedProjectName = projects?.some(project => project.name === projectName.trim());

if (isEmptyString(projectName)) throw new Error("프로젝트 이름을 입력해주세요.");
if (isDuplicatedProjectName) throw new Error("중복된 프로젝트 이름입니다. 다시 입력해주세요.");

const project = await createProject(projectName.trim());

history.push(ROUTE.GET_SCRIPT_PUBLISHING(project.id));
} catch (error) {
alert(error.message);
console.error(error.message);
}
};

return (
<ScreenContainer>
<Container>
<Title>새 프로젝트 만들기</Title>
<Form onSubmit={onSubmit}>
<Label htmlFor="project-name">프로젝트 이름</Label>
<Input id="project-name" value={projectName} onChange={onChangeProjectName} />
<Input id="project-name" value={projectName} onChange={onChangeProjectName} autoFocus />
<SubmitButton>등록</SubmitButton>
</Form>
</Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import SyntaxHighlighter from "react-syntax-highlighter";
import { xcode } from "react-syntax-highlighter/dist/esm/styles/hljs";
import { useCopyButton } from "../../../hooks";
import ScreenContainer from "../../../styles/ScreenContainer";
import { B, CodeBlockWrapper, Container, Content, CopyButton, P, Section, Title } from "./styles";
import { B, CodeBlockWrapper, Container, Content, CopyButton, P, Ol, Section, Title } from "./styles";

const scriptCode = (projectSecretKey: string) => `
<!-- 다라쓰 설치 코드 -->
Expand Down Expand Up @@ -65,13 +65,11 @@ const ScriptPublishing = ({ projectSecretKey }: Props) => {
다라쓰는 아래의 최신 브라우저 사용을 권장합니다. 구형 브라우저에서는 일부 기능이 동작하지 않을 수
있습니다.
</P>
<P>
<ol>
<li>Chrome</li>
<li>Safari</li>
<li>Samsung browser</li>
</ol>
</P>
<Ol>
<li>Chrome</li>
<li>Safari</li>
<li>Samsung browser</li>
</Ol>
</Content>
</Section>
</Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@ const P = styled.p`
word-break: keep-all;
`;

export { Container, Section, Title, CodeBlockWrapper, Content, B, P, CopyButton };
const Ol = styled.ol`
font-size: 1.4rem;
`;

export { Container, Section, Title, CodeBlockWrapper, Content, B, P, Ol, CopyButton };
1 change: 1 addition & 0 deletions frontend/manage/src/constants/regex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const allSpaces = /(\s*)/g;
12 changes: 6 additions & 6 deletions frontend/manage/src/styles/palette.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export enum PALETTE {
"PRIMARY"= "#10DF99",
"SECONDARY" = "#0BC586",
"TERTIARY" = "#FFE200",
"WHITE" = "#FFFFFF",
"BLACK_700" = "#303030",
"PRIMARY" = "#10DF99",
"SECONDARY" = "#0BC586",
"TERTIARY" = "#FFE200",
"WHITE" = "#FFFFFF",
"BLACK_700" = "#303030",
"RED_600" = "#E41E1E"
}

3 changes: 3 additions & 0 deletions frontend/manage/src/utils/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { allSpaces } from "../constants/regex";

export const isEmptyString = (str: string) => str.replace(allSpaces, "").length === 0;
Loading

0 comments on commit 3269692

Please sign in to comment.