Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ 역 즐겨찾기 우선순위 적용 (#339) #340

Merged
merged 5 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
package backend.team.ahachul_backend.api.member.adapter.web.`in`.dto

import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommand
import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommands

class BookmarkStationDto {

data class Request(
val stationNames: List<String>
val stations: List<BookmarkStation>
) {
fun toCommand(): BookmarkStationCommand {
return BookmarkStationCommand(
stationNames = stationNames.toMutableList()
fun toCommand(): BookmarkStationCommands {
return BookmarkStationCommands(
stations.map { BookmarkStationCommand(it.stationName, it.label) }
)
}
}

data class Response(
val memberStationIds: List<Long>
)

data class BookmarkStation(
val stationName: String,
val label: String?,
)
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존의 BookmarkStationCommandBookmarkStationCommands로 변경하고,
BookmarkStationCommand를 새롭게 작성하였습니다.

이에 따른 API 요청 스펙을 변경하였습니다. stationNames 👉 stations

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class GetBookmarkStationDto {
data class StationInfo(
val stationId: Long,
val stationName: String,
val label: String?,
val subwayLineInfoList: List<SubwayLineInfo>
)
Comment on lines 9 to 14
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조회 API 응답 스펙에도 label을 추가하였습니다. 😂


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package backend.team.ahachul_backend.api.member.application.port.`in`

import backend.team.ahachul_backend.api.member.adapter.web.`in`.dto.*
import backend.team.ahachul_backend.api.member.application.command.SearchMemberCommand
import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommand
import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommands
import backend.team.ahachul_backend.api.member.application.port.`in`.command.CheckNicknameCommand
import backend.team.ahachul_backend.api.member.application.port.`in`.command.UpdateMemberCommand

Expand All @@ -14,7 +14,7 @@ interface MemberUseCase {

fun checkNickname(command: CheckNicknameCommand): CheckNicknameDto.Response

fun bookmarkStation(command: BookmarkStationCommand): BookmarkStationDto.Response
fun bookmarkStation(command: BookmarkStationCommands): BookmarkStationDto.Response

fun getBookmarkStation(): GetBookmarkStationDto.Response

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import backend.team.ahachul_backend.api.common.application.port.out.StationReade
import backend.team.ahachul_backend.api.common.application.port.out.SubwayLineStationReader
import backend.team.ahachul_backend.api.common.domain.entity.StationEntity
import backend.team.ahachul_backend.api.member.adapter.web.`in`.dto.*
import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommand
import backend.team.ahachul_backend.api.member.application.command.SearchMemberCommand
import backend.team.ahachul_backend.api.member.application.port.`in`.MemberUseCase
import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommand
import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommands
import backend.team.ahachul_backend.api.member.application.port.`in`.command.CheckNicknameCommand
import backend.team.ahachul_backend.api.member.application.port.`in`.command.UpdateMemberCommand
import backend.team.ahachul_backend.api.member.application.port.out.MemberReader
Expand Down Expand Up @@ -53,9 +54,9 @@ class MemberService(
}

@Transactional
override fun bookmarkStation(command: BookmarkStationCommand): BookmarkStationDto.Response {
override fun bookmarkStation(command: BookmarkStationCommands): BookmarkStationDto.Response {
val member = memberReader.getMember(RequestUtils.getAttribute("memberId")!!.toLong())
val bookmarkStations = command.stationNames
val bookmarkStations = command.stations
val originMemberStations = memberStationReader.getByMember(member)

if (originMemberStations.isNotEmpty()) {
Expand All @@ -66,13 +67,13 @@ class MemberService(
return BookmarkStationDto.Response(bookmarkStationIds)
}

private fun saveNewStations(member: MemberEntity, bookmarkStations: List<String>): List<Long> {
private fun saveNewStations(member: MemberEntity, bookmarkStations: List<BookmarkStationCommand>): List<Long> {
return bookmarkStations
.map { stationReader.getByName(it) }
.map { station ->
.map {
val memberStation = MemberStationEntity(
member = member,
station = station
member = member,
station = stationReader.getByName(it.stationName),
label = it.label
)
memberStationWriter.save(memberStation).id
}
Expand All @@ -86,9 +87,10 @@ class MemberService(
.map {
val station = it.station
GetBookmarkStationDto.StationInfo(
stationId = station.id,
stationName = station.name,
subwayLineInfoList = getSubwayLineInfos(station)
stationId = station.id,
stationName = station.name,
label = it.label,
subwayLineInfoList = getSubwayLineInfos(station)
)
}

Expand All @@ -106,12 +108,12 @@ class MemberService(
return SearchMemberDto.Response.of(members)
}

private fun getSubwayLineInfos(station: StationEntity): List<GetBookmarkStationDto.SubwayLineInfo>{
private fun getSubwayLineInfos(station: StationEntity): List<GetBookmarkStationDto.SubwayLineInfo> {
val subwayLineStations = subwayLineStationReader.findByStation(station)
return subwayLineStations.map {
GetBookmarkStationDto.SubwayLineInfo(
subwayLineId = it.subwayLine.id,
subwayLineName = it.subwayLine.name
subwayLineId = it.subwayLine.id,
subwayLineName = it.subwayLine.name
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package backend.team.ahachul_backend.api.member.adapter.web.`in`

import backend.team.ahachul_backend.api.member.adapter.web.`in`.dto.*
import backend.team.ahachul_backend.api.member.adapter.web.`in`.dto.BookmarkStationDto.BookmarkStation
import backend.team.ahachul_backend.api.member.application.port.`in`.MemberUseCase
import backend.team.ahachul_backend.api.member.domain.model.GenderType
import backend.team.ahachul_backend.config.controller.CommonDocsTestConfig
Expand Down Expand Up @@ -169,7 +170,11 @@ class MemberControllerDocsTest : CommonDocsTestConfig() {
given(memberUseCase.bookmarkStation(any()))
.willReturn(response)

val request = BookmarkStationDto.Request(listOf("발산역", "우장산역", "화곡역"))
val request = BookmarkStationDto.Request(listOf(
BookmarkStation("발산역", "집"),
BookmarkStation("우장산역", "학교"),
BookmarkStation("화곡역", "즐겨찾는 장소"),
))

// when
val result = mockMvc.perform(
Expand All @@ -187,7 +192,9 @@ class MemberControllerDocsTest : CommonDocsTestConfig() {
getDocsRequest(),
getDocsResponse(),
requestFields(
fieldWithPath("stationNames").type(JsonFieldType.ARRAY).description("즐겨찾는 역 이름 리스트"),
fieldWithPath("stations").type(JsonFieldType.ARRAY).description("즐겨찾는 역 이름 및 별명 리스트"),
fieldWithPath("stations[].stationName").type(JsonFieldType.STRING).description("즐겨찾는 역 이름"),
fieldWithPath("stations[].label").type(JsonFieldType.STRING).description("즐겨찾는 역 별명").optional(),
),
responseFields(
*commonResponseFields(),
Expand All @@ -205,6 +212,7 @@ class MemberControllerDocsTest : CommonDocsTestConfig() {
GetBookmarkStationDto.StationInfo(
stationId = 1L,
stationName = "시청역",
label = "집",
subwayLineInfoList = listOf(
GetBookmarkStationDto.SubwayLineInfo(
subwayLineId = 1L,
Expand Down Expand Up @@ -236,6 +244,7 @@ class MemberControllerDocsTest : CommonDocsTestConfig() {
fieldWithPath("result.stationInfoList").type(JsonFieldType.ARRAY).description("즐겨찾기 한 역 정보 리스트"),
fieldWithPath("result.stationInfoList[].stationId").type(JsonFieldType.NUMBER).description("역 고유 ID"),
fieldWithPath("result.stationInfoList[].stationName").type(JsonFieldType.STRING).description("역 이름"),
fieldWithPath("result.stationInfoList[].label").type(JsonFieldType.STRING).description("역 별명").optional(),
fieldWithPath("result.stationInfoList[].subwayLineInfoList").type(JsonFieldType.ARRAY).description("해당 역이 존재하는 노선 리스트"),
fieldWithPath("result.stationInfoList[].subwayLineInfoList[].subwayLineId").type(JsonFieldType.NUMBER).description("노선 고유 ID"),
fieldWithPath("result.stationInfoList[].subwayLineInfoList[].subwayLineName").type(JsonFieldType.STRING).description("노선 이름"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import backend.team.ahachul_backend.api.common.domain.entity.StationEntity
import backend.team.ahachul_backend.api.common.domain.entity.SubwayLineStationEntity
import backend.team.ahachul_backend.api.member.adapter.web.out.MemberRepository
import backend.team.ahachul_backend.api.member.adapter.web.out.MemberStationRepository
import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommand
import backend.team.ahachul_backend.api.member.application.command.SearchMemberCommand
import backend.team.ahachul_backend.api.member.application.port.`in`.MemberUseCase
import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommand
import backend.team.ahachul_backend.api.member.application.command.BookmarkStationCommands
import backend.team.ahachul_backend.api.member.application.port.`in`.command.CheckNicknameCommand
import backend.team.ahachul_backend.api.member.application.port.`in`.command.UpdateMemberCommand
import backend.team.ahachul_backend.api.member.application.port.out.MemberWriter
Expand All @@ -24,8 +25,7 @@ import backend.team.ahachul_backend.common.persistence.SubwayLineRepository
import backend.team.ahachul_backend.common.response.ResponseCode
import backend.team.ahachul_backend.common.utils.RequestUtils
import backend.team.ahachul_backend.config.controller.CommonServiceTestConfig
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.assertj.core.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
Expand Down Expand Up @@ -159,8 +159,12 @@ class MemberServiceTest(
)
stations.forEach { stationRepository.save(it) }

val command = BookmarkStationCommand(
stationNames = mutableListOf("시청역", "발산역", "강남역")
val command = BookmarkStationCommands(
stations = listOf(
BookmarkStationCommand("시청역", ""),
BookmarkStationCommand("발산역", "집"),
BookmarkStationCommand("강남역", "회사"),
)
)

// when
Expand Down Expand Up @@ -188,20 +192,23 @@ class MemberServiceTest(
memberStationRepository.save(
MemberStationEntity(
member = member!!,
station = it
station = it,
label = ""
)
)
}

val command = BookmarkStationCommand(
stationNames = mutableListOf("발산역", "우장산역")
val command = BookmarkStationCommands(
stations = listOf(
BookmarkStationCommand("시청역", "집"),
)
)

// when
val result = memberUseCase.bookmarkStation(command)

// then
assertThat(result.memberStationIds.size).isEqualTo(2) // new bookmark
assertThat(result.memberStationIds.size).isEqualTo(1) // new bookmark
}

@Test
Expand All @@ -222,33 +229,50 @@ class MemberServiceTest(
memberStationRepository.save(
MemberStationEntity(
member = member!!,
station = it
station = it,
label = ""
)
)
}

val command = BookmarkStationCommand(
stationNames = mutableListOf("발산역", "시청역", "강남역")
val command = BookmarkStationCommands(
stations = listOf(
BookmarkStationCommand("시청역", "회사"),
BookmarkStationCommand("강남역", "집"),
BookmarkStationCommand("우장산역", "즐겨찾는 장소"),
BookmarkStationCommand("발산역", "학교"),
)
)

// when
memberUseCase.bookmarkStation(command)

// then
val result = memberUseCase.getBookmarkStation()
assertThat(result.stationInfoList.size).isEqualTo(3)
assertThat(result.stationInfoList[0].stationName).isEqualTo("발산역")
assertThat(result.stationInfoList[1].stationName).isEqualTo("시청역")
assertThat(result.stationInfoList[2].stationName).isEqualTo("강남역")
assertThat(result.stationInfoList.size).isEqualTo(4)

assertThat(result.stationInfoList)
.extracting("stationName", "label")
.containsExactly(
tuple("시청역", "회사"),
tuple("강남역", "집"),
tuple("우장산역", "즐겨찾는 장소"),
tuple("발산역", "학교"),
)
}

@Test
fun 즐겨찾는_역이_3개_이상이면_실패() {
// given
fun 즐겨찾는_역이_4개_보다_크면_실패() {
// when + then
assertThatThrownBy {
BookmarkStationCommand(
stationNames = mutableListOf("시청역", "발산역", "강남역", "구로역")
BookmarkStationCommands(
stations = listOf(
BookmarkStationCommand("시청역", "회사"),
BookmarkStationCommand("강남역", "집"),
BookmarkStationCommand("우장산역", "즐겨찾는 장소"),
BookmarkStationCommand("발산역", "학교"),
BookmarkStationCommand("양재역", ""),
)
)
}
.isExactlyInstanceOf(BusinessException::class.java)
Expand All @@ -270,7 +294,8 @@ class MemberServiceTest(
memberStationRepository.save(
MemberStationEntity(
member = member!!,
station = stationEntity
station = stationEntity,
label = ""
)
)
subwayLineStationRepository.save(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
package backend.team.ahachul_backend.api.member.application.command

import backend.team.ahachul_backend.common.exception.BusinessException
import backend.team.ahachul_backend.common.response.ResponseCode

data class BookmarkStationCommand(
val stationNames: MutableList<String>
) {
init {
if (stationNames.size > MAX_STATION_COUNT) {
throw BusinessException(ResponseCode.EXCEED_MAXIMUM_STATION_COUNT)
}
}

companion object {
const val MAX_STATION_COUNT = 3
}
}
val stationName: String,
val label: String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package backend.team.ahachul_backend.api.member.application.command

import backend.team.ahachul_backend.common.exception.BusinessException
import backend.team.ahachul_backend.common.response.ResponseCode

data class BookmarkStationCommands(
val stations: List<BookmarkStationCommand>
) {
init {
if (stations.size > MAX_STATION_COUNT) {
throw BusinessException(ResponseCode.EXCEED_MAXIMUM_STATION_COUNT)
}
}

companion object {
const val MAX_STATION_COUNT = 4
}
Comment on lines +15 to +17
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최대 가능 개수를 4로 확장하였습니다.

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class MemberStationEntity(
@Column(name = "member_station_id")
val id: Long = 0,

var label: String?,

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
val member: MemberEntity,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE tb_member_station
ADD COLUMN label VARCHAR(100) NULL AFTER member_station_id;
Comment on lines +1 to +2
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

즐겨찾기 역 라벨 컬럼을 추가하였습니다.

Loading