Skip to content
This repository was archived by the owner on Jul 7, 2025. It is now read-only.

Commit 34cdd81

Browse files
authored
Merge pull request #136 from ASAP-Lettering/ASAP-460
ASAP-460 익명 편지 전송 시 발신자 이름 지원 추가
2 parents 0e176ae + d225ebd commit 34cdd81

File tree

13 files changed

+246
-28
lines changed

13 files changed

+246
-28
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ out/
3838

3939
### Kotlin ###
4040
.kotlin
41+
42+
### claude ###
43+
CLAUDE.md

Application-Module/src/main/kotlin/com/asap/application/letter/port/in/SendLetterUsecase.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ interface SendLetterUsecase {
1515
)
1616

1717
data class AnonymousCommand(
18+
val senderName: String? = null,
1819
val receiverName: String,
1920
val content: String,
2021
val images: List<String>,

Application-Module/src/main/kotlin/com/asap/application/letter/service/LetterCommandService.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class LetterCommandService(
7070
letterCodeGenerator.generateCode(
7171
content = command.content,
7272
),
73+
senderName = command.senderName ?: ANONYMOUS_SENDER_NAME,
7374
)
7475

7576
sendLetterManagementPort.save(sendLetter)
@@ -111,9 +112,10 @@ class LetterCommandService(
111112
SenderInfo(
112113
senderId = sendLetter.senderId,
113114
senderName =
114-
sendLetter.senderId
115-
?.let { userManagementPort.getUserNotNull(it).username }
116-
.orEmpty(),
115+
sendLetter.senderName
116+
?: sendLetter.senderId
117+
?.let { userManagementPort.getUserNotNull(it).username }
118+
.orEmpty(),
117119
),
118120
receiver =
119121
ReceiverInfo(
@@ -273,4 +275,8 @@ class LetterCommandService(
273275
)
274276
spaceLetterManagementPort.save(spaceLetter)
275277
}
278+
279+
companion object {
280+
private const val ANONYMOUS_SENDER_NAME = "Anonymous"
281+
}
276282
}

Application-Module/src/test/kotlin/com/asap/application/letter/service/LetterCommandServiceTest.kt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,52 @@ class LetterCommandServiceTest :
7575
verify { mockSendLetterManagementPort.save(any()) }
7676
}
7777
}
78+
79+
val commandWithSenderName =
80+
SendLetterUsecase.AnonymousCommand(
81+
senderName = "Test Sender",
82+
receiverName = "receiver-name",
83+
content = "content",
84+
images = emptyList(),
85+
templateType = 1,
86+
)
87+
`when`("발송자 이름이 제공된 익명 편지 전송 요청을 처리하면") {
88+
val response = letterCommandService.sendAnonymous(commandWithSenderName)
89+
then("편지 코드가 생성되고, 제공된 발송자 이름으로 편지가 저장되어야 한다") {
90+
response.letterCode shouldNotBeNull {
91+
this.isNotBlank()
92+
this.isNotEmpty()
93+
}
94+
verify {
95+
mockSendLetterManagementPort.save(match { sendLetter ->
96+
sendLetter.senderName == "Test Sender"
97+
})
98+
}
99+
}
100+
}
101+
102+
val commandWithNullSenderName =
103+
SendLetterUsecase.AnonymousCommand(
104+
senderName = null,
105+
receiverName = "receiver-name",
106+
content = "content",
107+
images = emptyList(),
108+
templateType = 1,
109+
)
110+
`when`("발송자 이름이 null인 익명 편지 전송 요청을 처리하면") {
111+
val response = letterCommandService.sendAnonymous(commandWithNullSenderName)
112+
then("편지 코드가 생성되고, Anonymous로 편지가 저장되어야 한다") {
113+
response.letterCode shouldNotBeNull {
114+
this.isNotBlank()
115+
this.isNotEmpty()
116+
}
117+
verify {
118+
mockSendLetterManagementPort.save(match { sendLetter ->
119+
sendLetter.senderName == "Anonymous"
120+
})
121+
}
122+
}
123+
}
78124
}
79125

80126
given("편지 검증 시에") {
@@ -381,6 +427,7 @@ class LetterCommandServiceTest :
381427
content = content,
382428
receiverName = "receiverName",
383429
letterCode = letterCode,
430+
senderName = "Anonymous",
384431
)
385432

386433
every {

Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/letter/controller/LetterController.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ class LetterController(
270270
val response =
271271
sendLetterUsecase.sendAnonymous(
272272
SendLetterUsecase.AnonymousCommand(
273+
senderName = request.senderName,
273274
receiverName = request.receiverName,
274275
content = request.content,
275276
images = request.images,

Bootstrap-Module/src/main/kotlin/com/asap/bootstrap/web/letter/dto/AnonymousSendLetterRequest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.asap.bootstrap.web.letter.dto
22

33
data class AnonymousSendLetterRequest(
4+
val senderName: String? = null,
45
val receiverName: String,
56
val content: String,
67
val images: List<String>,

Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/acceptance/letter/controller/LetterControllerTest.kt

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,4 +626,84 @@ class LetterControllerTest : LetterAcceptanceSupporter() {
626626
}
627627
}
628628
}
629+
630+
@Test
631+
fun sendAnonymousLetterWithSenderName() {
632+
// given
633+
val request =
634+
AnonymousSendLetterRequest(
635+
senderName = "Test Sender",
636+
receiverName = "receiverName",
637+
content = "content",
638+
images = listOf("images"),
639+
templateType = 1,
640+
)
641+
BDDMockito
642+
.given(
643+
sendLetterUsecase.sendAnonymous(
644+
SendLetterUsecase.AnonymousCommand(
645+
senderName = request.senderName,
646+
receiverName = request.receiverName,
647+
content = request.content,
648+
images = request.images,
649+
templateType = request.templateType,
650+
),
651+
),
652+
).willReturn(SendLetterUsecase.Response("letterCode"))
653+
// when
654+
val response =
655+
mockMvc.post("/api/v1/letters/anonymous/send") {
656+
contentType = MediaType.APPLICATION_JSON
657+
content = objectMapper.writeValueAsString(request)
658+
}
659+
// then
660+
response.andExpect {
661+
status { isOk() }
662+
jsonPath("$.letterCode") {
663+
exists()
664+
isString()
665+
isNotEmpty()
666+
}
667+
}
668+
}
669+
670+
@Test
671+
fun sendAnonymousLetterWithNullSenderName() {
672+
// given
673+
val request =
674+
AnonymousSendLetterRequest(
675+
senderName = null,
676+
receiverName = "receiverName",
677+
content = "content",
678+
images = listOf("images"),
679+
templateType = 1,
680+
)
681+
BDDMockito
682+
.given(
683+
sendLetterUsecase.sendAnonymous(
684+
SendLetterUsecase.AnonymousCommand(
685+
senderName = null,
686+
receiverName = request.receiverName,
687+
content = request.content,
688+
images = request.images,
689+
templateType = request.templateType,
690+
),
691+
),
692+
).willReturn(SendLetterUsecase.Response("letterCode"))
693+
// when
694+
val response =
695+
mockMvc.post("/api/v1/letters/anonymous/send") {
696+
contentType = MediaType.APPLICATION_JSON
697+
content = objectMapper.writeValueAsString(request)
698+
}
699+
// then
700+
response.andExpect {
701+
status { isOk() }
702+
jsonPath("$.letterCode") {
703+
exists()
704+
isString()
705+
isNotEmpty()
706+
}
707+
}
708+
}
629709
}

Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/letter/LetterApiIntegrationTest.kt

Lines changed: 92 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ package com.asap.bootstrap.integration.letter
33
import com.asap.application.letter.LetterMockManager
44
import com.asap.application.space.SpaceMockManager
55
import com.asap.bootstrap.IntegrationSupporter
6-
import com.asap.bootstrap.web.letter.dto.*
6+
import com.asap.bootstrap.web.letter.dto.AddPhysicalLetterRequest
7+
import com.asap.bootstrap.web.letter.dto.AddVerifiedLetterRequest
8+
import com.asap.bootstrap.web.letter.dto.AnonymousSendLetterRequest
9+
import com.asap.bootstrap.web.letter.dto.DeleteSendLettersRequest
10+
import com.asap.bootstrap.web.letter.dto.LetterVerifyRequest
11+
import com.asap.bootstrap.web.letter.dto.ModifyLetterRequest
12+
import com.asap.bootstrap.web.letter.dto.SendLetterRequest
713
import org.junit.jupiter.api.DisplayName
814
import org.junit.jupiter.api.Nested
915
import org.junit.jupiter.api.Test
@@ -1082,30 +1088,92 @@ class LetterApiIntegrationTest : IntegrationSupporter() {
10821088
}
10831089
}
10841090

1085-
@Test
1086-
@DisplayName("비회원 편지 쓰기")
1087-
fun sendAnonymousLetter() {
1088-
// given
1089-
val request =
1090-
AnonymousSendLetterRequest(
1091-
receiverName = "receiverName",
1092-
content = "content",
1093-
images = listOf("images"),
1094-
templateType = 1,
1095-
)
1096-
// when
1097-
val response =
1098-
mockMvc.post("/api/v1/letters/anonymous/send") {
1099-
contentType = MediaType.APPLICATION_JSON
1100-
content = objectMapper.writeValueAsString(request)
1091+
@Nested
1092+
@DisplayName("익명 편지 전송")
1093+
inner class SendAnonymousLetter {
1094+
@Test
1095+
@DisplayName("발송자 이름 없이 익명 편지 전송")
1096+
fun sendAnonymousLetter() {
1097+
// given
1098+
val request =
1099+
AnonymousSendLetterRequest(
1100+
receiverName = "receiverName",
1101+
content = "content",
1102+
images = listOf("images"),
1103+
templateType = 1,
1104+
)
1105+
// when
1106+
val response =
1107+
mockMvc.post("/api/v1/letters/anonymous/send") {
1108+
contentType = MediaType.APPLICATION_JSON
1109+
content = objectMapper.writeValueAsString(request)
1110+
}
1111+
// then
1112+
response.andExpect {
1113+
status { isOk() }
1114+
jsonPath("$.letterCode") {
1115+
exists()
1116+
isString()
1117+
isNotEmpty()
1118+
}
11011119
}
1102-
// then
1103-
response.andExpect {
1104-
status { isOk() }
1105-
jsonPath("$.letterCode") {
1106-
exists()
1107-
isString()
1108-
isNotEmpty()
1120+
}
1121+
1122+
@Test
1123+
@DisplayName("발송자 이름과 함께 익명 편지 전송")
1124+
fun sendAnonymousLetterWithSenderName() {
1125+
// given
1126+
val request =
1127+
AnonymousSendLetterRequest(
1128+
senderName = "Test Sender",
1129+
receiverName = "receiverName",
1130+
content = "content",
1131+
images = listOf("images"),
1132+
templateType = 1,
1133+
)
1134+
// when
1135+
val response =
1136+
mockMvc.post("/api/v1/letters/anonymous/send") {
1137+
contentType = MediaType.APPLICATION_JSON
1138+
content = objectMapper.writeValueAsString(request)
1139+
}
1140+
// then
1141+
response.andExpect {
1142+
status { isOk() }
1143+
jsonPath("$.letterCode") {
1144+
exists()
1145+
isString()
1146+
isNotEmpty()
1147+
}
1148+
}
1149+
}
1150+
1151+
@Test
1152+
@DisplayName("발송자 이름이 null인 익명 편지 전송")
1153+
fun sendAnonymousLetterWithNullSenderName() {
1154+
// given
1155+
val request =
1156+
AnonymousSendLetterRequest(
1157+
senderName = null,
1158+
receiverName = "receiverName",
1159+
content = "content",
1160+
images = listOf("images"),
1161+
templateType = 1,
1162+
)
1163+
// when
1164+
val response =
1165+
mockMvc.post("/api/v1/letters/anonymous/send") {
1166+
contentType = MediaType.APPLICATION_JSON
1167+
content = objectMapper.writeValueAsString(request)
1168+
}
1169+
// then
1170+
response.andExpect {
1171+
status { isOk() }
1172+
jsonPath("$.letterCode") {
1173+
exists()
1174+
isString()
1175+
isNotEmpty()
1176+
}
11091177
}
11101178
}
11111179
}

Bootstrap-Module/src/test/kotlin/com/asap/bootstrap/integration/user/UserApiIntegrationTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ class UserApiIntegrationTest(
332332
content = letterContent,
333333
receiverName = receiverName,
334334
letterCode = "test-letter-code",
335-
status = LetterStatus.SENDING,
335+
senderName = "Anonymous",
336336
)
337337
sendLetterManagementPort.save(anonymousSendLetter)
338338

Domain-Module/src/main/kotlin/com/asap/domain/letter/entity/SendLetter.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class SendLetter(
1313
id: DomainId,
1414
val content: LetterContent,
1515
var senderId: DomainId?,
16+
var senderName: String?,
1617
var receiverName: String,
1718
var letterCode: String?,
1819
var status: LetterStatus,
@@ -37,6 +38,7 @@ class SendLetter(
3738
id = DomainId.generate(),
3839
content = content,
3940
senderId = senderId,
41+
senderName = null,
4042
receiverName = receiverName,
4143
letterCode = letterCode,
4244
status = status,
@@ -51,6 +53,7 @@ class SendLetter(
5153
content: LetterContent,
5254
receiverName: String,
5355
letterCode: String?,
56+
senderName: String,
5457
status: LetterStatus = LetterStatus.SENDING,
5558
receiverId: DomainId? = null,
5659
createdAt: LocalDateTime = LocalDateTime.now(),
@@ -60,6 +63,7 @@ class SendLetter(
6063
id = DomainId.generate(),
6164
content = content,
6265
senderId = null,
66+
senderName = senderName,
6367
receiverName = receiverName,
6468
letterCode = letterCode,
6569
status = status,

0 commit comments

Comments
 (0)