-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feat-question-comment' into dev
- Loading branch information
Showing
15 changed files
with
313 additions
and
20 deletions.
There are no files selected for viewing
6 changes: 6 additions & 0 deletions
6
src/main/kotlin/site/qbox/qboxserver/domain/answer/command/AnswerCommentRepo.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package site.qbox.qboxserver.domain.answer.command | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository | ||
import site.qbox.qboxserver.domain.answer.command.entity.AnswerComment | ||
|
||
interface AnswerCommentRepo : JpaRepository<AnswerComment, Long> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
src/main/kotlin/site/qbox/qboxserver/domain/answer/command/AnswerSvc.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,21 @@ | ||
package site.qbox.qboxserver.domain.answer.command | ||
|
||
import site.qbox.qboxserver.domain.answer.command.dto.CreateAnswerCommentReq | ||
import site.qbox.qboxserver.domain.answer.command.dto.CreateAnswerReq | ||
import site.qbox.qboxserver.domain.answer.command.entity.Answer | ||
import site.qbox.qboxserver.domain.answer.command.entity.AnswerComment | ||
import site.qbox.qboxserver.global.annotation.CommandService | ||
|
||
@CommandService | ||
class AnswerSvc ( | ||
private val answerRepo: AnswerRepo, | ||
private val answerCommentRepo: AnswerCommentRepo, | ||
){ | ||
fun create(req: CreateAnswerReq, writer: String) { | ||
answerRepo.save(Answer(req.content, req.question, writer)) | ||
} | ||
|
||
fun addAnswer(req: CreateAnswerCommentReq, writer: String) { | ||
answerCommentRepo.save(AnswerComment(req.content, writer, req.answer)) | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/kotlin/site/qbox/qboxserver/domain/answer/command/dto/CreateAnswerCommentReq.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package site.qbox.qboxserver.domain.answer.command.dto | ||
|
||
import site.qbox.qboxserver.domain.answer.command.entity.AnswerId | ||
|
||
data class CreateAnswerCommentReq ( | ||
val answer: AnswerId, | ||
val content: String, | ||
) |
11 changes: 11 additions & 0 deletions
11
src/main/kotlin/site/qbox/qboxserver/domain/answer/command/entity/AnswerComment.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package site.qbox.qboxserver.domain.answer.command.entity | ||
|
||
import jakarta.persistence.* | ||
|
||
@Entity | ||
class AnswerComment( | ||
@Lob var content: String, | ||
var commentWriterId: String, | ||
@Embedded val answer: AnswerId, | ||
@Id @GeneratedValue val id: Long = 0L, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/main/kotlin/site/qbox/qboxserver/domain/answer/query/dto/AnswerCommentRes.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package site.qbox.qboxserver.domain.answer.query.dto | ||
|
||
import com.querydsl.core.annotations.QueryProjection | ||
import site.qbox.qboxserver.domain.member.query.dto.MemberRes | ||
|
||
data class AnswerCommentRes @QueryProjection constructor( | ||
val id: Long, | ||
val content: String, | ||
val writer: MemberRes, | ||
) |
9 changes: 6 additions & 3 deletions
9
src/main/kotlin/site/qbox/qboxserver/domain/answer/query/dto/AnswerRes.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,13 @@ | ||
package site.qbox.qboxserver.domain.answer.query.dto | ||
|
||
import com.querydsl.core.annotations.QueryProjection | ||
import site.qbox.qboxserver.domain.member.query.dto.MemberRes | ||
|
||
data class AnswerRes @QueryProjection constructor( | ||
data class AnswerRes( | ||
val content: String, | ||
val questionId: Long, | ||
val writer: MemberRes, | ||
) | ||
val comments: List<AnswerCommentRes> | ||
) { | ||
constructor(res: AnswerSummary, comments: List<AnswerCommentRes>) : | ||
this(res.content, res.questionId, res.writer, comments) | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/kotlin/site/qbox/qboxserver/domain/answer/query/dto/AnswerSummary.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package site.qbox.qboxserver.domain.answer.query.dto | ||
|
||
import com.querydsl.core.annotations.QueryProjection | ||
import site.qbox.qboxserver.domain.member.query.dto.MemberRes | ||
|
||
data class AnswerSummary @QueryProjection constructor( | ||
val content: String, | ||
val questionId: Long, | ||
val writer: MemberRes | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,9 @@ import org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath | |
import org.springframework.restdocs.payload.PayloadDocumentation.requestFields | ||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status | ||
import site.qbox.qboxserver.config.WebClientDocsTest | ||
import site.qbox.qboxserver.domain.answer.command.dto.CreateAnswerCommentReq | ||
import site.qbox.qboxserver.domain.answer.command.dto.CreateAnswerReq | ||
import site.qbox.qboxserver.domain.answer.command.entity.AnswerId | ||
|
||
@WebMvcTest(AnswerCtrl::class) | ||
@DisplayName("AnswerCtrl") | ||
|
@@ -32,6 +34,23 @@ class AnswerCtrlTest : WebClientDocsTest() { | |
)) | ||
) | ||
} | ||
|
||
it("answer에 대한 댓글을 생성한다.") { | ||
val req = CreateAnswerCommentReq(AnswerId(4, "[email protected]"), "댓글내용") | ||
|
||
val action = performPost("/answers/comments", req) | ||
|
||
action.andExpect(status().isCreated) | ||
|
||
action.andDo( | ||
print("create-answer-comment", | ||
requestFields( | ||
fieldWithPath("answer.questionId").type(JsonFieldType.NUMBER).description("답변의 Question ID"), | ||
fieldWithPath("answer.writerId").type(JsonFieldType.STRING).description("답변 작성자 email"), | ||
fieldWithPath("content").type(JsonFieldType.STRING).description("댓글 내용"), | ||
)) | ||
) | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ import io.kotest.matchers.nulls.shouldNotBeNull | |
import io.kotest.matchers.shouldBe | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.boot.test.context.SpringBootTest | ||
import site.qbox.qboxserver.domain.answer.command.dto.CreateAnswerCommentReq | ||
import site.qbox.qboxserver.domain.answer.command.dto.CreateAnswerReq | ||
import site.qbox.qboxserver.domain.answer.command.entity.AnswerId | ||
|
||
|
@@ -17,6 +18,8 @@ class AnswerSvcTest : DescribeSpec() { | |
|
||
@Autowired | ||
lateinit var answerRepo: AnswerRepo | ||
@Autowired | ||
lateinit var answerCommentRepo: AnswerCommentRepo | ||
|
||
@Autowired | ||
lateinit var answerSvc: AnswerSvc | ||
|
@@ -36,5 +39,24 @@ class AnswerSvcTest : DescribeSpec() { | |
result.id.questionId shouldBe question | ||
result.id.writerId shouldBe writer | ||
} | ||
|
||
it("answer comment 생성을 수행한다") { | ||
val content = "댓글내용" | ||
val req = CreateAnswerCommentReq(AnswerId(4, "[email protected]"), content) | ||
|
||
answerSvc.addAnswer(req, "댓글작성자") | ||
answerSvc.addAnswer(req, "댓글작성자") | ||
answerSvc.addAnswer(req, "댓글작성자") | ||
|
||
val result = answerCommentRepo.findAll() | ||
|
||
result.size shouldBe 3 | ||
result.map { it.content }.containsAll(listOf(content, content, content)) | ||
} | ||
|
||
afterEach { | ||
answerRepo.deleteAll() | ||
answerCommentRepo.deleteAll() | ||
} | ||
} | ||
} |
118 changes: 118 additions & 0 deletions
118
src/test/kotlin/site/qbox/qboxserver/domain/answer/query/AnswerDaoQueryDslTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package site.qbox.qboxserver.domain.answer.query | ||
|
||
import com.querydsl.core.group.GroupBy.groupBy | ||
import com.querydsl.core.group.GroupBy.list | ||
import com.querydsl.jpa.impl.JPAQueryFactory | ||
import io.kotest.core.spec.DisplayName | ||
import io.kotest.core.spec.style.DescribeSpec | ||
import io.kotest.extensions.spring.SpringExtension | ||
import io.kotest.matchers.shouldBe | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.boot.test.context.SpringBootTest | ||
import org.springframework.security.crypto.password.PasswordEncoder | ||
import site.qbox.qboxserver.domain.answer.command.AnswerCommentRepo | ||
import site.qbox.qboxserver.domain.answer.command.AnswerRepo | ||
import site.qbox.qboxserver.domain.answer.command.entity.Answer | ||
import site.qbox.qboxserver.domain.answer.command.entity.AnswerComment | ||
import site.qbox.qboxserver.domain.answer.command.entity.AnswerId | ||
import site.qbox.qboxserver.domain.answer.command.entity.QAnswer.* | ||
import site.qbox.qboxserver.domain.answer.command.entity.QAnswerComment.answerComment | ||
import site.qbox.qboxserver.domain.answer.query.dto.QAnswerCommentRes | ||
import site.qbox.qboxserver.domain.member.command.MemberRepo | ||
import site.qbox.qboxserver.domain.member.command.entity.Member | ||
import site.qbox.qboxserver.domain.member.command.entity.QMember.member | ||
import site.qbox.qboxserver.domain.member.query.dto.QMemberRes | ||
|
||
@DisplayName("querydsl-answer") | ||
@SpringBootTest | ||
class AnswerDaoQueryDslTest : DescribeSpec() { | ||
override fun extensions() = listOf(SpringExtension) | ||
|
||
@Autowired | ||
lateinit var queryFactory: JPAQueryFactory | ||
|
||
@Autowired | ||
lateinit var answerRepo: AnswerRepo | ||
|
||
@Autowired | ||
lateinit var answerCommentRepo: AnswerCommentRepo | ||
|
||
@Autowired | ||
lateinit var memberRepo: MemberRepo | ||
|
||
@Autowired | ||
lateinit var passwordEncoder: PasswordEncoder | ||
|
||
lateinit var members: List<Member> | ||
lateinit var answers: List<Answer> | ||
lateinit var answerComments: List<AnswerComment> | ||
|
||
init { | ||
describe("querydsl 에서") { | ||
beforeEach { | ||
members = memberRepo.saveAll( | ||
listOf( | ||
Member("[email protected]", "n1", "p1", passwordEncoder), | ||
Member("[email protected]", "n2", "p2", passwordEncoder), | ||
Member("[email protected]", "n3", "p4", passwordEncoder), | ||
Member("[email protected]", "n4", "32", passwordEncoder), | ||
Member("[email protected]", "n5", "42", passwordEncoder), | ||
) | ||
) | ||
|
||
answers = answerRepo.saveAll( | ||
listOf( | ||
Answer("내용1", AnswerId(1, members[0].email)), | ||
Answer("내용2", AnswerId(1, members[1].email)), | ||
Answer("내용3", AnswerId(1, members[2].email)), | ||
Answer("내용4", AnswerId(1, members[3].email)), | ||
Answer("내용5", AnswerId(1, members[4].email)), | ||
Answer("내용6", AnswerId(2, members[0].email)), | ||
Answer("내용7", AnswerId(2, members[1].email)), | ||
Answer("내용8", AnswerId(2, members[2].email)), | ||
) | ||
) | ||
|
||
answerComments = answerCommentRepo.saveAll( | ||
listOf( | ||
AnswerComment("댓글1", members[0].email, answers[1].id), | ||
AnswerComment("댓글2", members[1].email, answers[1].id), | ||
AnswerComment("댓글3", members[1].email, answers[1].id), | ||
AnswerComment("댓글4", members[2].email, answers[1].id), | ||
AnswerComment("댓글5", members[1].email, answers[2].id), | ||
AnswerComment("댓글6", members[3].email, answers[2].id), | ||
AnswerComment("댓글7", members[3].email, answers[7].id), | ||
) | ||
) | ||
} | ||
|
||
it("question별 answer comment 조회를 수행한다.") { | ||
val result = queryFactory.from(answerComment) | ||
.where(answerComment.answer.questionId.eq(1)) | ||
.join(member).on(answerComment.commentWriterId.eq(member.email)) | ||
.transform( | ||
groupBy(answerComment.answer).`as`(list( | ||
QAnswerCommentRes( | ||
answerComment.id, | ||
answerComment.content, | ||
QMemberRes(member.email, member.nickname) | ||
) | ||
)) | ||
) | ||
|
||
result[answers[1].id]?.size shouldBe 4 | ||
result[answers[1].id]?.map { it.content }?.containsAll(listOf("댓글1", "댓글2","댓글3", "댓글4")) | ||
result[answers[1].id]?.map { it.writer.nickname }?.containsAll(listOf("n1", "n2","n3", "n4")) | ||
} | ||
} | ||
|
||
|
||
afterEach { | ||
memberRepo.deleteAll() | ||
answerRepo.deleteAll() | ||
answerCommentRepo.deleteAll() | ||
} | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.