Skip to content

Commit

Permalink
🔧refactor: 내 식물 조회 API 수정 (#136)
Browse files Browse the repository at this point in the history
* fix: 내 식물 전체 조회 쿼리 수정

* refactor: 기본 Myplant url null처리

* style: ktlint format

* fix: fix test
  • Loading branch information
stophwan authored Oct 11, 2024
1 parent 61491a8 commit 1fa8cc7
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ data class MyPlantResponse(
@field:Schema(description = "등록 일자", example = "2024-09-03T14:30:45")
val registeredDateTime: LocalDateTime,
@field:Schema(description = "이미지 URL", example = "image.com/7")
val imageUrl: String,
val imageUrl: String?,
@field:Schema(description = "내 식물 학명", example = "몬스테라 델리오사")
val scientificName: String,
@field:Schema(description = "마지막 물주기로부터 지난 날짜", example = "2")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class MyPlantService(
now: LocalDate,
user: User,
): List<MyPlantResponse> {
val myPlantsWithImageUrl: List<MyPlantWithImageUrl> = imageRepository.findMyPlantAndMostRecentFavoriteImageByUser(user)
val myPlantsWithImageUrl: List<MyPlantWithImageUrl> = myPlantRepository.findMyPlantAndMostRecentFavoriteImageByUser(user)

return MyPlantResponse.fromMyPlantWithImageUrlList(myPlantsWithImageUrl, now)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ import java.time.LocalDate

class MyPlantServiceTest : DescribeSpec(
{
val myPlantRepsitory = mockk<MyPlantRepository>()
val myPlantRepository = mockk<MyPlantRepository>()
val plantRepository = mockk<PlantRepository>()
val locationRepository = mockk<LocationRepository>()
val imageRepository = mockk<ImageRepository>()
val myPlantMessageFactory = mockk<MyPlantMessageFactory>()
val myPlantService =
MyPlantService(
myPlantRepsitory,
myPlantRepository,
plantRepository,
locationRepository,
myPlantMessageFactory,
Expand All @@ -58,7 +58,7 @@ class MyPlantServiceTest : DescribeSpec(
"등록 되었습니다."
every { plantRepository.findByIdOrNull(PLANT_ID) } returns
PLANT
every { myPlantRepsitory.save(any()) } returns
every { myPlantRepository.save(any()) } returns
MyPlant(
scientificName = SCIENTIFIC_NAME,
nickname = NICKNAME,
Expand Down Expand Up @@ -137,9 +137,9 @@ class MyPlantServiceTest : DescribeSpec(
id = 3
location = null
}
every { myPlantRepsitory.findAllByUser(any()) } returns
every { myPlantRepository.findAllByUser(any()) } returns
listOf(myPlant1, myPlant2, myPlant3)
every { imageRepository.findMyPlantAndMostRecentFavoriteImageByUser(any()) } returns
every { myPlantRepository.findMyPlantAndMostRecentFavoriteImageByUser(any()) } returns
listOf(
MyPlantWithImageUrl(myPlant1, "url1"),
MyPlantWithImageUrl(myPlant2, "url2"),
Expand Down Expand Up @@ -190,7 +190,7 @@ class MyPlantServiceTest : DescribeSpec(
}

describe("내 식물 상세 조회") {
every { myPlantRepsitory.findByIdAndUser(MYPLANT_ID, any()) } returns
every { myPlantRepository.findByIdAndUser(MYPLANT_ID, any()) } returns
MyPlant(
scientificName = SCIENTIFIC_NAME,
nickname = NICKNAME,
Expand All @@ -202,7 +202,7 @@ class MyPlantServiceTest : DescribeSpec(
).apply {
id = MYPLANT_ID
}
every { myPlantRepsitory.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
every { myPlantRepository.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
null
every { imageRepository.findAllByMyPlant(any()) } returns
listOf(
Expand All @@ -224,7 +224,7 @@ class MyPlantServiceTest : DescribeSpec(
FERTILIZER_TITLE
every { myPlantMessageFactory.createFertilizerInfo(any(), any()) } returns
FERTILIZER_INFO
every { myPlantRepsitory.findByIdOrNull(not(eq(MYPLANT_ID))) } returns
every { myPlantRepository.findByIdOrNull(not(eq(MYPLANT_ID))) } returns
null
context("존재하는 ID로 상세 조회하면") {
it("내 식물의 상세 정보가 조회되어야 한다.") {
Expand Down Expand Up @@ -254,7 +254,7 @@ class MyPlantServiceTest : DescribeSpec(
}

describe("내 식물 수정") {
every { myPlantRepsitory.findByIdAndUser(any(), any()) } returns
every { myPlantRepository.findByIdAndUser(any(), any()) } returns
MyPlant(
scientificName = SCIENTIFIC_NAME,
nickname = NICKNAME,
Expand All @@ -264,7 +264,7 @@ class MyPlantServiceTest : DescribeSpec(
lastHealthCheckDate = LAST_HEALTHCHECK_DATE,
alarm = ALARM,
)
every { myPlantRepsitory.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
every { myPlantRepository.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
null
every { locationRepository.findByIdAndUser(LOCATION_ID, any()) } returns
Location(
Expand Down Expand Up @@ -334,7 +334,7 @@ class MyPlantServiceTest : DescribeSpec(
}

describe("내 식물 삭제") {
every { myPlantRepsitory.findByIdAndUser(MYPLANT_ID, any()) } returns
every { myPlantRepository.findByIdAndUser(MYPLANT_ID, any()) } returns
MyPlant(
scientificName = SCIENTIFIC_NAME,
nickname = NICKNAME,
Expand All @@ -346,9 +346,9 @@ class MyPlantServiceTest : DescribeSpec(
).apply {
id = MYPLANT_ID
}
every { myPlantRepsitory.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
every { myPlantRepository.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
null
every { myPlantRepsitory.delete(any()) } just runs
every { myPlantRepository.delete(any()) } just runs
every { imageRepository.deleteAllInBatchByMyPlant(any()) } just runs

context("정상 요청으로 삭제하면") {
Expand All @@ -367,7 +367,7 @@ class MyPlantServiceTest : DescribeSpec(
}

describe("내 식물 물주기") {
every { myPlantRepsitory.findByIdAndUser(MYPLANT_ID, any()) } returns
every { myPlantRepository.findByIdAndUser(MYPLANT_ID, any()) } returns
MyPlant(
scientificName = SCIENTIFIC_NAME,
nickname = NICKNAME,
Expand All @@ -379,7 +379,7 @@ class MyPlantServiceTest : DescribeSpec(
).apply {
id = MYPLANT_ID
}
every { myPlantRepsitory.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
every { myPlantRepository.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
null
context("존재하는 내 식물 ID로 내 식물 물주기 요청하면") {
it("정상 흐름이 반환된다.") {
Expand All @@ -401,7 +401,7 @@ class MyPlantServiceTest : DescribeSpec(
}

describe("내 식물 비료주기") {
every { myPlantRepsitory.findByIdAndUser(MYPLANT_ID, any()) } returns
every { myPlantRepository.findByIdAndUser(MYPLANT_ID, any()) } returns
MyPlant(
scientificName = SCIENTIFIC_NAME,
nickname = NICKNAME,
Expand All @@ -413,7 +413,7 @@ class MyPlantServiceTest : DescribeSpec(
).apply {
id = MYPLANT_ID
}
every { myPlantRepsitory.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
every { myPlantRepository.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
null
context("존재하는 내 식물 ID로 내 식물 비료주기 요청하면") {
it("정상 흐름이 반환된다.") {
Expand All @@ -435,7 +435,7 @@ class MyPlantServiceTest : DescribeSpec(
}

describe("내 식물 눈길주기") {
every { myPlantRepsitory.findByIdAndUser(MYPLANT_ID, any()) } returns
every { myPlantRepository.findByIdAndUser(MYPLANT_ID, any()) } returns
MyPlant(
scientificName = SCIENTIFIC_NAME,
nickname = NICKNAME,
Expand All @@ -447,7 +447,7 @@ class MyPlantServiceTest : DescribeSpec(
).apply {
id = MYPLANT_ID
}
every { myPlantRepsitory.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
every { myPlantRepository.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
null
every { myPlantMessageFactory.createHealthCheckMessage() } returns
""
Expand All @@ -471,7 +471,7 @@ class MyPlantServiceTest : DescribeSpec(
}

describe("알림 변경") {
every { myPlantRepsitory.findByIdAndUser(MYPLANT_ID, any()) } returns
every { myPlantRepository.findByIdAndUser(MYPLANT_ID, any()) } returns
MyPlant(
scientificName = SCIENTIFIC_NAME,
nickname = NICKNAME,
Expand All @@ -483,7 +483,7 @@ class MyPlantServiceTest : DescribeSpec(
).apply {
id = MYPLANT_ID
}
every { myPlantRepsitory.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
every { myPlantRepository.findByIdAndUser(not(eq(MYPLANT_ID)), any()) } returns
null
context("존재하는 ID와 요청으로 알림 변경 요청을 하면") {
val request =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ class PlantNotificationReader(
@StepScope
fun waterNotificationItemReader(): ListItemReader<UserPlantDto> {
val now: LocalTime = LocalTime.now()
// val alarmTime = AlarmTime.fromHour(now)
val alarmTime = AlarmTime.TIME_10_11
val alarmTime = AlarmTime.fromHour(now)

val userPlantByAlarmTime: List<UserPlantDto> =
myPlantRepository.findNeedWaterPlantsByAlarmTimeInBatch(alarmTime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MyPlant(
var id: Long? = null

@Column
var plantImageUrl: String = "블루밍 대표 이미지"
var plantImageUrl: String? = null
// TODO : 블루밍 대표 이미지 넣기

@ManyToOne(fetch = FetchType.LAZY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dnd11th.blooming.core.repository.image

import dnd11th.blooming.core.entity.image.Image
import dnd11th.blooming.core.entity.myplant.MyPlant
import dnd11th.blooming.core.entity.myplant.MyPlantWithImageUrl
import dnd11th.blooming.core.entity.user.User
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Modifying
Expand All @@ -12,26 +11,6 @@ import org.springframework.data.repository.query.Param
interface ImageRepository : JpaRepository<Image, Long> {
fun findAllByMyPlant(myPlant: MyPlant): List<Image>

@Query(
"""
SELECT new dnd11th.blooming.core.entity.myplant.MyPlantWithImageUrl(mp, i.url)
FROM Image i
JOIN i.myPlant mp
JOIN FETCH mp.location l
WHERE mp.user = :user
AND i.favorite = true
AND i.updatedDate = (
SELECT MAX(i2.updatedDate)
FROM Image i2
WHERE i2.myPlant = mp
AND i2.favorite = true
)
""",
)
fun findMyPlantAndMostRecentFavoriteImageByUser(
@Param("user") user: User,
): List<MyPlantWithImageUrl>

@Modifying
@Query(
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package dnd11th.blooming.core.repository.myplant

import dnd11th.blooming.core.entity.location.Location
import dnd11th.blooming.core.entity.myplant.MyPlant
import dnd11th.blooming.core.entity.myplant.MyPlantWithImageUrl
import dnd11th.blooming.core.entity.user.User
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param

interface MyPlantRepository :
JpaRepository<MyPlant, Long>,
MyPlantQueryDslRepository {
interface MyPlantRepository : JpaRepository<MyPlant, Long>, MyPlantQueryDslRepository {
fun findByIdAndUser(
id: Long,
user: User,
Expand All @@ -31,4 +30,23 @@ interface MyPlantRepository :
fun deleteAllByUser(
@Param("user") user: User,
)

@Query(
"""
SELECT new dnd11th.blooming.core.entity.myplant.MyPlantWithImageUrl(
mp,
(SELECT i.url
FROM Image i
WHERE i.myPlant = mp AND i.favorite = true
ORDER BY i.updatedDate
DESC LIMIT 1)
)
FROM MyPlant mp
JOIN FETCH mp.location l
WHERE mp.user = :user
""",
)
fun findMyPlantAndMostRecentFavoriteImageByUser(
@Param("user") user: User,
): List<MyPlantWithImageUrl>
}

0 comments on commit 1fa8cc7

Please sign in to comment.