목차
2022.12.20 테스트 코드 작성-포스트상세-Controller 내용 수정
- 5가지 항목 → 4가지 항목
수행 사항
필수과제
•
회원가입
•
Swagger
•
AWS EC2에 Docker 배포
•
Gitlab CI & Crontab CD
•
로그인
•
포스트 작성, 수정, 삭제, 리스트
도전과제
•
화면 UI 개발
◦
회원가입, 로그인, 글쓰기, 조회
•
ADMIN 회원으로 등급업하는 기능
•
초기 ADMIN 회원은 하나가 존재하고 ADMIN 회원은 일반회원의 권한을 ADMIN으로 승격시킬 수 있다.
•
ADMIN 회원이 일반 회원을 ADMIN으로 승격시키는 기능
◦
POST /users/{id}/role/change
▪
Body {”role”:”admin” | “user”} admin 또는 user로 변경할 수 있습니다.
•
ADMIN 회원이 로그인 시 자신이 쓴 글이 아닌 글과 댓글에 수정, 삭제를 할 수 있는 기능
Architecture(아키텍처)
▲ 위 Layered Architecture 구조에 맞게 작성 해주세요.
•
Println 사용 추천
◦
Controller와 Service와 Repository의 호출 여부 확인
◦
디버깅시 유용함
•
각 단에 데이터를 전달 받을시 DTO 형태로 전달한다.
ERD
주의
AWS EC2에 배포되지 않은 기능은 점수로 들어가지 않습니다. 배포가 아무것도 되지 않았다면 0점 입니다.
미션 개요 - 요구사항 정의
Swagger 3.0.0
ex)
API에 접근하기 편하게 하기 위해 Swagger를 추가 해주세요.
AWS EC2에 Docker로 배포
AWS EC2에 Docker로 배포해주세요.
Gitlab CI & Crontab CD 구성
Gitlab에 Push하면 Docker Build되어 Container Registry에 배포되고 1분에 1번씩 Crontab을 걸어 Docker에도 바뀐 내용이 반영되게 해주세요.
Crontab설정
회원가입과 로그인
•
회원은 일반회원(USER)과 ADMIN 회원이 있다.
•
회원가입
◦
회원가입 성공 시 "회원가입 성공" 을 리턴한다.
•
로그인
◦
Spring Security와 JWT를 사용하여 구현한다.
◦
로그인 성공 시 token 을 리턴한다.
▪
{”jwt”:”eyJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Imt5~~~”}
포스트 작성, 상세조회, 수정, 삭제, 목록
•
포스트 상세 (1개 조회)
◦
회원, 비회원 모두 볼 수 있다.
◦
글의 제목, 내용, 글쓴이, 작성날짜, 마지막 수정날짜가 표시된다.
•
회원만이 글 작성을 할 수 있다.
•
포스트 수정 / 삭제
◦
ADMIN회원이나 글을 작성한 일반회원이 글에 대한 수정과 삭제를 할 수 있다.
•
리스트
◦
회원, 비회원 모두 볼 수 있다.
◦
제목, 글쓴이, 마지막 수정날짜가 표시된다.
◦
포스트를 클릭하면 포스트의 상세 내역을 볼 수 있다.
◦
목록 기능은 페이징 기능이 포함된다. (Pageable 사용)
▪
한 페이지당 default 피드 갯수는 20개이다.
▪
총 페이지 갯수가 표시된다.
▪
작성날짜 기준으로 최신순으로 Sort한다.
공통 에러처리
1. ErrorCode에서 정의한 HttpStatus를 StatusCode로 Return하게 할 것
•
ex) join할 때 duplicated면 409 나올 것
2. result.errorCode 존재 할 것 ex)
️ DUPLICATED_USER_NAME
3. message 존재 해야 함
ex)
{
"resultCode":"ERROR",
"result":{
"errorCode":"POST_NOT_FOUND",
"message":"Post not founded"
}
}
JavaScript
복사
엔드 포인트
기본 url : /api/v1/
회원 인증·인가
회원 url : /users
회원가입
POST /join
•
입력 폼 (JSON 형식)
{
"userName" : "user1",
"password" : "user1234"
}
JSON
복사
•
리턴 (JSON 형식)
{
"resultCode": "SUCCESS",
"result": {
"userId": 5,
"userName": "test1"
}
}
JSON
복사
로그인
POST /login
•
입력폼 (JSON 형식)
{
"userName" : "user1",
"password" : "user1234"
}
JSON
복사
•
리턴 (JSON 형식)
{
"resultCode": "SUCCESS",
"result": {
"jwt": "eyJhbGciOiJIU",
}
}
JSON
복사
포스트
포스트 url : /posts
포스트 리스트
GET
•
최신 순으로 20개씩 표시 (Pageable 사용)
•
리턴 (JSON 형식)
{
"resultCode": "SUCCESS",
"result": {
"content": [
{
"id": 10,
"title": "글이 들어온다아아아",
"body": "글들어온다아앙",
"userName": "손흥민",
"createdAt": "2022/12/22 10:43:25",
"lastModifiedAt": "2022/12/22 10:43:25"
},
{
"id": 9,
"title": "`12`1",
"body": "2`12`12`12",
"userName": "손흥민",
"createdAt": "2022/12/22 10:42:44",
"lastModifiedAt": "2022/12/22 10:42:44"
},
{
"id": 8,
"title": "오늘은 더 추워",
"body": "집이 최고",
"userName": "손흥민",
"createdAt": "2022/12/22 10:08:10",
"lastModifiedAt": "2022/12/22 10:08:10"
},
{
"id": 6,
"title": "오늘 춥네요",
"body": "눈이 엄청왔어요",
"userName": "string",
"createdAt": "2022/12/21 13:29:02",
"lastModifiedAt": "2022/12/21 13:29:02"
}
],
"pageable": "INSTANCE",
"last": true,
"totalPages": 1,
"totalElements": 4,
"size": 4,
"number": 0,
"sort": {
"empty": true,
"sorted": false,
"unsorted": true
},
"first": true,
"numberOfElements": 4,
"empty": false
}
}
JSON
복사
포스트 상세
GET /posts/{postsId}
•
id, 제목, 내용, 작성자, 작성날짜, 수정날짜
•
리턴 (JSON 형식)
{
"resultCode":"SUCCESS",
"result":{
"id" : 1,
"title" : "title1",
"body" : "body",
"userName" : "user1",
"createdAt" : yyyy-mm-dd hh:mm:ss,
"lastModifiedAt" : yyyy-mm-dd hh:mm:ss
}
}
JSON
복사
포스트 등록
POST /posts
•
입력폼 (JSON 형식)
{
"title" : "title1",
"body" : "body1"
}
JSON
복사
•
리턴 (JSON 형식)
{
"resultCode":"SUCCESS",
"result":{
"message":"포스트 등록 완료",
"postId":0
}
}
JSON
복사
포스트 수정
PUT /posts/{id}
•
입력폼 (JSON 형식)
{
"title" : "modified title",
"body" : "modified body"
}
JSON
복사
•
리턴 (JSON 형식)
{
"resultCode":"SUCCESS",
"result":{
"message":"포스트 수정 완료",
"postId":0
}
}
JSON
복사
포스트 삭제
DELETE /posts/{id}
•
리턴 (JSON 형식)
{
"resultCode":"SUCCESS",
"result":{
"message":"포스트 삭제 완료",
"postId":0
}
}
JSON
복사
ErrorCode
1.
DUPLICATED_USER_NAME(HttpStatus.CONFLICT, "UserName이 중복됩니다.")
2.
USERNAME_NOT_FOUND(HttpStatus.NOT_FOUND,"Not founded")
3.
INVALID_PASSWORD(HttpStatus.UNAUTHORIZED, "패스워드가 잘못되었습니다.")
4.
INVALID_TOKEN(HttpStatus.UNAUTHORIZED, "잘못된 토큰입니다.")
5.
INVALID_PERMISSION(HttpStatus.UNAUTHORIZED, "사용자가 권한이 없습니다.")
6.
POST_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 포스트가 없습니다.")
7.
DATABASE_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "DB에러")
테스트 코드 작성
목표
•
1. controller / 2. service로 나눠서 테스트를 진행해야 함.
•
1. 성공, 2. 실패 테스트 케이스를 모두 통과하는 실제 코드 작성.
•
Exception 처리는 enum Error코드에 작성 후 호출 해서 사용
◦
실패의 경우 enum값의 errorCode로처리하기
•
when(어떤 상황일 때)를 각각 설계해보고, Test case에 따라 예상되는 결과값을 작성해주기
•
Controller, Service 두 클래스의 테스트 코드 작성하기
회원가입
Controller
회원가입 성공
회원가입 실패 - userName중복인 경우
Service
없음
로그인
Controller
로그인 성공
로그인 실패 - userName없음
로그인 실패 - password틀림
Service
없음
포스트 상세
Controller
GET /posts/1 로 조회시
조회 성공 - id, title, body, userName 4가지 항목이 있는지 검증
Service
조회 성공
포스트 등록
Controller
포스트 작성 성공
포스트 작성 실패(1) - 인증 실패 - JWT를 Bearer Token으로 보내지 않은 경우
포스트 작성 실패(2) - 인증 실패 - JWT가 유효하지 않은 경우
Service
등록 실패 : 유저가 존재하지 않을 때
등록 성공
포스트 수정
Controller
포스트 수정 실패(1) : 인증 실패
포스트 수정 실패(2) : 작성자 불일치
포스트 수정 실패(3) : 데이터베이스 에러
포스트 수정 성공
Service
수정 실패 : 포스트 존재하지 않음
수정 실패 : 작성자!=유저
수정 실패 : 유저 존재하지 않음
포스트 삭제
Controller
포스트 삭제 성공
포스트 삭제 실패(1) : 인증 실패
포스트 삭제 실패(2) : 작성자 불일치
포스트 삭제 실패(3) : 데이터베이스 에러
Service
삭제 실패 : 유저 존재하지 않음
삭제 실패 : 포스트 존재하지 않음
포스트 리스트
Controller
조회 성공 : 0번이 1번보다 날짜가 최신
Service
없음
참고자료