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

건물 등록에 층 정보, 계단 높이, 출입구 유형 추가하기 #249

Merged
Show file tree
Hide file tree
Changes from all commits
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
16 changes: 16 additions & 0 deletions app-server/subprojects/api_specification/api/scc-api/api-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -799,16 +799,24 @@ components:
type: string
entranceStairInfo:
$ref: '#/components/schemas/StairInfo'
entranceStairHeightLevel:
$ref: '#/components/schemas/StairHeightLevel'
entranceImageUrls:
type: array
items:
type: string
entranceDoorTypes:
type: array
items:
$ref: '#/components/schemas/EntranceDoorType'
hasSlope:
type: boolean
hasElevator:
type: boolean
elevatorStairInfo:
$ref: '#/components/schemas/StairInfo'
elevatorStairHeightLevel:
$ref: '#/components/schemas/StairHeightLevel'
elevatorImageUrls:
type: array
items:
Expand Down Expand Up @@ -1340,16 +1348,24 @@ components:
type: string
entranceStairInfo:
$ref: '#/components/schemas/StairInfo'
entranceStairHeightLevel:
$ref: '#/components/schemas/StairHeightLevel'
entranceImageUrls:
type: array
items:
type: string
entranceDoorTypes:
type: array
items:
$ref: '#/components/schemas/EntranceDoorType'
hasSlope:
type: boolean
hasElevator:
type: boolean
elevatorStairInfo:
$ref: '#/components/schemas/StairInfo'
elevatorStairHeightLevel:
$ref: '#/components/schemas/StairHeightLevel'
elevatorImageUrls:
type: array
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ class AccessibilityApplicationService(
createBuildingAccessibilityParams: BuildingAccessibilityRepository.CreateParams,
createBuildingAccessibilityCommentParams: BuildingAccessibilityCommentRepository.CreateParams?,
): RegisterBuildingAccessibilityResult {
if (createBuildingAccessibilityParams.isValid().not()) {
throw SccDomainException("잘못된 접근성 정보입니다. 필수 입력을 빠트렸거나 조건을 다시 한 번 확인해주세요.", SccDomainException.ErrorCode.INVALID_ARGUMENTS)
}
val buildingId = createBuildingAccessibilityParams.buildingId
if (buildingAccessibilityRepository.findByBuildingId(buildingId) != null) {
throw SccDomainException("이미 접근성 정보가 등록된 건물입니다.")
Expand All @@ -194,10 +197,13 @@ class AccessibilityApplicationService(
id = EntityIdGenerator.generateRandom(),
buildingId = it.buildingId,
entranceStairInfo = it.entranceStairInfo,
entranceStairHeightLevel = it.entranceStairHeightLevel,
entranceImageUrls = it.entranceImageUrls,
hasSlope = it.hasSlope,
hasElevator = it.hasElevator,
entranceDoorTypes = it.entranceDoorTypes,
elevatorStairInfo = it.elevatorStairInfo,
elevatorStairHeightLevel = it.elevatorStairHeightLevel,
elevatorImageUrls = it.elevatorImageUrls,
userId = it.userId,
createdAt = clock.instant(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package club.staircrusher.accessibility.application.port.out.persistence

import club.staircrusher.accessibility.domain.model.BuildingAccessibility
import club.staircrusher.accessibility.domain.model.EntranceDoorType
import club.staircrusher.accessibility.domain.model.StairHeightLevel
import club.staircrusher.accessibility.domain.model.StairInfo
import club.staircrusher.stdlib.domain.repository.EntityRepository
import club.staircrusher.stdlib.geography.EupMyeonDong
Expand All @@ -12,14 +14,25 @@ interface BuildingAccessibilityRepository : EntityRepository<BuildingAccessibili
fun findByEupMyeonDong(eupMyeonDong: EupMyeonDong): List<BuildingAccessibility>
fun countByUserId(userId: String): Int
fun remove(id: String)

data class CreateParams(
val buildingId: String,
val entranceStairInfo: StairInfo,
val entranceStairHeightLevel: StairHeightLevel?,
val entranceImageUrls: List<String>,
val hasSlope: Boolean,
val hasElevator: Boolean,
val entranceDoorTypes: List<EntranceDoorType>?,
val elevatorStairInfo: StairInfo,
val elevatorStairHeightLevel: StairHeightLevel?,
val elevatorImageUrls: List<String>,
val userId: String?,
)
) {
fun isValid(): Boolean {
// 0401 버전에서 추가된 항목이 모두 있거나 모두 없거나
val isInputValid = listOf(entranceStairHeightLevel, entranceDoorTypes, elevatorStairHeightLevel).all { it == null } || listOf(entranceStairHeightLevel, entranceDoorTypes, elevatorStairHeightLevel).all { it != null }
val isDoorTypesInvalid = entranceDoorTypes?.isEmpty() == true || entranceDoorTypes?.let { it.contains(EntranceDoorType.None) && it.count() > 1 } ?: false
return isInputValid && isDoorTypesInvalid.not()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ data class BuildingAccessibility(
val id: String,
val buildingId: String,
val entranceStairInfo: StairInfo,
val entranceStairHeightLevel: StairHeightLevel?,
val entranceImageUrls: List<String>,
val hasSlope: Boolean,
val hasElevator: Boolean,
val entranceDoorTypes: List<EntranceDoorType>?,
val elevatorStairInfo: StairInfo,
val elevatorStairHeightLevel: StairHeightLevel?,
val elevatorImageUrls: List<String>,
val userId: String?,
val createdAt: Instant,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,27 @@ package club.staircrusher.accesssibility.infra.adapter.`in`.controller

import club.staircrusher.accessibility.application.port.out.persistence.BuildingAccessibilityRepository
import club.staircrusher.accessibility.application.port.out.persistence.BuildingAccessibilityUpvoteRepository
import club.staircrusher.accessibility.domain.model.EntranceDoorType
import club.staircrusher.accessibility.domain.model.StairHeightLevel
import club.staircrusher.accessibility.domain.model.StairInfo
import club.staircrusher.accessibility.infra.adapter.`in`.controller.toDTO
import club.staircrusher.accessibility.infra.adapter.`in`.controller.toModel
import club.staircrusher.accesssibility.infra.adapter.`in`.controller.base.AccessibilityITBase
import club.staircrusher.api.spec.dto.AccessibilityInfoDto
import club.staircrusher.api.spec.dto.GetAccessibilityPostRequest
import club.staircrusher.api.spec.dto.RegisterBuildingAccessibilityRequestDto
import club.staircrusher.place.domain.model.Building
import club.staircrusher.place.domain.model.BuildingAddress
import org.junit.jupiter.api.Assertions.assertArrayEquals
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired

class RegisterBuildingAccessibilityTest : AccessibilityITBase() {
@Autowired
private lateinit var buildingAccessibilityRepository: BuildingAccessibilityRepository

@Autowired
private lateinit var buildingAccessibilityUpvoteRepository: BuildingAccessibilityUpvoteRepository

Expand All @@ -31,7 +33,7 @@ class RegisterBuildingAccessibilityTest : AccessibilityITBase() {
}

@Test
fun testRegisterBuildingAccessibility() {
fun `정상적으로 등록된다`() {
repeat(3) { idx ->
val expectedRegisteredUserOrder = idx + 1
val user = transactionManager.doInTransaction {
Expand All @@ -49,15 +51,18 @@ class RegisterBuildingAccessibilityTest : AccessibilityITBase() {
val result = getResult(AccessibilityInfoDto::class)
val buildingAccessibility = result.buildingAccessibility!!
assertEquals(place.building.id, buildingAccessibility.buildingId)
assertEquals(StairInfo.NONE, buildingAccessibility.entranceStairInfo.toModel())
assertEquals(1, buildingAccessibility.entranceImageUrls.size)
assertEquals("buildingAccessibilityEntranceImage", buildingAccessibility.entranceImageUrls[0])
assertTrue(buildingAccessibility.hasSlope)
assertTrue(buildingAccessibility.hasElevator)
assertEquals(StairInfo.TWO_TO_FIVE, buildingAccessibility.elevatorStairInfo.toModel())
assertEquals(params.entranceStairInfo, buildingAccessibility.entranceStairInfo)
assertEquals(params.entranceStairHeightLevel, buildingAccessibility.entranceStairHeightLevel)
assertEquals(params.entranceImageUrls.size, buildingAccessibility.entranceImageUrls.size)
assertEquals(params.entranceImageUrls[0], buildingAccessibility.entranceImageUrls[0])
assertEquals(params.hasSlope, buildingAccessibility.hasSlope)
assertEquals(params.hasElevator, buildingAccessibility.hasElevator)
assertArrayEquals(params.entranceDoorTypes?.toTypedArray(), buildingAccessibility.entranceDoorTypes?.toTypedArray())
assertEquals(params.elevatorStairInfo, buildingAccessibility.elevatorStairInfo)
assertEquals(params.elevatorStairHeightLevel, buildingAccessibility.elevatorStairHeightLevel)
assertEquals(2, buildingAccessibility.elevatorImageUrls.size)
assertEquals("buildingAccessibilityElevatorImage1", buildingAccessibility.elevatorImageUrls[0])
assertEquals("buildingAccessibilityElevatorImage2", buildingAccessibility.elevatorImageUrls[1])
assertEquals(params.elevatorImageUrls[0], buildingAccessibility.elevatorImageUrls[0])
assertEquals(params.elevatorImageUrls[1], buildingAccessibility.elevatorImageUrls[1])
assertFalse(buildingAccessibility.isUpvoted)
assertEquals(0, buildingAccessibility.totalUpvoteCount)

Expand All @@ -69,6 +74,45 @@ class RegisterBuildingAccessibilityTest : AccessibilityITBase() {
}
}

@Test
fun `240401 이전 버전에서도 정상적으로 등록된다`() {
val user = transactionManager.doInTransaction {
testDataGenerator.createUser()
}
val place = transactionManager.doInTransaction {
testDataGenerator.createBuildingAndPlace(placeName = "장소장소")
}
val params = getDefaultRequestParamsBefore2404(place.building)
mvc.sccRequest("/registerBuildingAccessibility", params, user = user)
mvc
.sccRequest("/getAccessibility", GetAccessibilityPostRequest(place.id), user = user)
.apply {
val result = getResult(AccessibilityInfoDto::class)
val buildingAccessibility = result.buildingAccessibility!!
assertEquals(place.building.id, buildingAccessibility.buildingId)
assertEquals(params.entranceStairInfo, buildingAccessibility.entranceStairInfo)
assertEquals(params.entranceStairHeightLevel, null)
assertEquals(params.entranceImageUrls.size, buildingAccessibility.entranceImageUrls.size)
assertEquals(params.entranceImageUrls[0], buildingAccessibility.entranceImageUrls[0])
assertEquals(params.hasSlope, buildingAccessibility.hasSlope)
assertEquals(params.hasElevator, buildingAccessibility.hasElevator)
assertEquals(params.entranceDoorTypes, null)
assertEquals(params.elevatorStairInfo, buildingAccessibility.elevatorStairInfo)
assertEquals(params.elevatorStairHeightLevel, null)
assertEquals(2, buildingAccessibility.elevatorImageUrls.size)
assertEquals(params.elevatorImageUrls[0], buildingAccessibility.elevatorImageUrls[0])
assertEquals(params.elevatorImageUrls[1], buildingAccessibility.elevatorImageUrls[1])
assertFalse(buildingAccessibility.isUpvoted)
assertEquals(0, buildingAccessibility.totalUpvoteCount)

assertEquals(1, result.buildingAccessibilityComments.size)
assertEquals(place.building.id, result.buildingAccessibilityComments[0].buildingId)
assertEquals(user.id, result.buildingAccessibilityComments[0].user!!.id)
assertEquals("건물 코멘트", result.buildingAccessibilityComments[0].comment)
}
}


@Test
fun `클라이언트에서 올려준 정보의 정합성이 맞지 않는 경우 에러가 난다`() {
val user = transactionManager.doInTransaction {
Expand Down Expand Up @@ -144,19 +188,57 @@ class RegisterBuildingAccessibilityTest : AccessibilityITBase() {
}
}

private fun getDefaultRequestParams(building: Building): RegisterBuildingAccessibilityRequestDto {
private fun getDefaultRequestParams(
building: Building,
entranceStairInfo: StairInfo = StairInfo.ONE,
entranceStairHeightLevel: StairHeightLevel = StairHeightLevel.HALF_THUMB,
hasSlope: Boolean = true,
hasElevator: Boolean = true,
elevatorStairInfo: StairInfo = StairInfo.TWO_TO_FIVE,
elevatorStairHeightLevel: StairHeightLevel = StairHeightLevel.OVER_THUMB,
entranceDoorTypes: List<EntranceDoorType> = listOf(EntranceDoorType.Sliding, EntranceDoorType.Automatic)
): RegisterBuildingAccessibilityRequestDto {
return RegisterBuildingAccessibilityRequestDto(
buildingId = building.id,
entranceStairInfo = StairInfo.NONE.toDTO(),
entranceStairInfo = entranceStairInfo.toDTO(),
entranceStairHeightLevel = entranceStairHeightLevel.toDTO(),
entranceImageUrls = listOf("buildingAccessibilityEntranceImage"),
hasSlope = true,
hasElevator = true,
elevatorStairInfo = StairInfo.TWO_TO_FIVE.toDTO(),
hasSlope = hasSlope,
hasElevator = hasElevator,
entranceDoorTypes = entranceDoorTypes.map { it.toDTO() },
elevatorStairInfo = elevatorStairInfo.toDTO(),
elevatorStairHeightLevel = elevatorStairHeightLevel.toDTO(),
elevatorImageUrls = listOf(
"buildingAccessibilityElevatorImage1",
"buildingAccessibilityElevatorImage2",
),
comment = "건물 코멘트",
)
}

private fun getDefaultRequestParamsBefore2404(
building: Building,
entranceStairInfo: StairInfo = StairInfo.ONE,
hasSlope: Boolean = true,
hasElevator: Boolean = true,
elevatorStairInfo: StairInfo = StairInfo.TWO_TO_FIVE,
): RegisterBuildingAccessibilityRequestDto {
return RegisterBuildingAccessibilityRequestDto(
buildingId = building.id,
entranceStairInfo = entranceStairInfo.toDTO(),
entranceStairHeightLevel = null,
entranceImageUrls = listOf("buildingAccessibilityEntranceImage"),
entranceDoorTypes = null,
hasSlope = hasSlope,
hasElevator = hasElevator,
elevatorStairInfo = elevatorStairInfo.toDTO(),
elevatorStairHeightLevel = null,
elevatorImageUrls = listOf(
"buildingAccessibilityElevatorImage1",
"buildingAccessibilityElevatorImage2",
),
comment = "건물 코멘트",
)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ fun BuildingAccessibility.toDTO(
) = club.staircrusher.api.spec.dto.BuildingAccessibility(
id = id,
entranceStairInfo = entranceStairInfo.toDTO(),
entranceStairHeightLevel = entranceStairHeightLevel?.toDTO(),
entranceImageUrls = entranceImageUrls,
hasSlope = hasSlope,
hasElevator = hasElevator,
entranceDoorTypes = entranceDoorTypes?.map { it.toDTO() },
elevatorStairInfo = elevatorStairInfo.toDTO(),
elevatorStairHeightLevel = elevatorStairHeightLevel?.toDTO(),
elevatorImageUrls = elevatorImageUrls,
buildingId = buildingId,
isUpvoted = isUpvoted,
Expand Down Expand Up @@ -76,10 +79,13 @@ fun RegisterBuildingAccessibilityRequestDto.toModel(userId: String?) =
BuildingAccessibilityRepository.CreateParams(
buildingId = buildingId,
entranceStairInfo = entranceStairInfo.toModel(),
entranceStairHeightLevel = entranceStairHeightLevel?.toModel(),
entranceImageUrls = entranceImageUrls,
hasSlope = hasSlope,
hasElevator = hasElevator,
entranceDoorTypes = entranceDoorTypes?.map { it.toModel() },
elevatorStairInfo = elevatorStairInfo.toModel(),
elevatorStairHeightLevel = elevatorStairHeightLevel?.toModel(),
elevatorImageUrls = elevatorImageUrls,
userId = userId,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ fun Building_accessibility.toDomainModel() = BuildingAccessibility(
id = id,
buildingId = building_id,
entranceStairInfo = StairInfo.valueOf(entrance_stair_info),
entranceStairHeightLevel = entrance_stair_height_level,
entranceImageUrls = entrance_image_urls,
hasSlope = has_slope,
hasElevator = has_elevator,
entranceDoorTypes = entrance_door_types,
elevatorStairInfo = StairInfo.valueOf(elevator_stair_info),
elevatorStairHeightLevel = elevator_stair_height_level,
elevatorImageUrls = elevator_image_urls,
userId = user_id,
createdAt = created_at.toInstant(),
Expand All @@ -39,10 +42,13 @@ fun BuildingAccessibility.toPersistenceModel() = Building_accessibility(
id = id,
building_id = buildingId,
entrance_stair_info = entranceStairInfo.name,
entrance_stair_height_level = entranceStairHeightLevel,
entrance_image_urls = entranceImageUrls,
has_slope = hasSlope,
has_elevator = hasElevator,
entrance_door_types = entranceDoorTypes ?: emptyList(),
elevator_stair_info = elevatorStairInfo.name,
elevator_stair_height_level = elevatorStairHeightLevel,
elevator_image_urls = elevatorImageUrls,
user_id = userId,
created_at = createdAt.toOffsetDateTime(),
Expand Down Expand Up @@ -74,10 +80,13 @@ fun BuildingAccessibilityUpvoteFindById.toDomainModel(): BuildingAccessibilityUp
id = id_,
buildingId = building_id,
entranceStairInfo = StairInfo.valueOf(entrance_stair_info),
entranceStairHeightLevel = entrance_stair_height_level,
entranceImageUrls = entrance_image_urls,
hasSlope = has_slope,
hasElevator = has_elevator,
entranceDoorTypes = entrance_door_types,
elevatorStairInfo = StairInfo.valueOf(elevator_stair_info),
elevatorStairHeightLevel = elevator_stair_height_level,
elevatorImageUrls = elevator_image_urls,
userId = user_id_,
createdAt = created_at_.toInstant(),
Expand All @@ -96,10 +105,13 @@ fun FindByUserAndBuildingAccessibilityAndNotDeleted.toDomainModel(): BuildingAcc
id = id_,
buildingId = building_id,
entranceStairInfo = StairInfo.valueOf(entrance_stair_info),
entranceStairHeightLevel = entrance_stair_height_level,
entranceImageUrls = entrance_image_urls,
hasSlope = has_slope,
hasElevator = has_elevator,
entranceDoorTypes = entrance_door_types,
elevatorStairInfo = StairInfo.valueOf(elevator_stair_info),
elevatorStairHeightLevel = elevator_stair_height_level,
elevatorImageUrls = elevator_image_urls,
userId = user_id_,
createdAt = created_at_.toInstant(),
Expand Down
Loading
Loading