Skip to content

Commit

Permalink
Implement goal modification (#25)
Browse files Browse the repository at this point in the history
Resolved: #22
  • Loading branch information
zionhann authored Aug 5, 2024
1 parent f03d2e5 commit 202e845
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 12 deletions.
33 changes: 33 additions & 0 deletions api-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,39 @@ paths:
title: 5kg 다이어트
streak: 0
status: CLOSED
/v1/goals/{goalId}:
put:
tags:
- goals
summary: 목표 수정(달성 상태 변경 포함)
description: " "
operationId: modifyGoal
parameters:
- name: goalId
in: path
required: true
schema:
type: string
description: 목표 ID
responses:
"200":
description: OK
delete:
tags:
- goals
summary: 목표 삭제
description: " "
operationId: deleteGoal
parameters:
- name: goalId
in: path
required: true
schema:
type: string
description: 목표 ID
responses:
"200":
description: OK

# journals
/v1/goals/{goalId}/journals:
Expand Down
25 changes: 16 additions & 9 deletions src/main/kotlin/com/likelionhgu/stepper/goal/Goal.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class Goal(
@Column
var title: String,

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
val member: Member? = null,

@Column
var startDate: LocalDate? = null,

Expand All @@ -28,18 +32,21 @@ class Goal(
@Column(length = 512)
var thumbnail: String? = null,

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
val member: Member
@Column
var status: GoalStatus = GoalStatus.OPEN
) : BaseTime() {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val goalId = 0L

@Column
var status = GoalStatus.OPEN
val goalId: Long = 0L

@Column
var streak = 0
var streak: Int = 0

fun update(targetGoal: Goal) {
title = targetGoal.title
startDate = targetGoal.startDate
endDate = targetGoal.endDate
thumbnail = targetGoal.thumbnail
status = targetGoal.status
}
}
19 changes: 19 additions & 0 deletions src/main/kotlin/com/likelionhgu/stepper/goal/GoalController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ package com.likelionhgu.stepper.goal

import com.likelionhgu.stepper.goal.enums.GoalSortType
import com.likelionhgu.stepper.goal.request.GoalRequest
import com.likelionhgu.stepper.goal.request.GoalUpdateRequest
import com.likelionhgu.stepper.goal.response.GoalResponseWrapper
import com.likelionhgu.stepper.security.oauth2.CommonOAuth2Attribute
import jakarta.validation.Valid
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
Expand Down Expand Up @@ -38,4 +42,19 @@ class GoalController(
val responseBody = GoalResponseWrapper.of(goals)
return ResponseEntity.ok(responseBody)
}

@PutMapping("/v1/goals/{goalId}")
fun updateGoal(
@PathVariable goalId: Long,
@RequestBody goalRequest: GoalUpdateRequest,
) {
goalService.updateGoal(goalId, goalRequest)
}

@DeleteMapping("/v1/goals/{goalId}")
fun deleteGoal(
@PathVariable goalId: Long
) {
goalService.deleteGoal(goalId)
}
}
18 changes: 16 additions & 2 deletions src/main/kotlin/com/likelionhgu/stepper/goal/GoalService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.likelionhgu.stepper.exception.GoalNotFoundException
import com.likelionhgu.stepper.exception.MemberNotFoundException
import com.likelionhgu.stepper.goal.enums.GoalSortType
import com.likelionhgu.stepper.goal.request.GoalRequest
import com.likelionhgu.stepper.goal.request.GoalUpdateRequest
import com.likelionhgu.stepper.member.MemberRepository
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
Expand All @@ -21,15 +22,16 @@ class GoalService(

val goal = Goal(
goalRequest.title!!,
member,
goalRequest.startDate,
goalRequest.endDate,
goalRequest.thumbnail,
member
goalRequest.thumbnail
).let(goalRepository::save)

return goal.goalId
}

@Transactional(readOnly = true)
fun memberGoals(oauth2UserId: String, sortType: GoalSortType): List<Goal> {
val member = memberRepository.findByOauth2Id(oauth2UserId)
?: throw MemberNotFoundException("The member with the oauth2 sub \"$oauth2UserId\" does not exist")
Expand All @@ -44,8 +46,20 @@ class GoalService(
* @return Goal The `Goal` entity corresponding to the provided ID.
* @throws GoalNotFoundException if no goal is found with the provided ID.
*/
@Transactional(readOnly = true)
fun goalInfo(goalId: Long): Goal {
return goalRepository.findById(goalId).getOrNull()
?: throw GoalNotFoundException("The goal with the id \"$goalId\" does not exist")
}

fun updateGoal(goalId: Long, goalRequest: GoalUpdateRequest) {
val sourceGoal = goalRepository.findById(goalId).getOrNull()
?: throw GoalNotFoundException("The goal with the id \"$goalId\" does not exist")

goalRequest.toEntity().also(sourceGoal::update)
}

fun deleteGoal(goalId: Long) {
goalRepository.deleteById(goalId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.likelionhgu.stepper.goal.request

import com.likelionhgu.stepper.goal.Goal
import com.likelionhgu.stepper.goal.enums.GoalStatus
import jakarta.validation.constraints.NotNull
import org.springframework.format.annotation.DateTimeFormat
import java.time.LocalDate

data class GoalUpdateRequest(

@field:NotNull(message = "The title must not be null")
val title: String?,

@field:NotNull(message = "The status must not be null")
val status: GoalStatus?,

@field:DateTimeFormat(pattern = "yyyy-MM-dd")
val startDate: LocalDate? = null,

@field:DateTimeFormat(pattern = "yyyy-MM-dd")
val endDate: LocalDate? = null,

val thumbnail: String? = null,

) {
fun toEntity() = Goal(
title = title!!,
startDate = startDate,
endDate = endDate,
thumbnail = thumbnail,
status = status!!
)
}
26 changes: 25 additions & 1 deletion src/test/kotlin/com/likelionhgu/stepper/goal/GoalServiceTest.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.likelionhgu.stepper.goal

import com.likelionhgu.stepper.goal.enums.GoalSortType
import com.likelionhgu.stepper.goal.enums.GoalStatus
import com.likelionhgu.stepper.goal.request.GoalRequest
import com.likelionhgu.stepper.goal.request.GoalUpdateRequest
import com.likelionhgu.stepper.member.Member
import com.likelionhgu.stepper.member.MemberRepository
import io.kotest.core.spec.style.BehaviorSpec
Expand Down Expand Up @@ -67,14 +69,36 @@ class GoalServiceTest(
}

`when`("the goals are retrieved with an order of descending") {

then("the goals should be sorted by ascending") {
val goals = goalService.memberGoals(oauth2UserId, GoalSortType.DESC)

goals[0].goalId shouldBe goalId2
goals[1].goalId shouldBe goalId1
}
}

`when`("the goal is updated") {
then("the goal should be updated") {
val request = GoalUpdateRequest(
title = goalTitle,
status = GoalStatus.CLOSED
)
goalService.updateGoal(goalId1, request)

val goal = goalService.goalInfo(goalId1)
goal shouldNotBe null
goal.status shouldBe GoalStatus.CLOSED
}
}

`when`("the goal is deleted") {
then("the goal should be deleted") {
goalService.deleteGoal(goalId1)

val goal = goalRepository.findById(goalId1).getOrNull()
goal shouldBe null
}
}
}
}) {
override fun extensions() = listOf(SpringExtension)
Expand Down

0 comments on commit 202e845

Please sign in to comment.