From 246faad1976d69667abc4f65d482108670c4294a Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 12:59:27 +0900 Subject: [PATCH 01/17] =?UTF-8?q?feat:=20BadWords=20Checker=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/domain/BadWordsCheckerTest.kt | 29 + .../main/kotlin/com/wespot/common/BadWords.kt | 610 ++++++++++++++++++ .../com/wespot/common/BadWordsChecker.kt | 72 +++ 3 files changed, 711 insertions(+) create mode 100644 app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt create mode 100644 domain/src/main/kotlin/com/wespot/common/BadWords.kt create mode 100644 domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt diff --git a/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt b/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt new file mode 100644 index 00000000..ad613506 --- /dev/null +++ b/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt @@ -0,0 +1,29 @@ +package com.wespot.common.domain + +import com.wespot.common.BadWordsChecker +import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.shouldBe + +class BadWordsCheckerTest : BehaviorSpec({ + + given("사용자가 내용을 입력할 때") { + val badWords = listOf( + "ㅅ_ㅂ", + "ㅅ________________ㅂ", + "너는 ㅅ!ㅂ", + "너는 f@uck" + ) + `when`("욕설이 존재하면") { + println(BadWordsChecker.check(badWords[0])) + println(BadWordsChecker.check(badWords[1])) + println(BadWordsChecker.check(badWords[2])) + println(BadWordsChecker.check(badWords[3])) + val allMatch = badWords.stream() + .allMatch { BadWordsChecker.check(it) } + then("true를 반환한다.") { + allMatch shouldBe true + } + } + } + +}) diff --git a/domain/src/main/kotlin/com/wespot/common/BadWords.kt b/domain/src/main/kotlin/com/wespot/common/BadWords.kt new file mode 100644 index 00000000..3e32bc57 --- /dev/null +++ b/domain/src/main/kotlin/com/wespot/common/BadWords.kt @@ -0,0 +1,610 @@ +package com.wespot.common + +class BadWords { // 조금 많이 자극적입니다..... 참아주세요.... + + companion object { + val badWords = listOf( + "ㅅㅂ", + "씨발", + "씨바", + "개세끼", + "18년", + "18놈", + "18새끼", + "ㄱㅐㅅㅐㄲl", + "ㄱㅐㅈㅏ", + "가슴만져", + "가슴빨아", + "가슴빨어", + "가슴조물락", + "가슴주물럭", + "가슴쪼물딱", + "가슴쪼물락", + "가슴핧아", + "가슴핧어", + "강간", + "개가튼년", + "개가튼뇬", + "개같은년", + "개걸레", + "개고치", + "개너미", + "개넘", + "개년", + "개놈", + "개늠", + "개똥", + "개떵", + "개떡", + "개라슥", + "개보지", + "개부달", + "개부랄", + "개불랄", + "개붕알", + "개새", + "개세", + "개쓰래기", + "개쓰레기", + "개씁년", + "개씁블", + "개씁자지", + "개씨발", + "개씨블", + "개자식", + "개자지", + "개잡년", + "개젓가튼넘", + "개좆", + "개지랄", + "개후라년", + "개후라들놈", + "개후라새끼", + "걔잡년", + "거시기", + "걸래년", + "걸레같은년", + "걸레년", + "걸레핀년", + "게부럴", + "게세끼", + "게이", + "게새끼", + "게늠", + "게자식", + "게지랄놈", + "고환", + "공지", + "공지사항", + "귀두", + "깨쌔끼", + "난자마셔", + "난자먹어", + "난자핧아", + "내꺼빨아", + "내꺼핧아", + "내버지", + "내자지", + "내잠지", + "내조지", + "너거애비", + "노옴", + "누나강간", + "니기미", + "니뿡", + "니뽕", + "니씨브랄", + "니아범", + "니아비", + "니애미", + "니애뷔", + "니애비", + "니할애비", + "닝기미", + "닌기미", + "니미", + "닳은년", + "덜은새끼", + "돈새끼", + "돌으년", + "돌은넘", + "돌은새끼", + "동생강간", + "동성애자", + "딸딸이", + "똥구녁", + "똥꾸뇽", + "똥구뇽", + "똥", + "띠발뇬", + "띠팔", + "띠펄", + "띠풀", + "띠벌", + "띠벨", + "띠빌", + "마스터", + "막간년", + "막대쑤셔줘", + "막대핧아줘", + "맛간년", + "맛없는년", + "맛이간년", + "멜리스", + "미친구녕", + "미친구멍", + "미친넘", + "미친년", + "미친놈", + "미친눔", + "미친새끼", + "미친쇄리", + "미친쇠리", + "미친쉐이", + "미친씨부랄", + "미튄", + "미티넘", + "미틴", + "미틴넘", + "미틴년", + "미틴놈", + "미틴것", + "백보지", + "버따리자지", + "버지구녕", + "버지구멍", + "버지냄새", + "버지따먹기", + "버지뚫어", + "버지뜨더", + "버지물마셔", + "버지벌려", + "버지벌료", + "버지빨아", + "버지빨어", + "버지썰어", + "버지쑤셔", + "버지털", + "버지핧아", + "버짓물", + "버짓물마셔", + "벌창같은년", + "벵신", + "병닥", + "병딱", + "병신", + "보쥐", + "보지", + "보지핧어", + "보짓물", + "보짓물마셔", + "봉알", + "부랄", + "불알", + "붕알", + "붜지", + "뷩딱", + "븅쉰", + "븅신", + "빙띤", + "빙신", + "빠가십새", + "빠가씹새", + "빠구리", + "빠굴이", + "뻑큐", + "뽕알", + "뽀지", + "뼝신", + "사까시", + "상년", + "새꺄", + "새뀌", + "새끼", + "색갸", + "색끼", + "색스", + "색키", + "샤발", + "써글", + "써글년", + "성교", + "성폭행", + "세꺄", + "세끼", + "섹스", + "섹스하자", + "섹스해", + "섹쓰", + "섹히", + "수셔", + "쑤셔", + "쉐끼", + "쉑갸", + "쉑쓰", + "쉬발", + "쉬방", + "쉬밸년", + "쉬벌", + "쉬불", + "쉬붕", + "쉬빨", + "쉬이발", + "쉬이방", + "쉬이벌", + "쉬이불", + "쉬이붕", + "쉬이빨", + "쉬이팔", + "쉬이펄", + "쉬이풀", + "쉬팔", + "쉬펄", + "쉬풀", + "쉽쌔", + "시댕이", + "시발", + "시발년", + "시발놈", + "시발새끼", + "시방새", + "시밸", + "시벌", + "시불", + "시붕", + "시이발", + "시이벌", + "시이불", + "시이붕", + "시이팔", + "시이펄", + "시이풀", + "시팍새끼", + "시팔", + "시팔넘", + "시팔년", + "시팔놈", + "시팔새끼", + "시펄", + "실프", + "십8", + "십때끼", + "십떼끼", + "십버지", + "십부랄", + "십부럴", + "십새", + "십세이", + "십셰리", + "십쉐", + "십자석", + "십자슥", + "십지랄", + "십창녀", + "십창", + "십탱", + "십탱구리", + "십탱굴이", + "십팔새끼", + "ㅆㅂ", + "ㅆㅂㄹㅁ", + "ㅆㅂㄻ", + "ㅆㅣ", + "쌍넘", + "쌍년", + "쌍놈", + "쌍눔", + "쌍보지", + "쌔끼", + "쌔리", + "쌕스", + "쌕쓰", + "썅년", + "썅놈", + "썅뇬", + "썅늠", + "쓉새", + "쓰바새끼", + "쓰브랄쉽세", + "씌발", + "씌팔", + "씨가랭넘", + "씨가랭년", + "씨가랭놈", + "씨발", + "씨발년", + "씨발롬", + "씨발병신", + "씨방새", + "씨방세", + "씨밸", + "씨뱅가리", + "씨벌", + "씨벌년", + "씨벌쉐이", + "씨부랄", + "씨부럴", + "씨불", + "씨불알", + "씨붕", + "씨브럴", + "씨블", + "씨블년", + "씨븡새끼", + "씨빨", + "씨이발", + "씨이벌", + "씨이불", + "씨이붕", + "씨이팔", + "씨파넘", + "씨팍새끼", + "씨팍세끼", + "씨팔", + "씨펄", + "씨퐁넘", + "씨퐁뇬", + "씨퐁보지", + "씨퐁자지", + "씹년", + "씹물", + "씹미랄", + "씹버지", + "씹보지", + "씹부랄", + "씹브랄", + "씹빵구", + "씹뽀지", + "씹새", + "씹새끼", + "씹세", + "씹쌔끼", + "씹자석", + "씹자슥", + "씹자지", + "씹지랄", + "씹창", + "씹창녀", + "씹탱", + "씹탱굴이", + "씹탱이", + "씹팔", + "아가리", + "애무", + "애미", + "애미랄", + "애미보지", + "애미씨뱅", + "애미자지", + "애미잡년", + "애미좃물", + "애비", + "애자", + "양아치", + "어미강간", + "어미따먹자", + "어미쑤시자", + "영자", + "엄창", + "에미", + "에비", + "엔플레버", + "엠플레버", + "염병", + "염병할", + "염뵹", + "엿먹어라", + "오랄", + "오르가즘", + "왕버지", + "왕자지", + "왕잠지", + "왕털버지", + "왕털보지", + "왕털자지", + "왕털잠지", + "우미쑤셔", + "운디네", + "운영자", + "유두", + "유두빨어", + "유두핧어", + "유방", + "유방만져", + "유방빨아", + "유방주물럭", + "유방쪼물딱", + "유방쪼물럭", + "유방핧아", + "유방핧어", + "육갑", + "이그니스", + "이년", + "이프리트", + "자기핧아", + "자지", + "자지구녕", + "자지구멍", + "자지꽂아", + "자지넣자", + "자지뜨더", + "자지뜯어", + "자지박어", + "자지빨아", + "자지빨아줘", + "자지빨어", + "자지쑤셔", + "자지쓰레기", + "자지정개", + "자지짤라", + "자지털", + "자지핧아", + "자지핧아줘", + "자지핧어", + "작은보지", + "잠지", + "잠지뚫어", + "잠지물마셔", + "잠지털", + "잠짓물마셔", + "잡년", + "잡놈", + "저년", + "점물", + "젓가튼", + "젓가튼쉐이", + "젓같내", + "젓같은", + "젓까", + "젓나", + "젓냄새", + "젓대가리", + "젓떠", + "젓마무리", + "젓만이", + "젓물", + "젓물냄새", + "젓밥", + "정액마셔", + "정액먹어", + "정액발사", + "정액짜", + "정액핧아", + "정자마셔", + "정자먹어", + "정자핧아", + "젖같은", + "젖까", + "젖밥", + "젖탱이", + "조개넓은년", + "조개따조", + "조개마셔줘", + "조개벌려조", + "조개속물", + "조개쑤셔줘", + "조개핧아줘", + "조까", + "조또", + "족같내", + "족까", + "족까내", + "존나", + "존나게", + "존니", + "졸라", + "좀마니", + "좀물", + "좀쓰레기", + "좁빠라라", + "좃가튼뇬", + "좃간년", + "좃까", + "좃까리", + "좃깟네", + "좃냄새", + "좃넘", + "좃대가리", + "좃도", + "좃또", + "좃만아", + "좃만이", + "좃만한것", + "좃만한쉐이", + "좃물", + "좃물냄새", + "좃보지", + "좃부랄", + "좃빠구리", + "좃빠네", + "좃빠라라", + "좃털", + "좆같은놈", + "좆같은새끼", + "좆까", + "좆까라", + "좆나", + "좆년", + "좆도", + "좆만아", + "좆만한년", + "좆만한놈", + "좆만한새끼", + "좆먹어", + "좆물", + "좆밥", + "좆빨아", + "좆새끼", + "좆털", + "좋만한것", + "주글년", + "주길년", + "쥐랄", + "지랄", + "지랼", + "지럴", + "지뢀", + "쪼까튼", + "쪼다", + "쪼다새끼", + "찌랄", + "찌질이", + "창남", + "창녀", + "창녀버지", + "창년", + "처먹고", + "처먹을", + "쳐먹고", + "쳐쑤셔박어", + "촌씨브라리", + "촌씨브랑이", + "촌씨브랭이", + "크리토리스", + "큰보지", + "클리토리스", + "트랜스젠더", + "페니스", + "항문수셔", + "항문쑤셔", + "허덥", + "허버리년", + "허벌년", + "허벌보지", + "허벌자식", + "허벌자지", + "허접", + "허젚", + "허졉", + "허좁", + "헐렁보지", + "혀로보지핧기", + "호냥년", + "호로", + "호로새끼", + "호로자슥", + "호로자식", + "호로짜식", + "호루자슥", + "호모", + "호졉", + "호좁", + "후라덜넘", + "후장", + "후장꽂아", + "후장뚫어", + "흐접", + "흐젚", + "흐졉", + "bitch", + "fuck", + "fuckyou", + "nflavor", + "penis", + "pennis", + "pussy", + "sex" + ) + } + +} diff --git a/domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt b/domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt new file mode 100644 index 00000000..12304acb --- /dev/null +++ b/domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt @@ -0,0 +1,72 @@ +package com.wespot.common + +object BadWordsChecker { + + private val replaceCharacters = listOf( + " ", + "@", + "_", + "-", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "(", + ")", + "!", + ",", + ".", + "?", + "/", + "\\", + "[", + "]", + "{", + "}", + "<", + ">", + "*", + "&", + "^", + "%", + "$", + "#", + "@", + "!", + "~", + "`", + "-", + "_", + "=", + "+", + "|", + ";", + ":", + "'", + "\"" + ) + + fun check(content: String): Boolean { + val contentAfterRemoveProfanityMasking = removeProfanityMasking(content) + println(contentAfterRemoveProfanityMasking) + + return BadWords.badWords + .stream() + .anyMatch(contentAfterRemoveProfanityMasking::contains) + } + + private fun removeProfanityMasking(content: String): String { + var replaceContent = content + for (replaceCharacter in replaceCharacters) { + replaceContent = replaceContent.replace(replaceCharacter, "") + } + return replaceContent + } + +} From 32d8d1106bc659cfdba40ec7ea348f94632952b9 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 13:02:03 +0900 Subject: [PATCH 02/17] =?UTF-8?q?feat:=20VoteOption=20Content=20VO=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/voteoption/VoteOption.kt | 7 ++---- .../wespot/voteoption/VoteOptionContent.kt | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt diff --git a/domain/src/main/kotlin/com/wespot/voteoption/VoteOption.kt b/domain/src/main/kotlin/com/wespot/voteoption/VoteOption.kt index 387a9ddc..c9217247 100644 --- a/domain/src/main/kotlin/com/wespot/voteoption/VoteOption.kt +++ b/domain/src/main/kotlin/com/wespot/voteoption/VoteOption.kt @@ -5,7 +5,7 @@ import java.util.* data class VoteOption( val id: Long, - val content: String, + val content: VoteOptionContent, val createdAt: LocalDateTime, val updatedAt: LocalDateTime, ) { @@ -17,12 +17,9 @@ data class VoteOption( createdAt: LocalDateTime, updatedAt: LocalDateTime ): VoteOption { - if (Objects.isNull(content) || content.isBlank()) { - throw IllegalArgumentException("선택지의 내용은 필수로 존재해야합니다.") - } return VoteOption( id = id, - content = content, + content = VoteOptionContent.from(content), createdAt = createdAt, updatedAt = updatedAt ) diff --git a/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt b/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt new file mode 100644 index 00000000..34641d03 --- /dev/null +++ b/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt @@ -0,0 +1,22 @@ +package com.wespot.voteoption + +import com.wespot.common.BadWordsChecker + +data class VoteOptionContent( + val content: String +) { + + companion object { + + fun from(content: String): VoteOptionContent { + BadWordsChecker.check(content) + validateContent(content) + return VoteOptionContent(content) + } + + private fun validateContent(content: String) { + require(content.isNotBlank()) { "선택지의 내용은 필수로 존재해야합니다." } + } + + } +} From 15cdecf65a01ef58fff932d45b6abdc65616b8b6 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 13:11:29 +0900 Subject: [PATCH 03/17] =?UTF-8?q?refactor:=20=ED=85=8D=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=ED=95=84=EB=93=9C=EC=97=90=20=EC=9A=95=EC=84=A4=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/domain/BadWordsCheckerTest.kt | 10 ++++---- .../com/wespot/common/BadWordsChecker.kt | 2 +- .../main/kotlin/com/wespot/message/Message.kt | 8 +++---- .../com/wespot/message/MessageContent.kt | 21 ++++++++++++++++ .../kotlin/com/wespot/user/Introduction.kt | 24 +++++++++++++++++++ .../src/main/kotlin/com/wespot/user/User.kt | 8 +++---- .../com/wespot/voteoption/VoteOption.kt | 1 - .../wespot/voteoption/VoteOptionContent.kt | 3 ++- 8 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 domain/src/main/kotlin/com/wespot/message/MessageContent.kt create mode 100644 domain/src/main/kotlin/com/wespot/user/Introduction.kt diff --git a/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt b/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt index ad613506..6779a661 100644 --- a/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt +++ b/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt @@ -14,12 +14,12 @@ class BadWordsCheckerTest : BehaviorSpec({ "너는 f@uck" ) `when`("욕설이 존재하면") { - println(BadWordsChecker.check(badWords[0])) - println(BadWordsChecker.check(badWords[1])) - println(BadWordsChecker.check(badWords[2])) - println(BadWordsChecker.check(badWords[3])) + println(BadWordsChecker.checkProfanity(badWords[0])) + println(BadWordsChecker.checkProfanity(badWords[1])) + println(BadWordsChecker.checkProfanity(badWords[2])) + println(BadWordsChecker.checkProfanity(badWords[3])) val allMatch = badWords.stream() - .allMatch { BadWordsChecker.check(it) } + .allMatch { BadWordsChecker.checkProfanity(it) } then("true를 반환한다.") { allMatch shouldBe true } diff --git a/domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt b/domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt index 12304acb..c3b15566 100644 --- a/domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt +++ b/domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt @@ -52,7 +52,7 @@ object BadWordsChecker { "\"" ) - fun check(content: String): Boolean { + fun checkProfanity(content: String): Boolean { val contentAfterRemoveProfanityMasking = removeProfanityMasking(content) println(contentAfterRemoveProfanityMasking) diff --git a/domain/src/main/kotlin/com/wespot/message/Message.kt b/domain/src/main/kotlin/com/wespot/message/Message.kt index b77d60b1..aa819917 100644 --- a/domain/src/main/kotlin/com/wespot/message/Message.kt +++ b/domain/src/main/kotlin/com/wespot/message/Message.kt @@ -7,7 +7,7 @@ import java.time.LocalDateTime data class Message( val id: Long, - val content: String, + val content: MessageContent, val senderId: Long, val senderName: String, val receiverId: Long, @@ -38,7 +38,7 @@ data class Message( validateMessageUpdateTime() val message = Message( id = id, - content = content, + content = MessageContent.from(content), senderId = senderId, senderName = senderName, messageType = MessageType.SENT, @@ -109,7 +109,7 @@ data class Message( } fun validateDeleteReceivedMessage(loginUser: User) { - require(receiverId == loginUser.id) { "메시지를 삭제할 권한이 없습니다." } + require(receiverId == loginUser.id) { "메시지를 삭제할 권한이 없습니다." } } private fun validateReportMessage(reportSenderId: Long) { @@ -166,7 +166,7 @@ data class Message( validateMessageSendTime() val message = Message( id = 0L, - content = content, + content = MessageContent.from(content), senderId = senderId, senderName = senderName, messageType = MessageType.SENT, diff --git a/domain/src/main/kotlin/com/wespot/message/MessageContent.kt b/domain/src/main/kotlin/com/wespot/message/MessageContent.kt new file mode 100644 index 00000000..f0ab23d3 --- /dev/null +++ b/domain/src/main/kotlin/com/wespot/message/MessageContent.kt @@ -0,0 +1,21 @@ +package com.wespot.message + +import com.wespot.common.BadWordsChecker + +data class MessageContent( + val content: String +) { + + companion object { + fun from(content: String): MessageContent { + validateContent(content) + return MessageContent(content) + } + + private fun validateContent(content: String) { + require(!BadWordsChecker.checkProfanity(content)) { "메시지의 내용에는 욕설이 포함될 수 없습니다." } + require(content.isNotBlank()) { "메시지의 내용은 필수로 존재해야합니다." } + } + } + +} diff --git a/domain/src/main/kotlin/com/wespot/user/Introduction.kt b/domain/src/main/kotlin/com/wespot/user/Introduction.kt new file mode 100644 index 00000000..13b0aab9 --- /dev/null +++ b/domain/src/main/kotlin/com/wespot/user/Introduction.kt @@ -0,0 +1,24 @@ +package com.wespot.user + +import com.wespot.common.BadWordsChecker + +data class Introduction( + val introduction: String +) { + companion object { + + fun emptyIntroduction(): Introduction { + return Introduction("") + } + + fun from(introduction: String): Introduction { + BadWordsChecker.checkProfanity(introduction) + return Introduction(introduction) + } + + private fun validateIntroduction(content: String) { + require(!BadWordsChecker.checkProfanity(content)) { "소개에는 욕설이 포함될 수 없습니다." } + } + + } +} diff --git a/domain/src/main/kotlin/com/wespot/user/User.kt b/domain/src/main/kotlin/com/wespot/user/User.kt index 9af57d17..3b7b4544 100644 --- a/domain/src/main/kotlin/com/wespot/user/User.kt +++ b/domain/src/main/kotlin/com/wespot/user/User.kt @@ -8,7 +8,7 @@ data class User( val email: String, val password: String, val name: String, - val introduction: String, + val introduction: Introduction, val gender: String, val role: Role, val schoolId: Long, @@ -33,7 +33,7 @@ data class User( email = email, password = password, name = name, - introduction = introduction, + introduction = Introduction.from(introduction), gender = gender, role = role, schoolId = schoolId, @@ -56,7 +56,7 @@ data class User( email = "", password = "", name = "", - introduction = "", + introduction = Introduction.emptyIntroduction(), gender = gender, role = Role.GUEST, schoolId = schoolId, @@ -94,7 +94,7 @@ data class User( email = email, password = password, name = name, - introduction = "", + introduction = Introduction.emptyIntroduction(), gender = gender, role = Role.USER, schoolId = schoolId, diff --git a/domain/src/main/kotlin/com/wespot/voteoption/VoteOption.kt b/domain/src/main/kotlin/com/wespot/voteoption/VoteOption.kt index c9217247..cbd59eb1 100644 --- a/domain/src/main/kotlin/com/wespot/voteoption/VoteOption.kt +++ b/domain/src/main/kotlin/com/wespot/voteoption/VoteOption.kt @@ -1,7 +1,6 @@ package com.wespot.voteoption import java.time.LocalDateTime -import java.util.* data class VoteOption( val id: Long, diff --git a/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt b/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt index 34641d03..188956e4 100644 --- a/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt +++ b/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt @@ -9,12 +9,13 @@ data class VoteOptionContent( companion object { fun from(content: String): VoteOptionContent { - BadWordsChecker.check(content) + BadWordsChecker.checkProfanity(content) validateContent(content) return VoteOptionContent(content) } private fun validateContent(content: String) { + require(!BadWordsChecker.checkProfanity(content)) { "선택지의 내용에는 욕설이 포함될 수 없습니다." } require(content.isNotBlank()) { "선택지의 내용은 필수로 존재해야합니다." } } From 418e720597dbbdf3738019af6ec3016720561e36 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 13:19:01 +0900 Subject: [PATCH 04/17] =?UTF-8?q?test:=20VoteOptionContent=20Test=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 --- .../domain/VoteOptionContentTest.kt | 20 +++++++++++++++++++ .../voteoption/domain/VoteOptionTest.kt | 18 +++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt diff --git a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt new file mode 100644 index 00000000..9334d941 --- /dev/null +++ b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt @@ -0,0 +1,20 @@ +package com.wespot.voteoption.domain + +import com.wespot.voteoption.VoteOptionContent +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.throwable.shouldHaveMessage + +class VoteOptionContentTest : BehaviorSpec({ + + given("선택지에") { + val badWordsContent = "ㅂㅁㄴ이;라ㅓ 싮ㅂㅅㅂㅅㅂㅅㅂ시ㅂ 선택지" + `when`("욕설이 포함되어 있는 경우") { + val shouldThrow = shouldThrow { VoteOptionContent.from(badWordsContent) } + then("예외가 발생한다.") { + shouldThrow shouldHaveMessage "선택지의 내용에는 욕설이 포함될 수 없습니다." + } + } + } + +}) diff --git a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt index 2dfec6b5..3f2e276b 100644 --- a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt +++ b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt @@ -4,6 +4,7 @@ import com.wespot.voteoption.VoteOption import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe +import io.kotest.matchers.throwable.shouldHaveMessage import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource import java.time.LocalDateTime @@ -26,6 +27,23 @@ class VoteOptionTest() : BehaviorSpec() { } } } + + given("선택지에") { + val badWordsContent = "ㅅㅂㅂㅂㅂㅂㅂㅂㅂㅂ 선택지" + `when`("욕설이 포함되어 있는 경우") { + val shouldThrow = shouldThrow { + VoteOption.of( + 0L, + badWordsContent, + LocalDateTime.now(), + LocalDateTime.now() + ) + } + then("예외가 발생한다.") { + shouldThrow shouldHaveMessage "선택지의 내용에는 욕설이 포함될 수 없습니다." + } + } + } } @ParameterizedTest From ec4db0f97884ed6a15f5c84dffb4d47a502d0dac Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 13:30:35 +0900 Subject: [PATCH 05/17] =?UTF-8?q?test:=20MessageContentTest=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../message/domain/MessageContentTest.kt | 35 +++++++++++++++++ .../com/wespot/message/domain/MessageTest.kt | 38 +++++++++++++++++++ .../domain/VoteOptionContentTest.kt | 8 ++++ 3 files changed, 81 insertions(+) create mode 100644 app/src/test/kotlin/com/wespot/message/domain/MessageContentTest.kt diff --git a/app/src/test/kotlin/com/wespot/message/domain/MessageContentTest.kt b/app/src/test/kotlin/com/wespot/message/domain/MessageContentTest.kt new file mode 100644 index 00000000..e66435eb --- /dev/null +++ b/app/src/test/kotlin/com/wespot/message/domain/MessageContentTest.kt @@ -0,0 +1,35 @@ +package com.wespot.message.domain + +import com.wespot.message.MessageContent +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.shouldBe +import io.kotest.matchers.throwable.shouldHaveMessage + +class MessageContentTest : BehaviorSpec({ + + given("메시지 컨텐츠에") { + val badWordsContent = "ㅂㅁㄴ이;라ㅓ 싮ㅂㅅㅂㅅㅂㅅㅂ시ㅂ 메시지" + val emptyContent = "" + val validContent = "헬로우" + `when`("욕설이 포함되어 있는 경우") { + val shouldThrow = shouldThrow { MessageContent.from(badWordsContent) } + then("예외가 발생한다.") { + shouldThrow shouldHaveMessage "메시지의 내용에는 욕설이 포함될 수 없습니다." + } + } + `when`("아무런 내용이 없는 경우") { + val shouldThrow = shouldThrow { MessageContent.from(emptyContent) } + then("예외가 발생한다.") { + shouldThrow shouldHaveMessage "메시지의 내용은 필수로 존재해야합니다." + } + } + `when`("정상적인 값이 입력되는 경우") { + val messageContent = MessageContent.from(validContent) + then("예외가 발생하지 않는다.") { + messageContent.content shouldBe validContent + } + } + } + +}) diff --git a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt index 11cb668a..98005ce5 100644 --- a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt +++ b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt @@ -1,5 +1,6 @@ package com.wespot.message.domain +import com.wespot.message.Message import com.wespot.message.fixture.MessageFixture import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec @@ -7,6 +8,7 @@ import io.kotest.matchers.shouldBe import io.kotest.matchers.throwable.shouldHaveMessage import io.mockk.every import io.mockk.mockkStatic +import io.mockk.unmockkStatic import java.time.LocalDateTime class MessageTest : BehaviorSpec({ @@ -36,4 +38,40 @@ class MessageTest : BehaviorSpec({ } } + given("메시지 컨텐츠에") { + mockkStatic(LocalDateTime::class) + every { LocalDateTime.now() } returns LocalDateTime.of(2024, 8, 9, 19, 0) + val badWordsContent = "ㅂㅁㄴ이;라ㅓ 싮ㅂㅅㅂㅅㅂㅅㅂ시ㅂ 메시지" + val emptyContent = "" + `when`("욕설이 포함되어 있는 경우") { + val shouldThrow = shouldThrow { + Message.sendMessage( + badWordsContent, + 1, + 2, + "senderName", + false + ) + } + then("예외가 발생한다.") { + shouldThrow shouldHaveMessage "메시지의 내용에는 욕설이 포함될 수 없습니다." + } + } + `when`("아무런 내용이 없는 경우") { + val shouldThrow = shouldThrow { + Message.sendMessage( + emptyContent, + 1, + 2, + "senderName", + false + ) + } + then("예외가 발생한다.") { + shouldThrow shouldHaveMessage "메시지의 내용은 필수로 존재해야합니다." + } + } + unmockkStatic(LocalDateTime::class) + } + }) diff --git a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt index 9334d941..8513f161 100644 --- a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt +++ b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt @@ -3,6 +3,7 @@ package com.wespot.voteoption.domain import com.wespot.voteoption.VoteOptionContent import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.shouldBe import io.kotest.matchers.throwable.shouldHaveMessage class VoteOptionContentTest : BehaviorSpec({ @@ -15,6 +16,13 @@ class VoteOptionContentTest : BehaviorSpec({ shouldThrow shouldHaveMessage "선택지의 내용에는 욕설이 포함될 수 없습니다." } } + val validContent = "헬로우" + `when`("정상적인 값이 입력되는 경우") { + val voteOptionContent = VoteOptionContent.from(validContent) + then("예외가 발생하지 않는다.") { + voteOptionContent.content shouldBe validContent + } + } } }) From f05fb2933d38dc8b11c0858011d18cfee4515d41 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 13:37:23 +0900 Subject: [PATCH 06/17] =?UTF-8?q?test:=20Introduction=20Test=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/domain/UserIntroductionTest.kt | 38 +++++++++++++++++++ .../kotlin/com/wespot/user/domain/UserTest.kt | 13 +++++++ .../kotlin/com/wespot/user/Introduction.kt | 15 ++++---- .../src/main/kotlin/com/wespot/user/User.kt | 8 ++-- 4 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 app/src/test/kotlin/com/wespot/user/domain/UserIntroductionTest.kt diff --git a/app/src/test/kotlin/com/wespot/user/domain/UserIntroductionTest.kt b/app/src/test/kotlin/com/wespot/user/domain/UserIntroductionTest.kt new file mode 100644 index 00000000..594b4ce7 --- /dev/null +++ b/app/src/test/kotlin/com/wespot/user/domain/UserIntroductionTest.kt @@ -0,0 +1,38 @@ +package com.wespot.user.domain + +import com.wespot.user.UserIntroduction +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.shouldBe +import io.kotest.matchers.throwable.shouldHaveMessage + +class UserIntroductionTest : BehaviorSpec({ + + given("소개에") { + val badWordsIntroduction = "ㅅㅂㅅㅂㅅㅂㅅㅂㅅㅂㅅㅂㅂㅂㅂㅂㅂ" + val validIntroduction = "헬로우" + `when`("욕설이 포함되어 있는 경우") { + val shouldThrow = shouldThrow { UserIntroduction.from(badWordsIntroduction) } + then("예외가 발생한다.") { + shouldThrow shouldHaveMessage "소개에는 욕설이 포함될 수 없습니다." + } + } + `when`("정상적인 값이 입력되는 경우") { + val userIntroduction = UserIntroduction.from(validIntroduction) + then("예외가 발생하지 않는다.") { + userIntroduction.introduction shouldBe validIntroduction + } + } + } + + given("처음 소개를 생성할 때") { + val expectedIntroduction = "" + `when`("빈 문자열로") { + val actual = UserIntroduction.emptyUserIntroduction() + then("생성한다.") { + actual.introduction shouldBe expectedIntroduction + } + } + } + +}) diff --git a/app/src/test/kotlin/com/wespot/user/domain/UserTest.kt b/app/src/test/kotlin/com/wespot/user/domain/UserTest.kt index 97ea76e5..fe3fe278 100644 --- a/app/src/test/kotlin/com/wespot/user/domain/UserTest.kt +++ b/app/src/test/kotlin/com/wespot/user/domain/UserTest.kt @@ -2,9 +2,11 @@ package com.wespot.user.domain import com.wespot.user.fixture.RestrictionFixture import com.wespot.user.fixture.UserFixture +import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe +import io.kotest.matchers.throwable.shouldHaveMessage class UserTest : BehaviorSpec({ @@ -70,4 +72,15 @@ class UserTest : BehaviorSpec({ } } + given("소개에") { + val badWordsIntroduction = "ㅅㅂㅅㅂㅅㅂㅅㅂㅅㅂㅅㅂㅂㅂㅂㅂㅂ" + `when`("욕설이 포함되어 있는 경우") { + val createUser = UserFixture.createWithId(1) + val shouldThrow = shouldThrow { createUser.updateProfile(badWordsIntroduction) } + then("예외가 발생한다.") { + shouldThrow shouldHaveMessage "소개에는 욕설이 포함될 수 없습니다." + } + } + } + }) diff --git a/domain/src/main/kotlin/com/wespot/user/Introduction.kt b/domain/src/main/kotlin/com/wespot/user/Introduction.kt index 13b0aab9..d5f29453 100644 --- a/domain/src/main/kotlin/com/wespot/user/Introduction.kt +++ b/domain/src/main/kotlin/com/wespot/user/Introduction.kt @@ -2,21 +2,22 @@ package com.wespot.user import com.wespot.common.BadWordsChecker -data class Introduction( +data class UserIntroduction( val introduction: String ) { companion object { - fun emptyIntroduction(): Introduction { - return Introduction("") + fun emptyUserIntroduction(): UserIntroduction { + return UserIntroduction("") } - fun from(introduction: String): Introduction { - BadWordsChecker.checkProfanity(introduction) - return Introduction(introduction) + fun from(introduction: String): UserIntroduction { + validateUserIntroduction(introduction) + + return UserIntroduction(introduction) } - private fun validateIntroduction(content: String) { + private fun validateUserIntroduction(content: String) { require(!BadWordsChecker.checkProfanity(content)) { "소개에는 욕설이 포함될 수 없습니다." } } diff --git a/domain/src/main/kotlin/com/wespot/user/User.kt b/domain/src/main/kotlin/com/wespot/user/User.kt index 3b7b4544..3cc8c441 100644 --- a/domain/src/main/kotlin/com/wespot/user/User.kt +++ b/domain/src/main/kotlin/com/wespot/user/User.kt @@ -8,7 +8,7 @@ data class User( val email: String, val password: String, val name: String, - val introduction: Introduction, + val introduction: UserIntroduction, val gender: String, val role: Role, val schoolId: Long, @@ -33,7 +33,7 @@ data class User( email = email, password = password, name = name, - introduction = Introduction.from(introduction), + introduction = UserIntroduction.from(introduction), gender = gender, role = role, schoolId = schoolId, @@ -56,7 +56,7 @@ data class User( email = "", password = "", name = "", - introduction = Introduction.emptyIntroduction(), + introduction = UserIntroduction.emptyUserIntroduction(), gender = gender, role = Role.GUEST, schoolId = schoolId, @@ -94,7 +94,7 @@ data class User( email = email, password = password, name = name, - introduction = Introduction.emptyIntroduction(), + introduction = UserIntroduction.emptyUserIntroduction(), gender = gender, role = Role.USER, schoolId = schoolId, From e251ad260adb16df8bd594dbbb105be9bceffdb2 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 13:51:35 +0900 Subject: [PATCH 07/17] =?UTF-8?q?feat:=20=EB=B9=84=EC=86=8D=EC=96=B4=20?= =?UTF-8?q?=ED=8C=90=EB=B3=84=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/common/ProfanityController.kt | 25 +++++++++++++++++++ .../common/domain/BadWordsCheckerTest.kt | 12 ++++----- .../common/dto/CheckProfanityRequest.kt | 6 +++++ .../wespot/common/in/CheckProfanityUseCase.kt | 9 +++++++ .../common/service/CheckProfanityService.kt | 15 +++++++++++ ...BadWordsChecker.kt => ProfanityChecker.kt} | 6 ++++- .../com/wespot/message/MessageContent.kt | 4 +-- .../kotlin/com/wespot/user/Introduction.kt | 4 +-- .../wespot/voteoption/VoteOptionContent.kt | 6 ++--- 9 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 app/src/main/kotlin/com/wespot/common/ProfanityController.kt create mode 100644 core/src/main/kotlin/com/wespot/common/dto/CheckProfanityRequest.kt create mode 100644 core/src/main/kotlin/com/wespot/common/in/CheckProfanityUseCase.kt create mode 100644 core/src/main/kotlin/com/wespot/common/service/CheckProfanityService.kt rename domain/src/main/kotlin/com/wespot/common/{BadWordsChecker.kt => ProfanityChecker.kt} (88%) diff --git a/app/src/main/kotlin/com/wespot/common/ProfanityController.kt b/app/src/main/kotlin/com/wespot/common/ProfanityController.kt new file mode 100644 index 00000000..82e083e4 --- /dev/null +++ b/app/src/main/kotlin/com/wespot/common/ProfanityController.kt @@ -0,0 +1,25 @@ +package com.wespot.common + +import com.wespot.common.dto.CheckProfanityRequest +import com.wespot.common.`in`.CheckProfanityUseCase +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/api/v1/check-profanity") +class ProfanityController( + private val checkProfanityUseCase: CheckProfanityUseCase +) { + + @PostMapping + fun checkProfanity(@RequestBody message: CheckProfanityRequest): ResponseEntity { + checkProfanityUseCase.checkProfanity(message) + + return ResponseEntity.noContent() + .build() + } + +} diff --git a/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt b/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt index 6779a661..5c3352d1 100644 --- a/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt +++ b/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt @@ -1,6 +1,6 @@ package com.wespot.common.domain -import com.wespot.common.BadWordsChecker +import com.wespot.common.ProfanityChecker import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe @@ -14,12 +14,12 @@ class BadWordsCheckerTest : BehaviorSpec({ "너는 f@uck" ) `when`("욕설이 존재하면") { - println(BadWordsChecker.checkProfanity(badWords[0])) - println(BadWordsChecker.checkProfanity(badWords[1])) - println(BadWordsChecker.checkProfanity(badWords[2])) - println(BadWordsChecker.checkProfanity(badWords[3])) + println(ProfanityChecker.checkProfanity(badWords[0])) + println(ProfanityChecker.checkProfanity(badWords[1])) + println(ProfanityChecker.checkProfanity(badWords[2])) + println(ProfanityChecker.checkProfanity(badWords[3])) val allMatch = badWords.stream() - .allMatch { BadWordsChecker.checkProfanity(it) } + .allMatch { ProfanityChecker.checkProfanity(it) } then("true를 반환한다.") { allMatch shouldBe true } diff --git a/core/src/main/kotlin/com/wespot/common/dto/CheckProfanityRequest.kt b/core/src/main/kotlin/com/wespot/common/dto/CheckProfanityRequest.kt new file mode 100644 index 00000000..a7bfb6bc --- /dev/null +++ b/core/src/main/kotlin/com/wespot/common/dto/CheckProfanityRequest.kt @@ -0,0 +1,6 @@ +package com.wespot.common.dto + +data class CheckProfanityRequest( + val message: String +) { +} diff --git a/core/src/main/kotlin/com/wespot/common/in/CheckProfanityUseCase.kt b/core/src/main/kotlin/com/wespot/common/in/CheckProfanityUseCase.kt new file mode 100644 index 00000000..3f4218c3 --- /dev/null +++ b/core/src/main/kotlin/com/wespot/common/in/CheckProfanityUseCase.kt @@ -0,0 +1,9 @@ +package com.wespot.common.`in` + +import com.wespot.common.dto.CheckProfanityRequest + +interface CheckProfanityUseCase { + + fun checkProfanity(checkProfanityRequest: CheckProfanityRequest) + +} diff --git a/core/src/main/kotlin/com/wespot/common/service/CheckProfanityService.kt b/core/src/main/kotlin/com/wespot/common/service/CheckProfanityService.kt new file mode 100644 index 00000000..d1183c2c --- /dev/null +++ b/core/src/main/kotlin/com/wespot/common/service/CheckProfanityService.kt @@ -0,0 +1,15 @@ +package com.wespot.common.service + +import com.wespot.common.ProfanityChecker +import com.wespot.common.dto.CheckProfanityRequest +import com.wespot.common.`in`.CheckProfanityUseCase +import org.springframework.stereotype.Service + +@Service +class CheckProfanityService : CheckProfanityUseCase { + + override fun checkProfanity(checkProfanityRequest: CheckProfanityRequest) { + ProfanityChecker.validateContent(checkProfanityRequest.message) + } + +} diff --git a/domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt b/domain/src/main/kotlin/com/wespot/common/ProfanityChecker.kt similarity index 88% rename from domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt rename to domain/src/main/kotlin/com/wespot/common/ProfanityChecker.kt index c3b15566..9cf1c578 100644 --- a/domain/src/main/kotlin/com/wespot/common/BadWordsChecker.kt +++ b/domain/src/main/kotlin/com/wespot/common/ProfanityChecker.kt @@ -1,6 +1,6 @@ package com.wespot.common -object BadWordsChecker { +object ProfanityChecker { private val replaceCharacters = listOf( " ", @@ -52,6 +52,10 @@ object BadWordsChecker { "\"" ) + fun validateContent(content: String) { + require(!checkProfanity(content)) { "비속어가 포함되어 있습니다." } + } + fun checkProfanity(content: String): Boolean { val contentAfterRemoveProfanityMasking = removeProfanityMasking(content) println(contentAfterRemoveProfanityMasking) diff --git a/domain/src/main/kotlin/com/wespot/message/MessageContent.kt b/domain/src/main/kotlin/com/wespot/message/MessageContent.kt index f0ab23d3..b3d5f666 100644 --- a/domain/src/main/kotlin/com/wespot/message/MessageContent.kt +++ b/domain/src/main/kotlin/com/wespot/message/MessageContent.kt @@ -1,6 +1,6 @@ package com.wespot.message -import com.wespot.common.BadWordsChecker +import com.wespot.common.ProfanityChecker data class MessageContent( val content: String @@ -13,7 +13,7 @@ data class MessageContent( } private fun validateContent(content: String) { - require(!BadWordsChecker.checkProfanity(content)) { "메시지의 내용에는 욕설이 포함될 수 없습니다." } + require(!ProfanityChecker.checkProfanity(content)) { "메시지의 내용에는 욕설이 포함될 수 없습니다." } require(content.isNotBlank()) { "메시지의 내용은 필수로 존재해야합니다." } } } diff --git a/domain/src/main/kotlin/com/wespot/user/Introduction.kt b/domain/src/main/kotlin/com/wespot/user/Introduction.kt index d5f29453..93435de0 100644 --- a/domain/src/main/kotlin/com/wespot/user/Introduction.kt +++ b/domain/src/main/kotlin/com/wespot/user/Introduction.kt @@ -1,6 +1,6 @@ package com.wespot.user -import com.wespot.common.BadWordsChecker +import com.wespot.common.ProfanityChecker data class UserIntroduction( val introduction: String @@ -18,7 +18,7 @@ data class UserIntroduction( } private fun validateUserIntroduction(content: String) { - require(!BadWordsChecker.checkProfanity(content)) { "소개에는 욕설이 포함될 수 없습니다." } + require(!ProfanityChecker.checkProfanity(content)) { "소개에는 욕설이 포함될 수 없습니다." } } } diff --git a/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt b/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt index 188956e4..49a8263b 100644 --- a/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt +++ b/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt @@ -1,6 +1,6 @@ package com.wespot.voteoption -import com.wespot.common.BadWordsChecker +import com.wespot.common.ProfanityChecker data class VoteOptionContent( val content: String @@ -9,13 +9,13 @@ data class VoteOptionContent( companion object { fun from(content: String): VoteOptionContent { - BadWordsChecker.checkProfanity(content) + ProfanityChecker.checkProfanity(content) validateContent(content) return VoteOptionContent(content) } private fun validateContent(content: String) { - require(!BadWordsChecker.checkProfanity(content)) { "선택지의 내용에는 욕설이 포함될 수 없습니다." } + require(!ProfanityChecker.checkProfanity(content)) { "선택지의 내용에는 욕설이 포함될 수 없습니다." } require(content.isNotBlank()) { "선택지의 내용은 필수로 존재해야합니다." } } From 23e1261edc036d10e11dd247794adcc09a5e3c0f Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 13:57:12 +0900 Subject: [PATCH 08/17] =?UTF-8?q?test:=20validate=20test=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/domain/BadWordsCheckerTest.kt | 29 -------------- .../common/domain/ProfanityCheckerTest.kt | 39 +++++++++++++++++++ 2 files changed, 39 insertions(+), 29 deletions(-) delete mode 100644 app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt create mode 100644 app/src/test/kotlin/com/wespot/common/domain/ProfanityCheckerTest.kt diff --git a/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt b/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt deleted file mode 100644 index 5c3352d1..00000000 --- a/app/src/test/kotlin/com/wespot/common/domain/BadWordsCheckerTest.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.wespot.common.domain - -import com.wespot.common.ProfanityChecker -import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.shouldBe - -class BadWordsCheckerTest : BehaviorSpec({ - - given("사용자가 내용을 입력할 때") { - val badWords = listOf( - "ㅅ_ㅂ", - "ㅅ________________ㅂ", - "너는 ㅅ!ㅂ", - "너는 f@uck" - ) - `when`("욕설이 존재하면") { - println(ProfanityChecker.checkProfanity(badWords[0])) - println(ProfanityChecker.checkProfanity(badWords[1])) - println(ProfanityChecker.checkProfanity(badWords[2])) - println(ProfanityChecker.checkProfanity(badWords[3])) - val allMatch = badWords.stream() - .allMatch { ProfanityChecker.checkProfanity(it) } - then("true를 반환한다.") { - allMatch shouldBe true - } - } - } - -}) diff --git a/app/src/test/kotlin/com/wespot/common/domain/ProfanityCheckerTest.kt b/app/src/test/kotlin/com/wespot/common/domain/ProfanityCheckerTest.kt new file mode 100644 index 00000000..248243f7 --- /dev/null +++ b/app/src/test/kotlin/com/wespot/common/domain/ProfanityCheckerTest.kt @@ -0,0 +1,39 @@ +package com.wespot.common.domain + +import com.wespot.common.ProfanityChecker +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.shouldBe +import io.kotest.matchers.throwable.shouldHaveMessage + +class ProfanityCheckerTest : BehaviorSpec({ + + given("사용자가 내용을 입력할 때") { + val badWords = listOf( + "ㅅ_ㅂ", + "ㅅ________________ㅂ", + "너는 ㅅ!ㅂ", + "너는 f@uck" + ) + `when`("욕설이 존재하면") { + val allMatch = badWords.stream() + .allMatch { ProfanityChecker.checkProfanity(it) } + then("true를 반환한다.") { + allMatch shouldBe true + } + } + `when`("욕설이 존재하면") { + val shouldThrow1 = shouldThrow { ProfanityChecker.validateContent(badWords[0]) } + val shouldThrow2 = shouldThrow { ProfanityChecker.validateContent(badWords[1]) } + val shouldThrow3 = shouldThrow { ProfanityChecker.validateContent(badWords[2]) } + val shouldThrow4 = shouldThrow { ProfanityChecker.validateContent(badWords[3]) } + then("에외를 발생시킨다.") { + shouldThrow1 shouldHaveMessage "비속어가 포함되어 있습니다." + shouldThrow2 shouldHaveMessage "비속어가 포함되어 있습니다." + shouldThrow3 shouldHaveMessage "비속어가 포함되어 있습니다." + shouldThrow4 shouldHaveMessage "비속어가 포함되어 있습니다." + } + } + } + +}) From 58e18fcd48c67396e852cc4c9952768c2e258550 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 13:59:31 +0900 Subject: [PATCH 09/17] =?UTF-8?q?test:=20ServiceTest=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CheckProfanityServiceTest.kt | 37 +++++++++++++++++++ .../com/wespot/common/ProfanityChecker.kt | 1 - 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 app/src/test/kotlin/com/wespot/common/service/CheckProfanityServiceTest.kt diff --git a/app/src/test/kotlin/com/wespot/common/service/CheckProfanityServiceTest.kt b/app/src/test/kotlin/com/wespot/common/service/CheckProfanityServiceTest.kt new file mode 100644 index 00000000..fb82b670 --- /dev/null +++ b/app/src/test/kotlin/com/wespot/common/service/CheckProfanityServiceTest.kt @@ -0,0 +1,37 @@ +package com.wespot.common.service + +import com.wespot.common.dto.CheckProfanityRequest +import io.kotest.assertions.throwables.shouldNotThrow +import io.kotest.assertions.throwables.shouldThrow +import io.kotest.matchers.throwable.shouldHaveMessage +import org.junit.jupiter.api.Test + +class CheckProfanityServiceTest( + private val checkProfanityService: CheckProfanityService +) : ServiceTest() { + + @Test + fun `욕설이 아닌 값이 입력되면 예외를 반환하지 않는다`() { + // given + val validWord = "안녕" + val checkProfanityRequest = CheckProfanityRequest(validWord) + + // when then + shouldNotThrow { checkProfanityService.checkProfanity(checkProfanityRequest) } + } + + @Test + fun `욕설이 입력되면 예외를 반환한다`() { + // given + val badWord = "너는 ㅅ_____________112231ㅂ" + val checkProfanityRequest = CheckProfanityRequest(badWord) + + // when + val shouldThrow = + shouldThrow { checkProfanityService.checkProfanity(checkProfanityRequest) } + + // then + shouldThrow shouldHaveMessage "비속어가 포함되어 있습니다." + } + +} diff --git a/domain/src/main/kotlin/com/wespot/common/ProfanityChecker.kt b/domain/src/main/kotlin/com/wespot/common/ProfanityChecker.kt index 9cf1c578..1843dfd4 100644 --- a/domain/src/main/kotlin/com/wespot/common/ProfanityChecker.kt +++ b/domain/src/main/kotlin/com/wespot/common/ProfanityChecker.kt @@ -58,7 +58,6 @@ object ProfanityChecker { fun checkProfanity(content: String): Boolean { val contentAfterRemoveProfanityMasking = removeProfanityMasking(content) - println(contentAfterRemoveProfanityMasking) return BadWords.badWords .stream() From 5de78433a1b255868a0998d25b5474229b494b8f Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 14:02:54 +0900 Subject: [PATCH 10/17] =?UTF-8?q?test:=20Pagination=20Test=20=EB=B3=B4?= =?UTF-8?q?=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fixtrue/NotificationFixture.kt | 16 +++++++++++++ .../mysql/NotificationJpaRepositoryTest.kt | 20 +++++++++------- .../mysql/VoteJpaRepositoryTest.kt | 24 +++++++++++++++++++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/notification/fixtrue/NotificationFixture.kt b/app/src/test/kotlin/com/wespot/notification/fixtrue/NotificationFixture.kt index b4c3f5c9..e2bbe2bf 100644 --- a/app/src/test/kotlin/com/wespot/notification/fixtrue/NotificationFixture.kt +++ b/app/src/test/kotlin/com/wespot/notification/fixtrue/NotificationFixture.kt @@ -22,6 +22,22 @@ object NotificationFixture { updatedAt = LocalDateTime.now() ) + fun createWithUserIdAndType(userId: Long, notificationType: NotificationType) = Notification( + id = 0L, + userId = userId, + type = notificationType, + date = LocalDate.now(), + targetId = 1L, + title = "title", + body = "body", + isRead = false, + readAt = LocalDateTime.now(), + isEnabled = true, + createdAt = LocalDateTime.now(), + updatedAt = LocalDateTime.now() + ) + + fun createWithTypeAndCreatedAt(notificationType: NotificationType, createdAt: LocalDateTime) = Notification( id = 0L, userId = 1L, diff --git a/app/src/test/kotlin/com/wespot/notification/infrastructure/mysql/NotificationJpaRepositoryTest.kt b/app/src/test/kotlin/com/wespot/notification/infrastructure/mysql/NotificationJpaRepositoryTest.kt index cfc912c1..24d1cd29 100644 --- a/app/src/test/kotlin/com/wespot/notification/infrastructure/mysql/NotificationJpaRepositoryTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/infrastructure/mysql/NotificationJpaRepositoryTest.kt @@ -18,12 +18,16 @@ class NotificationJpaRepositoryTest @Autowired constructor( @Test fun `알림 목록 조회에 Cursor Based Pagination을 도입한다`() { // given - val notification1 = createSavedNotification() - val notification2 = createSavedNotification() - val notification3 = createSavedNotification() - val notification4 = createSavedNotification() - val notification5 = createSavedNotification() - val userId = notification1.userId + val userId = 1L + val notification1 = createSavedNotificationBy(userId) + createSavedNotificationBy(2) + val notification2 = createSavedNotificationBy(userId) + createSavedNotificationBy(3) + val notification3 = createSavedNotificationBy(userId) + createSavedNotificationBy(4) + val notification4 = createSavedNotificationBy(userId) + createSavedNotificationBy(5) + val notification5 = createSavedNotificationBy(userId) // when val firstSearch = @@ -41,8 +45,8 @@ class NotificationJpaRepositoryTest @Autowired constructor( secondSearch[1] shouldBe notification1 } - private fun createSavedNotification(): NotificationJpaEntity { - val notification = NotificationFixture.createWithType(NotificationType.MESSAGE) + private fun createSavedNotificationBy(userId: Long): NotificationJpaEntity { + val notification = NotificationFixture.createWithUserIdAndType(userId, NotificationType.MESSAGE) val notificationJpaEntity = NotificationMapper.mapToJpaEntity(notification) return notificationJpaRepository.save(notificationJpaEntity) diff --git a/app/src/test/kotlin/com/wespot/vote/infrastructure/mysql/VoteJpaRepositoryTest.kt b/app/src/test/kotlin/com/wespot/vote/infrastructure/mysql/VoteJpaRepositoryTest.kt index f4e9e7b8..d53a23b9 100644 --- a/app/src/test/kotlin/com/wespot/vote/infrastructure/mysql/VoteJpaRepositoryTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/infrastructure/mysql/VoteJpaRepositoryTest.kt @@ -27,6 +27,14 @@ class VoteJpaRepositoryTest @Autowired constructor( now.minusDays(3) ) ) + voteJpaRepository.save( + VoteJpaEntityFixture.createWithSchoolIdAndGradeAndClassNumberAndDate( + 1, + 1, + 2, + now.minusDays(3) + ) + ) val vote3 = voteJpaRepository.save( VoteJpaEntityFixture.createWithSchoolIdAndGradeAndClassNumberAndDate( 1, @@ -35,6 +43,14 @@ class VoteJpaRepositoryTest @Autowired constructor( now.minusDays(2) ) ) + voteJpaRepository.save( + VoteJpaEntityFixture.createWithSchoolIdAndGradeAndClassNumberAndDate( + 1, + 1, + 3, + now.minusDays(3) + ) + ) val vote4 = voteJpaRepository.save( VoteJpaEntityFixture.createWithSchoolIdAndGradeAndClassNumberAndDate( 1, @@ -43,6 +59,14 @@ class VoteJpaRepositoryTest @Autowired constructor( now.minusDays(1) ) ) + voteJpaRepository.save( + VoteJpaEntityFixture.createWithSchoolIdAndGradeAndClassNumberAndDate( + 1, + 1, + 4, + now.minusDays(3) + ) + ) val vote5 = voteJpaRepository.save( VoteJpaEntityFixture.createWithSchoolIdAndGradeAndClassNumberAndDate( 1, From 865fb9fe0d82cc69c994ebdab4176ee04a5eef41 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 14:13:55 +0900 Subject: [PATCH 11/17] =?UTF-8?q?test:=20Test=20=EC=BB=B4=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=97=90=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/message/domain/MessageTest.kt | 15 +++++++++++++++ .../wespot/message/fixture/MessageFixture.kt | 7 ++++--- .../message/service/ModifyMessageServiceTest.kt | 3 ++- .../com/wespot/user/fixture/UserFixture.kt | 17 +++++++++-------- .../com/wespot/user/service/UserServiceTest.kt | 5 +++-- .../wespot/voteoption/domain/VoteOptionTest.kt | 2 +- .../voteoption/fixture/VoteOptionFixture.kt | 5 +++-- .../voteoption/mapper/VoteOptionMapperTest.kt | 4 ++-- .../dto/response/MessageBlockedResponse.kt | 2 +- .../message/dto/response/MessageResponse.kt | 2 +- .../wespot/user/dto/response/UserResponse.kt | 2 +- .../vote/dto/response/VoteOptionResponse.kt | 2 +- .../vote/dto/response/VoteUserResponse.kt | 2 +- .../kotlin/com/wespot/message/MessageMapper.kt | 4 ++-- .../kotlin/com/wespot/user/mapper/UserMapper.kt | 5 +++-- .../com/wespot/voteoption/VoteOptionMapper.kt | 4 ++-- 16 files changed, 51 insertions(+), 30 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt index 98005ce5..966bfa87 100644 --- a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt +++ b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt @@ -1,18 +1,33 @@ package com.wespot.message.domain import com.wespot.message.Message +import com.wespot.message.MessageTimeValidator import com.wespot.message.fixture.MessageFixture import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.throwable.shouldHaveMessage +import io.mockk.clearAllMocks import io.mockk.every import io.mockk.mockkStatic import io.mockk.unmockkStatic +import java.time.Clock +import java.time.Instant import java.time.LocalDateTime +import java.time.ZoneId class MessageTest : BehaviorSpec({ + beforeContainer { + val fixedClock = Clock.fixed(Instant.parse("2023-03-18T18:00:00Z"), ZoneId.of("UTC")) + MessageTimeValidator.setClock(fixedClock) + } + + afterContainer { + clearAllMocks() + MessageTimeValidator.resetClock() + } + given("메시지를") { val message = MessageFixture.createWithIdAndSenderIdAndReceiverId(1, 1, 2) diff --git a/app/src/test/kotlin/com/wespot/message/fixture/MessageFixture.kt b/app/src/test/kotlin/com/wespot/message/fixture/MessageFixture.kt index f4cf9af2..248edf13 100644 --- a/app/src/test/kotlin/com/wespot/message/fixture/MessageFixture.kt +++ b/app/src/test/kotlin/com/wespot/message/fixture/MessageFixture.kt @@ -1,6 +1,7 @@ package com.wespot.message.fixture import com.wespot.message.Message +import com.wespot.message.MessageContent import com.wespot.message.MessageType import java.time.LocalDateTime @@ -9,7 +10,7 @@ object MessageFixture { fun createWithId(id: Long) = Message( id = id, - content = "content", + content = MessageContent.from("content"), senderId = 1, senderName = "senderName", receiverId = 2, @@ -31,7 +32,7 @@ object MessageFixture { fun createWithIdAndSenderIdAndReceiverId(id: Long, senderId: Long, receiverId: Long) = Message( id = id, - content = "content", + content = MessageContent.from("content"), senderId = senderId, senderName = "senderName", receiverId = receiverId, @@ -59,7 +60,7 @@ object MessageFixture { ): Message { return Message( id = 0, - content = content, + content = MessageContent.from(content), senderId = senderId, senderName = senderName, receiverId = receiverId, diff --git a/app/src/test/kotlin/com/wespot/message/service/ModifyMessageServiceTest.kt b/app/src/test/kotlin/com/wespot/message/service/ModifyMessageServiceTest.kt index 45a45a2d..f9a9e710 100644 --- a/app/src/test/kotlin/com/wespot/message/service/ModifyMessageServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/message/service/ModifyMessageServiceTest.kt @@ -2,6 +2,7 @@ package com.wespot.message.service import com.wespot.auth.service.SecurityUtils import com.wespot.message.Message +import com.wespot.message.MessageContent import com.wespot.message.MessageTimeValidator import com.wespot.message.dto.request.UpdateMessageRequest import com.wespot.message.dto.response.UpdateMessageResponse @@ -68,7 +69,7 @@ class ModifyMessageServiceTest : BehaviorSpec({ every { userPort.findById(receiver.id) } returns receiver every { messagePort.findById(message.id) } returns message every { SecurityUtils.getLoginUser(userPort) } returns sender - every { messagePort.save(any()) } returns message.copy(content = updateMessageRequest.content) + every { messagePort.save(any()) } returns message.copy(content = MessageContent.from(updateMessageRequest.content)) then("메시지가 올바르게 업데이트되어야 한다") { val response = modifyMessageService.updateMessage(message.id, updateMessageRequest) diff --git a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt index 7d5e6848..84878880 100644 --- a/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt +++ b/app/src/test/kotlin/com/wespot/user/fixture/UserFixture.kt @@ -12,6 +12,7 @@ import com.wespot.user.Social import com.wespot.user.SocialType import com.wespot.user.User import com.wespot.user.UserConsent +import com.wespot.user.UserIntroduction import com.wespot.user.dto.request.UpdateProfileRequest import org.springframework.security.authentication.TestingAuthenticationToken import org.springframework.security.core.context.SecurityContextHolder @@ -27,7 +28,7 @@ object UserFixture { password = "TestPassword", role = Role.USER, name = "TestUser", - introduction = "hello", + introduction = UserIntroduction.from("hello"), gender = "male", schoolId = 1L, grade = 1, @@ -62,7 +63,7 @@ object UserFixture { password = "TestPassword", role = Role.USER, name = "TestUser", - introduction = "hello", + introduction = UserIntroduction.from("hello"), gender = "male", schoolId = 1L, grade = 1, @@ -96,7 +97,7 @@ object UserFixture { password = "password", role = Role.USER, name = "Sender", - introduction = "intro", + introduction = UserIntroduction.from("intro"), gender = "M", schoolId = 1L, grade = 1, @@ -130,7 +131,7 @@ object UserFixture { password = "password", role = Role.USER, name = "Receiver", - introduction = "intro", + introduction = UserIntroduction.from("intro"), gender = "M", schoolId = 1L, grade = 1, @@ -187,7 +188,7 @@ object UserFixture { email = email, password = "password", name = name, - introduction = "소개 $id", + introduction = UserIntroduction.from("소개 $id"), gender = "M", schoolId = schoolId, profile = Profile(profileId, "", ""), @@ -225,7 +226,7 @@ object UserFixture { password = "TestPassword", role = Role.USER, name = "TestUser", - introduction = "hello", + introduction = UserIntroduction.from("hello"), gender = "male", schoolId = schoolId, grade = grade, @@ -262,7 +263,7 @@ object UserFixture { password = "TestPassword", role = Role.USER, name = "TestUser", - introduction = "hello", + introduction = UserIntroduction.from("hello"), gender = "male", schoolId = schoolId, grade = grade, @@ -299,7 +300,7 @@ object UserFixture { password = "TestPassword", role = Role.USER, name = "TestUser", - introduction = "hello", + introduction = UserIntroduction.from("hello"), gender = "male", schoolId = schoolId, grade = grade, diff --git a/app/src/test/kotlin/com/wespot/user/service/UserServiceTest.kt b/app/src/test/kotlin/com/wespot/user/service/UserServiceTest.kt index eed07971..4af6a8d2 100644 --- a/app/src/test/kotlin/com/wespot/user/service/UserServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/user/service/UserServiceTest.kt @@ -11,6 +11,7 @@ import com.wespot.user.port.out.UserPort import com.wespot.school.port.out.SchoolPort import com.wespot.user.Profile import com.wespot.user.User +import com.wespot.user.UserIntroduction import com.wespot.user.fixture.ProfileFixture import com.wespot.user.port.out.ProfilePort import io.kotest.core.spec.style.BehaviorSpec @@ -77,7 +78,7 @@ class UserServiceTest : BehaviorSpec({ every { getLoginUser(userPort) } returns user every { user.updateProfile(any()) } returns user.copy( - introduction = profileRequest.introduction + introduction = UserIntroduction.from(profileRequest.introduction) ) every { profile.update(any(), any()) } returns profile.copy( backgroundColor = profileRequest.profile.backgroundColor, @@ -89,7 +90,7 @@ class UserServiceTest : BehaviorSpec({ userService.updateProfile(profileRequest) then("프로필이 업데이트 되어야 한다") { - user.introduction shouldBe profileRequest.introduction + user.introduction.introduction shouldBe profileRequest.introduction user.profile.backgroundColor shouldBe profileRequest.profile.backgroundColor user.profile.iconUrl shouldBe profileRequest.profile.iconUrl } diff --git a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt index 3f2e276b..0c6a5362 100644 --- a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt +++ b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt @@ -21,7 +21,7 @@ class VoteOptionTest() : BehaviorSpec() { val voteOption = VoteOption.of(id, content, createdAt, updatedAt) then("정상적으로 생성된다.") { voteOption.id shouldBe id - voteOption.content shouldBe content + voteOption.content.content shouldBe content voteOption.createdAt shouldBe createdAt voteOption.updatedAt shouldBe updatedAt } diff --git a/app/src/test/kotlin/com/wespot/voteoption/fixture/VoteOptionFixture.kt b/app/src/test/kotlin/com/wespot/voteoption/fixture/VoteOptionFixture.kt index 0e437335..715f0180 100644 --- a/app/src/test/kotlin/com/wespot/voteoption/fixture/VoteOptionFixture.kt +++ b/app/src/test/kotlin/com/wespot/voteoption/fixture/VoteOptionFixture.kt @@ -1,20 +1,21 @@ package com.wespot.voteoption.fixture import com.wespot.voteoption.VoteOption +import com.wespot.voteoption.VoteOptionContent import java.time.LocalDateTime object VoteOptionFixture { fun create() = VoteOption( id = 0L, - content = "Mock 질문을 만듭니다.", + content = VoteOptionContent.from("Mock 질문을 만듭니다."), createdAt = LocalDateTime.now(), updatedAt = LocalDateTime.now(), ) fun createWithId(id: Long) = VoteOption( id = id, - content = "id가 지정된 질문지입니다.", + content = VoteOptionContent.from("id가 지정된 질문지입니다."), createdAt = LocalDateTime.now(), updatedAt = LocalDateTime.now(), ) diff --git a/app/src/test/kotlin/com/wespot/voteoption/mapper/VoteOptionMapperTest.kt b/app/src/test/kotlin/com/wespot/voteoption/mapper/VoteOptionMapperTest.kt index cea15de3..d75434cd 100644 --- a/app/src/test/kotlin/com/wespot/voteoption/mapper/VoteOptionMapperTest.kt +++ b/app/src/test/kotlin/com/wespot/voteoption/mapper/VoteOptionMapperTest.kt @@ -14,7 +14,7 @@ class VoteOptionMapperTest : BehaviorSpec({ val domainEntity = VoteOptionMapper.mapToDomainEntity(jpaEntity) then("Domain Entity를 반환한다") { domainEntity.id shouldBe jpaEntity.id - domainEntity.content shouldBe jpaEntity.content + domainEntity.content.content shouldBe jpaEntity.content domainEntity.createdAt shouldBe jpaEntity.baseEntity.createdAt domainEntity.updatedAt shouldBe jpaEntity.baseEntity.updatedAt } @@ -27,7 +27,7 @@ class VoteOptionMapperTest : BehaviorSpec({ val jpaEntity = VoteOptionMapper.mapToJpaEntity(domainEntity) then("Jpa Entity를 반환한다") { jpaEntity.id shouldBe domainEntity.id - jpaEntity.content shouldBe domainEntity.content + jpaEntity.content shouldBe domainEntity.content.content jpaEntity.baseEntity.createdAt shouldBe domainEntity.createdAt jpaEntity.baseEntity.updatedAt shouldBe domainEntity.updatedAt } diff --git a/core/src/main/kotlin/com/wespot/message/dto/response/MessageBlockedResponse.kt b/core/src/main/kotlin/com/wespot/message/dto/response/MessageBlockedResponse.kt index be31daa0..a9255226 100644 --- a/core/src/main/kotlin/com/wespot/message/dto/response/MessageBlockedResponse.kt +++ b/core/src/main/kotlin/com/wespot/message/dto/response/MessageBlockedResponse.kt @@ -35,7 +35,7 @@ data class MessageBlockedResponse( senderName = message.senderName, senderProfile = senderProfile, receiver = UserResponse.from(receiver, school.name), - content = message.content, + content = message.content.content, receivedAt = message.receivedAt?.toString(), isRead = message.isReceiverRead, isBlocked = isBlocked, diff --git a/core/src/main/kotlin/com/wespot/message/dto/response/MessageResponse.kt b/core/src/main/kotlin/com/wespot/message/dto/response/MessageResponse.kt index 85560769..fffb537f 100644 --- a/core/src/main/kotlin/com/wespot/message/dto/response/MessageResponse.kt +++ b/core/src/main/kotlin/com/wespot/message/dto/response/MessageResponse.kt @@ -31,7 +31,7 @@ data class MessageResponse( id = message.id, senderName = message.senderName, receiver = UserResponse.from(receiver, school.name), - content = message.content, + content = message.content.content, receivedAt = message.receivedAt?.toString(), isRead = message.isReceiverRead, isBlocked = isBlocked, diff --git a/core/src/main/kotlin/com/wespot/user/dto/response/UserResponse.kt b/core/src/main/kotlin/com/wespot/user/dto/response/UserResponse.kt index 469645d1..967f985b 100644 --- a/core/src/main/kotlin/com/wespot/user/dto/response/UserResponse.kt +++ b/core/src/main/kotlin/com/wespot/user/dto/response/UserResponse.kt @@ -20,7 +20,7 @@ data class UserResponse( id = user.id, name = user.name, gender = user.name, - introduction = user.introduction, + introduction = user.introduction.introduction, schoolName = school, grade = user.grade, classNumber = user.classNumber, diff --git a/core/src/main/kotlin/com/wespot/vote/dto/response/VoteOptionResponse.kt b/core/src/main/kotlin/com/wespot/vote/dto/response/VoteOptionResponse.kt index 6a65a194..3bdc0a86 100644 --- a/core/src/main/kotlin/com/wespot/vote/dto/response/VoteOptionResponse.kt +++ b/core/src/main/kotlin/com/wespot/vote/dto/response/VoteOptionResponse.kt @@ -12,7 +12,7 @@ data class VoteOptionResponse( fun from(voteOption: VoteOption): VoteOptionResponse { return VoteOptionResponse( id = voteOption.id, - content = voteOption.content + content = voteOption.content.content ) } diff --git a/core/src/main/kotlin/com/wespot/vote/dto/response/VoteUserResponse.kt b/core/src/main/kotlin/com/wespot/vote/dto/response/VoteUserResponse.kt index bb063823..573dac1e 100644 --- a/core/src/main/kotlin/com/wespot/vote/dto/response/VoteUserResponse.kt +++ b/core/src/main/kotlin/com/wespot/vote/dto/response/VoteUserResponse.kt @@ -16,7 +16,7 @@ data class VoteUserResponse( return VoteUserResponse( id = user.id, name = user.name, - introduction = user.introduction, + introduction = user.introduction.introduction, profile = user.profile.let { ProfileResponse.from(it) } ) } diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/message/MessageMapper.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/message/MessageMapper.kt index 9f8be9b0..88e11cd0 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/message/MessageMapper.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/message/MessageMapper.kt @@ -7,7 +7,7 @@ object MessageMapper { fun mapToDomainEntity(messageJpaEntity: MessageJpaEntity): Message = Message( id = messageJpaEntity.id, - content = messageJpaEntity.content, + content = MessageContent.from(messageJpaEntity.content), senderId = messageJpaEntity.senderId, senderName = messageJpaEntity.senderName, receiverId = messageJpaEntity.receiverId, @@ -30,7 +30,7 @@ object MessageMapper { fun mapToJpaEntity(message: Message): MessageJpaEntity = MessageJpaEntity( id = message.id, - content = message.content, + content = message.content.content, senderId = message.senderId, senderName = message.senderName, receiverId = message.receiverId, diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/mapper/UserMapper.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/mapper/UserMapper.kt index f0c84337..c9d32edd 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/mapper/UserMapper.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/mapper/UserMapper.kt @@ -3,6 +3,7 @@ package com.wespot.user.mapper import com.wespot.common.BaseEntity import com.wespot.user.Restriction import com.wespot.user.User +import com.wespot.user.UserIntroduction import com.wespot.user.entity.UserJpaEntity object UserMapper { @@ -13,7 +14,7 @@ object UserMapper { email = userJpaEntity.email, password = userJpaEntity.password, name = userJpaEntity.name, - introduction = userJpaEntity.introduction, + introduction = UserIntroduction.from(userJpaEntity.introduction), gender = userJpaEntity.gender, schoolId = userJpaEntity.schoolId, grade = userJpaEntity.grade, @@ -37,7 +38,7 @@ object UserMapper { email = user.email, password = user.password, name = user.name, - introduction = user.introduction, + introduction = user.introduction.introduction, gender = user.gender, schoolId = user.schoolId, grade = user.grade, diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/voteoption/VoteOptionMapper.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/voteoption/VoteOptionMapper.kt index 088c6bd7..68c783d7 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/voteoption/VoteOptionMapper.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/voteoption/VoteOptionMapper.kt @@ -7,7 +7,7 @@ object VoteOptionMapper { fun mapToDomainEntity(voteOptionJpaEntity: VoteOptionJpaEntity): VoteOption = VoteOption( id = voteOptionJpaEntity.id, - content = voteOptionJpaEntity.content, + content = VoteOptionContent.from(voteOptionJpaEntity.content), createdAt = voteOptionJpaEntity.baseEntity.createdAt, updatedAt = voteOptionJpaEntity.baseEntity.updatedAt ) @@ -15,7 +15,7 @@ object VoteOptionMapper { fun mapToJpaEntity(voteOption: VoteOption): VoteOptionJpaEntity = VoteOptionJpaEntity( id = voteOption.id, - content = voteOption.content, + content = voteOption.content.content, baseEntity = BaseEntity( createdAt = voteOption.createdAt, updatedAt = voteOption.updatedAt From 2f694e06a9dcba15f7b281f8471b50d38f14d400 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Fri, 9 Aug 2024 14:29:20 +0900 Subject: [PATCH 12/17] =?UTF-8?q?test:=20SpringBootTest=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/common/service/CheckProfanityServiceTest.kt | 3 ++- .../notification/service/CreatedVoteNotificationServiceTest.kt | 1 - .../notification/service/DisabledNotificationServiceTest.kt | 1 - .../notification/service/InquiryNotificationServiceTest.kt | 1 - .../com/wespot/notification/service/NotificationHelperTest.kt | 1 - .../service/listener/MessageNotificationEventListenerTest.kt | 2 -- .../service/listener/VoteNotificationEventListenerTest.kt | 1 - .../com/wespot/report/service/RevokeRestrictionServiceTest.kt | 1 - .../kotlin/com/wespot/report/service/SavedReportServiceTest.kt | 1 - .../kotlin/com/wespot/user/service/UserSettingServiceTest.kt | 1 - .../kotlin/com/wespot/vote/service/CreatedVoteServiceTest.kt | 1 - .../kotlin/com/wespot/vote/service/ReceivedVoteServiceTest.kt | 1 - .../kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt | 1 - .../test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt | 1 - .../test/kotlin/com/wespot/vote/service/VoteRankServiceTest.kt | 1 - 15 files changed, 2 insertions(+), 16 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/common/service/CheckProfanityServiceTest.kt b/app/src/test/kotlin/com/wespot/common/service/CheckProfanityServiceTest.kt index fb82b670..7762c196 100644 --- a/app/src/test/kotlin/com/wespot/common/service/CheckProfanityServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/common/service/CheckProfanityServiceTest.kt @@ -5,8 +5,9 @@ import io.kotest.assertions.throwables.shouldNotThrow import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.throwable.shouldHaveMessage import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired -class CheckProfanityServiceTest( +class CheckProfanityServiceTest @Autowired constructor( private val checkProfanityService: CheckProfanityService ) : ServiceTest() { diff --git a/app/src/test/kotlin/com/wespot/notification/service/CreatedVoteNotificationServiceTest.kt b/app/src/test/kotlin/com/wespot/notification/service/CreatedVoteNotificationServiceTest.kt index 8be19777..9bf64ea1 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/CreatedVoteNotificationServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/CreatedVoteNotificationServiceTest.kt @@ -13,7 +13,6 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import kotlin.test.Test -@SpringBootTest class CreatedVoteNotificationServiceTest @Autowired constructor( private val createdVoteNotificationService: CreatedVoteNotificationService, private val notificationPort: NotificationPort, diff --git a/app/src/test/kotlin/com/wespot/notification/service/DisabledNotificationServiceTest.kt b/app/src/test/kotlin/com/wespot/notification/service/DisabledNotificationServiceTest.kt index a3444d33..9fcd87a7 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/DisabledNotificationServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/DisabledNotificationServiceTest.kt @@ -10,7 +10,6 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate -@SpringBootTest class DisabledNotificationServiceTest @Autowired constructor( private val notificationPort: NotificationPort, private val disabledNotificationService: DisabledNotificationService, diff --git a/app/src/test/kotlin/com/wespot/notification/service/InquiryNotificationServiceTest.kt b/app/src/test/kotlin/com/wespot/notification/service/InquiryNotificationServiceTest.kt index 5de39340..5331ae44 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/InquiryNotificationServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/InquiryNotificationServiceTest.kt @@ -11,7 +11,6 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest -@SpringBootTest class InquiryNotificationServiceTest @Autowired constructor( private val inquiryNotificationService: InquiryNotificationService, private val userPort: UserPort, diff --git a/app/src/test/kotlin/com/wespot/notification/service/NotificationHelperTest.kt b/app/src/test/kotlin/com/wespot/notification/service/NotificationHelperTest.kt index 64ab053b..da1ef798 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/NotificationHelperTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/NotificationHelperTest.kt @@ -14,7 +14,6 @@ import org.junit.jupiter.api.Test import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate -@SpringBootTest class NotificationHelperTest : ServiceTest() { private val notificationSendService = mockk() diff --git a/app/src/test/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListenerTest.kt b/app/src/test/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListenerTest.kt index 7f337beb..bf923aa6 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListenerTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListenerTest.kt @@ -20,10 +20,8 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest -@SpringBootTest class MessageNotificationEventListenerTest @Autowired constructor( private val messageNotificationEventListener: MessageNotificationEventListener, - private val databaseCleanup: DatabaseCleanup, private val userPort: UserPort, private val messagePort: MessagePort, private val notificationPort: NotificationPort, diff --git a/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt b/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt index f3bb5711..15c3fc3c 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/listener/VoteNotificationEventListenerTest.kt @@ -23,7 +23,6 @@ import java.time.LocalDate import java.time.LocalDateTime import kotlin.test.Test -@SpringBootTest class VoteNotificationEventListenerTest @Autowired constructor( private val voteNotificationEventListener: VoteNotificationEventListener, private val userPort: UserPort, diff --git a/app/src/test/kotlin/com/wespot/report/service/RevokeRestrictionServiceTest.kt b/app/src/test/kotlin/com/wespot/report/service/RevokeRestrictionServiceTest.kt index 2a34a22f..11d15deb 100644 --- a/app/src/test/kotlin/com/wespot/report/service/RevokeRestrictionServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/report/service/RevokeRestrictionServiceTest.kt @@ -12,7 +12,6 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate -@SpringBootTest class RevokeRestrictionServiceTest @Autowired constructor( private val revokeRestrictionService: RevokeRestrictionService, private val userJpaRepository: UserJpaRepository, diff --git a/app/src/test/kotlin/com/wespot/report/service/SavedReportServiceTest.kt b/app/src/test/kotlin/com/wespot/report/service/SavedReportServiceTest.kt index 12696970..17637a8f 100644 --- a/app/src/test/kotlin/com/wespot/report/service/SavedReportServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/report/service/SavedReportServiceTest.kt @@ -18,7 +18,6 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest -@SpringBootTest class SavedReportServiceTest @Autowired constructor( private val savedReportService: SavedReportService, private val userJpaRepository: UserJpaRepository, diff --git a/app/src/test/kotlin/com/wespot/user/service/UserSettingServiceTest.kt b/app/src/test/kotlin/com/wespot/user/service/UserSettingServiceTest.kt index e13a42a8..655117c7 100644 --- a/app/src/test/kotlin/com/wespot/user/service/UserSettingServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/user/service/UserSettingServiceTest.kt @@ -9,7 +9,6 @@ import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest -@SpringBootTest class UserSettingServiceTest @Autowired constructor( private val userSettingService: UserSettingService, private val userPort: UserPort diff --git a/app/src/test/kotlin/com/wespot/vote/service/CreatedVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/CreatedVoteServiceTest.kt index 2bbf1d38..36f8f4b4 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/CreatedVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/CreatedVoteServiceTest.kt @@ -24,7 +24,6 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate -@SpringBootTest class CreatedVoteServiceTest @Autowired constructor( private var createdVoteService: CreatedVoteService, private var userJpaRepository: UserJpaRepository, diff --git a/app/src/test/kotlin/com/wespot/vote/service/ReceivedVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/ReceivedVoteServiceTest.kt index e441e327..4db9396e 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/ReceivedVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/ReceivedVoteServiceTest.kt @@ -25,7 +25,6 @@ import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate import java.time.LocalDateTime -@SpringBootTest class ReceivedVoteServiceTest @Autowired constructor( private var receivedVoteService: ReceivedVoteService, private var userJpaRepository: UserJpaRepository, diff --git a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt index 0e374582..18f2e9f2 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt @@ -25,7 +25,6 @@ import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate import kotlin.test.Test -@SpringBootTest class SavedVoteServiceTest @Autowired constructor( private var voteService: SavedVoteService, private var userJpaRepository: UserJpaRepository, diff --git a/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt index 26a1c9c0..b9a12a43 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt @@ -23,7 +23,6 @@ import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate import java.time.LocalDateTime -@SpringBootTest class SentVoteServiceTest @Autowired constructor( private var sentVoteService: SentVoteService, private var userJpaRepository: UserJpaRepository, diff --git a/app/src/test/kotlin/com/wespot/vote/service/VoteRankServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/VoteRankServiceTest.kt index 2662726e..4f937bb3 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/VoteRankServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/VoteRankServiceTest.kt @@ -23,7 +23,6 @@ import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate import java.time.LocalDateTime -@SpringBootTest class VoteRankServiceTest @Autowired constructor( private var voteRankService: VoteRankService, private var userJpaRepository: UserJpaRepository, From ad69e429ca6510dca19599434b21d446c913bb5f Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Sat, 10 Aug 2024 01:08:18 +0900 Subject: [PATCH 13/17] =?UTF-8?q?refactor:=20lastCursorId=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wespot/notification/NotificationController.kt | 3 +-- .../main/kotlin/com/wespot/vote/VoteController.kt | 8 +++----- .../service/InquiryNotificationServiceTest.kt | 5 +++-- .../wespot/vote/service/ReceivedVoteServiceTest.kt | 4 +++- .../com/wespot/vote/service/SentVoteServiceTest.kt | 3 +++ .../notification/dto/NotificationResponses.kt | 12 +++++++++++- .../dto/response/received/ReceivedVotesResponses.kt | 13 ++++++++++++- .../vote/dto/response/sent/SentVotesResponses.kt | 12 +++++++++++- 8 files changed, 47 insertions(+), 13 deletions(-) diff --git a/app/src/main/kotlin/com/wespot/notification/NotificationController.kt b/app/src/main/kotlin/com/wespot/notification/NotificationController.kt index c0e91360..f06bacac 100644 --- a/app/src/main/kotlin/com/wespot/notification/NotificationController.kt +++ b/app/src/main/kotlin/com/wespot/notification/NotificationController.kt @@ -20,9 +20,8 @@ class NotificationController( @GetMapping fun getNotifications( @RequestParam(required = false) cursorId: Long?, - @RequestParam limit: Long ): ResponseEntity { - val notifications = inquiryNotificationUseCase.getNotifications(cursorId, limit) + val notifications = inquiryNotificationUseCase.getNotifications(cursorId, 10) return ResponseEntity.ok(notifications) } diff --git a/app/src/main/kotlin/com/wespot/vote/VoteController.kt b/app/src/main/kotlin/com/wespot/vote/VoteController.kt index d960bcdb..08cf1f97 100644 --- a/app/src/main/kotlin/com/wespot/vote/VoteController.kt +++ b/app/src/main/kotlin/com/wespot/vote/VoteController.kt @@ -67,10 +67,9 @@ class VoteController( @GetMapping("/received") fun getReceivedVotes( - @RequestParam(required = false) cursorId: Long?, - @RequestParam limit: Long + @RequestParam(required = false) cursorId: Long? ): ResponseEntity { - val responses = receivedVoteUseCase.getReceivedVotes(cursorId, limit) + val responses = receivedVoteUseCase.getReceivedVotes(cursorId, 10) return ResponseEntity.ok(responses) } @@ -88,9 +87,8 @@ class VoteController( @GetMapping("/sent") fun getSentVotes( @RequestParam(required = false) cursorId: Long?, - @RequestParam limit: Long ): ResponseEntity { - val responses = sentVoteUseCase.getSentVotes(cursorId, limit) + val responses = sentVoteUseCase.getSentVotes(cursorId, 10) return ResponseEntity.ok(responses) } diff --git a/app/src/test/kotlin/com/wespot/notification/service/InquiryNotificationServiceTest.kt b/app/src/test/kotlin/com/wespot/notification/service/InquiryNotificationServiceTest.kt index 5331ae44..311bf3d5 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/InquiryNotificationServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/InquiryNotificationServiceTest.kt @@ -9,7 +9,6 @@ import com.wespot.user.port.out.UserPort import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest class InquiryNotificationServiceTest @Autowired constructor( private val inquiryNotificationService: InquiryNotificationService, @@ -41,14 +40,16 @@ class InquiryNotificationServiceTest @Autowired constructor( // when val responses1 = inquiryNotificationService.getNotifications(null, 1) - val responses2= inquiryNotificationService.getNotifications(responses1.notifications[0].id, 1) + val responses2 = inquiryNotificationService.getNotifications(responses1.notifications[0].id, 1) // then responses1.notifications.size shouldBe 1 responses1.notifications[0].id shouldBe savedNotification.id + responses1.lastCursorId shouldBe savedNotification.id responses1.hasNext shouldBe true responses2.notifications.size shouldBe 1 responses2.notifications[0].id shouldBe notifications[0].id + responses2.lastCursorId shouldBe notifications[0].id responses2.hasNext shouldBe false } diff --git a/app/src/test/kotlin/com/wespot/vote/service/ReceivedVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/ReceivedVoteServiceTest.kt index 4db9396e..acdbd27a 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/ReceivedVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/ReceivedVoteServiceTest.kt @@ -21,7 +21,6 @@ import io.kotest.matchers.throwable.shouldHaveMessage import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate import java.time.LocalDateTime @@ -122,11 +121,14 @@ class ReceivedVoteServiceTest @Autowired constructor( receivedVotes1.voteData[0].receivedVoteResults[1].isNew shouldBe true receivedVotes1.voteData[1].date shouldBe now.minusDays(1).toLocalDate().toString() receivedVotes1.voteData[1].receivedVoteResults.size shouldBe 0 + receivedVotes1.lastCursorId shouldBe vote2!!.id receivedVotes2.voteData.size shouldBe 1 receivedVotes2.voteData[0].voteId shouldBe vote1!!.id + receivedVotes2.lastCursorId shouldBe vote1!!.id receivedVotes2.hasNext shouldBe true receivedVotes3.voteData.size shouldBe 1 receivedVotes3.voteData[0].voteId shouldBe vote2!!.id + receivedVotes3.lastCursorId shouldBe vote2!!.id receivedVotes3.hasNext shouldBe false } diff --git a/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt index b9a12a43..f09c226e 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt @@ -119,12 +119,15 @@ class SentVoteServiceTest @Autowired constructor( sentVotes1.voteData[0].sentVoteResults[1].vote.user.id shouldBe users[2].id sentVotes1.voteData[1].date shouldBe now.minusDays(1).toLocalDate().toString() sentVotes1.voteData[1].sentVoteResults.size shouldBe 0 + sentVotes1.lastCursorId shouldBe vote2!!.id sentVotes1.hasNext shouldBe false sentVotes2.voteData.size shouldBe 1 sentVotes2.voteData[0].voteId shouldBe vote1!!.id + sentVotes2.lastCursorId shouldBe vote1!!.id sentVotes2.hasNext shouldBe true sentVotes3.voteData.size shouldBe 1 sentVotes3.voteData[0].voteId shouldBe vote2!!.id + sentVotes3.lastCursorId shouldBe vote2!!.id sentVotes3.hasNext shouldBe false } diff --git a/core/src/main/kotlin/com/wespot/notification/dto/NotificationResponses.kt b/core/src/main/kotlin/com/wespot/notification/dto/NotificationResponses.kt index ce528aea..ae015f0e 100644 --- a/core/src/main/kotlin/com/wespot/notification/dto/NotificationResponses.kt +++ b/core/src/main/kotlin/com/wespot/notification/dto/NotificationResponses.kt @@ -4,6 +4,7 @@ import com.wespot.notification.Notification data class NotificationResponses( val notifications: List, + val lastCursorId: Long, val hasNext: Boolean ) { @@ -14,7 +15,16 @@ data class NotificationResponses( .map { NotificationResponse.from(it) } .toList() - return NotificationResponses(response, hasNext) + return NotificationResponses(response, getLastCursorId(notifications), hasNext) + } + + private fun getLastCursorId(notifications: List): Long { + if (notifications.isEmpty()) { + return 0 + } + + return notifications.last() + .id } } diff --git a/core/src/main/kotlin/com/wespot/vote/dto/response/received/ReceivedVotesResponses.kt b/core/src/main/kotlin/com/wespot/vote/dto/response/received/ReceivedVotesResponses.kt index 4bf5f288..5ffa7bf8 100644 --- a/core/src/main/kotlin/com/wespot/vote/dto/response/received/ReceivedVotesResponses.kt +++ b/core/src/main/kotlin/com/wespot/vote/dto/response/received/ReceivedVotesResponses.kt @@ -6,6 +6,7 @@ import com.wespot.voteoption.VoteOption data class ReceivedVotesResponses( val voteData: List, + val lastCursorId: Long, val hasNext: Boolean ) { companion object { @@ -14,7 +15,17 @@ data class ReceivedVotesResponses( val voteData = voteResults .map { ReceivedVotesResponse.of(it.key, it.value) } .toList() - return ReceivedVotesResponses(voteData, hasNext) + + return ReceivedVotesResponses(voteData, getLastCursorId(voteData), hasNext) + } + + private fun getLastCursorId(receivedVotesResponse: List): Long { + if (receivedVotesResponse.isEmpty()) { + return 0 + } + + return receivedVotesResponse.last() + .voteId } } diff --git a/core/src/main/kotlin/com/wespot/vote/dto/response/sent/SentVotesResponses.kt b/core/src/main/kotlin/com/wespot/vote/dto/response/sent/SentVotesResponses.kt index 55a2cd02..5c6fa52b 100644 --- a/core/src/main/kotlin/com/wespot/vote/dto/response/sent/SentVotesResponses.kt +++ b/core/src/main/kotlin/com/wespot/vote/dto/response/sent/SentVotesResponses.kt @@ -5,6 +5,7 @@ import com.wespot.vote.Vote data class SentVotesResponses( val voteData: List, + val lastCursorId: Long, val hasNext: Boolean ) { companion object { @@ -13,7 +14,16 @@ data class SentVotesResponses( val voteData = voteResult .map { SentVotesResponse.of(it.key, it.value) } .toList() - return SentVotesResponses(voteData, hasNext) + return SentVotesResponses(voteData, getLastCursorId(voteData), hasNext) + } + + private fun getLastCursorId(sentVotesResponse: List): Long { + if (sentVotesResponse.isEmpty()) { + return 0 + } + + return sentVotesResponse.last() + .voteId } } From d851ba9ffdf3181d03d4812f945d5cd33ed04259 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Sat, 10 Aug 2024 01:39:07 +0900 Subject: [PATCH 14/17] =?UTF-8?q?refactor:=20Transactional=20=EC=96=B4?= =?UTF-8?q?=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wespot/auth/service/AuthServiceTest.kt | 4 +++- .../wespot/vote/service/SavedVoteServiceTest.kt | 15 +++++++++------ .../com/wespot/vote/service/CreatedVoteService.kt | 2 -- .../wespot/vote/service/ReceivedVoteService.kt | 3 ++- .../com/wespot/vote/service/SavedVoteService.kt | 3 ++- .../com/wespot/vote/service/SentVoteService.kt | 2 ++ .../com/wespot/vote/service/VoteRankService.kt | 3 +++ 7 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt b/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt index 2110960f..1010bb7e 100644 --- a/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt @@ -24,6 +24,7 @@ import io.mockk.every import io.mockk.just import io.mockk.mockk import io.mockk.spyk +import org.springframework.context.ApplicationEventPublisher import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.core.Authentication import org.springframework.security.crypto.password.PasswordEncoder @@ -42,6 +43,7 @@ class AuthServiceTest : BehaviorSpec({ val authenticationManager = mockk() val passwordEncoder = mockk() val refreshTokenService = mockk() + val eventPublisher = mockk() val secretKey = "testSecretKey" @@ -59,7 +61,7 @@ class AuthServiceTest : BehaviorSpec({ authenticationManager = authenticationManager, passwordEncoder = passwordEncoder, refreshTokenService = refreshTokenService, - eventPublisher = mockk(), + eventPublisher = eventPublisher, secretKey = secretKey ) ) diff --git a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt index 18f2e9f2..bf479f55 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt @@ -1,6 +1,7 @@ package com.wespot.vote.service import com.wespot.common.service.ServiceTest +import com.wespot.notification.port.out.NotificationPort import com.wespot.user.entity.UserJpaEntity import com.wespot.user.fixture.UserFixture import com.wespot.user.mapper.UserMapper @@ -21,16 +22,16 @@ import io.kotest.matchers.shouldBe import io.kotest.matchers.throwable.shouldHaveMessage import org.junit.jupiter.api.BeforeEach import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate import kotlin.test.Test class SavedVoteServiceTest @Autowired constructor( - private var voteService: SavedVoteService, - private var userJpaRepository: UserJpaRepository, - private var voteOptionJpaRepository: VoteOptionJpaRepository, - private var ballotJpaRepository: BallotJpaRepository, - private var votePort: VotePort, + private val voteService: SavedVoteService, + private val userJpaRepository: UserJpaRepository, + private val voteOptionJpaRepository: VoteOptionJpaRepository, + private val ballotJpaRepository: BallotJpaRepository, + private val votePort: VotePort, + private val notificationPort: NotificationPort, ) : ServiceTest() { private var users: MutableList = mutableListOf() @@ -189,6 +190,7 @@ class SavedVoteServiceTest @Autowired constructor( val loginUser = UserMapper.mapToDomainEntity(users[users.size - 1]) UserFixture.setSecurityContextUser(loginUser) voteService.saveVote(requests) + val notifications = notificationPort.findAll() // then val ballots = ballotJpaRepository.findAll() @@ -206,6 +208,7 @@ class SavedVoteServiceTest @Autowired constructor( ballots[2].receiverId shouldBeIn votedUserIds ballots[3].receiverId shouldBeIn votedUserIds ballots[4].receiverId shouldBeIn votedUserIds + notifications.size shouldBe 5 } } diff --git a/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt index 30901fb3..0aef26ae 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt @@ -8,7 +8,6 @@ import com.wespot.vote.event.EndVoteEvent import com.wespot.vote.port.`in`.CreatedVoteUseCase import com.wespot.vote.port.out.VoteOptionPort import com.wespot.vote.port.out.VotePort -import com.wespot.vote.service.helper.VoteServiceHelper import com.wespot.voteoption.VoteOption import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Service @@ -67,7 +66,6 @@ class CreatedVoteService( @Transactional override fun createVoteByUser(user: User) { - VoteServiceHelper.findUser(userPort, user.id) val allVoteOptions = voteOptionPort.findAll() val today = LocalDate.now() val voteIdentifier = VoteIdentifier.of(user, today) diff --git a/core/src/main/kotlin/com/wespot/vote/service/ReceivedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/ReceivedVoteService.kt index 2798f1d8..a14de7a6 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/ReceivedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/ReceivedVoteService.kt @@ -13,8 +13,8 @@ import com.wespot.vote.port.out.VoteOptionPort import com.wespot.vote.port.out.VotePort import com.wespot.vote.service.helper.VoteServiceHelper import com.wespot.voteoption.VoteOption -import jakarta.transaction.Transactional import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional import java.time.LocalDate @Service @@ -25,6 +25,7 @@ class ReceivedVoteService( private val receivedVoteCalculateService: ReceivedVoteCalculateService ) : ReceivedVoteUseCase { + @Transactional(readOnly = true) override fun getReceivedVotes(cursorId: Long?, limit: Long): ReceivedVotesResponses { val user = VoteServiceHelper.findLoginUser(userPort) val votes = VoteServiceHelper.findVotesOrderByDateDesc( diff --git a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt index b1f4177d..df376a96 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/SavedVoteService.kt @@ -12,9 +12,9 @@ import com.wespot.vote.event.RegisteredVoteEvent import com.wespot.vote.port.`in`.SavedVoteUseCase import com.wespot.vote.port.out.VotePort import com.wespot.vote.service.helper.VoteServiceHelper -import jakarta.transaction.Transactional import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional import java.time.LocalDate import java.time.LocalDateTime @@ -25,6 +25,7 @@ class SavedVoteService( private val eventPublisher: ApplicationEventPublisher, ) : SavedVoteUseCase { + @Transactional(readOnly = true) override fun getVoteOptions(): VoteItems { val user = VoteServiceHelper.findLoginUser(userPort) val classmates = VoteServiceHelper.findClassmatesByUser(userPort, user) diff --git a/core/src/main/kotlin/com/wespot/vote/service/SentVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/SentVoteService.kt index f7b99c35..d8c9d467 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/SentVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/SentVoteService.kt @@ -10,6 +10,7 @@ import com.wespot.vote.port.`in`.SentVoteUseCase import com.wespot.vote.port.out.VotePort import com.wespot.vote.service.helper.VoteServiceHelper import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class SentVoteService( @@ -17,6 +18,7 @@ class SentVoteService( private val userPort: UserPort, ) : SentVoteUseCase { + @Transactional(readOnly = true) override fun getSentVotes(cursorId: Long?, limit: Long): SentVotesResponses { val user = VoteServiceHelper.findLoginUser(userPort) val votes = VoteServiceHelper.findVotesOrderByDateDesc( diff --git a/core/src/main/kotlin/com/wespot/vote/service/VoteRankService.kt b/core/src/main/kotlin/com/wespot/vote/service/VoteRankService.kt index 94486ef1..46681dd0 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/VoteRankService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/VoteRankService.kt @@ -10,6 +10,7 @@ import com.wespot.vote.port.out.VotePort import com.wespot.vote.service.helper.VoteServiceHelper import com.wespot.voteoption.VoteOption import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional import java.time.LocalDate @Service @@ -19,6 +20,7 @@ class VoteRankService( private val rankCalculateService: RankCalculateService ) : VoteRankUseCase { + @Transactional(readOnly = true) override fun getVoteResultsOfTop5(date: LocalDate): VoteResultResponsesOfTop5 { return VoteResultResponsesOfTop5.from(getRankedVoteResults(date)) } @@ -34,6 +36,7 @@ class VoteRankService( return rankedVoteResults } + @Transactional(readOnly = true) override fun getVoteResultsOfTop1(date: LocalDate): VoteResultResponsesOfTop1 { return VoteResultResponsesOfTop1.from(getRankedVoteResults(date)) } From 4123b73fe89a9b466dd83cc746aca58aa6a70d9d Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Sat, 10 Aug 2024 02:54:46 +0900 Subject: [PATCH 15/17] =?UTF-8?q?test:=20Test=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/wespot/message/domain/MessageContentTest.kt | 2 +- .../test/kotlin/com/wespot/message/domain/MessageTest.kt | 2 +- .../kotlin/com/wespot/user/domain/UserIntroductionTest.kt | 2 +- app/src/test/kotlin/com/wespot/user/domain/UserTest.kt | 2 +- .../com/wespot/voteoption/domain/VoteOptionContentTest.kt | 2 +- .../kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt | 2 +- core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt | 6 ++++++ .../src/main/kotlin/com/wespot/message/MessageContent.kt | 2 +- .../wespot/user/{Introduction.kt => UserIntroduction.kt} | 2 +- .../main/kotlin/com/wespot/user/event/CreatedVoteEvent.kt | 7 +++++++ .../main/kotlin/com/wespot/voteoption/VoteOptionContent.kt | 2 +- .../com/wespot/user/adapter/UserPersistenceAdapter.kt | 5 ++++- .../kotlin/com/wespot/user/repository/UserJpaRepository.kt | 6 ++++++ 13 files changed, 32 insertions(+), 10 deletions(-) rename domain/src/main/kotlin/com/wespot/user/{Introduction.kt => UserIntroduction.kt} (91%) create mode 100644 domain/src/main/kotlin/com/wespot/user/event/CreatedVoteEvent.kt diff --git a/app/src/test/kotlin/com/wespot/message/domain/MessageContentTest.kt b/app/src/test/kotlin/com/wespot/message/domain/MessageContentTest.kt index e66435eb..76b4d9d5 100644 --- a/app/src/test/kotlin/com/wespot/message/domain/MessageContentTest.kt +++ b/app/src/test/kotlin/com/wespot/message/domain/MessageContentTest.kt @@ -15,7 +15,7 @@ class MessageContentTest : BehaviorSpec({ `when`("욕설이 포함되어 있는 경우") { val shouldThrow = shouldThrow { MessageContent.from(badWordsContent) } then("예외가 발생한다.") { - shouldThrow shouldHaveMessage "메시지의 내용에는 욕설이 포함될 수 없습니다." + shouldThrow shouldHaveMessage "메시지의 내용에 비속어가 포함되어 있습니다." } } `when`("아무런 내용이 없는 경우") { diff --git a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt index 966bfa87..ec9f3247 100644 --- a/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt +++ b/app/src/test/kotlin/com/wespot/message/domain/MessageTest.kt @@ -69,7 +69,7 @@ class MessageTest : BehaviorSpec({ ) } then("예외가 발생한다.") { - shouldThrow shouldHaveMessage "메시지의 내용에는 욕설이 포함될 수 없습니다." + shouldThrow shouldHaveMessage "메시지의 내용에 비속어가 포함되어 있습니다." } } `when`("아무런 내용이 없는 경우") { diff --git a/app/src/test/kotlin/com/wespot/user/domain/UserIntroductionTest.kt b/app/src/test/kotlin/com/wespot/user/domain/UserIntroductionTest.kt index 594b4ce7..e63ea2fa 100644 --- a/app/src/test/kotlin/com/wespot/user/domain/UserIntroductionTest.kt +++ b/app/src/test/kotlin/com/wespot/user/domain/UserIntroductionTest.kt @@ -14,7 +14,7 @@ class UserIntroductionTest : BehaviorSpec({ `when`("욕설이 포함되어 있는 경우") { val shouldThrow = shouldThrow { UserIntroduction.from(badWordsIntroduction) } then("예외가 발생한다.") { - shouldThrow shouldHaveMessage "소개에는 욕설이 포함될 수 없습니다." + shouldThrow shouldHaveMessage "소개에 비속어가 포함되어 있습니다." } } `when`("정상적인 값이 입력되는 경우") { diff --git a/app/src/test/kotlin/com/wespot/user/domain/UserTest.kt b/app/src/test/kotlin/com/wespot/user/domain/UserTest.kt index fe3fe278..c37537c6 100644 --- a/app/src/test/kotlin/com/wespot/user/domain/UserTest.kt +++ b/app/src/test/kotlin/com/wespot/user/domain/UserTest.kt @@ -78,7 +78,7 @@ class UserTest : BehaviorSpec({ val createUser = UserFixture.createWithId(1) val shouldThrow = shouldThrow { createUser.updateProfile(badWordsIntroduction) } then("예외가 발생한다.") { - shouldThrow shouldHaveMessage "소개에는 욕설이 포함될 수 없습니다." + shouldThrow shouldHaveMessage "소개에 비속어가 포함되어 있습니다." } } } diff --git a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt index 8513f161..f070c028 100644 --- a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt +++ b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionContentTest.kt @@ -13,7 +13,7 @@ class VoteOptionContentTest : BehaviorSpec({ `when`("욕설이 포함되어 있는 경우") { val shouldThrow = shouldThrow { VoteOptionContent.from(badWordsContent) } then("예외가 발생한다.") { - shouldThrow shouldHaveMessage "선택지의 내용에는 욕설이 포함될 수 없습니다." + shouldThrow shouldHaveMessage "선택지의 내용에 비속어가 포함되어 있습니다." } } val validContent = "헬로우" diff --git a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt index 0c6a5362..9652c0b4 100644 --- a/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt +++ b/app/src/test/kotlin/com/wespot/voteoption/domain/VoteOptionTest.kt @@ -40,7 +40,7 @@ class VoteOptionTest() : BehaviorSpec() { ) } then("예외가 발생한다.") { - shouldThrow shouldHaveMessage "선택지의 내용에는 욕설이 포함될 수 없습니다." + shouldThrow shouldHaveMessage "선택지의 내용에 비속어가 포함되어 있습니다." } } } diff --git a/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt b/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt index 7e1dca94..c811f7c0 100644 --- a/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt +++ b/core/src/main/kotlin/com/wespot/user/port/out/UserPort.kt @@ -43,4 +43,10 @@ interface UserPort { cursorSchoolTypeOrder: Int?, cursorId: Long? ): Long + + fun countBySchoolIdAndGradeAndClassNumber( + schoolId: Long, + grade: Int, + classNumber: Int + ): Long } diff --git a/domain/src/main/kotlin/com/wespot/message/MessageContent.kt b/domain/src/main/kotlin/com/wespot/message/MessageContent.kt index b3d5f666..483f8cec 100644 --- a/domain/src/main/kotlin/com/wespot/message/MessageContent.kt +++ b/domain/src/main/kotlin/com/wespot/message/MessageContent.kt @@ -13,7 +13,7 @@ data class MessageContent( } private fun validateContent(content: String) { - require(!ProfanityChecker.checkProfanity(content)) { "메시지의 내용에는 욕설이 포함될 수 없습니다." } + require(!ProfanityChecker.checkProfanity(content)) { "메시지의 내용에 비속어가 포함되어 있습니다." } require(content.isNotBlank()) { "메시지의 내용은 필수로 존재해야합니다." } } } diff --git a/domain/src/main/kotlin/com/wespot/user/Introduction.kt b/domain/src/main/kotlin/com/wespot/user/UserIntroduction.kt similarity index 91% rename from domain/src/main/kotlin/com/wespot/user/Introduction.kt rename to domain/src/main/kotlin/com/wespot/user/UserIntroduction.kt index 93435de0..10ef34c9 100644 --- a/domain/src/main/kotlin/com/wespot/user/Introduction.kt +++ b/domain/src/main/kotlin/com/wespot/user/UserIntroduction.kt @@ -18,7 +18,7 @@ data class UserIntroduction( } private fun validateUserIntroduction(content: String) { - require(!ProfanityChecker.checkProfanity(content)) { "소개에는 욕설이 포함될 수 없습니다." } + require(!ProfanityChecker.checkProfanity(content)) { "소개에 비속어가 포함되어 있습니다." } } } diff --git a/domain/src/main/kotlin/com/wespot/user/event/CreatedVoteEvent.kt b/domain/src/main/kotlin/com/wespot/user/event/CreatedVoteEvent.kt new file mode 100644 index 00000000..a5b022e4 --- /dev/null +++ b/domain/src/main/kotlin/com/wespot/user/event/CreatedVoteEvent.kt @@ -0,0 +1,7 @@ +package com.wespot.user.event + +import com.wespot.user.User + +data class CreatedVoteEvent( + val signUpUser: User +) diff --git a/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt b/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt index 49a8263b..0be422d3 100644 --- a/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt +++ b/domain/src/main/kotlin/com/wespot/voteoption/VoteOptionContent.kt @@ -15,7 +15,7 @@ data class VoteOptionContent( } private fun validateContent(content: String) { - require(!ProfanityChecker.checkProfanity(content)) { "선택지의 내용에는 욕설이 포함될 수 없습니다." } + require(!ProfanityChecker.checkProfanity(content)) { "선택지의 내용에 비속어가 포함되어 있습니다." } require(content.isNotBlank()) { "선택지의 내용은 필수로 존재해야합니다." } } diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt index 732dea22..47a0baad 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/adapter/UserPersistenceAdapter.kt @@ -29,7 +29,6 @@ class UserPersistenceAdapter( .let { UserMapper.mapToDomainEntity(it) } } - override fun searchUsers( name: String, cursorName: String?, @@ -66,6 +65,10 @@ class UserPersistenceAdapter( ) } + override fun countBySchoolIdAndGradeAndClassNumber(schoolId: Long, grade: Int, classNumber: Int): Long { + return userJpaRepository.countBySchoolIdAndGradeAndClassNumber(schoolId, grade, classNumber) + } + override fun findById(userId: Long): User? { return userJpaRepository.findByIdOrNull(userId) ?.let { UserMapper.mapToDomainEntity(it) } diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt index 2755d424..21688071 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/user/repository/UserJpaRepository.kt @@ -94,4 +94,10 @@ interface UserJpaRepository : JpaRepository { @Param("cursorId") cursorId: Long? ): Long + fun countBySchoolIdAndGradeAndClassNumber( + schoolId: Long, + grade: Int, + classNumber: Int + ): Long + } From 7117deccd62c88c5c9bfad12d14b529b7c23d23c Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Sat, 10 Aug 2024 03:03:47 +0900 Subject: [PATCH 16/17] =?UTF-8?q?refactor:=20CreatedVote=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 --- .../wespot/auth/service/AuthServiceTest.kt | 4 ++ .../vote/service/CreatedVoteServiceTest.kt | 3 +- .../vote/service/SavedVoteServiceTest.kt | 68 +++++++++++++++++++ .../vote/service/SentVoteServiceTest.kt | 1 - .../com/wespot/auth/service/AuthService.kt | 18 +++-- .../wespot/vote/service/CreatedVoteService.kt | 13 +++- .../service/listener/VoteEventListener.kt | 4 +- 7 files changed, 96 insertions(+), 15 deletions(-) diff --git a/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt b/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt index 1010bb7e..a239d8d0 100644 --- a/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/auth/service/AuthServiceTest.kt @@ -12,6 +12,8 @@ import com.wespot.auth.port.out.RefreshTokenPort import com.wespot.auth.service.jwt.JwtTokenProvider import com.wespot.school.port.out.SchoolPort import com.wespot.user.SocialType +import com.wespot.user.event.CreatedVoteEvent +import com.wespot.user.event.SignUpUserEvent import com.wespot.user.fixture.UserFixture import com.wespot.user.port.out.ProfilePort import com.wespot.user.port.out.UserConsentPort @@ -192,6 +194,8 @@ class AuthServiceTest : BehaviorSpec({ every { userPort.save(any()) } returns user every { authService.saveRelatedEntities(user, signUpRequest) } just Runs every { authService.signIn(any()) } returns tokenAndUserDetailResponse + every { eventPublisher.publishEvent(SignUpUserEvent(user)) } returns Unit + every { eventPublisher.publishEvent(CreatedVoteEvent(user)) } returns Unit `when`("사용자가 signUp을 호출할 때") { val response = authService.signUp(signUpRequest) diff --git a/app/src/test/kotlin/com/wespot/vote/service/CreatedVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/CreatedVoteServiceTest.kt index 36f8f4b4..daa618b4 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/CreatedVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/CreatedVoteServiceTest.kt @@ -21,7 +21,6 @@ import io.kotest.matchers.throwable.shouldHaveMessage import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate class CreatedVoteServiceTest @Autowired constructor( @@ -130,6 +129,7 @@ class CreatedVoteServiceTest @Autowired constructor( @Test fun `학급에 처음으로 가입한 회원이 존재하는 경우 투표를 생성한다`() { // given + userJpaRepository.deleteAll() val savedUserJpaEntity = userJpaRepository.save(UserMapper.mapToJpaEntity(users[0])) val savedUserDomainEntity = UserMapper.mapToDomainEntity(savedUserJpaEntity) @@ -156,6 +156,7 @@ class CreatedVoteServiceTest @Autowired constructor( @Test fun `오늘의 질문이 잘 생성되는지 확인한다`() { + userJpaRepository.deleteAll() val savedUserJpaEntity = userJpaRepository.save(UserMapper.mapToJpaEntity(users[0])) val savedUserDomainEntity = UserMapper.mapToDomainEntity(savedUserJpaEntity) diff --git a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt index bf479f55..c5166df0 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/SavedVoteServiceTest.kt @@ -211,4 +211,72 @@ class SavedVoteServiceTest @Autowired constructor( notifications.size shouldBe 5 } + @Test + fun `투표를 5명이 보내면 알림이 발생한다`() { + // given + val requests1 = VoteRequests( + listOf( + VoteRequest( + userId = users[0].id, + voteOptionId = voteOptions[0].id + ) + ) + ) + val requests2 = VoteRequests( + listOf( + VoteRequest( + userId = users[1].id, + voteOptionId = voteOptions[0].id + ) + ) + ) + val requests3 = VoteRequests( + listOf( + VoteRequest( + userId = users[2].id, + voteOptionId = voteOptions[0].id + ) + ) + ) + val requests4 = VoteRequests( + listOf( + VoteRequest( + userId = users[3].id, + voteOptionId = voteOptions[0].id + ) + ) + ) + val requests5 = VoteRequests( + listOf( + VoteRequest( + userId = users[4].id, + voteOptionId = voteOptions[0].id + ) + ) + ) + + // when + var loginUser = UserMapper.mapToDomainEntity(users[users.size - 1]) + UserFixture.setSecurityContextUser(loginUser) + voteService.saveVote(requests1) + loginUser = UserMapper.mapToDomainEntity(users[users.size - 2]) + UserFixture.setSecurityContextUser(loginUser) + voteService.saveVote(requests2) + loginUser = UserMapper.mapToDomainEntity(users[users.size - 3]) + UserFixture.setSecurityContextUser(loginUser) + voteService.saveVote(requests3) + loginUser = UserMapper.mapToDomainEntity(users[users.size - 6]) + UserFixture.setSecurityContextUser(loginUser) + voteService.saveVote(requests4) + loginUser = UserMapper.mapToDomainEntity(users[users.size - 7]) + UserFixture.setSecurityContextUser(loginUser) + voteService.saveVote(requests5) + val notifications = notificationPort.findAll() + + // then + notifications.size shouldBe 12 + notifications[5].title shouldBe "우리 반 투표 결과가 업데이트 되었어요 \uD83D\uDC40" + notifications[5].body shouldBe "실시간 1등은 누구일까요? 눌러서 바로 확인해 보세요" + } + } diff --git a/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt b/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt index f09c226e..f229d52d 100644 --- a/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/vote/service/SentVoteServiceTest.kt @@ -19,7 +19,6 @@ import io.kotest.matchers.shouldBe import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest import java.time.LocalDate import java.time.LocalDateTime diff --git a/core/src/main/kotlin/com/wespot/auth/service/AuthService.kt b/core/src/main/kotlin/com/wespot/auth/service/AuthService.kt index 4911f6e5..44554de9 100644 --- a/core/src/main/kotlin/com/wespot/auth/service/AuthService.kt +++ b/core/src/main/kotlin/com/wespot/auth/service/AuthService.kt @@ -5,7 +5,11 @@ import com.wespot.auth.dto.request.AuthLoginRequest import com.wespot.auth.dto.request.RefreshTokenRequest import com.wespot.auth.dto.request.SignInRequest import com.wespot.auth.dto.request.SignUpRequest -import com.wespot.auth.dto.response.* +import com.wespot.auth.dto.response.SettingResponse +import com.wespot.auth.dto.response.SignUpResponse +import com.wespot.auth.dto.response.SocialResponse +import com.wespot.auth.dto.response.TokenAndUserDetailResponse +import com.wespot.auth.dto.response.TokenResponse import com.wespot.auth.port.`in`.AuthUseCase import com.wespot.auth.port.out.AuthDataPort import com.wespot.auth.port.out.RefreshTokenPort @@ -17,6 +21,7 @@ import com.wespot.user.Social import com.wespot.user.SocialType import com.wespot.user.User import com.wespot.user.UserConsent +import com.wespot.user.event.CreatedVoteEvent import com.wespot.user.event.SignUpUserEvent import com.wespot.user.port.out.ProfilePort import com.wespot.user.port.out.UserConsentPort @@ -94,7 +99,8 @@ class AuthService( val user = createUser(signUpToken, signUpRequest) val savedUser = userPort.save(user) - createVoteIfRegisterFirstForClass(user) + eventPublisher.publishEvent(CreatedVoteEvent(savedUser)) + eventPublisher.publishEvent(SignUpUserEvent(savedUser)) saveRelatedEntities(savedUser, signUpRequest) @@ -138,14 +144,6 @@ class AuthService( ) } - fun createVoteIfRegisterFirstForClass(user: User) { - if (userPort.existsBySchoolIdAndGradeAndClassNumber(user.schoolId, user.grade, user.classNumber)) { - return - } - - eventPublisher.publishEvent(SignUpUserEvent(user)) - } - fun saveRelatedEntities( user: User, signUpRequest: SignUpRequest diff --git a/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt b/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt index 0aef26ae..9437b035 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/CreatedVoteService.kt @@ -8,6 +8,7 @@ import com.wespot.vote.event.EndVoteEvent import com.wespot.vote.port.`in`.CreatedVoteUseCase import com.wespot.vote.port.out.VoteOptionPort import com.wespot.vote.port.out.VotePort +import com.wespot.vote.service.helper.VoteServiceHelper import com.wespot.voteoption.VoteOption import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Service @@ -66,10 +67,20 @@ class CreatedVoteService( @Transactional override fun createVoteByUser(user: User) { + val savedUser = VoteServiceHelper.findUser(userPort, user.id) + if (!isFirstSignUpUser(savedUser)) { + return + } val allVoteOptions = voteOptionPort.findAll() val today = LocalDate.now() - val voteIdentifier = VoteIdentifier.of(user, today) + val voteIdentifier = VoteIdentifier.of(savedUser, today) saveVote(voteIdentifier, allVoteOptions) } + private fun isFirstSignUpUser(user: User): Boolean { + val numberOfUsers = userPort.countBySchoolIdAndGradeAndClassNumber(user.schoolId, user.grade, user.classNumber) + + return numberOfUsers == 1L + } + } diff --git a/core/src/main/kotlin/com/wespot/vote/service/listener/VoteEventListener.kt b/core/src/main/kotlin/com/wespot/vote/service/listener/VoteEventListener.kt index 3b7b4491..132f8cba 100644 --- a/core/src/main/kotlin/com/wespot/vote/service/listener/VoteEventListener.kt +++ b/core/src/main/kotlin/com/wespot/vote/service/listener/VoteEventListener.kt @@ -1,6 +1,6 @@ package com.wespot.vote.service.listener -import com.wespot.user.event.SignUpUserEvent +import com.wespot.user.event.CreatedVoteEvent import com.wespot.vote.port.`in`.CreatedVoteUseCase import org.springframework.context.event.EventListener import org.springframework.stereotype.Component @@ -11,7 +11,7 @@ class VoteEventListener( ) { @EventListener - fun signUpNewUser(event: SignUpUserEvent) { + fun signUpNewUser(event: CreatedVoteEvent) { createdVoteUseCase.createVoteByUser(event.signUpUser) } From e79e0c25d2a199388920276b8887ed4fd9f7a644 Mon Sep 17 00:00:00 2001 From: jaeyeon kim Date: Sat, 10 Aug 2024 04:10:50 +0900 Subject: [PATCH 17/17] =?UTF-8?q?test:=20Event=20Test=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../message/service/SendMessageServiceTest.kt | 2 +- .../real/RealModifyMessageServiceTest.kt | 60 +++++++++ .../real/RealSendMessageServiceTest.kt | 74 +++++++++++ ...edMessageNotificationByLimitServiceTest.kt | 6 +- .../MessageNotificationEventListenerTest.kt | 2 +- .../listener/NotificationEventListenerTest.kt | 117 ++++++++++++++++++ .../message/service/SendMessageService.kt | 2 +- .../port/in/DisabledNotificationUseCase.kt | 2 +- .../notification/port/out/NotificationPort.kt | 2 +- .../service/DisabledNotificationService.kt | 6 +- .../service/NotificationFinder.kt | 8 +- .../MessageNotificationEventListener.kt | 2 +- .../wespot/message/event/MessageLimitEvent.kt | 2 +- ...sabledMessageNotificationByLimitService.kt | 1 - .../notification/NotificationJpaRepository.kt | 6 +- .../NotificationPersistenceAdapter.kt | 7 +- 16 files changed, 280 insertions(+), 19 deletions(-) create mode 100644 app/src/test/kotlin/com/wespot/message/service/real/RealModifyMessageServiceTest.kt create mode 100644 app/src/test/kotlin/com/wespot/message/service/real/RealSendMessageServiceTest.kt create mode 100644 app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt diff --git a/app/src/test/kotlin/com/wespot/message/service/SendMessageServiceTest.kt b/app/src/test/kotlin/com/wespot/message/service/SendMessageServiceTest.kt index 0ccf2e67..8090e460 100644 --- a/app/src/test/kotlin/com/wespot/message/service/SendMessageServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/message/service/SendMessageServiceTest.kt @@ -75,7 +75,7 @@ class SendMessageServiceTest : BehaviorSpec({ every { messagePort.save(any()) } returns message every { messagePort.sendMessageCount(sender.id) } returns 0 every { messagePort.hasSentMessageToday(sender.id, receiver.id) } returns false - every { eventPublisher.publishEvent(MessageLimitEvent(0, 0)) } returns Unit + every { eventPublisher.publishEvent(MessageLimitEvent(sender.id, 0)) } returns Unit every { eventPublisher.publishEvent(ReceivedMessageEvent(receiver, 0)) } returns Unit every { blockedUserPort.existsByBlockerIdAndBlockedId(1, 2) } returns false every { blockedUserPort.existsByBlockerIdAndBlockedId(2, 1) } returns false diff --git a/app/src/test/kotlin/com/wespot/message/service/real/RealModifyMessageServiceTest.kt b/app/src/test/kotlin/com/wespot/message/service/real/RealModifyMessageServiceTest.kt new file mode 100644 index 00000000..595ca1a7 --- /dev/null +++ b/app/src/test/kotlin/com/wespot/message/service/real/RealModifyMessageServiceTest.kt @@ -0,0 +1,60 @@ +package com.wespot.message.service.real + +import com.wespot.common.service.ServiceTest +import com.wespot.message.MessageTimeValidator +import com.wespot.message.fixture.MessageFixture +import com.wespot.message.port.out.MessagePort +import com.wespot.message.service.ModifyMessageService +import com.wespot.notification.port.out.NotificationPort +import com.wespot.user.fixture.UserFixture +import com.wespot.user.port.out.UserPort +import io.kotest.matchers.shouldBe +import io.mockk.clearAllMocks +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import java.time.Clock +import java.time.Instant +import java.time.ZoneId + +class RealModifyMessageServiceTest @Autowired constructor( + private val modifyMessageService: ModifyMessageService, + private val userPort: UserPort, + private val messagePort: MessagePort, + private val notificationPort: NotificationPort +) : ServiceTest() { + + @Test + fun `쪽지를 처음 읽었을 때, 송신자에게 알림이 발송된다`() { + // given + val fixedClock = Clock.fixed(Instant.parse("2023-03-18T18:00:00Z"), ZoneId.of("UTC")) + MessageTimeValidator.setClock(fixedClock) + + val receiver = userPort.save(UserFixture.createWithIdAndEmail(0, "Test1@KAKAO")) + val sender = userPort.save(UserFixture.createWithIdAndEmail(0, "Test2@KAKAO")) + UserFixture.setSecurityContextUser(receiver) + val message = messagePort.save( + MessageFixture.createMessageWithReceived( + content = "content", + receiverId = receiver.id, + senderId = sender.id, + senderName = "senderName", + ) + ) + + // when + modifyMessageService.readMessage(messageId = message.id) + modifyMessageService.readMessage(messageId = message.id) + val notifications = notificationPort.findAll() + + // then + notifications.size shouldBe 1 + notifications[0].targetId shouldBe message.id + notifications[0].userId shouldBe sender.id + notifications[0].title shouldBe "방금 ${receiver.name}님이 내가 보낸 쪽지를 읽었어요 \uD83E\uDEE2" + notifications[0].body shouldBe "앞으로도 에버가 큐피드가 되어 드릴게요" + + clearAllMocks() + MessageTimeValidator.resetClock() + } + +} diff --git a/app/src/test/kotlin/com/wespot/message/service/real/RealSendMessageServiceTest.kt b/app/src/test/kotlin/com/wespot/message/service/real/RealSendMessageServiceTest.kt new file mode 100644 index 00000000..cf4f3ae8 --- /dev/null +++ b/app/src/test/kotlin/com/wespot/message/service/real/RealSendMessageServiceTest.kt @@ -0,0 +1,74 @@ +package com.wespot.message.service.real + +import com.wespot.common.service.ServiceTest +import com.wespot.message.Message +import com.wespot.message.MessageTimeValidator +import com.wespot.message.event.MessageLimitEvent +import com.wespot.message.port.out.MessagePort +import com.wespot.notification.Notification +import com.wespot.notification.NotificationType +import com.wespot.notification.port.out.NotificationPort +import com.wespot.user.fixture.UserFixture +import com.wespot.user.port.out.UserPort +import io.kotest.matchers.shouldBe +import io.mockk.clearAllMocks +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.ApplicationEventPublisher +import java.time.Clock +import java.time.Instant +import java.time.ZoneId + +class RealSendMessageServiceTest @Autowired constructor( + private val userPort: UserPort, + private val messagePort: MessagePort, + private val notificationPort: NotificationPort, + private val eventPublisher: ApplicationEventPublisher +) : ServiceTest() { + + @Test + fun `쪽지를 3개 보냈을 때, 쪽지 독려 알림이 비활성화된다`() { + // given + val fixedClock = Clock.fixed(Instant.parse("2023-03-18T18:00:00Z"), ZoneId.of("UTC")) + MessageTimeValidator.setClock(fixedClock) + + val sender = userPort.save(UserFixture.createWithIdAndEmail(0, "Test1@KAKAO")) + val receiver = userPort.save(UserFixture.createWithIdAndEmail(0, "Test2@KAKAO")) + UserFixture.setSecurityContextUser(sender) + val message = messagePort.save( + Message.sendMessage( + content = "content", + receiverId = receiver.id, + senderId = sender.id, + senderName = "senderName", + isAnonymous = false + ) + ) + notificationPort.save( + Notification.createMessageInitialState( + userId = sender.id, + type = NotificationType.MESSAGE, + targetId = 0, + title = "ㅎㅇ", + body = "ㅎㅇ", + ) + ) + + // when + eventPublisher.publishEvent( + MessageLimitEvent( + sender.id, + 3 + ) + ) + val notifications = notificationPort.findAll() + + // then + notifications.size shouldBe 1 + notifications[0].isEnabled shouldBe false + + clearAllMocks() + MessageTimeValidator.resetClock() + } + +} diff --git a/app/src/test/kotlin/com/wespot/notification/domain/message/DisabledMessageNotificationByLimitServiceTest.kt b/app/src/test/kotlin/com/wespot/notification/domain/message/DisabledMessageNotificationByLimitServiceTest.kt index 2430c8e0..61392d7c 100644 --- a/app/src/test/kotlin/com/wespot/notification/domain/message/DisabledMessageNotificationByLimitServiceTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/domain/message/DisabledMessageNotificationByLimitServiceTest.kt @@ -16,7 +16,7 @@ class DisabledMessageNotificationByLimitServiceTest : BehaviorSpec({ Notification.createMessageInitialState(1, NotificationType.MESSAGE_RECEIVED, 1, "title", "body"), ) `when`("3개가 아니라면") { - val disableMessageNotification = service.disableMessageNotification(1, 2) { notifications } + val disableMessageNotification = service.disableMessageNotification(2) { notifications } then("비활성화되지 않는다.") { disableMessageNotification.size shouldBe 3 disableMessageNotification[0].isEnabled shouldBe true @@ -25,7 +25,7 @@ class DisabledMessageNotificationByLimitServiceTest : BehaviorSpec({ } } `when`("3개라면") { - val disableMessageNotification = service.disableMessageNotification(1, 3) { notifications } + val disableMessageNotification = service.disableMessageNotification(3) { notifications } then("비활성화 된다.") { disableMessageNotification.size shouldBe 3 disableMessageNotification[0].isEnabled shouldBe false @@ -33,7 +33,7 @@ class DisabledMessageNotificationByLimitServiceTest : BehaviorSpec({ disableMessageNotification[2].isEnabled shouldBe true } - val enableMessageNotification = service.disableMessageNotification(1, 2) { notifications } + val enableMessageNotification = service.disableMessageNotification(2) { notifications } then("다시 3개 이하로 내려가면 활성화 된다.") { enableMessageNotification.size shouldBe 3 enableMessageNotification[0].isEnabled shouldBe true diff --git a/app/src/test/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListenerTest.kt b/app/src/test/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListenerTest.kt index bf923aa6..274f6416 100644 --- a/app/src/test/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListenerTest.kt +++ b/app/src/test/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListenerTest.kt @@ -43,7 +43,7 @@ class MessageNotificationEventListenerTest @Autowired constructor( ) // when - messageNotificationEventListener.disableMessageNotificationByLimit(MessageLimitEvent(message.id, 3)) + messageNotificationEventListener.disableMessageNotificationByLimit(MessageLimitEvent(sender.id, 3)) val disableNotification = notificationPort.findById(notification.id) // then diff --git a/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt b/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt new file mode 100644 index 00000000..00ba00bd --- /dev/null +++ b/app/src/test/kotlin/com/wespot/notification/service/listener/NotificationEventListenerTest.kt @@ -0,0 +1,117 @@ +package com.wespot.notification.service.listener + +import com.wespot.common.service.ServiceTest +import com.wespot.message.Message +import com.wespot.message.MessageTimeValidator +import com.wespot.message.event.ReceivedMessageEvent +import com.wespot.message.fixture.MessageFixture +import com.wespot.message.port.out.MessagePort +import com.wespot.notification.NotificationType +import com.wespot.notification.port.out.NotificationPort +import com.wespot.user.event.SignUpUserEvent +import com.wespot.user.fixture.UserFixture +import com.wespot.user.port.out.UserPort +import com.wespot.vote.event.EndVoteEvent +import io.kotest.matchers.shouldBe +import io.mockk.clearAllMocks +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.ApplicationEventPublisher +import java.time.Clock +import java.time.Instant +import java.time.ZoneId + +class NotificationEventListenerTest @Autowired constructor( + private val eventPublisher: ApplicationEventPublisher, + private val userPort: UserPort, + private val messagePort: MessagePort, + private val notificationPort: NotificationPort, +) : ServiceTest() { + + @Test + fun `수신자가 쪽지를 받았을 때, 알림이 발생한다`() { + // given + val fixedClock = Clock.fixed(Instant.parse("2023-03-18T18:00:00Z"), ZoneId.of("UTC")) + MessageTimeValidator.setClock(fixedClock) + + val sender = userPort.save(UserFixture.createWithIdAndEmail(0, "Test1@KAKAO")) + UserFixture.setSecurityContextUser(sender) + val receiver = userPort.save(UserFixture.createWithIdAndEmail(0, "Test2@KAKAO")) + val message = messagePort.save( + Message.sendMessage( + content = "content", + receiverId = receiver.id, + senderId = sender.id, + senderName = sender.name, + isAnonymous = false + ) + ) + + // when + eventPublisher.publishEvent( + ReceivedMessageEvent( + receiver = receiver, + messageId = message.id + ) + ) + val notifications = notificationPort.findAll() + + // then + notifications.size shouldBe 1 + notifications[0].userId shouldBe receiver.id + notifications[0].type shouldBe NotificationType.MESSAGE_RECEIVED + notifications[0].targetId shouldBe message.id + + clearAllMocks() + MessageTimeValidator.resetClock() + } + + @Test + fun `유저가 회원가입했을 때, 알림이 발생한다`() { + // given + val users = listOf( + userPort.save(UserFixture.createWithIdAndEmail(0, "Test1@KAKAO")), + userPort.save(UserFixture.createWithIdAndEmail(0, "Test2@KAKAO")), + userPort.save(UserFixture.createWithIdAndEmail(0, "Test3@KAKAO")), + userPort.save(UserFixture.createWithIdAndEmail(0, "Test4@KAKAO")), + userPort.save(UserFixture.createWithIdAndEmail(0, "Test5@KAKAO")) + ) + + // when + eventPublisher.publishEvent(SignUpUserEvent(users[0])) + val notifications = notificationPort.findAll() + + // then + notifications.size shouldBe 4 + notifications[0].userId shouldBe users[1].id + notifications[1].userId shouldBe users[2].id + notifications[2].userId shouldBe users[3].id + notifications[3].userId shouldBe users[4].id + } + + @Test + fun `투표 종료가 되었을 때, 알림이 발생한다`() { + // given + val users = listOf( + userPort.save(UserFixture.createWithIdAndEmail(0, "Test1@KAKAO")), + userPort.save(UserFixture.createWithIdAndEmail(0, "Test2@KAKAO")), + userPort.save(UserFixture.createWithIdAndEmail(0, "Test3@KAKAO")), + userPort.save(UserFixture.createWithIdAndEmail(0, "Test4@KAKAO")), + userPort.save(UserFixture.createWithIdAndEmail(0, "Test5@KAKAO")) + ) + + // when + eventPublisher.publishEvent(EndVoteEvent()) + val notifications = notificationPort.findAll() + + // then + notifications.size shouldBe 5 + notifications[0].userId shouldBe users[0].id + notifications[1].userId shouldBe users[1].id + notifications[2].userId shouldBe users[2].id + notifications[3].userId shouldBe users[3].id + notifications[4].userId shouldBe users[4].id + notifications[0].type shouldBe NotificationType.VOTE_RESULT + } + +} diff --git a/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt b/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt index bf722d00..31216182 100644 --- a/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt +++ b/core/src/main/kotlin/com/wespot/message/service/SendMessageService.kt @@ -48,7 +48,7 @@ class SendMessageService( val saveMessage = messagePort.save(sendMessage) eventPublisher.publishEvent( MessageLimitEvent( - saveMessage.id, + senderId = loginUser.id, messagePort.sendMessageCount(loginUser.id) ) ) // TODO : 나중에 메시지 예약 취소하는 경우에도 해당 이벤트 발생시켜주시면 좋을 것 같아요. diff --git a/core/src/main/kotlin/com/wespot/notification/port/in/DisabledNotificationUseCase.kt b/core/src/main/kotlin/com/wespot/notification/port/in/DisabledNotificationUseCase.kt index 37894f94..42b01a98 100644 --- a/core/src/main/kotlin/com/wespot/notification/port/in/DisabledNotificationUseCase.kt +++ b/core/src/main/kotlin/com/wespot/notification/port/in/DisabledNotificationUseCase.kt @@ -8,6 +8,6 @@ interface DisabledNotificationUseCase { fun disableMessageNotifications(today: LocalDate) - fun disableMessageNotification(messageId: Long, sendMessageCount: Int) + fun disableMessageNotification(senderId: Long, sendMessageCount: Int) } diff --git a/core/src/main/kotlin/com/wespot/notification/port/out/NotificationPort.kt b/core/src/main/kotlin/com/wespot/notification/port/out/NotificationPort.kt index 5d03fc4d..d7c94172 100644 --- a/core/src/main/kotlin/com/wespot/notification/port/out/NotificationPort.kt +++ b/core/src/main/kotlin/com/wespot/notification/port/out/NotificationPort.kt @@ -19,6 +19,6 @@ interface NotificationPort { fun findAllFromDate(today: LocalDate): List - fun findAllByTargetId(targetId: Long): List + fun findAllByUserIdAndFromDate(userId: Long, today: LocalDate): List } diff --git a/core/src/main/kotlin/com/wespot/notification/service/DisabledNotificationService.kt b/core/src/main/kotlin/com/wespot/notification/service/DisabledNotificationService.kt index 6234a186..718c2f62 100644 --- a/core/src/main/kotlin/com/wespot/notification/service/DisabledNotificationService.kt +++ b/core/src/main/kotlin/com/wespot/notification/service/DisabledNotificationService.kt @@ -28,11 +28,11 @@ class DisabledNotificationService( } @Transactional - override fun disableMessageNotification(messageId: Long, sendMessageCount: Int) { + override fun disableMessageNotification(senderId: Long, sendMessageCount: Int) { + val today = LocalDate.now() val notifications = disabledMessageNotificationByLimitService.disableMessageNotification( - messageId, sendMessageCount - ) { NotificationFinder.findAllByTargetId(notificationPort, messageId) } + ) { NotificationFinder.findAllByUserIdAndFromDate(notificationPort, senderId, today) } notificationPort.saveAll(notifications) } diff --git a/core/src/main/kotlin/com/wespot/notification/service/NotificationFinder.kt b/core/src/main/kotlin/com/wespot/notification/service/NotificationFinder.kt index 0ae0cc68..9200ac49 100644 --- a/core/src/main/kotlin/com/wespot/notification/service/NotificationFinder.kt +++ b/core/src/main/kotlin/com/wespot/notification/service/NotificationFinder.kt @@ -32,8 +32,12 @@ object NotificationFinder { return notificationPort.findAllFromDate(today) } - fun findAllByTargetId(notificationPort: NotificationPort, targetId: Long): List { - return notificationPort.findAllByTargetId(targetId) + fun findAllByUserIdAndFromDate( + notificationPort: NotificationPort, + userId: Long, + today: LocalDate + ): List { + return notificationPort.findAllByUserIdAndFromDate(userId, today) } } diff --git a/core/src/main/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListener.kt b/core/src/main/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListener.kt index 34c77978..420e71cd 100644 --- a/core/src/main/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListener.kt +++ b/core/src/main/kotlin/com/wespot/notification/service/listener/MessageNotificationEventListener.kt @@ -17,7 +17,7 @@ class MessageNotificationEventListener( @EventListener fun disableMessageNotificationByLimit(messageLimitEvent: MessageLimitEvent) { disabledNotificationService.disableMessageNotification( - messageLimitEvent.messageId, + messageLimitEvent.senderId, messageLimitEvent.sendMessageCount ) } diff --git a/domain/src/main/kotlin/com/wespot/message/event/MessageLimitEvent.kt b/domain/src/main/kotlin/com/wespot/message/event/MessageLimitEvent.kt index d5b0c808..30ec162b 100644 --- a/domain/src/main/kotlin/com/wespot/message/event/MessageLimitEvent.kt +++ b/domain/src/main/kotlin/com/wespot/message/event/MessageLimitEvent.kt @@ -1,6 +1,6 @@ package com.wespot.message.event data class MessageLimitEvent( - val messageId: Long, + val senderId: Long, val sendMessageCount: Int ) diff --git a/domain/src/main/kotlin/com/wespot/notification/message/DisabledMessageNotificationByLimitService.kt b/domain/src/main/kotlin/com/wespot/notification/message/DisabledMessageNotificationByLimitService.kt index ceb69109..fdca6c87 100644 --- a/domain/src/main/kotlin/com/wespot/notification/message/DisabledMessageNotificationByLimitService.kt +++ b/domain/src/main/kotlin/com/wespot/notification/message/DisabledMessageNotificationByLimitService.kt @@ -7,7 +7,6 @@ import org.springframework.stereotype.Component class DisabledMessageNotificationByLimitService { fun disableMessageNotification( - messageId: Long, sendMessageCount: Int, fetchNotifications: () -> List ): List { diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/notification/NotificationJpaRepository.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/notification/NotificationJpaRepository.kt index 70e6ff70..4848d732 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/notification/NotificationJpaRepository.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/notification/NotificationJpaRepository.kt @@ -27,6 +27,10 @@ interface NotificationJpaRepository : JpaRepository createdAtEnd: LocalDateTime ): List - fun findAllByTargetId(targetId: Long): List + fun findAllByUserIdAndBaseEntityCreatedAtBetween( + userId: Long, + createdAtStart: LocalDateTime, + createdAtEnd: LocalDateTime + ): List } diff --git a/infrastructure/mysql/src/main/kotlin/com/wespot/notification/NotificationPersistenceAdapter.kt b/infrastructure/mysql/src/main/kotlin/com/wespot/notification/NotificationPersistenceAdapter.kt index 133ad215..953b7f65 100644 --- a/infrastructure/mysql/src/main/kotlin/com/wespot/notification/NotificationPersistenceAdapter.kt +++ b/infrastructure/mysql/src/main/kotlin/com/wespot/notification/NotificationPersistenceAdapter.kt @@ -54,8 +54,11 @@ class NotificationPersistenceAdapter( .map { NotificationMapper.mapToDomainEntity(it) } } - override fun findAllByTargetId(targetId: Long): List { - return notificationJpaRepository.findAllByTargetId(targetId) + override fun findAllByUserIdAndFromDate(userId: Long, today: LocalDate): List { + val todayTime = today.atStartOfDay() + val tomorrowTime = todayTime.plusDays(1) + + return notificationJpaRepository.findAllByUserIdAndBaseEntityCreatedAtBetween(userId, todayTime, tomorrowTime) .map { NotificationMapper.mapToDomainEntity(it) } }