Skip to content

Commit

Permalink
Merge pull request #75 from KUSITMS-29th-TEAM-B/feat/flight-74
Browse files Browse the repository at this point in the history
feat: 경험 수정 API 구현(#74)
  • Loading branch information
whereami2048 authored May 19, 2024
2 parents d15b49e + 9f20d69 commit daed752
Show file tree
Hide file tree
Showing 23 changed files with 383 additions and 156 deletions.
5 changes: 5 additions & 0 deletions Api-Module/src/docs/asciidoc/Experience.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ operation::ExperienceControllerTest/createOverTitleLengthTest/[snippets='http-re

operation::ExperienceControllerTest/createOverStrongPointCountTest/[snippets='http-request,request-headers,request-body,http-response,response-body,response-fields']

[[EditExperienceTest]]
=== 경험 수정 API

operation::ExperienceControllerTest/editExperienceTest/[snippets='http-request,path-parameters,request-headers,request-body,http-response,response-body']

[[DeleteExperienceTest]]
=== 경험 삭제 API

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.bamyanggang.apimodule.domain.experience.application.dto

import com.bamyanggang.apimodule.domain.experience.application.dto.CreateExperience.ExperienceContentRequest
import java.time.LocalDateTime
import java.util.*

class EditExperience {
data class Request(
val title: String,
val parentTagId: UUID,
val childTagId: UUID,
val strongPointIds: List<UUID>,
val contents: List<ExperienceContentRequest>,
val startedAt: LocalDateTime,
val endedAt: LocalDateTime,
)

data class ExperienceContentRequest(
val question: String,
val answer: String,
)

data class Response(val id: UUID)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,39 @@ package com.bamyanggang.apimodule.domain.experience.application.service

import com.bamyanggang.apimodule.common.getAuthenticationPrincipal
import com.bamyanggang.apimodule.domain.experience.application.dto.CreateExperience
import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceContent
import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceStrongPoint
import com.bamyanggang.domainmodule.domain.experience.service.ExperienceAppender
import com.bamyanggang.domainmodule.domain.experience.service.ExperienceContentAppender
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class ExperienceCreateService(
val experienceAppender: ExperienceAppender,
val experienceContentAppender: ExperienceContentAppender,
val experienceAppender: ExperienceAppender
) {
@Transactional
fun createExperience(request: CreateExperience.Request):CreateExperience.Response {
val currentUserId = getAuthenticationPrincipal()

val newExperience = experienceAppender.appendExperience(
val newContents = request.contents.map {
ExperienceContent.create(it.question, it.answer)
}

val newExperienceStrongPoints = request.strongPointIds.map {
ExperienceStrongPoint.create(it)
}

return experienceAppender.appendExperience(
title = request.title,
userId = currentUserId,
parentTagId = request.parentTagId,
childTagId = request.childTagId,
contents = newContents,
experienceStrongPoints = newExperienceStrongPoints,
startedAt = request.startedAt,
endedAt = request.endedAt
)

request.contents.forEach {
experienceContentAppender.appendExperienceContent(it.question, it.answer, newExperience.id)
).let {
CreateExperience.Response(it.id)
}

return CreateExperience.Response(newExperience.id)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.bamyanggang.apimodule.domain.experience.application.service

import com.bamyanggang.apimodule.common.getAuthenticationPrincipal
import com.bamyanggang.apimodule.domain.experience.application.dto.EditExperience
import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceContent
import com.bamyanggang.domainmodule.domain.experience.aggregate.ExperienceStrongPoint
import com.bamyanggang.domainmodule.domain.experience.service.ExperienceModifier
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*

@Service
class ExperienceEditService(
private val experienceModifier: ExperienceModifier,
) {
@Transactional
fun editExperience(request: EditExperience.Request, experienceId: UUID) : EditExperience.Response{
val newContents = request.contents.map {
ExperienceContent.create(it.question, it.answer)
}

val newExperienceStrongPoints = request.strongPointIds.map {
ExperienceStrongPoint.create(it)
}

return getAuthenticationPrincipal().let {
experienceModifier.modifyExperience(
experienceId = experienceId,
userId = it,
title = request.title,
parentTagId = request.parentTagId,
childTagId = request.childTagId,
contents = newContents,
experienceStrongPoints = newExperienceStrongPoints,
startedAt = request.startedAt,
endedAt = request.endedAt
)
}.let { EditExperience.Response(it.id) }
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package com.bamyanggang.apimodule.domain.experience.presentation

import com.bamyanggang.apimodule.domain.experience.application.dto.CreateExperience
import com.bamyanggang.apimodule.domain.experience.application.dto.EditExperience
import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceCreateService
import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceDeleteService
import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceEditService
import org.springframework.web.bind.annotation.*
import java.util.*

@RestController
class ExperienceController(
private val experienceCreateService: ExperienceCreateService,
private val experienceDeleteService: ExperienceDeleteService
private val experienceDeleteService: ExperienceDeleteService,
private val experienceEditService: ExperienceEditService
) {
@PostMapping(ExperienceApi.BASE_URL)
fun createExperience(@RequestBody request: CreateExperience.Request): CreateExperience.Response {
Expand All @@ -20,4 +23,10 @@ class ExperienceController(
fun deleteExperience(@PathVariable("experienceId") experienceId: UUID) {
experienceDeleteService.deleteExperienceById(experienceId)
}

@PatchMapping(ExperienceApi.EXPERIENCE_PATH_VARIABLE_URL)
fun editExperience(@RequestBody request: EditExperience.Request,
@PathVariable experienceId: UUID): EditExperience.Response {
return experienceEditService.editExperience(request, experienceId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package com.bamyanggang.apimodule.domain.experience.presentation

import com.bamyanggang.apimodule.BaseRestDocsTest
import com.bamyanggang.apimodule.domain.experience.application.dto.CreateExperience
import com.bamyanggang.apimodule.domain.experience.application.dto.EditExperience
import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceCreateService
import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceDeleteService
import com.bamyanggang.apimodule.domain.experience.application.service.ExperienceEditService
import com.bamyanggang.commonmodule.exception.ExceptionHandler
import com.bamyanggang.commonmodule.fixture.generateFixture
import org.junit.jupiter.api.DisplayName
Expand Down Expand Up @@ -34,6 +36,9 @@ class ExperienceControllerTest : BaseRestDocsTest() {
@MockBean
private lateinit var experienceDeleteService: ExperienceDeleteService

@MockBean
private lateinit var experienceEditService: ExperienceEditService

@Test
@DisplayName("경험을 등록한다.")
fun createExperienceTest() {
Expand Down Expand Up @@ -220,5 +225,64 @@ class ExperienceControllerTest : BaseRestDocsTest() {
)
)
}

@Test
@DisplayName("경험을 수정한다.")
fun editExperienceTest() {
//given
val content1 = EditExperience.ExperienceContentRequest("질문1", "답변1")
val content2 = EditExperience.ExperienceContentRequest("질문2", "답변2")

val contentRequest = arrayListOf(content1, content2)

val editExperienceRequest : EditExperience.Request = generateFixture {
it.set("title", "제목")
it.set("contents", contentRequest)
it.set("strongPointIds", generateFixture<List<UUID>>())
it.set("parentTagId", generateFixture<UUID>())
it.set("childTagId", generateFixture<UUID>())
it.set("startedAt", generateFixture<LocalDateTime>())
it.set("endedAt", generateFixture<LocalDateTime>())
}

val editedExperienceId : UUID = UUID.randomUUID()
val editExperienceResponse : EditExperience.Response = generateFixture()

given(experienceEditService.editExperience(editExperienceRequest, editedExperienceId)).willReturn(editExperienceResponse)

val request = RestDocumentationRequestBuilders.patch(ExperienceApi.EXPERIENCE_PATH_VARIABLE_URL, editedExperienceId)
.header("Authorization", "Bearer Access Token")
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsString(editExperienceRequest))

//when
val result = mockMvc.perform(request)

//then
result.andExpect(status().isOk).andDo(
resultHandler.document(
requestHeaders(
headerWithName("Authorization").description("엑세스 토큰")
),
pathParameters(
parameterWithName("experienceId").description("경험 id")
),
requestFields(
fieldWithPath("title").description("경험 제목"),
fieldWithPath("contents").description("경험 내용"),
fieldWithPath("contents[].question").description("경험 내용 질문"),
fieldWithPath("contents[].answer").description("경험 내용 답변"),
fieldWithPath("strongPointIds").description("관련된 역량 키워드"),
fieldWithPath("parentTagId").description("속한 상위 태그"),
fieldWithPath("childTagId").description("속한 하위 태그"),
fieldWithPath("startedAt").description("경험 시작 날짜"),
fieldWithPath("endedAt").description("경험 종료 날짜"),
),
responseFields(
fieldWithPath("id").description("경험 id")
)
)
)
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,62 @@ import java.util.*

data class Experience(
override val id: UUID = UuidCreator.create(),
val userId : UUID,
val title : String,
val userId : UUID,
val parentTagId: UUID,
val childTagId: UUID,
val experienceStrongPoints: List<ExperienceStrongPoint> = emptyList(),
val contents: List<ExperienceContent>,
val startedAt : LocalDateTime,
val endedAt : LocalDateTime,
val createdAt : LocalDateTime,
val updatedAt : LocalDateTime,
) : AggregateRoot {
fun update(
title: String,
userId: UUID,
parentTagId: UUID,
childTagId: UUID,
contents: List<ExperienceContent>,
experienceStrongPoints: List<ExperienceStrongPoint>,
startedAt: LocalDateTime,
endedAt: LocalDateTime,
): Experience {
return copy(
title = title,
userId = userId,
parentTagId = parentTagId,
childTagId = childTagId,
contents = contents,
experienceStrongPoints = experienceStrongPoints,
startedAt = startedAt,
endedAt = endedAt,
createdAt = createdAt,
updatedAt = LocalDateTime.now(),
)
}

init {
require(title.length < 50) { "제목의 글자 수는 50자 제한입니다." }
}
companion object {
fun create(
title: String,
userId: UUID,
parentTagId: UUID,
childTagId: UUID,
contents: List<ExperienceContent>,
experienceStrongPoints: List<ExperienceStrongPoint>,
startedAt: LocalDateTime,
endedAt: LocalDateTime,
): Experience {
return Experience(
userId = userId,
title = title,
parentTagId = parentTagId,
childTagId = childTagId,
contents = contents,
experienceStrongPoints = experienceStrongPoints,
startedAt = startedAt,
endedAt = endedAt,
createdAt = LocalDateTime.now(),
Expand All @@ -38,6 +74,10 @@ data class Experience(
id: UUID,
userId: UUID,
title: String,
parentTagId: UUID,
childTagId: UUID,
contents: List<ExperienceContent>,
experienceStrongPoints: List<ExperienceStrongPoint>,
startedAt: LocalDateTime,
endedAt: LocalDateTime,
createdAt: LocalDateTime,
Expand All @@ -47,6 +87,10 @@ data class Experience(
id = id,
userId = userId,
title = title,
parentTagId = parentTagId,
childTagId = childTagId,
contents = contents,
experienceStrongPoints = experienceStrongPoints,
startedAt = startedAt,
endedAt = endedAt,
createdAt = createdAt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ data class ExperienceContent(
override val id: UUID = UuidCreator.create(),
val question: String,
val answer: String,
val experienceId: UUID
) : DomainEntity {

companion object {
fun create(question: String, answer: String, experienceId: UUID): ExperienceContent {
return ExperienceContent(question = question, answer = answer, experienceId = experienceId)
fun create(question: String, answer: String): ExperienceContent {
return ExperienceContent(question = question, answer = answer)
}

fun toDomain(id: UUID, question: String, answer: String, experienceId: UUID): ExperienceContent {
return ExperienceContent(id, question, answer, experienceId)
fun toDomain(id: UUID, question: String, answer: String): ExperienceContent {
return ExperienceContent(id, question, answer)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.bamyanggang.domainmodule.domain.experience.aggregate

import com.bamyanggang.domainmodule.common.entity.DomainEntity
import com.example.uuid.UuidCreator
import java.util.*

data class ExperienceStrongPoint(
override val id: UUID = UuidCreator.create(),
val strongPointId: UUID
) : DomainEntity {

companion object {
fun create(strongPointId: UUID): ExperienceStrongPoint {
return ExperienceStrongPoint(strongPointId = strongPointId)
}

fun toDomain(id: UUID, strongPointId: UUID): ExperienceStrongPoint {
return ExperienceStrongPoint(id, strongPointId)
}
}
}

This file was deleted.

Loading

0 comments on commit daed752

Please sign in to comment.