Skip to content

Commit

Permalink
merge: (#80) menu 조회
Browse files Browse the repository at this point in the history
  • Loading branch information
softpeanut authored Sep 26, 2022
2 parents 4f5bc9e + 8607989 commit 4439a44
Show file tree
Hide file tree
Showing 22 changed files with 338 additions and 8 deletions.
4 changes: 4 additions & 0 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ object Dependencies {
// transaction
const val SPRING_TRANSACTION = "org.springframework:spring-tx:${DependencyVersions.SPRING_TRANSACTION}"

// querydsl
const val QUERYDSL = "com.querydsl:querydsl-jpa:${DependencyVersions.QUERYDSL}"
const val QUERYDSL_PROCESSOR = "com.querydsl:querydsl-apt:${DependencyVersions.QUERYDSL}:jpa"

// configuration
const val CONFIGURATION_PROCESSOR = "org.springframework.boot:spring-boot-configuration-processor"

Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/DependencyVersions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ object DependencyVersions {
const val AWS_SES_VERSION = "1.12.296"
const val SPRING_TRANSACTION = "5.3.22"
const val S3MOCK = "0.2.4"

const val QUERYDSL = "5.0.0"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package team.comit.simtong.domain.auth.spi

import team.comit.simtong.domain.menu.spi.MenuSecurityPort
import team.comit.simtong.domain.user.spi.UserSecurityPort

/**
Expand All @@ -10,4 +11,4 @@ import team.comit.simtong.domain.user.spi.UserSecurityPort
* @date 2022/09/18
* @version 1.0.0
**/
interface SecurityPort : UserSecurityPort
interface SecurityPort : UserSecurityPort, MenuSecurityPort
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package team.comit.simtong.domain.menu.dto

import java.time.LocalDate

/**
*
* 메뉴를 반환하는 MenuResponse
*
* @author kimbeomjin
* @date 2022/09/26
* @version 1.0.0
**/
data class MenuResponse(
val menu: List<MenuElement>
) {
data class MenuElement(
val date: LocalDate,
val meal: String
)
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package team.comit.simtong.domain.menu.spi

/**
*
* Menu에 관한 요청을 하는 MenuPort
*
* @author kimbeomjin
* @date 2022/09/21
* @version 1.0.0
**/
interface MenuPort : QueryMenuPort {
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package team.comit.simtong.domain.menu.usecase

import team.comit.simtong.domain.menu.dto.MenuResponse
import team.comit.simtong.domain.menu.spi.MenuQueryUserPort
import team.comit.simtong.domain.menu.spi.MenuSecurityPort
import team.comit.simtong.domain.menu.spi.QueryMenuPort
import team.comit.simtong.domain.user.exception.UserNotFoundException
import team.comit.simtong.global.annotation.ReadOnlyUseCase
import java.time.LocalDate

/**
*
* Menu 조회 기능을 담당하는 QueryMenuByMonthUseCase
*
* @author kimbeomjin
* @date 2022/09/21
* @version 1.0.0
**/
@ReadOnlyUseCase
class QueryMenuByMonthUseCase(
private val queryMenuPort: QueryMenuPort,
private val queryUserPort: MenuQueryUserPort,
private val menuSecurityPort: MenuSecurityPort
) {

fun execute(today: LocalDate): MenuResponse {
val currentUserId = menuSecurityPort.getCurrentUserId()
val user = queryUserPort.queryUserById(currentUserId) ?: throw UserNotFoundException.EXCEPTION

val menu = queryMenuPort.queryMenuByMonth(today.year, today.monthValue, user.spotId)
val result = menu.map { MenuResponse.MenuElement(it.date, it.meal) }

return MenuResponse(result)
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package team.comit.simtong.domain.user.spi

import team.comit.simtong.domain.menu.spi.MenuQueryUserPort

/**
*
* User에 관한 요청하는 UserPort
Expand All @@ -8,4 +10,4 @@ package team.comit.simtong.domain.user.spi
* @date 2022/09/18
* @version 1.0.0
**/
interface UserPort : QueryUserPort, CommandUserPort
interface UserPort : QueryUserPort, CommandUserPort, MenuQueryUserPort
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package team.comit.simtong.domain.menu.usecase

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.BDDMockito.given
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.test.context.junit.jupiter.SpringExtension
import team.comit.simtong.domain.menu.model.Menu
import team.comit.simtong.domain.menu.spi.MenuQueryUserPort
import team.comit.simtong.domain.menu.spi.MenuSecurityPort
import team.comit.simtong.domain.menu.spi.QueryMenuPort
import team.comit.simtong.domain.user.exception.UserNotFoundException
import team.comit.simtong.domain.user.model.Authority
import team.comit.simtong.domain.user.model.User
import java.time.LocalDate
import java.util.*

@ExtendWith(SpringExtension::class)
class QueryMenuByMonthUseCaseTests {

@MockBean
private lateinit var queryMenuPort: QueryMenuPort

@MockBean
private lateinit var queryUserPort: MenuQueryUserPort

@MockBean
private lateinit var menuSecurityPort: MenuSecurityPort

private lateinit var queryMenuByMonthUseCase: QueryMenuByMonthUseCase

private val currentUserId = UUID.randomUUID()
private val spotId = UUID.randomUUID()
private val now = LocalDate.now()

private val userStub: User by lazy {
User(
id = currentUserId,
name = "test name",
nickname = "test nickname",
email = "test email",
password = "test encode password",
employeeNumber = 1234567891,
authority = Authority.ROLE_COMMON,
spotId = spotId,
teamId = UUID.randomUUID(),
profileImagePath = "test profileImagePath"
)
}

private val menuStub: Menu by lazy {
Menu(
date = LocalDate.of(2022, 9, 1),
meal = "오늘 아침은 아침밥",
spotId = UUID.randomUUID()
)
}

private val menuStub2: Menu by lazy {
Menu(
date = LocalDate.of(2022, 9, 30),
meal = "오늘 점심은 점심밥",
spotId = UUID.randomUUID()
)
}

@BeforeEach
fun setUp() {
queryMenuByMonthUseCase = QueryMenuByMonthUseCase(queryMenuPort, queryUserPort, menuSecurityPort)
}

@Test
fun `메뉴 조회 성공`() {
// given
given(menuSecurityPort.getCurrentUserId())
.willReturn(currentUserId)

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

given(queryMenuPort.queryMenuByMonth(now.year, now.monthValue, userStub.spotId))
.willReturn(
listOf(menuStub, menuStub2)
)

// when
val response = queryMenuByMonthUseCase.execute(now)

// then
assertThat(response).isNotNull
}

@Test
fun `유저가 존재하지 않음`() {
// given
given(menuSecurityPort.getCurrentUserId())
.willReturn(currentUserId)

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

// when & then
assertThrows<UserNotFoundException> {
queryMenuByMonthUseCase.execute(now)
}
}

}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package team.comit.simtong.domain.menu.spi

import team.comit.simtong.domain.user.model.User
import java.util.*

/**
*
* Menu에서 User에 관한 Query를 요청하는 MenuQueryUserPort
*
* @author kimbeomjin
* @date 2022/09/26
* @version 1.0.0
**/
interface MenuQueryUserPort {

fun queryUserById(userId: UUID): User?

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

import java.util.*

/**
*
* Menu에서 보안 처리를 요청하는 MenuSecurityPort
*
* @author kimbeomjin
* @date 2022/09/26
* @version 1.0.0
**/
interface MenuSecurityPort {

fun getCurrentUserId(): UUID

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

import team.comit.simtong.domain.menu.model.Menu
import java.util.*

/**
*
* Menu에 관한 Query룰 요청하는 QueryMenuPort
*
* @author kimbeomjin
* @date 2022/09/21
* @version 1.0.0
**/
interface QueryMenuPort {

fun queryMenuByMonth(year: Int, month: Int, spotId: UUID): List<Menu>

}
4 changes: 4 additions & 0 deletions simtong-infrastructure/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ dependencies {
implementation(Dependencies.REDIS)
implementation(Dependencies.SPRING_REDIS)

// querydsl
implementation(Dependencies.QUERYDSL)
kapt(Dependencies.QUERYDSL_PROCESSOR)

// aws
implementation(Dependencies.SPRING_AWS)
implementation(Dependencies.AWS_SES)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package team.comit.simtong.global.config

import com.querydsl.jpa.impl.JPAQueryFactory
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import javax.persistence.EntityManager

/**
*
* JPAQueryFactory를 Bean 등록하는 QuerydslConfig
*
* @author kimbeomjin
* @date 2022/09/26
* @version 1.0.0
**/
@Configuration
class QuerydslConfig(
private val entityManager: EntityManager
) {

@Bean
protected fun queryFactory(): JPAQueryFactory = JPAQueryFactory(entityManager)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package team.comit.simtong.global.security

import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Component
import team.comit.simtong.domain.auth.spi.SecurityPort
import java.util.*

/**
*
Expand All @@ -24,4 +26,8 @@ class SecurityAdapter(
return passwordEncoder.encode(password)
}

override fun getCurrentUserId(): UUID {
return UUID.fromString(SecurityContextHolder.getContext().authentication.name)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class SecurityConfig(
.antMatchers(HttpMethod.GET, "/commons/employee-number").permitAll()
.antMatchers(HttpMethod.PUT, "/commons/token/reissue").permitAll()

// menu
.antMatchers(HttpMethod.GET, "/menu").permitAll()

// files
.antMatchers(HttpMethod.POST, "/files").permitAll()
.antMatchers(HttpMethod.POST, "/files/list").permitAll()
Expand Down
Loading

0 comments on commit 4439a44

Please sign in to comment.