From 535294eccd5f8fabddd76a80d54fa987291a488b Mon Sep 17 00:00:00 2001 From: hs12 Date: Mon, 2 Sep 2024 15:46:39 +0900 Subject: [PATCH 01/19] =?UTF-8?q?[feat]=20:=20mongoDB=20=EC=8B=9C=EA=B0=84?= =?UTF-8?q?=20UTC=20->=20KST=EC=B2=98=EB=9F=BC=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gongmuin/common/config/MongoConfig.java | 25 +++++++++++++++++++ .../DateToLocalDateTimeKstConverter.java | 19 ++++++++++++++ .../LocalDateTimeToDateKstConverter.java | 17 +++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 src/main/java/com/dnd/gongmuin/common/config/MongoConfig.java create mode 100644 src/main/java/com/dnd/gongmuin/converter/DateToLocalDateTimeKstConverter.java create mode 100644 src/main/java/com/dnd/gongmuin/converter/LocalDateTimeToDateKstConverter.java diff --git a/src/main/java/com/dnd/gongmuin/common/config/MongoConfig.java b/src/main/java/com/dnd/gongmuin/common/config/MongoConfig.java new file mode 100644 index 00000000..d0dffbe8 --- /dev/null +++ b/src/main/java/com/dnd/gongmuin/common/config/MongoConfig.java @@ -0,0 +1,25 @@ +package com.dnd.gongmuin.common.config; + +import java.util.Arrays; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; + +import com.dnd.gongmuin.converter.DateToLocalDateTimeKstConverter; +import com.dnd.gongmuin.converter.LocalDateTimeToDateKstConverter; + +@Configuration +public class MongoConfig { + + @Bean + public MongoCustomConversions customConversions( + LocalDateTimeToDateKstConverter localDateTimeToDateKstConverter, + DateToLocalDateTimeKstConverter dateToLocalDateTimeKstConverter) { + + return new MongoCustomConversions(Arrays.asList( + localDateTimeToDateKstConverter, + dateToLocalDateTimeKstConverter + )); + } +} \ No newline at end of file diff --git a/src/main/java/com/dnd/gongmuin/converter/DateToLocalDateTimeKstConverter.java b/src/main/java/com/dnd/gongmuin/converter/DateToLocalDateTimeKstConverter.java new file mode 100644 index 00000000..f47a322a --- /dev/null +++ b/src/main/java/com/dnd/gongmuin/converter/DateToLocalDateTimeKstConverter.java @@ -0,0 +1,19 @@ +package com.dnd.gongmuin.converter; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.ReadingConverter; +import org.springframework.stereotype.Component; + +@Component +@ReadingConverter +public class DateToLocalDateTimeKstConverter implements Converter { + + @Override + public LocalDateTime convert(Date source) { + return source.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().minusHours(9); + } +} diff --git a/src/main/java/com/dnd/gongmuin/converter/LocalDateTimeToDateKstConverter.java b/src/main/java/com/dnd/gongmuin/converter/LocalDateTimeToDateKstConverter.java new file mode 100644 index 00000000..4f1b02bf --- /dev/null +++ b/src/main/java/com/dnd/gongmuin/converter/LocalDateTimeToDateKstConverter.java @@ -0,0 +1,17 @@ +package com.dnd.gongmuin.converter; + +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.Date; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; + +@Component +public class LocalDateTimeToDateKstConverter implements Converter { + + @Override + public Date convert(LocalDateTime source) { + return Timestamp.valueOf(source.plusHours(9)); + } +} From fa63445c2a7242e06d05353e482ad005a46934bf Mon Sep 17 00:00:00 2001 From: hs12 Date: Mon, 2 Sep 2024 15:55:00 +0900 Subject: [PATCH 02/19] =?UTF-8?q?[style]=20:=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=20=EC=9D=91=EB=8B=B5=20dto=20=ED=95=84=EB=93=9C=EB=AA=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java | 2 +- .../dnd/gongmuin/chat/controller/ChatRoomControllerTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java index cb0a4fb3..2ae29500 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java @@ -1,7 +1,7 @@ package com.dnd.gongmuin.chat.dto; public record ChatMessageResponse( - Long memberId, + Long senderId, Long chatRoomId, String content, String type diff --git a/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java b/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java index 1756cf5a..b73127bc 100644 --- a/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java @@ -31,7 +31,7 @@ void getChatMessages() throws Exception { .cookie(accessToken)) .andExpect(status().isOk()) .andExpect(jsonPath("$.size").value(2)) - .andExpect(jsonPath("$.content[0].memberId").value(chatMessages.get(0).getMemberId())) + .andExpect(jsonPath("$.content[0].senderId").value(chatMessages.get(0).getMemberId())) .andExpect(jsonPath("$.content[0].chatRoomId").value(chatMessages.get(0).getChatRoomId())) .andExpect(jsonPath("$.content[0].content").value(chatMessages.get(0).getContent())) .andExpect(jsonPath("$.content[0].type").value(chatMessages.get(0).getType().getLabel())); From 8f28c904156a1d74b931e300669492358db1fe66 Mon Sep 17 00:00:00 2001 From: hs12 Date: Mon, 2 Sep 2024 15:56:03 +0900 Subject: [PATCH 03/19] =?UTF-8?q?[feat]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=95=84=EC=9D=B4=EB=94=94=20=EC=9D=91=EB=8B=B5=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=EC=97=90=EC=84=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java | 1 - src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java | 1 - .../com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java | 1 - 3 files changed, 3 deletions(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java index e1d2273e..bc1f51b0 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java @@ -14,7 +14,6 @@ public static ChatMessageResponse toChatMessageResponse( ) { return new ChatMessageResponse( chatMessage.getMemberId(), - chatMessage.getChatRoomId(), chatMessage.getContent(), chatMessage.getType().getLabel() ); diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java index 2ae29500..8e4e693c 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java @@ -2,7 +2,6 @@ public record ChatMessageResponse( Long senderId, - Long chatRoomId, String content, String type ) { diff --git a/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java b/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java index b73127bc..2f44a2f8 100644 --- a/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java @@ -32,7 +32,6 @@ void getChatMessages() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.size").value(2)) .andExpect(jsonPath("$.content[0].senderId").value(chatMessages.get(0).getMemberId())) - .andExpect(jsonPath("$.content[0].chatRoomId").value(chatMessages.get(0).getChatRoomId())) .andExpect(jsonPath("$.content[0].content").value(chatMessages.get(0).getContent())) .andExpect(jsonPath("$.content[0].type").value(chatMessages.get(0).getType().getLabel())); } From 7c03c9f8f243315c88cab2a7010116491f17db6d Mon Sep 17 00:00:00 2001 From: hs12 Date: Mon, 2 Sep 2024 15:57:26 +0900 Subject: [PATCH 04/19] =?UTF-8?q?[feat]=20:=20=EC=9D=91=EB=8B=B5=20DTO=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=EC=97=90=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=8B=9C=EA=B0=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java | 3 ++- .../java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java index bc1f51b0..86e837f3 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java @@ -15,7 +15,8 @@ public static ChatMessageResponse toChatMessageResponse( return new ChatMessageResponse( chatMessage.getMemberId(), chatMessage.getContent(), - chatMessage.getType().getLabel() + chatMessage.getType().getLabel(), + chatMessage.getCreatedAt().toString() ); } diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java index 8e4e693c..0962655d 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java @@ -3,6 +3,7 @@ public record ChatMessageResponse( Long senderId, String content, - String type + String type, + String createdAt ) { } From 6cac33fa23fba4d194f08cef60d2cf468bde17f4 Mon Sep 17 00:00:00 2001 From: hs12 Date: Thu, 5 Sep 2024 23:58:54 +0900 Subject: [PATCH 05/19] =?UTF-8?q?[feat]=20:=20chatRoomRepository=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dnd/gongmuin/chat/repository/ChatRoomRepository.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomRepository.java diff --git a/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomRepository.java b/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomRepository.java new file mode 100644 index 00000000..7ea09775 --- /dev/null +++ b/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomRepository.java @@ -0,0 +1,8 @@ +package com.dnd.gongmuin.chat.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.dnd.gongmuin.chat.domain.ChatRoom; + +public interface ChatRoomRepository extends JpaRepository { +} From 0cbb486b7d05863996150f9bd0e8f22370c97365 Mon Sep 17 00:00:00 2001 From: hs12 Date: Mon, 9 Sep 2024 22:29:41 +0900 Subject: [PATCH 06/19] =?UTF-8?q?[feat]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dnd/gongmuin/chat/exception/ChatErrorCode.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/exception/ChatErrorCode.java b/src/main/java/com/dnd/gongmuin/chat/exception/ChatErrorCode.java index c0e65406..d26d0a57 100644 --- a/src/main/java/com/dnd/gongmuin/chat/exception/ChatErrorCode.java +++ b/src/main/java/com/dnd/gongmuin/chat/exception/ChatErrorCode.java @@ -9,7 +9,8 @@ @RequiredArgsConstructor public enum ChatErrorCode implements ErrorCode { - INVALID_MESSAGE_TYPE("메시지 타입을 올바르게 입력해주세요.", "CH_001"); + INVALID_MESSAGE_TYPE("메시지 타입을 올바르게 입력해주세요.", "CH_001"), + NOT_FOUND_CHAT_ROOM("해당 아이디의 채팅방이 존재하지 않습니다.", "CH_002"); private final String message; private final String code; From 12eddef01893af5c0f81647ead820f966a694b53 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 13:48:48 +0900 Subject: [PATCH 07/19] =?UTF-8?q?[feat]=20:=20chatRoom=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dnd/gongmuin/chat/domain/ChatRoom.java | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/domain/ChatRoom.java b/src/main/java/com/dnd/gongmuin/chat/domain/ChatRoom.java index 11aaef9c..4e840fff 100644 --- a/src/main/java/com/dnd/gongmuin/chat/domain/ChatRoom.java +++ b/src/main/java/com/dnd/gongmuin/chat/domain/ChatRoom.java @@ -16,7 +16,6 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import lombok.AccessLevel; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -31,25 +30,36 @@ public class ChatRoom extends TimeBaseEntity { private Long id; @ManyToOne(fetch = LAZY) - @JoinColumn(name = "questioner_id", nullable = false, + @JoinColumn(name = "question_post_id", + nullable = false, foreignKey = @ForeignKey(NO_CONSTRAINT)) - private Member questioner; + private QuestionPost questionPost; @ManyToOne(fetch = LAZY) - @JoinColumn(name = "answerer_id", nullable = false, + @JoinColumn(name = "requester_id", nullable = false, foreignKey = @ForeignKey(NO_CONSTRAINT)) - private Member answerer; + private Member requester; @ManyToOne(fetch = LAZY) - @JoinColumn(name = "question_post_id", - nullable = false, + @JoinColumn(name = "answerer_id", nullable = false, foreignKey = @ForeignKey(NO_CONSTRAINT)) - private QuestionPost questionPost; + private Member answerer; - @Builder - public ChatRoom(Member questioner, Member answerer, QuestionPost questionPost) { - this.questioner = questioner; - this.answerer = answerer; + @Column(name = "is_accepted", nullable = false) + private boolean isAccepted; + + private ChatRoom(QuestionPost questionPost, Member requester, Member answerer) { this.questionPost = questionPost; + this.requester = requester; + this.answerer = answerer; + this.isAccepted = false; + } + + public static ChatRoom of( + QuestionPost questionPost, + Member requester, + Member answerer + ) { + return new ChatRoom(questionPost, requester, answerer); } } From 3658af5c810683adf159bcafe9e2b418c94a4471 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 14:42:52 +0900 Subject: [PATCH 08/19] =?UTF-8?q?[feat]=20:=20chatRoom=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=ED=95=84=EB=93=9C=EB=AA=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dnd/gongmuin/chat/domain/ChatRoom.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/domain/ChatRoom.java b/src/main/java/com/dnd/gongmuin/chat/domain/ChatRoom.java index 4e840fff..8f7c386f 100644 --- a/src/main/java/com/dnd/gongmuin/chat/domain/ChatRoom.java +++ b/src/main/java/com/dnd/gongmuin/chat/domain/ChatRoom.java @@ -4,7 +4,9 @@ import static jakarta.persistence.FetchType.*; import com.dnd.gongmuin.common.entity.TimeBaseEntity; +import com.dnd.gongmuin.common.exception.runtime.ValidationException; import com.dnd.gongmuin.member.domain.Member; +import com.dnd.gongmuin.member.exception.MemberErrorCode; import com.dnd.gongmuin.question_post.domain.QuestionPost; import jakarta.persistence.Column; @@ -36,9 +38,9 @@ public class ChatRoom extends TimeBaseEntity { private QuestionPost questionPost; @ManyToOne(fetch = LAZY) - @JoinColumn(name = "requester_id", nullable = false, + @JoinColumn(name = "inquirer_id", nullable = false, foreignKey = @ForeignKey(NO_CONSTRAINT)) - private Member requester; + private Member inquirer; @ManyToOne(fetch = LAZY) @JoinColumn(name = "answerer_id", nullable = false, @@ -48,18 +50,25 @@ public class ChatRoom extends TimeBaseEntity { @Column(name = "is_accepted", nullable = false) private boolean isAccepted; - private ChatRoom(QuestionPost questionPost, Member requester, Member answerer) { + private ChatRoom(QuestionPost questionPost, Member inquirer, Member answerer) { this.questionPost = questionPost; - this.requester = requester; + this.inquirer = inquirer; this.answerer = answerer; this.isAccepted = false; + validateInquirerCredit(); } public static ChatRoom of( QuestionPost questionPost, - Member requester, + Member inquirer, Member answerer ) { - return new ChatRoom(questionPost, requester, answerer); + return new ChatRoom(questionPost, inquirer, answerer); + } + + private void validateInquirerCredit() { + if (inquirer.getCredit() < 2000) { + throw new ValidationException(MemberErrorCode.NOT_ENOUGH_CREDIT); + } } } From 0458f9ef506ad5527d8a827715101b9326f61b02 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 15:11:22 +0900 Subject: [PATCH 09/19] =?UTF-8?q?[rename]=20:=20request,=20response=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=B6=94=EA=B0=80=ED=95=B4=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gongmuin/chat/dto/{ => request}/ChatMessageRequest.java | 2 +- .../gongmuin/chat/dto/{ => response}/ChatMessageResponse.java | 2 +- .../com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) rename src/main/java/com/dnd/gongmuin/chat/dto/{ => request}/ChatMessageRequest.java (89%) rename src/main/java/com/dnd/gongmuin/chat/dto/{ => response}/ChatMessageResponse.java (70%) diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageRequest.java b/src/main/java/com/dnd/gongmuin/chat/dto/request/ChatMessageRequest.java similarity index 89% rename from src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageRequest.java rename to src/main/java/com/dnd/gongmuin/chat/dto/request/ChatMessageRequest.java index 3deffea8..90654923 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageRequest.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/request/ChatMessageRequest.java @@ -1,4 +1,4 @@ -package com.dnd.gongmuin.chat.dto; +package com.dnd.gongmuin.chat.dto.request; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatMessageResponse.java similarity index 70% rename from src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java rename to src/main/java/com/dnd/gongmuin/chat/dto/response/ChatMessageResponse.java index 0962655d..c436ce89 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageResponse.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatMessageResponse.java @@ -1,4 +1,4 @@ -package com.dnd.gongmuin.chat.dto; +package com.dnd.gongmuin.chat.dto.response; public record ChatMessageResponse( Long senderId, diff --git a/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java b/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java index 347587ff..cfa083e3 100644 --- a/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java @@ -16,7 +16,7 @@ import org.springframework.data.domain.SliceImpl; import com.dnd.gongmuin.chat.domain.ChatMessage; -import com.dnd.gongmuin.chat.dto.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; import com.dnd.gongmuin.chat.repository.ChatMessageRepository; import com.dnd.gongmuin.common.fixture.ChatMessageFixture; @@ -45,7 +45,6 @@ void getChatMessages() { //then assertAll( - () -> assertThat(response.get(0).chatRoomId()).isEqualTo(1L), () -> assertThat(response).hasSize(1) ); } From c2729f92afac547111817393ed10f20b3f0dd7c5 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 15:17:25 +0900 Subject: [PATCH 10/19] =?UTF-8?q?[feat]=20:=20chatMessageMapper=EB=A1=9C?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/controller/ChatMessageController.java | 4 ++-- .../dto/{ChatMapper.java => ChatMessageMapper.java} | 4 +++- .../dnd/gongmuin/chat/service/ChatMessageService.java | 11 ++++++----- 3 files changed, 11 insertions(+), 8 deletions(-) rename src/main/java/com/dnd/gongmuin/chat/dto/{ChatMapper.java => ChatMessageMapper.java} (82%) diff --git a/src/main/java/com/dnd/gongmuin/chat/controller/ChatMessageController.java b/src/main/java/com/dnd/gongmuin/chat/controller/ChatMessageController.java index 4647425f..0ce6aac0 100644 --- a/src/main/java/com/dnd/gongmuin/chat/controller/ChatMessageController.java +++ b/src/main/java/com/dnd/gongmuin/chat/controller/ChatMessageController.java @@ -6,8 +6,8 @@ import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Controller; -import com.dnd.gongmuin.chat.dto.ChatMessageRequest; -import com.dnd.gongmuin.chat.dto.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.request.ChatMessageRequest; +import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; import com.dnd.gongmuin.chat.service.ChatMessageService; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageMapper.java similarity index 82% rename from src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java rename to src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageMapper.java index 86e837f3..6ef1bf27 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/ChatMapper.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/ChatMessageMapper.java @@ -2,12 +2,14 @@ import com.dnd.gongmuin.chat.domain.ChatMessage; import com.dnd.gongmuin.chat.domain.MessageType; +import com.dnd.gongmuin.chat.dto.request.ChatMessageRequest; +import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; import lombok.AccessLevel; import lombok.NoArgsConstructor; @NoArgsConstructor(access = AccessLevel.PRIVATE) -public class ChatMapper { +public class ChatMessageMapper { public static ChatMessageResponse toChatMessageResponse( ChatMessage chatMessage diff --git a/src/main/java/com/dnd/gongmuin/chat/service/ChatMessageService.java b/src/main/java/com/dnd/gongmuin/chat/service/ChatMessageService.java index 85a7c092..f001e5db 100644 --- a/src/main/java/com/dnd/gongmuin/chat/service/ChatMessageService.java +++ b/src/main/java/com/dnd/gongmuin/chat/service/ChatMessageService.java @@ -4,9 +4,9 @@ import org.springframework.transaction.annotation.Transactional; import com.dnd.gongmuin.chat.domain.ChatMessage; -import com.dnd.gongmuin.chat.dto.ChatMapper; -import com.dnd.gongmuin.chat.dto.ChatMessageRequest; -import com.dnd.gongmuin.chat.dto.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.ChatMessageMapper; +import com.dnd.gongmuin.chat.dto.request.ChatMessageRequest; +import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; import com.dnd.gongmuin.chat.repository.ChatMessageRepository; import lombok.RequiredArgsConstructor; @@ -25,8 +25,9 @@ public ChatMessageResponse saveChatMessage( Long chatRoomId ) { Long memberId = request.memberId(); - ChatMessage chatMessage = chatMessageRepository.save(ChatMapper.toChatMessage(request, chatRoomId, memberId)); + ChatMessage chatMessage = chatMessageRepository.save( + ChatMessageMapper.toChatMessage(request, chatRoomId, memberId)); log.info("chatRoomId = {}, memberId= {}, chatMessageId= {}", chatRoomId, memberId, chatMessage.getId()); - return ChatMapper.toChatMessageResponse(chatMessage); + return ChatMessageMapper.toChatMessageResponse(chatMessage); } } From 0221ed78f221897b71546d97c2c8338c4586453b Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 15:17:45 +0900 Subject: [PATCH 11/19] =?UTF-8?q?[feat]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1,=20=EC=83=81=EC=84=B8=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20DTO=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/dto/request/CreateChatRoomRequest.java | 12 ++++++++++++ .../chat/dto/response/ChatRoomDetailResponse.java | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java create mode 100644 src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomDetailResponse.java diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java b/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java new file mode 100644 index 00000000..4b8501ba --- /dev/null +++ b/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java @@ -0,0 +1,12 @@ +package com.dnd.gongmuin.chat.dto.request; + +import jakarta.validation.constraints.NotBlank; + +public record CreateChatRoomRequest( + @NotBlank(message = "질문 게시글 아이디를 입력해주세요.") + Long questionPostId, + + @NotBlank(message = "답변자 아이디를 입력해주세요.") + Long answererId +) { +} diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomDetailResponse.java b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomDetailResponse.java new file mode 100644 index 00000000..5906f60e --- /dev/null +++ b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomDetailResponse.java @@ -0,0 +1,12 @@ +package com.dnd.gongmuin.chat.dto.response; + +import com.dnd.gongmuin.question_post.dto.response.MemberInfo; + +public record ChatRoomDetailResponse( + Long questionPostId, + String targetJobGroup, + String title, + MemberInfo receiverInfo, + boolean isAccepted +) { +} From bc6c8079eba76c117e91d374ab47b0d948c80b19 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 15:23:19 +0900 Subject: [PATCH 12/19] =?UTF-8?q?[feat]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dnd/gongmuin/chat/dto/ChatRoomMapper.java | 44 +++++++++++++++++++ .../chat/service/ChatRoomService.java | 38 ++++++++++++++-- 2 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/dnd/gongmuin/chat/dto/ChatRoomMapper.java diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatRoomMapper.java b/src/main/java/com/dnd/gongmuin/chat/dto/ChatRoomMapper.java new file mode 100644 index 00000000..6f90e76e --- /dev/null +++ b/src/main/java/com/dnd/gongmuin/chat/dto/ChatRoomMapper.java @@ -0,0 +1,44 @@ +package com.dnd.gongmuin.chat.dto; + +import com.dnd.gongmuin.chat.domain.ChatRoom; +import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; +import com.dnd.gongmuin.member.domain.Member; +import com.dnd.gongmuin.question_post.domain.QuestionPost; +import com.dnd.gongmuin.question_post.dto.response.MemberInfo; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ChatRoomMapper { + + public static ChatRoom toChatRoom( + QuestionPost questionPost, + Member inquirer, + Member answerer + ) { + return ChatRoom.of( + questionPost, + inquirer, + answerer + ); + } + + public static ChatRoomDetailResponse toChatRoomDetailResponse(ChatRoom chatRoom) { + QuestionPost questionPost = chatRoom.getQuestionPost(); + Member answerer = chatRoom.getAnswerer(); // 요청자만 채팅방 생성 가능 -> 상태방: 답변자 + + return new ChatRoomDetailResponse( + questionPost.getId(), + questionPost.getJobGroup().getLabel(), + questionPost.getTitle(), + new MemberInfo( + answerer.getId(), + answerer.getNickname(), + answerer.getJobGroup().getLabel(), + answerer.getProfileImageNo() + ), + chatRoom.isAccepted() + ); + } +} diff --git a/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java b/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java index e8e25774..a80b6f78 100644 --- a/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java +++ b/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java @@ -5,11 +5,22 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.dnd.gongmuin.chat.dto.ChatMapper; -import com.dnd.gongmuin.chat.dto.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.ChatMessageMapper; +import com.dnd.gongmuin.chat.dto.ChatRoomMapper; +import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; +import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.repository.ChatMessageRepository; +import com.dnd.gongmuin.chat.repository.ChatRoomRepository; import com.dnd.gongmuin.common.dto.PageMapper; import com.dnd.gongmuin.common.dto.PageResponse; +import com.dnd.gongmuin.common.exception.runtime.NotFoundException; +import com.dnd.gongmuin.member.domain.Member; +import com.dnd.gongmuin.member.exception.MemberErrorCode; +import com.dnd.gongmuin.member.repository.MemberRepository; +import com.dnd.gongmuin.question_post.domain.QuestionPost; +import com.dnd.gongmuin.question_post.exception.QuestionPostErrorCode; +import com.dnd.gongmuin.question_post.repository.QuestionPostRepository; import lombok.RequiredArgsConstructor; @@ -18,13 +29,34 @@ public class ChatRoomService { private final ChatMessageRepository chatMessageRepository; + private final ChatRoomRepository chatRoomRepository; + private final MemberRepository memberRepository; + private final QuestionPostRepository questionPostRepository; @Transactional(readOnly = true) public PageResponse getChatMessages(Long chatRoomId, Pageable pageable) { Slice responsePage = chatMessageRepository .findByChatRoomIdOrderByCreatedAtDesc(chatRoomId, pageable) - .map(ChatMapper::toChatMessageResponse); + .map(ChatMessageMapper::toChatMessageResponse); return PageMapper.toPageResponse(responsePage); } + @Transactional + public ChatRoomDetailResponse createChatRoom(CreateChatRoomRequest request, Member inquirer) { + QuestionPost questionPost = getQuestionPostById(request.questionPostId()); + Member answerer = getMemberById(request.answererId()); + return ChatRoomMapper.toChatRoomDetailResponse( + chatRoomRepository.save(ChatRoomMapper.toChatRoom(questionPost, inquirer, answerer)) + ); + } + + private QuestionPost getQuestionPostById(Long id){ + return questionPostRepository.findById(id) + .orElseThrow(() -> new NotFoundException(QuestionPostErrorCode.NOT_FOUND_QUESTION_POST)); + } + private Member getMemberById(Long id){ + return memberRepository.findById(id) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.NOT_FOUND_MEMBER)); + } } + From 876af4c51001f187ae1d4032f0d23607a6870970 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 15:44:56 +0900 Subject: [PATCH 13/19] =?UTF-8?q?[test]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/service/ChatRoomServiceTest.java | 51 +++++++++++++++++++ .../common/fixture/ChatRoomFixture.java | 24 +++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/test/java/com/dnd/gongmuin/common/fixture/ChatRoomFixture.java diff --git a/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java b/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java index cfa083e3..a85b5b38 100644 --- a/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java @@ -5,6 +5,7 @@ import static org.mockito.BDDMockito.*; import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -16,9 +17,20 @@ import org.springframework.data.domain.SliceImpl; import com.dnd.gongmuin.chat.domain.ChatMessage; +import com.dnd.gongmuin.chat.domain.ChatRoom; +import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; import com.dnd.gongmuin.chat.repository.ChatMessageRepository; +import com.dnd.gongmuin.chat.repository.ChatRoomRepository; import com.dnd.gongmuin.common.fixture.ChatMessageFixture; +import com.dnd.gongmuin.common.fixture.ChatRoomFixture; +import com.dnd.gongmuin.common.fixture.MemberFixture; +import com.dnd.gongmuin.common.fixture.QuestionPostFixture; +import com.dnd.gongmuin.member.domain.Member; +import com.dnd.gongmuin.member.repository.MemberRepository; +import com.dnd.gongmuin.question_post.domain.QuestionPost; +import com.dnd.gongmuin.question_post.repository.QuestionPostRepository; @DisplayName("[채팅방 메시지 서비스 단위 테스트]") @ExtendWith(MockitoExtension.class) @@ -29,6 +41,15 @@ class ChatRoomServiceTest { @Mock private ChatMessageRepository chatMessageRepository; + @Mock + private ChatRoomRepository chatRoomRepository; + + @Mock + private MemberRepository memberRepository; + + @Mock + private QuestionPostRepository questionPostRepository; + @InjectMocks private ChatRoomService chatRoomService; @@ -48,4 +69,34 @@ void getChatMessages() { () -> assertThat(response).hasSize(1) ); } + + @DisplayName("[요청자가 채팅방을 생성할 수 있다.]") + @Test + void createChatRoom() { + //given + Member inquirer = MemberFixture.member(1L); + Member answerer = MemberFixture.member(2L); + QuestionPost questionPost = QuestionPostFixture.questionPost(inquirer); + CreateChatRoomRequest request = new CreateChatRoomRequest( + questionPost.getId(), + answerer.getId() + ); + ChatRoom chatRoom = ChatRoomFixture.chatRoom(questionPost, inquirer, answerer); + + given(questionPostRepository.findById(questionPost.getId())) + .willReturn(Optional.of(questionPost)); + given(memberRepository.findById(answerer.getId())) + .willReturn(Optional.of(answerer)); + given(chatRoomRepository.save(any(ChatRoom.class))) + .willReturn(chatRoom); + + //when + ChatRoomDetailResponse response = chatRoomService.createChatRoom(request, inquirer); + + //then + assertAll( + () -> assertThat(response.questionPostId()).isEqualTo(request.questionPostId()), + () -> assertThat(response.receiverInfo().memberId()).isEqualTo(request.answererId()) + ); + } } \ No newline at end of file diff --git a/src/test/java/com/dnd/gongmuin/common/fixture/ChatRoomFixture.java b/src/test/java/com/dnd/gongmuin/common/fixture/ChatRoomFixture.java new file mode 100644 index 00000000..aebb8333 --- /dev/null +++ b/src/test/java/com/dnd/gongmuin/common/fixture/ChatRoomFixture.java @@ -0,0 +1,24 @@ +package com.dnd.gongmuin.common.fixture; + +import com.dnd.gongmuin.chat.domain.ChatRoom; +import com.dnd.gongmuin.member.domain.Member; +import com.dnd.gongmuin.question_post.domain.QuestionPost; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ChatRoomFixture { + + public static ChatRoom chatRoom( + QuestionPost questionPost, + Member inquirer, + Member answerer + ) { + return ChatRoom.of( + questionPost, + inquirer, + answerer + ); + } +} \ No newline at end of file From 65f40ffcfa30c1add440638f1c1a2c2c9598e9f1 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 15:48:38 +0900 Subject: [PATCH 14/19] =?UTF-8?q?[feat]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20API=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/controller/ChatRoomController.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java b/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java index f1c5fe2f..8bb75fe1 100644 --- a/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java +++ b/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java @@ -2,16 +2,22 @@ import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; -import com.dnd.gongmuin.chat.dto.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; +import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.service.ChatRoomService; import com.dnd.gongmuin.common.dto.PageResponse; +import com.dnd.gongmuin.member.domain.Member; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @Tag(name = "채팅방 API") @@ -31,4 +37,14 @@ public ResponseEntity> getChatMessages( chatRoomService.getChatMessages(chatRoomId, pageable); return ResponseEntity.ok(response); } + + @Operation(summary = "채팅방 생성 API", description = "요청자가 답변자와의 채팅방을 생성한다.") + @PostMapping("/api/chat-rooms") + public ResponseEntity createChatRoom( + @Valid CreateChatRoomRequest request, + @AuthenticationPrincipal Member member + ) { + ChatRoomDetailResponse response = chatRoomService.createChatRoom(request, member); + return ResponseEntity.ok(response); + } } From 56a66b83d47c606d70b9018209785e3695b840e6 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 15:59:56 +0900 Subject: [PATCH 15/19] =?UTF-8?q?[test]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=98=88=EC=99=B8=20=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/service/ChatRoomServiceTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java b/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java index a85b5b38..127470f2 100644 --- a/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java @@ -15,6 +15,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.SliceImpl; +import org.springframework.test.util.ReflectionTestUtils; import com.dnd.gongmuin.chat.domain.ChatMessage; import com.dnd.gongmuin.chat.domain.ChatRoom; @@ -23,11 +24,13 @@ import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; import com.dnd.gongmuin.chat.repository.ChatMessageRepository; import com.dnd.gongmuin.chat.repository.ChatRoomRepository; +import com.dnd.gongmuin.common.exception.runtime.ValidationException; import com.dnd.gongmuin.common.fixture.ChatMessageFixture; import com.dnd.gongmuin.common.fixture.ChatRoomFixture; import com.dnd.gongmuin.common.fixture.MemberFixture; import com.dnd.gongmuin.common.fixture.QuestionPostFixture; import com.dnd.gongmuin.member.domain.Member; +import com.dnd.gongmuin.member.exception.MemberErrorCode; import com.dnd.gongmuin.member.repository.MemberRepository; import com.dnd.gongmuin.question_post.domain.QuestionPost; import com.dnd.gongmuin.question_post.repository.QuestionPostRepository; @@ -99,4 +102,28 @@ void createChatRoom() { () -> assertThat(response.receiverInfo().memberId()).isEqualTo(request.answererId()) ); } + + @DisplayName("[요청자의 크레딧이 2000미만이면 채팅방을 생성할 수 없다.]") + @Test + void createChatRoom_fail() { + //given + Member inquirer = MemberFixture.member(1L); + Member answerer = MemberFixture.member(2L); + ReflectionTestUtils.setField(inquirer, "credit", 1999); + QuestionPost questionPost = QuestionPostFixture.questionPost(inquirer); + CreateChatRoomRequest request = new CreateChatRoomRequest( + questionPost.getId(), + answerer.getId() + ); + + given(questionPostRepository.findById(questionPost.getId())) + .willReturn(Optional.of(questionPost)); + given(memberRepository.findById(answerer.getId())) + .willReturn(Optional.of(answerer)); + + //when & then + assertThatThrownBy(() -> chatRoomService.createChatRoom(request, inquirer)) + .isInstanceOf(ValidationException.class) + .hasMessageContaining(MemberErrorCode.NOT_ENOUGH_CREDIT.getMessage()); + } } \ No newline at end of file From d71de7dce9e06ffab78dd77e20c17207bb1df1c0 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 16:12:03 +0900 Subject: [PATCH 16/19] =?UTF-8?q?[feat]=20:=20=EB=88=84=EB=9D=BD=EB=90=9C?= =?UTF-8?q?=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dnd/gongmuin/chat/controller/ChatRoomController.java | 3 ++- .../gongmuin/chat/dto/request/CreateChatRoomRequest.java | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java b/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java index 8bb75fe1..94496360 100644 --- a/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java +++ b/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; @@ -41,7 +42,7 @@ public ResponseEntity> getChatMessages( @Operation(summary = "채팅방 생성 API", description = "요청자가 답변자와의 채팅방을 생성한다.") @PostMapping("/api/chat-rooms") public ResponseEntity createChatRoom( - @Valid CreateChatRoomRequest request, + @Valid @RequestBody CreateChatRoomRequest request, @AuthenticationPrincipal Member member ) { ChatRoomDetailResponse response = chatRoomService.createChatRoom(request, member); diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java b/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java index 4b8501ba..99d40d86 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java @@ -1,12 +1,12 @@ package com.dnd.gongmuin.chat.dto.request; -import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; public record CreateChatRoomRequest( - @NotBlank(message = "질문 게시글 아이디를 입력해주세요.") + @NotNull(message = "질문 게시글 아이디를 입력해주세요.") Long questionPostId, - @NotBlank(message = "답변자 아이디를 입력해주세요.") + @NotNull(message = "답변자 아이디를 입력해주세요.") Long answererId ) { } From d20989bbb6ef58b8303d9d385e623ddc3a84920c Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 16:12:55 +0900 Subject: [PATCH 17/19] =?UTF-8?q?[test]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ChatRoomControllerTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java b/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java index 2f44a2f8..d818a601 100644 --- a/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java @@ -1,5 +1,6 @@ package com.dnd.gongmuin.chat.controller; +import static org.springframework.http.MediaType.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -10,9 +11,16 @@ import org.springframework.beans.factory.annotation.Autowired; import com.dnd.gongmuin.chat.domain.ChatMessage; +import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.repository.ChatMessageRepository; import com.dnd.gongmuin.common.fixture.ChatMessageFixture; +import com.dnd.gongmuin.common.fixture.MemberFixture; +import com.dnd.gongmuin.common.fixture.QuestionPostFixture; import com.dnd.gongmuin.common.support.ApiTestSupport; +import com.dnd.gongmuin.member.domain.Member; +import com.dnd.gongmuin.member.repository.MemberRepository; +import com.dnd.gongmuin.question_post.domain.QuestionPost; +import com.dnd.gongmuin.question_post.repository.QuestionPostRepository; @DisplayName("[ChatMessage 통합 테스트]") class ChatRoomControllerTest extends ApiTestSupport { @@ -20,6 +28,12 @@ class ChatRoomControllerTest extends ApiTestSupport { @Autowired private ChatMessageRepository chatMessageRepository; + @Autowired + private MemberRepository memberRepository; + + @Autowired + private QuestionPostRepository questionPostRepository; + @DisplayName("[채팅방 아이디로 메시지를 조회할 수 있다.]") @Test void getChatMessages() throws Exception { @@ -35,4 +49,19 @@ void getChatMessages() throws Exception { .andExpect(jsonPath("$.content[0].content").value(chatMessages.get(0).getContent())) .andExpect(jsonPath("$.content[0].type").value(chatMessages.get(0).getType().getLabel())); } + + @DisplayName("[채팅방을 생성할 수 있다.]") + @Test + void createChatRoom() throws Exception { + Member answerer = memberRepository.save(MemberFixture.member4()); + QuestionPost questionPost = questionPostRepository.save(QuestionPostFixture.questionPost(loginMember)); + CreateChatRoomRequest request = new CreateChatRoomRequest(questionPost.getId(), answerer.getId()); + + mockMvc.perform(post("/api/chat-rooms") + .cookie(accessToken) + .content(toJson(request)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()); + } + } \ No newline at end of file From b4fe52579f4b5b5833a9bebb99092ba900c2de6b Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 13 Sep 2024 16:13:24 +0900 Subject: [PATCH 18/19] =?UTF-8?q?[style]=20:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=ED=8F=AC=EB=A9=A7=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dnd/gongmuin/chat/controller/ChatRoomController.java | 2 +- .../com/dnd/gongmuin/chat/service/ChatRoomService.java | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java b/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java index 94496360..a007e754 100644 --- a/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java +++ b/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java @@ -9,9 +9,9 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; -import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.service.ChatRoomService; import com.dnd.gongmuin.common.dto.PageResponse; import com.dnd.gongmuin.member.domain.Member; diff --git a/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java b/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java index a80b6f78..5e6058b8 100644 --- a/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java +++ b/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java @@ -7,9 +7,9 @@ import com.dnd.gongmuin.chat.dto.ChatMessageMapper; import com.dnd.gongmuin.chat.dto.ChatRoomMapper; +import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; -import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.repository.ChatMessageRepository; import com.dnd.gongmuin.chat.repository.ChatRoomRepository; import com.dnd.gongmuin.common.dto.PageMapper; @@ -50,11 +50,12 @@ public ChatRoomDetailResponse createChatRoom(CreateChatRoomRequest request, Memb ); } - private QuestionPost getQuestionPostById(Long id){ + private QuestionPost getQuestionPostById(Long id) { return questionPostRepository.findById(id) .orElseThrow(() -> new NotFoundException(QuestionPostErrorCode.NOT_FOUND_QUESTION_POST)); } - private Member getMemberById(Long id){ + + private Member getMemberById(Long id) { return memberRepository.findById(id) .orElseThrow(() -> new NotFoundException(MemberErrorCode.NOT_FOUND_MEMBER)); } From 011d4d339d5b98f06d82e35a03fdce7bf6a97b5c Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 14 Sep 2024 15:33:11 +0900 Subject: [PATCH 19/19] =?UTF-8?q?[feat]=20:=20dto=20=EB=A9=94=EC=8B=9C?= =?UTF-8?q?=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java b/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java index 99d40d86..40f3e7bd 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/request/CreateChatRoomRequest.java @@ -3,10 +3,10 @@ import jakarta.validation.constraints.NotNull; public record CreateChatRoomRequest( - @NotNull(message = "질문 게시글 아이디를 입력해주세요.") + @NotNull(message = "질문 게시글 아이디는 필수 입력 항목입니다.") Long questionPostId, - @NotNull(message = "답변자 아이디를 입력해주세요.") + @NotNull(message = "답변 아이디는 필수 입력 항목입니다.") Long answererId ) { }