Skip to content

Commit

Permalink
Merge branch 'main' into feature/249-check-holiday-creation-period
Browse files Browse the repository at this point in the history
  • Loading branch information
khcho0125 authored Dec 22, 2022
2 parents d515693 + 2c3edfe commit f8c6085
Show file tree
Hide file tree
Showing 11 changed files with 480 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package team.comit.simtong.domain.holiday.dto

import team.comit.simtong.domain.holiday.model.HolidayType
import java.time.LocalDate
import java.util.UUID

/**
*
* 지점 직원의 휴무일을 반환하는 QueryEmployeeHolidayResponse
*
* @author kimbeomjin
* @date 2022/12/22
* @version 1.0.0
**/
data class QueryEmployeeHolidayResponse(
val holidays: List<Holiday>
) {

/**
*
* 지점 직원의 휴무일 정보를 반환하는 Holiday
*
* @author kimbeomjin
* @date 2022/12/22
* @version 1.0.0
**/
data class Holiday(
val date: LocalDate,
val type: HolidayType,
val user: Employee
) {

/**
*
* 지점 직원 정보를 반환하는 Employee
*
* @author kimbeomjin
* @date 2022/12/22
* @version 1.0.0
**/
data class Employee(
val id: UUID,
val name: String,
val team: String,
val spot: String
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package team.comit.simtong.domain.holiday.usecase

import team.comit.simtong.domain.holiday.dto.QueryEmployeeHolidayResponse
import team.comit.simtong.domain.holiday.model.HolidayQueryType
import team.comit.simtong.domain.holiday.model.HolidayType
import team.comit.simtong.domain.holiday.spi.HolidayQueryUserPort
import team.comit.simtong.domain.holiday.spi.HolidaySecurityPort
import team.comit.simtong.domain.holiday.spi.QueryHolidayPort
import team.comit.simtong.domain.user.exception.UserExceptions
import team.comit.simtong.global.annotation.ReadOnlyUseCase
import java.util.UUID

/**
*
* 해당하는 지점 직원의 휴무일을 확인하는 QueryEmployeeHolidayUseCase
*
* ALL / HOLIDAY / ANNUAL 로 구분해서 필터링
* teamId를 이용해 파트별로 구분 가능 (null이면 전체)
* HolidayStatus가 WRITTEN 상태인 것만 조회
*
* @author kimbeomjin
* @date 2022/12/22
* @version 1.0.0
**/
@ReadOnlyUseCase
class QueryEmployeeHolidayUseCase(
private val queryHolidayPort: QueryHolidayPort,
private val securityPort: HolidaySecurityPort,
private val queryUserPort: HolidayQueryUserPort
) {

fun execute(year: Int, month: Int, typeName: String, teamId: UUID?): QueryEmployeeHolidayResponse {
val currentUserId = securityPort.getCurrentUserId()
val user = queryUserPort.queryUserById(currentUserId) ?: throw UserExceptions.NotFound()

val holidays = when (HolidayQueryType.valueOf(typeName)) {
HolidayQueryType.HOLIDAY -> queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(
year = year, month = month,
type = HolidayType.HOLIDAY,
spotId = user.spotId,
teamId = teamId
)

HolidayQueryType.ANNUAL -> queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(
year = year, month = month,
type = HolidayType.ANNUAL,
spotId = user.spotId,
teamId = teamId
)

HolidayQueryType.ALL -> queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(
year = year, month = month,
type = null,
spotId = user.spotId,
teamId = teamId
)
}

val response = holidays.map {
QueryEmployeeHolidayResponse.Holiday(
date = it.date,
type = it.type,
user = QueryEmployeeHolidayResponse.Holiday.Employee(
id = it.userId,
name = it.userName,
team = it.teamName,
spot = it.spotName
)
)
}

return QueryEmployeeHolidayResponse(response)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package team.comit.simtong.domain.holiday.usecase

import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertDoesNotThrow
import org.junit.jupiter.api.assertThrows
import org.mockito.kotlin.given
import org.springframework.boot.test.mock.mockito.MockBean
import team.comit.simtong.domain.holiday.model.HolidayType
import team.comit.simtong.domain.holiday.spi.HolidayQueryUserPort
import team.comit.simtong.domain.holiday.spi.HolidaySecurityPort
import team.comit.simtong.domain.holiday.spi.QueryHolidayPort
import team.comit.simtong.domain.holiday.spi.vo.EmployeeHoliday
import team.comit.simtong.domain.user.exception.UserExceptions
import team.comit.simtong.domain.user.model.Authority
import team.comit.simtong.domain.user.model.User
import team.comit.simtong.global.annotation.SimtongTest
import java.time.LocalDate
import java.util.UUID

@SimtongTest
class QueryEmployeeHolidayUseCaseTests {

@MockBean
private lateinit var queryHolidayPort: QueryHolidayPort

@MockBean
private lateinit var securityPort: HolidaySecurityPort

@MockBean
private lateinit var queryUserPort: HolidayQueryUserPort

private lateinit var queryEmployeeHolidayUseCase: QueryEmployeeHolidayUseCase

private val userId = UUID.randomUUID()
private val spotId = UUID.randomUUID()
private val year = 2022
private val month = 12
private val teamId = UUID.randomUUID()

private val userStub by lazy {
User(
id = userId,
nickname = "test nickname",
name = "test name",
email = "[email protected]",
password = "test password",
employeeNumber = 1234567890,
authority = Authority.ROLE_COMMON,
spotId = spotId,
teamId = UUID.randomUUID(),
profileImagePath = User.DEFAULT_IMAGE
)
}

@BeforeEach
fun setUp() {
queryEmployeeHolidayUseCase = QueryEmployeeHolidayUseCase(
queryHolidayPort, securityPort, queryUserPort
)
}

@Test
fun `지점 직원 휴무일 조회 성공`() {
// given
given(securityPort.getCurrentUserId())
.willReturn(userId)

given(queryUserPort.queryUserById(userId))
.willReturn(userStub)

given(queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(year, month, HolidayType.HOLIDAY, spotId, teamId))
.willReturn(
listOf(
EmployeeHoliday(
date = LocalDate.of(year, month, 1),
userId = userId,
type = HolidayType.HOLIDAY,
userName = "test name",
teamName = "test team",
spotName = "test spot",
)
)
)

// when & then
assertDoesNotThrow {
queryEmployeeHolidayUseCase.execute(year, month, "HOLIDAY", teamId)
}
}

@Test
fun `지점 직원 연차 조회 성공`() {
// given
given(securityPort.getCurrentUserId())
.willReturn(userId)

given(queryUserPort.queryUserById(userId))
.willReturn(userStub)

given(queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(year, month, HolidayType.ANNUAL, spotId, teamId))
.willReturn(
listOf(
EmployeeHoliday(
date = LocalDate.of(year, month, 1),
userId = userId,
type = HolidayType.ANNUAL,
userName = "test name",
teamName = "test team",
spotName = "test spot",
)
)
)

// when & then
assertDoesNotThrow {
queryEmployeeHolidayUseCase.execute(year, month, "ANNUAL", teamId)
}
}

@Test
fun `지점 직원 휴무일 & 연차 조회 성공`() {
// given
given(securityPort.getCurrentUserId())
.willReturn(userId)

given(queryUserPort.queryUserById(userId))
.willReturn(userStub)

given(queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(year, month, null, spotId, teamId))
.willReturn(
listOf(
EmployeeHoliday(
date = LocalDate.of(year, month, 1),
userId = userId,
type = HolidayType.ANNUAL,
userName = "test name",
teamName = "test team",
spotName = "test spot",
)
)
)

// when & then
assertDoesNotThrow {
queryEmployeeHolidayUseCase.execute(year, month, "ALL", teamId)
}
}

@Test
fun `유저를 찾을 수 없음`() {
// given
given(securityPort.getCurrentUserId())
.willReturn(userId)

given(queryUserPort.queryUserById(userId))
.willReturn(null)

// when & then
assertThrows<UserExceptions.NotFound> {
queryEmployeeHolidayUseCase.execute(2022, 12, "HOLIDAY", null)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package team.comit.simtong.domain.holiday.model

/**
*
* 연차 및 휴무일을 필터링하기 위한 HolidayQueryType
*
* @author kimbeomjin
* @date 2022/12/22
* @version 1.0.0
**/
enum class HolidayQueryType {

/**
* 휴무일과 연차
*/
ALL,

/**
* 휴무일
*/
HOLIDAY,

/**
* 연차
*/
ANNUAL

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package team.comit.simtong.domain.holiday.spi
import team.comit.simtong.domain.holiday.model.Holiday
import team.comit.simtong.domain.holiday.model.HolidayStatus
import team.comit.simtong.domain.holiday.model.HolidayType
import team.comit.simtong.domain.holiday.spi.vo.EmployeeHoliday
import java.time.LocalDate
import java.util.UUID

Expand All @@ -27,6 +28,8 @@ interface QueryHolidayPort {

fun queryHolidaysByYearAndMonthAndSpotIdAndType(year: Int, month: Int, spotId: UUID, type: HolidayType) : List<Holiday>

fun queryHolidaysByYearAndMonthAndTeamId(year: Int, month: Int, type: HolidayType?, spotId: UUID, teamId: UUID?) : List<EmployeeHoliday>

fun existsHolidayByDateAndUserIdAndType(date: LocalDate, userId: UUID, type: HolidayType) : Boolean

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package team.comit.simtong.domain.holiday.spi.vo

import team.comit.simtong.domain.holiday.model.HolidayType
import java.time.LocalDate
import java.util.UUID

/**
*
* Holiday와 User 정보를 가져오는 EmployeeHoliday
*
* @author kimbeomjin
* @date 2022/12/22
* @version 1.0.0
**/
open class EmployeeHoliday(
val date: LocalDate,

val type: HolidayType,

val userId: UUID,

val userName: String,

val teamName: String,

val spotName: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class SecurityConfig(
.antMatchers(HttpMethod.PUT, "/holidays/public").hasRole(ROLE_ADMIN.role)
.antMatchers(HttpMethod.GET, "/holidays/annual/count").hasRole(ROLE_COMMON.role)
.antMatchers(HttpMethod.GET, "/holidays/verification-period").hasRole(ROLE_COMMON.role)
.antMatchers(HttpMethod.GET, "/holidays/employee").hasRole(ROLE_ADMIN.role)

// admins
.antMatchers(HttpMethod.POST, "/admins/tokens").permitAll()
Expand Down
Loading

0 comments on commit f8c6085

Please sign in to comment.