-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/#134 파트에 댓글 작성 기능 추가 #146
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨어요 스플릿 짱짱 👍 👍
|
||
public List<PartComment> getCommentsInRecentOrder() { | ||
return comments.stream() | ||
.sorted(Comparator.comparing((PartComment::getCreatedAt))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
recentOrder
이 최신순 정렬이 맞다면 createdAt
이 내림차순으로 정렬되어야 하지 않을까요 ?.?
그리고 괄호가 두 번 들어간건 혹시 의도된 것인지 궁금합니다!
.sorted(Comparator.comparing((PartComment::getCreatedAt))) | |
.sorted(Comparator.comparing(PartComment::getCreatedAt).reversed()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
괄호 두번은 전혀 의도되지 않았습니다ㅎㅎ 💩
import shook.shook.part.application.dto.PartCommentsResponse; | ||
|
||
@RequiredArgsConstructor | ||
@RequestMapping("/songs/{song_id}/parts/{part_id}/comment") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API url은 복수형으로 통일하는 것은 어떨까요 ㅎㅎ
comment -> comments
public class PartCommentsResponse { | ||
|
||
private List<PartCommentResponse> partReplies; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
) { | ||
final PartCommentsResponse partReplies = partCommentService.findPartReplies(partId); | ||
|
||
return ResponseEntity.ok().body(partReplies); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 body 로 따로 response를 담아준 이유가 있는지도 궁금해요~!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
메서드 체인닝 가독성 향상에 있어서 큰 장점 가진다고 생각합니다! 😊
ok(response)
보다는 ok().body(response)
가 가독성이 훨씬 좋다고 생각하여 택하였습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 나중에 같이 이야기해보고 통일하면 좋을 것 같습니당 ㅎ.ㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아니 제가 이전에는 ok(response) 를 사용했더라구요 😅 ㅎㅎㅎ
저도 익숙한게 ok(response) 인 것 같습니다!!
ok(response)로 적용하도록 하겠습니다!!👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네 ㅎㅎ
@NullSource | ||
@ParameterizedTest(name = "댓글의 내용이 \"{0}\" 일 때") | ||
@ValueSource(strings = {"", " "}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 👍 👍
final List<PartComment> repliesInRecentOrder = comments.getCommentsInRecentOrder(); | ||
|
||
//then | ||
assertThat(repliesInRecentOrder).usingRecursiveComparison().isEqualTo(List.of(early, late)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 테스트에서도 최신순 정렬이면 late이 먼저 오는게 맞지 않을까요 ?.?
assertThat(savedPartComment).isSameAs(partComment); | ||
assertThat(partComment.getId()).isNotNull(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 검증할 내용이 여러개인 경우에 assertAll 을 사용하는건 혹시 어떻게 생각하시나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 assertThat 문이 많아져 가독성이 떨어지는 경우 assertAll을 쓰는 편입니다!👍
하지만 개인적으로 검증 문이 2개 존재할 때 있어서 assertAll을 사용해서 묶어서 가독성 향상이 느껴지지는 않는 것 같아서 사용하지 않았습니다 😁
assertThat(response.getPartReplies()).hasSize(1); | ||
assertThat(response.getPartReplies().get(0).getContent()).isEqualTo("댓글 내용"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 요런 리스트를 검증하는 테스트에서 usingRecursiveComparison
을 사용하지 않고 따로 검증한 이유가 궁금해요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
검증하려는 대상에 @PrePersist 어노테이션에 의존하는 필드가 존재하여 모든 필드가 같은 Response 인스턴스 생성을 직접하기에는 불가한 상황이였습니다!
검증하려는 필드가 content 한개인 상황에서 usingRecursiveComparsion
을 사용하여 아래와 같은 메서드로 검증해도 좋다고 생각합니다~
assertThat(response.getPartReplies())
.usingRecursiveComparison()
.ignoringFields("createdAt")
.isEqualTo(List.of(new PartCommentResponse("댓글 내용", null)));
개인마다의 생각이 다를 테지만 저한테 있어서는 기존 코드가 조금 가독성이 좋다고 생각하여 사용하였습니다!!😊
backend/src/main/java/shook/shook/part/application/PartCommentService.java
Outdated
Show resolved
Hide resolved
reviewer : somsom13
TypeRef 사용에서 jsonPath().getList() 로 변경
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
전체적으로 코드가 엄청깔끔해서 읽기 쉬웠습니다 👍 👍 또 테스트 역시 꼼꼼하게 작성한 것 역시 좋았습니다
간단한 리뷰 몇가지 남겼습니다.
private final String content; | ||
private final LocalDateTime createdAt; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
id는 따로 응답값으로 안보내주는데 의도하신 것인가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 코드에서 댓글의 수정, 삭제에 대해서 고려를 하지 않아 필요하지 않은 응답이라고 생각해서 추가하지 않았습니다!!
근데 id는 기본 응답에 포함해도 괜찮을 것 같아요!! 추가하겠습니다~ 👍
@PathVariable(name = "part_id") final Long partId, | ||
@RequestBody PartCommentRegisterRequest request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분 @RequestBody
뒤에 final이 빠졌습니다!
public static PartCommentResponse from(final PartComment partComment) { | ||
return new PartCommentResponse(partComment.getContent(), partComment.getCreatedAt()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
정적 팩토리 메소드를 이용하는데 @AllArgsConstructor
의 접근제어자가 현재 public으로 되어 있습니다. 이 부분 private으로 변경하면 좋을 것 같아요~
.extract() | ||
.body() | ||
.jsonPath() | ||
.getList(".", PartCommentResponse.class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요청결과를 상태코드만 체크하는 것이 아니라 응답내용까지 체크하는 것 최곱니다 👍 👍
Reviewed-by: seokhwan-an
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
잘 구현해주셔서 코드적인 부분보다는 컨벤션 관련 코멘트가 많네요
수고 많으셨습니다 ~~~~
backend/src/main/java/shook/shook/part/application/PartCommentService.java
Outdated
Show resolved
Hide resolved
backend/src/main/java/shook/shook/part/application/dto/PartCommentRegisterRequest.java
Show resolved
Hide resolved
@PrePersist | ||
private void prePersist() { | ||
createdAt = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MILLIS truncate 하는 문제에 대해서는 같이 이야기 해봐야 할 듯 해요 🤔
저번에 문제 났던 부분이 createdAt
테스트 할 때 github flow 의 서버 시간 precision과 달라서 그랬었는데, createdAt
테스트를 따로 할 필요가 있을지도 같이 의논해보면 좋을 것 같습니다 ~ 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MILLIS truncate 관련으로 문제가 되었던 부분이 실제 DB 데이터에 시간이
와 같이 밀리초에 대한 정보가 없던 것이였습니다!! 🧐
근데 확인해보니 이 과정은 쿼리에 now() 함수를 사용하면서 생긴 문제였고 api를 사용하여 데이터를 생성시에는
밀리초까지 잘 나오는 것을 확인했습니다!! 👍
이전 createdAt 테스트에서 문제가 되었던 부분은 다시 재차 체크해보았는데 성공할 때도 있고 실패할때도 존재했습니다.
(prev를 저장 후 createdAt 생성까지 밀리초단위에서는 오차가 없는 경우) ( 차이가 있는 경우)이런 상황에서 isBefore(), isAfter()는 비교하는 시간과 같을 경우를 다르다고 판단하기에 실패하는 경우가 존재합니다!
그래서 추후에 isBetween() 은 검증하려는 시간이 비교하려는 시작과 끝에 포함되는 케이스까지 성공으로 판단하기에 검증 방식을 바꿈으로써 해결했었습니다.
제가 파악하기에는 서버 시간 precision 의 차이보다 위에 문제였던 것 같습니다!!
이 부분에 대한 테스트에 대한 필요에 대해서는 추후 논의 해보면 좋을 것 같습니다!!👍
@PostMapping | ||
public ResponseEntity<Void> registerPartComment( | ||
@PathVariable(name = "part_id") final Long partId, | ||
@RequestBody PartCommentRegisterRequest request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final
이 빠진 것 같아요 😄
//given | ||
//when | ||
//then | ||
Assertions.assertDoesNotThrow(() -> new PartCommentContent("댓글 내용")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬 static import 해주시면 제 마음이 편할 거 같아요 😊
@Autowired | ||
private PartCommentRepository partCommentRepository; | ||
|
||
@DisplayName("파트에 댓글 등록시 상태코드 CREATED 를 반환한다.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💬저번에 DisplayName은 상태코드 숫자를 썼던 것 같은데, 하나로 통일해보는 건 어떠신가요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
상태코드 숫자로 통일하였습니다!!👍
* config: dotenv설치 및 환경변수 설정 * config: msw 라이브러리 설치 및 적용 * refactor: msw 동적 import 로직 간결하게 변경 * config: package-lock 업데이트 및 script에 NODE_ENV 환경변수 * refactor: DefinePlugin common에서 공통적으로 적용 * feat: msw 파일 구조 변경 및 handler 실패시에도 response * config: package-lock.json 최신화 --------- Co-authored-by: cruelladevil <dev.timetravel@gmail.com>
* chore: 로고 아이콘 디렉터리 이동 * design: 헤더 높이 theme 추가 * design: 레이아웃 및 헤더 컴포넌트의 박스 사이징 조정 1. 헤더 높이에 맞게 main content 높이 조정 2. 로고 반응형 추가 3. 박스 사이징 시안에 맞게 수정 * design: 레이아웃 min-height 로 변경 컨텐츠가 높이를 넘어갔을 때 자연스럽게 표시되도록 수정 * design: 유튜브 영상 화면비 16:9로 반응형 구현 * design: 토글 그룹 spacing 삭제 * chore: 더미 앨범 자켓 이미지 추가 * design: 킬링파트 등록 페이지 디자인 조정 1. 더미 엘범 자켓 태그추가 2. spacing 세부 조정 3. 슬라이더 / 인터벌 인풋 위치 변경 4. 텍스트 반응형 디자인 추가 * design: theme 미적용된 속성에 theme 일괄 적용 * design: 인터벌 인풋 엑티브 색상 제거 * fix: jest 컴포넌트 랜더링 시 ThemeProvider를 제공하도록 수정 기존 render함수를 래핑한 renderWithTheme 함수 추가 및 적용 * config: 스토리북에 theme관련 설정 추가 1. 스토리북 themeProvider 적용 2. 스토리북 디렉터리 하위에도 tsc 적용되도록 설정 추가 --------- Co-authored-by: 윤정민 <dev.timetravel@gmail.com>
1. script에서 주입하던 NODE_ENV 환경변수 삭제 2. webpack.common.js 파일에서 분기로 처리하던 dotenv path 관련 로직 삭제 3. dev, prod 설정 파일 내 dotenv path 적용
Reviewed-by: somsom13, Cyma-s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아프신데도 열심히 해주셨네요
고생하셨습니다~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아픈 와중에도 너무 고생하셨어요~~~~ 최고예요!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
스플릿 사소한 부분까지 체크하는 것에서 좋았습니다.😄 리뷰 반영된 코드에서 수정할 부분이 없는 것 같습니다. 고생하셨습니다.
📝작업 내용
파트별 댓글
💬리뷰 참고사항
#️⃣연관된 이슈
close #134