diff --git a/build.gradle.kts b/build.gradle.kts index f3a54e00..6b76a05a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -67,7 +67,6 @@ dependencies { implementation(Dependencies.GOOGLE_OAUTH_CLIENT) implementation(Dependencies.YOUTUBE_ANALYTICS) implementation(Dependencies.GOOGLE_API_SERVICE) - implementation(Dependencies.GAUTH) // monitoring implementation(Dependencies.ACTUATOR) diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/exception/ExpiredTokenException.kt b/src/main/kotlin/com/dotori/v2/domain/auth/exception/ExpiredTokenException.kt deleted file mode 100644 index cb7cc8f2..00000000 --- a/src/main/kotlin/com/dotori/v2/domain/auth/exception/ExpiredTokenException.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.dotori.v2.domain.auth.exception - -import com.dotori.v2.global.error.ErrorCode -import com.dotori.v2.global.error.exception.BasicException - -class ExpiredTokenException : BasicException(ErrorCode.EXPIRED_CODE) { -} \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/exception/SecretMismatchException.kt b/src/main/kotlin/com/dotori/v2/domain/auth/exception/SecretMismatchException.kt deleted file mode 100644 index f123ea1a..00000000 --- a/src/main/kotlin/com/dotori/v2/domain/auth/exception/SecretMismatchException.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.dotori.v2.domain.auth.exception - -import com.dotori.v2.global.error.ErrorCode -import com.dotori.v2.global.error.exception.BasicException - -class SecretMismatchException : BasicException(ErrorCode.SECRET_MISMATCH) { -} \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/exception/ServiceNotFoundException.kt b/src/main/kotlin/com/dotori/v2/domain/auth/exception/ServiceNotFoundException.kt deleted file mode 100644 index 1c05df4b..00000000 --- a/src/main/kotlin/com/dotori/v2/domain/auth/exception/ServiceNotFoundException.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.dotori.v2.domain.auth.exception - -import com.dotori.v2.global.error.ErrorCode -import com.dotori.v2.global.error.exception.BasicException - -class ServiceNotFoundException : BasicException(ErrorCode.SERVICE_NOT_FOUND) { -} \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/presentation/AuthController.kt b/src/main/kotlin/com/dotori/v2/domain/auth/presentation/AuthController.kt index 9488050a..ddd4aa7e 100644 --- a/src/main/kotlin/com/dotori/v2/domain/auth/presentation/AuthController.kt +++ b/src/main/kotlin/com/dotori/v2/domain/auth/presentation/AuthController.kt @@ -1,7 +1,6 @@ package com.dotori.v2.domain.auth.presentation import com.dotori.v2.domain.auth.util.AuthConverter -import com.dotori.v2.domain.auth.presentation.data.req.SignInGAuthReqDto import com.dotori.v2.domain.auth.presentation.data.req.SignInEmailAndPasswordReqDto import com.dotori.v2.domain.auth.presentation.data.req.SignUpReqDto import com.dotori.v2.domain.auth.presentation.data.res.RefreshResDto @@ -17,11 +16,9 @@ import javax.validation.Valid @RequestMapping("/v2/auth") class AuthController ( private val signUpService: SignUpService, - private val signInGAuthService: SignInGAuthService, private val signInEmailAndPasswordService: SignInEmailAndPasswordService, private val refreshTokenService: RefreshTokenService, private val changePasswordService: ChangePasswordService, - private val logoutService: LogoutService, private val authConverter: AuthConverter, ) { @PostMapping("/signup") @@ -29,11 +26,6 @@ class AuthController ( signUpService.execute(signupReqDto) .run { ResponseEntity.ok().build() } - @PostMapping("/gauth") - fun signInGAuth(@Valid @RequestBody signInGAuthReqDto: SignInGAuthReqDto): ResponseEntity = - authConverter.toDto(signInGAuthReqDto) - .let { ResponseEntity.ok(signInGAuthService.execute(it)) } - @PostMapping fun signInEmailAndPassword(@Valid @RequestBody signInEmailAndPasswordReqDto: SignInEmailAndPasswordReqDto): ResponseEntity = authConverter.toDto(signInEmailAndPasswordReqDto) @@ -43,11 +35,6 @@ class AuthController ( fun getNewRefreshToken(@RequestHeader("Refresh-Token") refreshToken: String): ResponseEntity = ResponseEntity.ok().body(refreshTokenService.execute(refreshToken = refreshToken)) - @DeleteMapping("/logout") - fun logout(): ResponseEntity = - logoutService.execute() - .run { ResponseEntity.ok().build() } - @PatchMapping("/password") fun changePassword(@Valid @RequestBody newPasswordReqDto: NoAuthNewPasswordReqDto): ResponseEntity = changePasswordService.execute(newPasswordReqDto) diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/presentation/data/dto/SignInGAuthDto.kt b/src/main/kotlin/com/dotori/v2/domain/auth/presentation/data/dto/SignInGAuthDto.kt deleted file mode 100644 index cf742a8b..00000000 --- a/src/main/kotlin/com/dotori/v2/domain/auth/presentation/data/dto/SignInGAuthDto.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.dotori.v2.domain.auth.presentation.data.dto - -data class SignInGAuthDto( - val code: String -) \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/presentation/data/req/SignInGAuthReqDto.kt b/src/main/kotlin/com/dotori/v2/domain/auth/presentation/data/req/SignInGAuthReqDto.kt deleted file mode 100644 index d7323a36..00000000 --- a/src/main/kotlin/com/dotori/v2/domain/auth/presentation/data/req/SignInGAuthReqDto.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.dotori.v2.domain.auth.presentation.data.req - -import javax.validation.constraints.NotBlank - -data class SignInGAuthReqDto( - @field:NotBlank - val code: String -) \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/service/LogoutService.kt b/src/main/kotlin/com/dotori/v2/domain/auth/service/LogoutService.kt deleted file mode 100644 index 9535bdc5..00000000 --- a/src/main/kotlin/com/dotori/v2/domain/auth/service/LogoutService.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.dotori.v2.domain.auth.service - -interface LogoutService { - fun execute() -} \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/service/SignInGAuthService.kt b/src/main/kotlin/com/dotori/v2/domain/auth/service/SignInGAuthService.kt deleted file mode 100644 index a5def6e7..00000000 --- a/src/main/kotlin/com/dotori/v2/domain/auth/service/SignInGAuthService.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.dotori.v2.domain.auth.service - -import com.dotori.v2.domain.auth.presentation.data.dto.SignInGAuthDto -import com.dotori.v2.domain.auth.presentation.data.res.SignInResDto - -interface SignInGAuthService { - fun execute(signInDto: SignInGAuthDto): SignInResDto -} \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/LogoutServiceImpl.kt b/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/LogoutServiceImpl.kt deleted file mode 100644 index 30e5fc9f..00000000 --- a/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/LogoutServiceImpl.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.dotori.v2.domain.auth.service.impl - -import com.dotori.v2.domain.auth.domain.entity.RefreshToken -import com.dotori.v2.domain.auth.domain.repository.RefreshTokenRepository -import com.dotori.v2.domain.member.domain.entity.Member -import com.dotori.v2.domain.member.exception.MemberNotFoundException -import com.dotori.v2.domain.auth.service.LogoutService -import com.dotori.v2.global.util.UserUtil -import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional - -@Service -@Transactional(rollbackFor = [Exception::class]) -class LogoutServiceImpl( - private val userUtil: UserUtil, - private val refreshTokenRepository: RefreshTokenRepository -) : LogoutService { - override fun execute() { - val member: Member = userUtil.fetchCurrentUser() - - val refreshToken: RefreshToken = refreshTokenRepository.findByMemberId(member.id) - ?: throw MemberNotFoundException() - - refreshTokenRepository.delete(refreshToken) - } - -} \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/SignInEmailAndPasswordServiceImpl.kt b/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/SignInEmailAndPasswordServiceImpl.kt index d79796b7..12767260 100644 --- a/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/SignInEmailAndPasswordServiceImpl.kt +++ b/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/SignInEmailAndPasswordServiceImpl.kt @@ -15,7 +15,6 @@ import org.springframework.stereotype.Service import java.time.ZonedDateTime @Service -@Deprecated("GAuth 로그인으로 변환") class SignInEmailAndPasswordServiceImpl( private val memberRepository: MemberRepository, private val tokenProvider: TokenProvider, @@ -27,32 +26,32 @@ class SignInEmailAndPasswordServiceImpl( val member = memberRepository.findByEmail(signInEmailAndPasswordDto.email) ?: throw MemberNotFoundException() - if (passwordEncoder.matches(signInEmailAndPasswordDto.password, member.password)) { - val accessToken = - tokenProvider.generateAccessToken(signInEmailAndPasswordDto.email, role = member.roles.first()) - val accessExp = tokenProvider.accessExpiredTime - val expiresAt = tokenProvider.accessExpiredTime - val refreshToken = - tokenProvider.generateRefreshToken(signInEmailAndPasswordDto.email, role = member.roles.first()) - val refreshExp = tokenProvider.refreshExpiredTime - - refreshTokenRepository.save( - RefreshToken( - memberId = member.id, - token = refreshToken - ) - ) - return toResponse( - accessToken, - refreshToken, - accessExp, - refreshExp, - member.roles, - expiresAt - ) - } else { + if (!passwordEncoder.matches(signInEmailAndPasswordDto.password, member.password)) { throw PasswordMismatchException() } + + val accessToken = + tokenProvider.generateAccessToken(signInEmailAndPasswordDto.email, role = member.roles.first()) + val accessExp = tokenProvider.accessExpiredTime + val expiresAt = tokenProvider.accessExpiredTime + val refreshToken = + tokenProvider.generateRefreshToken(signInEmailAndPasswordDto.email, role = member.roles.first()) + val refreshExp = tokenProvider.refreshExpiredTime + + refreshTokenRepository.save( + RefreshToken( + memberId = member.id, + token = refreshToken + ) + ) + return toResponse( + accessToken = accessToken, + refreshToken = refreshToken, + accessExp = accessExp, + refreshExp = refreshExp, + roles = member.roles, + expiresAt = expiresAt + ) } private fun toResponse( diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/SignInGAuthServiceImpl.kt b/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/SignInGAuthServiceImpl.kt deleted file mode 100644 index b75c4f1b..00000000 --- a/src/main/kotlin/com/dotori/v2/domain/auth/service/impl/SignInGAuthServiceImpl.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.dotori.v2.domain.auth.service.impl - -import com.dotori.v2.domain.auth.domain.repository.RefreshTokenRepository -import com.dotori.v2.domain.auth.exception.ExpiredTokenException -import com.dotori.v2.domain.auth.exception.RoleNotExistException -import com.dotori.v2.domain.auth.exception.SecretMismatchException -import com.dotori.v2.domain.auth.exception.ServiceNotFoundException -import com.dotori.v2.domain.auth.presentation.data.dto.SignInGAuthDto -import com.dotori.v2.domain.auth.presentation.data.res.SignInResDto -import com.dotori.v2.domain.auth.service.SignInGAuthService -import com.dotori.v2.domain.auth.util.AuthConverter -import com.dotori.v2.domain.auth.util.AuthUtil -import com.dotori.v2.domain.member.domain.entity.Member -import com.dotori.v2.domain.member.domain.repository.MemberRepository -import com.dotori.v2.domain.member.enums.Role -import com.dotori.v2.domain.member.exception.MemberNotFoundException -import com.dotori.v2.global.config.gauth.properties.GAuthProperties -import com.dotori.v2.global.security.jwt.TokenProvider -import gauth.GAuth -import gauth.GAuthToken -import gauth.GAuthUserInfo -import gauth.exception.GAuthException -import org.springframework.beans.factory.annotation.Value -import org.springframework.stereotype.Service -import org.springframework.transaction.annotation.Transactional -import java.time.ZonedDateTime -import java.util.* - -@Service -@Transactional(rollbackFor = [Exception::class]) -class SignInGAuthServiceImpl( - private val gAuthProperties: GAuthProperties, - private val memberRepository: MemberRepository, - private val tokenProvider: TokenProvider, - private val gAuth: GAuth, - private val authUtil: AuthUtil, - private val authConverter: AuthConverter, -) : SignInGAuthService { - - @Value("\${secret-email}") - val secretEmail: String = "" - override fun execute(signInDto: SignInGAuthDto): SignInResDto = - runCatching { - val gAuthToken: GAuthToken = gAuth.generateToken( - signInDto.code, - gAuthProperties.clientId, - gAuthProperties.clientSecret, - gAuthProperties.redirectUri - ) - val gAuthUserInfo: GAuthUserInfo = gAuth.getUserInfo(gAuthToken.accessToken) - val memberExist = memberRepository.existsByEmail(gAuthUserInfo.email) - - val role = getRoleByGAuthInfo(gAuthUserInfo.role, gAuthUserInfo.email) - - val member = createMemberWhenNotExistMember( - isExist = memberExist, - member = authConverter.toEntity(gAuthUserInfo, role) - ) - - val accessToken: String = tokenProvider.generateAccessToken(gAuthUserInfo.email, role) - val refreshToken: String = tokenProvider.generateRefreshToken(gAuthUserInfo.email, role) - val accessExp: ZonedDateTime = tokenProvider.accessExpiredTime - val refreshExp: ZonedDateTime = tokenProvider.refreshExpiredTime - - authUtil.saveNewRefreshToken(member, refreshToken) - - SignInResDto( - accessToken = accessToken, - refreshToken = refreshToken, - accessExp = accessExp, - refreshExp = refreshExp, - roles = Collections.singletonList(role), - expiresAt = accessExp - ) - }.getOrElse { error -> - when (error) { - is GAuthException -> { - when (error.code) { - 400 -> throw SecretMismatchException() - 401 -> throw ExpiredTokenException() - 404 -> throw ServiceNotFoundException() - else -> throw error - } - } - - else -> throw error - } - } - - - private fun getRoleByGAuthInfo(role: String, email: String): Role = - when { - email == secretEmail -> Role.ROLE_ADMIN - role == "ROLE_STUDENT" -> Role.ROLE_MEMBER - else -> throw RoleNotExistException() - } - - private fun createMemberWhenNotExistMember(isExist: Boolean, member: Member): Member { - return if (!isExist) { - memberRepository.save(member) - } else { - memberRepository.findByEmail(member.email) ?: throw MemberNotFoundException() - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/util/AuthConverter.kt b/src/main/kotlin/com/dotori/v2/domain/auth/util/AuthConverter.kt index ed8c903b..aced3862 100644 --- a/src/main/kotlin/com/dotori/v2/domain/auth/util/AuthConverter.kt +++ b/src/main/kotlin/com/dotori/v2/domain/auth/util/AuthConverter.kt @@ -3,26 +3,12 @@ package com.dotori.v2.domain.auth.util import com.dotori.v2.domain.auth.domain.entity.RefreshToken import com.dotori.v2.domain.auth.presentation.data.dto.SignInEmailAndPasswordDto import com.dotori.v2.domain.member.domain.entity.Member -import com.dotori.v2.domain.auth.presentation.data.dto.SignInGAuthDto import com.dotori.v2.domain.auth.presentation.data.req.SignInEmailAndPasswordReqDto -import com.dotori.v2.domain.auth.presentation.data.req.SignInGAuthReqDto -import com.dotori.v2.domain.member.enums.Role -import gauth.GAuthUserInfo interface AuthConverter { - fun toDto(signInGAuthReqDto: SignInGAuthReqDto): SignInGAuthDto - fun toDto(signInEmailAndPasswordReqDto: SignInEmailAndPasswordReqDto): SignInEmailAndPasswordDto - fun toEntity(gAuthUserInfo: GAuthUserInfo, role: Role): Member - - fun toAdminEntity(gAuthUserInfo: GAuthUserInfo): Member - - fun toCouncillorEntity(gAuthUserInfo: GAuthUserInfo): Member - - fun toDeveloperEntity(gAuthUserInfo: GAuthUserInfo): Member - fun toEntity(memberInfo: Member, refreshToken: String): RefreshToken fun toEntity(memberId: Long?, refreshToken: String): RefreshToken diff --git a/src/main/kotlin/com/dotori/v2/domain/auth/util/impl/AuthConverterImpl.kt b/src/main/kotlin/com/dotori/v2/domain/auth/util/impl/AuthConverterImpl.kt index 7cf1efa2..9c088239 100644 --- a/src/main/kotlin/com/dotori/v2/domain/auth/util/impl/AuthConverterImpl.kt +++ b/src/main/kotlin/com/dotori/v2/domain/auth/util/impl/AuthConverterImpl.kt @@ -4,20 +4,12 @@ import com.dotori.v2.domain.auth.domain.entity.RefreshToken import com.dotori.v2.domain.auth.presentation.data.dto.SignInEmailAndPasswordDto import com.dotori.v2.domain.auth.util.AuthConverter import com.dotori.v2.domain.member.domain.entity.Member -import com.dotori.v2.domain.member.enums.Role -import com.dotori.v2.domain.auth.presentation.data.dto.SignInGAuthDto import com.dotori.v2.domain.auth.presentation.data.req.SignInEmailAndPasswordReqDto -import com.dotori.v2.domain.auth.presentation.data.req.SignInGAuthReqDto import com.dotori.v2.domain.member.enums.Gender -import gauth.GAuthUserInfo import org.springframework.stereotype.Component @Component class AuthConverterImpl : AuthConverter { - override fun toDto(signInReqDto: SignInGAuthReqDto): SignInGAuthDto = - SignInGAuthDto( - code = signInReqDto.code - ) override fun toDto(signInEmailAndPasswordReqDto: SignInEmailAndPasswordReqDto): SignInEmailAndPasswordDto = SignInEmailAndPasswordDto( @@ -25,53 +17,6 @@ class AuthConverterImpl : AuthConverter { password = signInEmailAndPasswordReqDto.password ) - override fun toEntity(gAuthUserInfo: GAuthUserInfo, role: Role): Member = - Member( - memberName = gAuthUserInfo.name, - stuNum = "${gAuthUserInfo.grade}${gAuthUserInfo.classNum}${gAuthUserInfo.num}", - email = gAuthUserInfo.email, - password = "", - gender = convertGender(gAuthUserInfo.gender), - roles = mutableListOf(role), - ruleViolation = mutableListOf(), - profileImage = gAuthUserInfo.profileUrl - ) - - override fun toAdminEntity(gAuthUserInfo: GAuthUserInfo): Member = - Member( - memberName = gAuthUserInfo.name, - stuNum = "${gAuthUserInfo.grade}${gAuthUserInfo.classNum}${gAuthUserInfo.num}", - email = gAuthUserInfo.email, - password = "", - gender = convertGender(gAuthUserInfo.gender), - roles = mutableListOf(Role.ROLE_ADMIN), - ruleViolation = mutableListOf(), - profileImage = gAuthUserInfo.profileUrl - ) - - override fun toCouncillorEntity(gAuthUserInfo: GAuthUserInfo): Member = - Member( - memberName = gAuthUserInfo.name, - stuNum = "${gAuthUserInfo.grade}${gAuthUserInfo.classNum}${gAuthUserInfo.num}", - email = gAuthUserInfo.email, - password = "", - gender = convertGender(gAuthUserInfo.gender), - roles = mutableListOf(Role.ROLE_COUNCILLOR), - ruleViolation = mutableListOf(), - profileImage = gAuthUserInfo.profileUrl - ) - - override fun toDeveloperEntity(gAuthUserInfo: GAuthUserInfo): Member = - Member( - memberName = gAuthUserInfo.name, - stuNum = "${gAuthUserInfo.grade}${gAuthUserInfo.classNum}${gAuthUserInfo.num}", - email = gAuthUserInfo.email, - password = "", - gender = convertGender(gAuthUserInfo.gender), - roles = mutableListOf(Role.ROLE_DEVELOPER), - ruleViolation = mutableListOf(), - profileImage = gAuthUserInfo.profileUrl - ) override fun toEntity(memberInfo: Member, refreshToken: String): RefreshToken = RefreshToken( diff --git a/src/main/kotlin/com/dotori/v2/domain/music/domain/repository/MusicLikeRepository.kt b/src/main/kotlin/com/dotori/v2/domain/music/domain/repository/MusicLikeRepository.kt index 520fdf57..dc10e3d5 100644 --- a/src/main/kotlin/com/dotori/v2/domain/music/domain/repository/MusicLikeRepository.kt +++ b/src/main/kotlin/com/dotori/v2/domain/music/domain/repository/MusicLikeRepository.kt @@ -12,5 +12,7 @@ interface MusicLikeRepository : JpaRepository { @Query("select l from MusicLike l where l.memberId = :memberId and l.musicId = :musicId") fun findByMemberIdAndMusicId(@Param("memberId") memberId: Long,@Param("musicId") musicId: Long): MusicLike? + fun deleteAllByMusicId(music: Long) + fun existsByMusicIdAndMemberId(musicId: Long, memberId: Long): Boolean } \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/domain/music/service/impl/DeleteMusicServiceImpl.kt b/src/main/kotlin/com/dotori/v2/domain/music/service/impl/DeleteMusicServiceImpl.kt index a9d422c0..51131b3c 100644 --- a/src/main/kotlin/com/dotori/v2/domain/music/service/impl/DeleteMusicServiceImpl.kt +++ b/src/main/kotlin/com/dotori/v2/domain/music/service/impl/DeleteMusicServiceImpl.kt @@ -2,6 +2,7 @@ package com.dotori.v2.domain.music.service.impl import com.dotori.v2.domain.member.enums.MusicStatus import com.dotori.v2.domain.music.domain.entity.Music +import com.dotori.v2.domain.music.domain.repository.MusicLikeRepository import com.dotori.v2.domain.music.domain.repository.MusicRepository import com.dotori.v2.domain.music.exception.MusicNotFoundException import com.dotori.v2.domain.music.presentation.data.res.MusicListResDto @@ -15,16 +16,20 @@ import org.springframework.transaction.annotation.Transactional @Transactional(rollbackFor = [Exception::class]) class DeleteMusicServiceImpl( private val musicRepository: MusicRepository, - private val redisCacheService: RedisCacheService + private val redisCacheService: RedisCacheService, + private val musicLikeRepository: MusicLikeRepository ) : DeleteMusicService { override fun execute(musicId: Long) { - val music: Music = musicRepository.findByIdOrNull(musicId) ?: throw MusicNotFoundException() + val music: Music = musicRepository.findByIdOrNull(musicId) + ?: throw MusicNotFoundException() val date = music.createdDate.toLocalDate().toString() redisCacheService.putToCacheMusic(date, MusicListResDto(mutableListOf())) + musicLikeRepository.deleteAllByMusicId(musicId) musicRepository.delete(music) music.member.updateMusicStatus(MusicStatus.CAN) } -} \ No newline at end of file + +} diff --git a/src/main/kotlin/com/dotori/v2/domain/music/service/impl/DeleteMyMusicServiceImpl.kt b/src/main/kotlin/com/dotori/v2/domain/music/service/impl/DeleteMyMusicServiceImpl.kt index bc8b125a..fac0081a 100644 --- a/src/main/kotlin/com/dotori/v2/domain/music/service/impl/DeleteMyMusicServiceImpl.kt +++ b/src/main/kotlin/com/dotori/v2/domain/music/service/impl/DeleteMyMusicServiceImpl.kt @@ -3,6 +3,7 @@ package com.dotori.v2.domain.music.service.impl import com.dotori.v2.domain.member.domain.entity.Member import com.dotori.v2.domain.member.enums.MusicStatus import com.dotori.v2.domain.music.domain.entity.Music +import com.dotori.v2.domain.music.domain.repository.MusicLikeRepository import com.dotori.v2.domain.music.domain.repository.MusicRepository import com.dotori.v2.domain.music.exception.MusicNotFoundException import com.dotori.v2.domain.music.exception.NotMyMusicException @@ -19,12 +20,15 @@ import org.springframework.transaction.annotation.Transactional class DeleteMyMusicServiceImpl( private val musicRepository: MusicRepository, private val userUtil: UserUtil, - private val redisCacheService: RedisCacheService + private val redisCacheService: RedisCacheService, + private val musicLikeRepository: MusicLikeRepository ) : DeleteMyMusicService { override fun execute(musicId: Long) { - val music: Music = musicRepository.findByIdOrNull(musicId) ?: throw MusicNotFoundException() + val music: Music = musicRepository.findByIdOrNull(musicId) + ?: throw MusicNotFoundException() + val member: Member = userUtil.fetchCurrentUser() validMusic(music, member) @@ -32,6 +36,7 @@ class DeleteMyMusicServiceImpl( val date = music.createdDate.toLocalDate().toString() redisCacheService.putToCacheMusic(date, MusicListResDto(mutableListOf())) + musicLikeRepository.deleteAllByMusicId(musicId) musicRepository.delete(music) music.member.updateMusicStatus(MusicStatus.CAN) } diff --git a/src/main/kotlin/com/dotori/v2/global/config/ConfigurationPropertiesScanConfig.kt b/src/main/kotlin/com/dotori/v2/global/config/ConfigurationPropertiesScanConfig.kt index d1b97d64..180877e1 100644 --- a/src/main/kotlin/com/dotori/v2/global/config/ConfigurationPropertiesScanConfig.kt +++ b/src/main/kotlin/com/dotori/v2/global/config/ConfigurationPropertiesScanConfig.kt @@ -1,6 +1,5 @@ package com.dotori.v2.global.config -import com.dotori.v2.global.config.gauth.properties.GAuthProperties import com.dotori.v2.global.security.jwt.properties.JwtProperties import com.dotori.v2.global.security.jwt.properties.JwtTimeProperties import org.springframework.boot.context.properties.ConfigurationPropertiesScan @@ -9,7 +8,6 @@ import org.springframework.context.annotation.Configuration @Configuration @ConfigurationPropertiesScan( basePackageClasses = [ - GAuthProperties::class, JwtProperties::class, JwtTimeProperties::class ] diff --git a/src/main/kotlin/com/dotori/v2/global/config/gauth/GAuthConfig.kt b/src/main/kotlin/com/dotori/v2/global/config/gauth/GAuthConfig.kt deleted file mode 100644 index f1147db2..00000000 --- a/src/main/kotlin/com/dotori/v2/global/config/gauth/GAuthConfig.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.dotori.v2.global.config.gauth - -import gauth.GAuth -import gauth.impl.GAuthImpl -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -@Configuration -class GAuthConfig { - @Bean - fun gAuth(): GAuth = GAuthImpl() -} \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/global/config/gauth/properties/GAuthProperties.kt b/src/main/kotlin/com/dotori/v2/global/config/gauth/properties/GAuthProperties.kt deleted file mode 100644 index 73ffc03e..00000000 --- a/src/main/kotlin/com/dotori/v2/global/config/gauth/properties/GAuthProperties.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.dotori.v2.global.config.gauth.properties - -import org.springframework.boot.context.properties.ConfigurationProperties -import org.springframework.boot.context.properties.ConstructorBinding - -@ConstructorBinding -@ConfigurationProperties(prefix = "gauth") -data class GAuthProperties( - val clientId: String, - val clientSecret: String, - val redirectUri: String -) \ No newline at end of file diff --git a/src/main/kotlin/com/dotori/v2/global/error/ErrorCode.kt b/src/main/kotlin/com/dotori/v2/global/error/ErrorCode.kt index f12cabde..2d525010 100644 --- a/src/main/kotlin/com/dotori/v2/global/error/ErrorCode.kt +++ b/src/main/kotlin/com/dotori/v2/global/error/ErrorCode.kt @@ -5,86 +5,82 @@ import org.springframework.http.HttpStatus enum class ErrorCode( val error: Int, val message: String, -){ +) { // *** SERVER ERROR *** - UNKNOWN_ERROR(HttpStatus.INTERNAL_SERVER_ERROR.value(), "알 수 없는 에러입니다."), - EMAIL_SEND_FAIL(HttpStatus.INTERNAL_SERVER_ERROR.value(), "이메일 발송에 실패하였습니다"), - BAD_REQUEST(HttpStatus.BAD_REQUEST.value(), "Bad Request"), + UNKNOWN_ERROR(HttpStatus.INTERNAL_SERVER_ERROR.value(),"알 수 없는 에러입니다."), + EMAIL_SEND_FAIL(HttpStatus.INTERNAL_SERVER_ERROR.value(),"이메일 발송에 실패하였습니다"), + BAD_REQUEST(HttpStatus.BAD_REQUEST.value(),"Bad Request"), // *** MASSAGE *** - MASSAGE_ALREADY(HttpStatus.CONFLICT.value(), "이미 안마의자 신청을 신청하신 회원입니다."), - MASSAGE_OVER(HttpStatus.CONFLICT.value(), "안마의자 신청 인원이 최대 인원을 초과 하였습니다."), - MASSAGE_CANT_REQUEST_THIS_TIME(HttpStatus.ACCEPTED.value(), "안마의자 신청은 오후 8시 20분부터 오후 9시까지만 신청이 가능합니다."), - MASSAGE_CANT_REQUEST_THIS_DATE(HttpStatus.ACCEPTED.value(), "안마의자 신청을 하실 수 없는 요일입니다."), - MASSAGE_CANT_CANCEL_THIS_TIME(HttpStatus.ACCEPTED.value(), "안마의자 신청 취소는 오후 8시 20분부터 오후 9시까지만 신청 취소가 가능합니다."), - MASSAGE_CANT_CANCEL_THIS_DATE(HttpStatus.ACCEPTED.value(), "안마의자 신청 취소를 할 수 없는 요일입니다."), - MASSAGE_ANYONE_NOT_REQUEST(HttpStatus.ACCEPTED.value(), "안마의자를 신청한 학생이 없습니다"), - MASSAGE_CANT_CANCEL_REQUEST(HttpStatus.ACCEPTED.value(), "안마의자 신청을 취소할 수 있는 상태가 아닙니다."), + MASSAGE_ALREADY(HttpStatus.CONFLICT.value(),"이미 안마의자 신청을 신청하신 회원입니다."), + MASSAGE_OVER(HttpStatus.CONFLICT.value(),"안마의자 신청 인원이 최대 인원을 초과 하였습니다."), + MASSAGE_CANT_REQUEST_THIS_TIME(HttpStatus.ACCEPTED.value(),"안마의자 신청은 오후 8시 20분부터 오후 9시까지만 신청이 가능합니다."), + MASSAGE_CANT_REQUEST_THIS_DATE(HttpStatus.ACCEPTED.value(),"안마의자 신청을 하실 수 없는 요일입니다."), + MASSAGE_CANT_CANCEL_THIS_TIME(HttpStatus.ACCEPTED.value(),"안마의자 신청 취소는 오후 8시 20분부터 오후 9시까지만 신청 취소가 가능합니다."), + MASSAGE_CANT_CANCEL_THIS_DATE(HttpStatus.ACCEPTED.value(),"안마의자 신청 취소를 할 수 없는 요일입니다."), + MASSAGE_ANYONE_NOT_REQUEST(HttpStatus.ACCEPTED.value(),"안마의자를 신청한 학생이 없습니다"), + MASSAGE_CANT_CANCEL_REQUEST(HttpStatus.ACCEPTED.value(),"안마의자 신청을 취소할 수 있는 상태가 아닙니다."), // *** BOARD *** - BOARD_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 게시글을 찾을 수 없습니다."), - BOARD_NOT_HAVE_PERMISSION_TO_CREATE(HttpStatus.FORBIDDEN.value(), "해당 게시물 생성 권한이 없습니다."), - BOARD_NOT_HAVE_PERMISSION_TO_MODIFY(HttpStatus.FORBIDDEN.value(), "해당 게시물 수정 권한이 없습니다."), - BOARD_NOT_HAVE_PERMISSION_TO_DELETE(HttpStatus.FORBIDDEN.value(), "해당 게시물 생성 권한이 없습니다."), - BOARD_EMPTY(HttpStatus.ACCEPTED.value(), "공지사항이 비어있습니다."), + BOARD_NOT_FOUND(HttpStatus.NOT_FOUND.value(),"해당 게시글을 찾을 수 없습니다."), + BOARD_NOT_HAVE_PERMISSION_TO_CREATE(HttpStatus.FORBIDDEN.value(),"해당 게시물 생성 권한이 없습니다."), + BOARD_NOT_HAVE_PERMISSION_TO_MODIFY(HttpStatus.FORBIDDEN.value(),"해당 게시물 수정 권한이 없습니다."), + BOARD_NOT_HAVE_PERMISSION_TO_DELETE(HttpStatus.FORBIDDEN.value(),"해당 게시물 생성 권한이 없습니다."), + BOARD_EMPTY(HttpStatus.ACCEPTED.value(),"공지사항이 비어있습니다."), // *** MEMBER *** - MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 유저를 찾을 수 없습니다."), - MEMBER_ROLE_NOT_EXIST(HttpStatus.NOT_FOUND.value(), "역할이 존재하지 않습니다"), - MEMBER_ALREADY(HttpStatus.CONFLICT.value(), "이미 가입된 유저입니다."), - MEMBER_PASSWORD_NOT_MATCHING(HttpStatus.BAD_REQUEST.value(), "비밀번호가 올바르지 않습니다."), - MEMBER_AUTHENTICATION_KEY_NOT_MATCHING(HttpStatus.BAD_REQUEST.value(), "인증 키가 일치하지 않습니다."), - MEMBER_ALREADY_JOIN_THIS_STUNUM(HttpStatus.CONFLICT.value(), "이미 존재하는 학번입니다."), - MEMBER_NOT_FOUND_BY_CLASS(HttpStatus.ACCEPTED.value(), "해당반에 해당하는 학생들이 없습니다."), - MEMBER_NO_INFORMATION(HttpStatus.ACCEPTED.value(), "회원 정보가 없습니다."), - MEMBER_OVER_CERTIFICATE_TIME(HttpStatus.ACCEPTED.value(), "인증 시간이 초과되었습니다."), - MEMBER_EMAIL_HAS_NOT_AUTH_KEY(HttpStatus.NOT_FOUND.value(), "인증번호가 존재 하지 않습니다"), - MEMBER_EMAIL_HAS_NOT_BEEN_CERTIFICATE(HttpStatus.ACCEPTED.value(), "이메일 인증이 되지않았습니다."), - MEMBER_NOT_SAME(HttpStatus.UNAUTHORIZED.value(), "유저가 일치하지 않습니다."), - MEMBER_PROFILE_IMG_NOT_ACCEPT_EXTENSION(HttpStatus.BAD_REQUEST.value(), "지원하지 않는 프로필 사진 확장자 입니다."), + MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND.value(),"해당 유저를 찾을 수 없습니다."), + MEMBER_ROLE_NOT_EXIST(HttpStatus.NOT_FOUND.value(),"역할이 존재하지 않습니다"), + MEMBER_ALREADY(HttpStatus.CONFLICT.value(),"이미 가입된 유저입니다."), + MEMBER_PASSWORD_NOT_MATCHING(HttpStatus.BAD_REQUEST.value(),"비밀번호가 올바르지 않습니다."), + MEMBER_AUTHENTICATION_KEY_NOT_MATCHING(HttpStatus.BAD_REQUEST.value(),"인증 키가 일치하지 않습니다."), + MEMBER_ALREADY_JOIN_THIS_STUNUM(HttpStatus.CONFLICT.value(),"이미 존재하는 학번입니다."), + MEMBER_NOT_FOUND_BY_CLASS(HttpStatus.ACCEPTED.value(),"해당반에 해당하는 학생들이 없습니다."), + MEMBER_NO_INFORMATION(HttpStatus.ACCEPTED.value(),"회원 정보가 없습니다."), + MEMBER_OVER_CERTIFICATE_TIME(HttpStatus.ACCEPTED.value(),"인증 시간이 초과되었습니다."), + MEMBER_EMAIL_HAS_NOT_AUTH_KEY(HttpStatus.NOT_FOUND.value(),"인증번호가 존재 하지 않습니다"), + MEMBER_EMAIL_HAS_NOT_BEEN_CERTIFICATE(HttpStatus.ACCEPTED.value(),"이메일 인증이 되지않았습니다."), + MEMBER_NOT_SAME(HttpStatus.UNAUTHORIZED.value(),"유저가 일치하지 않습니다."), + MEMBER_PROFILE_IMG_NOT_ACCEPT_EXTENSION(HttpStatus.BAD_REQUEST.value(),"지원하지 않는 프로필 사진 확장자 입니다."), // *** SELF STUDY *** - SELF_STUDY_ALREADY(HttpStatus.CONFLICT.value(), "이미 자습신청을 하신 상태입니다."), - SELF_STUDY_OVER(HttpStatus.CONFLICT.value(), "자습신청 인원이 최대 인원을 초과 하였습니다."), - SELF_STUDY_NOT_FOUND(HttpStatus.ACCEPTED.value(), "자습신청한 학생이 없습니다."), - SELF_STUDY_CANT_CANCEL(HttpStatus.ACCEPTED.value(), "자습신청을 취소할 수 있는 상태가 아닙니다."), - SELF_STUDY_CANT_REQUEST_DATE(HttpStatus.ACCEPTED.value(), "자습신청을 하실 수 없는 요일입니다."), - SELF_STUDY_CANT_REQUEST_TIME(HttpStatus.ACCEPTED.value(), "자습신청은 오후 8시부터 오후 9시까지만 가능합니다."), - SELF_STUDY_CANT_CANCEL_DATE(HttpStatus.ACCEPTED.value(), "자습신청을 취소 하실 수 없는 요일입니다."), - SELF_STUDY_CANT_CANCEL_TIME(HttpStatus.ACCEPTED.value(), "자습신청은 오후 8시부터 오후 9시까지만 취소가 가능합니다."), - SELF_STUDY_NOT_APPLIED(HttpStatus.BAD_REQUEST.value(), "자습신청을 하지 않았습니다."), + SELF_STUDY_ALREADY(HttpStatus.CONFLICT.value(),"이미 자습신청을 하신 상태입니다."), + SELF_STUDY_OVER(HttpStatus.CONFLICT.value(),"자습신청 인원이 최대 인원을 초과 하였습니다."), + SELF_STUDY_NOT_FOUND(HttpStatus.ACCEPTED.value(),"자습신청한 학생이 없습니다."), + SELF_STUDY_CANT_CANCEL(HttpStatus.ACCEPTED.value(),"자습신청을 취소할 수 있는 상태가 아닙니다."), + SELF_STUDY_CANT_REQUEST_DATE(HttpStatus.ACCEPTED.value(),"자습신청을 하실 수 없는 요일입니다."), + SELF_STUDY_CANT_REQUEST_TIME(HttpStatus.ACCEPTED.value(),"자습신청은 오후 8시부터 오후 9시까지만 가능합니다."), + SELF_STUDY_CANT_CANCEL_DATE(HttpStatus.ACCEPTED.value(),"자습신청을 취소 하실 수 없는 요일입니다."), + SELF_STUDY_CANT_CANCEL_TIME(HttpStatus.ACCEPTED.value(),"자습신청은 오후 8시부터 오후 9시까지만 취소가 가능합니다."), + SELF_STUDY_NOT_APPLIED(HttpStatus.BAD_REQUEST.value(),"자습신청을 하지 않았습니다."), // *** MUSIC *** - MUSIC_ALREADY(HttpStatus.CONFLICT.value(), "이미 음악을 신청하신 회원입니다."), - MUSIC_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 신청된 음악을 찾을 수 없습니다."), + MUSIC_ALREADY(HttpStatus.CONFLICT.value(),"이미 음악을 신청하신 회원입니다."), + MUSIC_NOT_FOUND(HttpStatus.NOT_FOUND.value(),"해당 신청된 음악을 찾을 수 없습니다."), MUSIC_NOT_MY(HttpStatus.FORBIDDEN.value(),"자신이 신청한 음악이 아닙니다"), - MUSIC_NOT_REQUESTED(HttpStatus.ACCEPTED.value(), "신청된 음악이 없습니다."), - MUSIC_CANT_REQUEST_DATE(HttpStatus.ACCEPTED.value(), "음악신청을 하실 수 없는 요일입니다."), - MUSIC_TODAY_NOT_REQUESTED(HttpStatus.ACCEPTED.value(), "오늘 신청된 음악이 없습니다."), - MUSIC_NOT_REQUEST_ON_THAT_DATE(HttpStatus.ACCEPTED.value(), "해당 날짜에 신청된 노래가 없습니다."), - NOT_VALID_YOUTUBE_URL(HttpStatus.BAD_REQUEST.value(), "유효하지 않은 유튜브 url 입니다."), - NOT_VALID_MUSIC_LIKE(HttpStatus.BAD_REQUEST.value(), "이미 지난 요일의 기상음악에는 좋아요를 누를 수 없습니다."), + MUSIC_NOT_REQUESTED(HttpStatus.ACCEPTED.value(),"신청된 음악이 없습니다."), + MUSIC_CANT_REQUEST_DATE(HttpStatus.ACCEPTED.value(),"음악신청을 하실 수 없는 요일입니다."), + MUSIC_TODAY_NOT_REQUESTED(HttpStatus.ACCEPTED.value(),"오늘 신청된 음악이 없습니다."), + MUSIC_NOT_REQUEST_ON_THAT_DATE(HttpStatus.ACCEPTED.value(),"해당 날짜에 신청된 노래가 없습니다."), + NOT_VALID_YOUTUBE_URL(HttpStatus.BAD_REQUEST.value(),"유효하지 않은 유튜브 url 입니다."), + NOT_VALID_MUSIC_LIKE(HttpStatus.BAD_REQUEST.value(),"이미 지난 요일의 기상음악에는 좋아요를 누를 수 없습니다."), // *** TOKEN *** - TOKEN_INVALID(HttpStatus.FORBIDDEN.value(), "변질된 토큰입니다."), - TOKEN_EXPIRED(HttpStatus.UNAUTHORIZED.value(), "토큰이 만료되었습니다."), - TOKEN_REFRESH_FAIL(HttpStatus.BAD_REQUEST.value(), "토큰 재발급에 실패했습니다."), + TOKEN_INVALID(HttpStatus.FORBIDDEN.value(),"변질된 토큰입니다."), + TOKEN_EXPIRED(HttpStatus.UNAUTHORIZED.value(),"토큰이 만료되었습니다."), + TOKEN_REFRESH_FAIL(HttpStatus.BAD_REQUEST.value(),"토큰 재발급에 실패했습니다."), // *** RULE *** - RULE_NO_HISTORY(HttpStatus.ACCEPTED.value(), "규정위반 내역이 없습니다."), - RULE_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 규정위반 내역을 찾지 못하였습니다."), + RULE_NO_HISTORY(HttpStatus.ACCEPTED.value(),"규정위반 내역이 없습니다."), + RULE_NOT_FOUND(HttpStatus.NOT_FOUND.value(),"해당 규정위반 내역을 찾지 못하였습니다."), //*** MAIL *** - MAIL_AUTH_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "메일을 발송하지 않았거나 만료되었습니다."), + MAIL_AUTH_NOT_FOUND(HttpStatus.NOT_FOUND.value(),"메일을 발송하지 않았거나 만료되었습니다."), - //. *** GAUTH *** - SERVICE_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "gAuth 서비스를 찾을 수 없습니다."), - SECRET_MISMATCH(HttpStatus.BAD_REQUEST.value(), "gAuth Secret 코드가 잘못되었습니다"), - EXPIRED_CODE(HttpStatus.UNAUTHORIZED.value(), "만료된 토큰입니다") } \ No newline at end of file diff --git a/src/test/kotlin/com/dotori/v2/domain/member/controller/LogoutControllerTest.kt b/src/test/kotlin/com/dotori/v2/domain/member/controller/LogoutControllerTest.kt deleted file mode 100644 index de8f7a36..00000000 --- a/src/test/kotlin/com/dotori/v2/domain/member/controller/LogoutControllerTest.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.dotori.v2.domain.member.controller - -import com.dotori.v2.domain.auth.presentation.AuthController -import com.dotori.v2.domain.auth.service.* -import com.dotori.v2.domain.auth.util.AuthConverter -import com.dotori.v2.domain.auth.util.impl.AuthConverterImpl -import com.dotori.v2.domain.member.service.ChangePasswordService -import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.shouldBe -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify -import org.springframework.context.annotation.Bean -import org.springframework.http.HttpStatus - -class LogoutControllerTest : BehaviorSpec({ - - @Bean - fun authConverter(): AuthConverter = - AuthConverterImpl() - - val refreshTokenService = mockk() - val signInGAuthService = mockk() - val signInEmailAndPasswordService = mockk() - val logoutService = mockk() - val signUpService = mockk() - val changePasswordService = mockk() - - val authController = AuthController( - authConverter = authConverter(), - signInGAuthService = signInGAuthService, - signInEmailAndPasswordService = signInEmailAndPasswordService, - refreshTokenService = refreshTokenService, - logoutService = logoutService, - signUpService = signUpService, - changePasswordService = changePasswordService - ) - - given("요청이 들어오면") { - `when`("is received") { - every { logoutService.execute() } returns Unit - val response = authController.logout() - then("서비스가 한번은 실행되어야 함") { - verify(exactly = 1) { logoutService.execute() } - } - then("response status should be ok") { - response.statusCode shouldBe HttpStatus.OK - } - } - } -}) \ No newline at end of file diff --git a/src/test/kotlin/com/dotori/v2/domain/member/controller/RefreshTokenControllerTest.kt b/src/test/kotlin/com/dotori/v2/domain/member/controller/RefreshTokenControllerTest.kt deleted file mode 100644 index 70e1239c..00000000 --- a/src/test/kotlin/com/dotori/v2/domain/member/controller/RefreshTokenControllerTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.dotori.v2.domain.member.controller - -import com.dotori.v2.domain.auth.presentation.AuthController -import com.dotori.v2.domain.auth.util.AuthConverter -import com.dotori.v2.domain.auth.util.impl.AuthConverterImpl -import com.dotori.v2.domain.auth.presentation.data.res.RefreshResDto -import com.dotori.v2.domain.auth.service.* -import com.dotori.v2.domain.member.enums.Role -import com.dotori.v2.domain.member.service.ChangePasswordService -import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.shouldBe -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify -import org.springframework.context.annotation.Bean -import org.springframework.http.HttpStatus -import java.time.ZonedDateTime -import java.util.* - -class RefreshTokenControllerTest : BehaviorSpec({ - - @Bean - fun authConverter(): AuthConverter = - AuthConverterImpl() - - val refreshTokenService = mockk() - val signInGAuthService = mockk() - val signInEmailAndPasswordService = mockk() - val logoutService = mockk() - val signUpService = mockk() - val changePasswordService = mockk() - - val authController = AuthController( - authConverter = authConverter(), - signInGAuthService = signInGAuthService, - signInEmailAndPasswordService = signInEmailAndPasswordService, - refreshTokenService = refreshTokenService, - logoutService = logoutService, - signUpService = signUpService, - changePasswordService = changePasswordService - ) - - - given("요청이 들어오면") { - val refreshToken = "thisIsRefresh" - `when`("is received") { - every { - refreshTokenService.execute(refreshToken) - } returns RefreshResDto( - accessToken = "thisIsAccess", - refreshToken = "thisIsRefresh", - accessExp = ZonedDateTime.now(), - refreshExp = ZonedDateTime.now(), - roles = Collections.singletonList(Role.ROLE_DEVELOPER), - expiresAt = ZonedDateTime.now() - ) - - val response = authController.getNewRefreshToken(refreshToken) - - then("서비스가 한번은 실행되어야 함") { - verify(exactly = 1) { refreshTokenService.execute(refreshToken) } - } - then("response status should be success") { - response.statusCode shouldBe HttpStatus.OK - } - } - } -}) \ No newline at end of file diff --git a/src/test/kotlin/com/dotori/v2/domain/member/controller/SignInControllerTest.kt b/src/test/kotlin/com/dotori/v2/domain/member/controller/SignInControllerTest.kt deleted file mode 100644 index f3eaac32..00000000 --- a/src/test/kotlin/com/dotori/v2/domain/member/controller/SignInControllerTest.kt +++ /dev/null @@ -1,69 +0,0 @@ -package com.dotori.v2.domain.member.controller - -import com.dotori.v2.domain.auth.presentation.AuthController -import com.dotori.v2.domain.auth.util.AuthConverter -import com.dotori.v2.domain.auth.util.impl.AuthConverterImpl -import com.dotori.v2.domain.auth.presentation.data.dto.SignInGAuthDto -import com.dotori.v2.domain.auth.presentation.data.req.SignInGAuthReqDto -import com.dotori.v2.domain.auth.presentation.data.res.SignInResDto -import com.dotori.v2.domain.auth.service.* -import com.dotori.v2.domain.member.enums.Role -import com.dotori.v2.domain.member.service.ChangePasswordService -import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.shouldBe -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify -import org.springframework.context.annotation.Bean -import org.springframework.http.HttpStatus -import java.time.ZonedDateTime -import java.util.* - -class SignInControllerTest : BehaviorSpec({ - @Bean - fun authConverter(): AuthConverter = - AuthConverterImpl() - - val refreshTokenService = mockk() - val signInGAuthService = mockk() - val signInEmailAndPasswordService = mockk() - val logoutService = mockk() - val signUpService = mockk() - val changePasswordService = mockk() - - val authController = AuthController( - authConverter = authConverter(), - signInGAuthService = signInGAuthService, - signInEmailAndPasswordService = signInEmailAndPasswordService, - refreshTokenService = refreshTokenService, - logoutService = logoutService, - signUpService = signUpService, - changePasswordService = changePasswordService - ) - given("요청이 들어오면") { - val dto = SignInGAuthDto( - code = "thisIsCode" - ) - val request = SignInGAuthReqDto( - code = "thisIsCode" - ) - `when`("is received") { - every { signInGAuthService.execute(dto) } returns SignInResDto( - accessToken = "thisIsAccess", - refreshToken = "thisIsRefresh", - accessExp = ZonedDateTime.now(), - refreshExp = ZonedDateTime.now(), - roles = Collections.singletonList(Role.ROLE_DEVELOPER), - expiresAt = ZonedDateTime.now() - ) - val response = authController.signInGAuth(request) - - then("서비스가 한번은 실행되어야 함") { - verify(exactly = 1) { signInGAuthService.execute(dto) } - } - then("response status should be success") { - response.statusCode shouldBe HttpStatus.OK - } - } - } -}) \ No newline at end of file diff --git a/src/test/kotlin/com/dotori/v2/domain/member/service/LogoutServiceTest.kt b/src/test/kotlin/com/dotori/v2/domain/member/service/LogoutServiceTest.kt deleted file mode 100644 index 7928bb22..00000000 --- a/src/test/kotlin/com/dotori/v2/domain/member/service/LogoutServiceTest.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.dotori.v2.domain.member.service - -import com.dotori.v2.domain.auth.domain.repository.RefreshTokenRepository -import com.dotori.v2.domain.auth.service.impl.LogoutServiceImpl -import com.dotori.v2.domain.member.domain.entity.Member -import com.dotori.v2.domain.member.enums.Gender -import com.dotori.v2.domain.member.enums.Role -import com.dotori.v2.global.util.UserUtil -import com.dotori.v2.util.TestUtils -import io.kotest.core.spec.style.BehaviorSpec -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify -import java.util.* - -class LogoutServiceTest : BehaviorSpec({ - val userUtil = mockk() - val refreshTokenRepository = mockk() - val logoutService = LogoutServiceImpl(userUtil, refreshTokenRepository) - given("refreshToken이 'testRefreshToken'인 유저가 주어지고") { - val testMember = Member( - memberName = "test", - stuNum = "2116", - email = "test@gsm.hs.kr", - password = "password1234", - gender = Gender.MAN, - roles = Collections.singletonList(Role.ROLE_MEMBER), - ruleViolation = mutableListOf(), - profileImage = null - ) - - every { userUtil.fetchCurrentUser() } returns testMember - val refreshToken = TestUtils.data().auth().entity(memberId = testMember.id) - every { refreshTokenRepository.findByMemberId(memberId = testMember.id) } returns refreshToken - `when`("logoutService를 실행하고") { - every { refreshTokenRepository.delete(refreshToken) } returns Unit - logoutService.execute() - then("그때 delete 쿼리가 한번 실행되어야 함") { - verify(exactly = 1) { refreshTokenRepository.delete(refreshToken) } - } - } - } -}) \ No newline at end of file diff --git a/src/test/kotlin/com/dotori/v2/domain/member/service/SignInServiceTest.kt b/src/test/kotlin/com/dotori/v2/domain/member/service/SignInServiceTest.kt deleted file mode 100644 index 72e68706..00000000 --- a/src/test/kotlin/com/dotori/v2/domain/member/service/SignInServiceTest.kt +++ /dev/null @@ -1,207 +0,0 @@ -package com.dotori.v2.domain.member.service - -import com.dotori.v2.domain.auth.domain.entity.RefreshToken -import com.dotori.v2.domain.auth.domain.repository.RefreshTokenRepository -import com.dotori.v2.domain.auth.util.AuthConverter -import com.dotori.v2.domain.auth.util.impl.AuthUtilImpl -import com.dotori.v2.domain.member.domain.entity.Member -import com.dotori.v2.domain.member.domain.repository.MemberRepository -import com.dotori.v2.domain.member.enums.Role -import com.dotori.v2.domain.auth.presentation.data.dto.SignInGAuthDto -import com.dotori.v2.domain.auth.service.impl.SignInGAuthServiceImpl -import com.dotori.v2.domain.member.enums.Gender -import com.dotori.v2.global.config.gauth.properties.GAuthProperties -import com.dotori.v2.global.security.jwt.TokenProvider -import gauth.GAuth -import gauth.GAuthToken -import gauth.GAuthUserInfo -import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.shouldBe -import io.mockk.Called -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify - -class SignInServiceTest : BehaviorSpec({ - val clientId = "thisIsClientId" - val clientSecret = "thisIsClientSecret" - val redirectUri = "thisIsRedirectUri" - - val tokenProvider = mockk(relaxed = true) - val gAuth = mockk() - val memberRepository = mockk() - val refreshTokenRepository = mockk() - val authConverter = mockk() - val gAuthProperties = GAuthProperties(clientId = clientId, clientSecret = clientSecret, redirectUri = redirectUri) - val authUtil = AuthUtilImpl( - refreshTokenRepository = refreshTokenRepository, - authConverter = authConverter, - ) - - val signInService = SignInGAuthServiceImpl( - gAuthProperties = gAuthProperties, - memberRepository = memberRepository, - tokenProvider = tokenProvider, - gAuth = gAuth, - authUtil = authUtil, - authConverter = authConverter - ) - - given("gAuth로 로그인 요청이 갔을때") { - val code = "thisIsCode" - - val map: Map = mapOf( - "accessToken" to "thisIsAccessToken", - "refreshToken" to "thisIsRefreshToken" - ) - - - val gAuthToken = GAuthToken(map) - every { - gAuth.generateToken( - code, - gAuthProperties.clientId, - gAuthProperties.clientSecret, - gAuthProperties.redirectUri - ) - } returns gAuthToken - - val accessToken = "thisIsAccessToken" - val refreshToken = "thisIsRefreshToken" - - val role = Role.ROLE_MEMBER - val member = Member(1, "최민욱", "string1!","2216", "s22034@gsm.hs.kr", Gender.MAN, mutableListOf(role), mutableListOf(), null) - - val userMap: Map = mapOf( - "email" to member.email, - "name" to "최민욱", - "grade" to 2, - "classNum" to 2, - "num" to 16, - "gender" to "MALE", - "profileUrl" to "https://project-miso.s3.ap-northeast-2.amazonaws.com/file/Rectangle+2083.png", - "role" to "ROLE_STUDENT" - ) - - val gAuthUserInfo = GAuthUserInfo(userMap) - - every { - gAuth.getUserInfo( - gAuthToken.accessToken - ) - } returns gAuthUserInfo - - val refreshTokenEntity = RefreshToken( - memberId = member.id, - token = refreshToken - ) - - every { - authUtil.saveNewRefreshToken(memberInfo = member, refreshToken = refreshToken) - } returns refreshTokenEntity - - val signInDto = SignInGAuthDto( - code = "thisIsCode" - ) - - every { - tokenProvider.generateAccessToken(gAuthUserInfo.email, role) - } returns accessToken - - every { - tokenProvider.generateRefreshToken(gAuthUserInfo.email, role) - } returns refreshToken - - val accessExp = tokenProvider.accessExpiredTime - val refreshExp = tokenProvider.refreshExpiredTime - val expiresAt = tokenProvider.accessExpiredTime - - every { - tokenProvider.accessExpiredTime - } returns accessExp - - every { - tokenProvider.refreshExpiredTime - } returns refreshExp - - every { - authConverter.toEntity(gAuthUserInfo, role) - } returns member - - every { - authConverter.toEntity(member, refreshToken) - } returns refreshTokenEntity - - every { - memberRepository.save(member) - } returns member - - memberRepository.save(member) - - every { - refreshTokenRepository.save(refreshTokenEntity) - } returns refreshTokenEntity - - refreshTokenRepository.save(refreshTokenEntity) - - `when`("signInDto가 주어지고 유저가 첫 로그인 시도 일때") { - - every { - memberRepository.findByEmail(gAuthUserInfo.email) - } returns null - - every { - memberRepository.existsByEmail(gAuthUserInfo.email) - } returns false - - then("user insert 쿼리가 실행되어야 함") { - verify(exactly = 1) { memberRepository.save(member) } - } - - then("refreshToken insert 쿼리가 실행되어야 함") { - verify(exactly = 1) { refreshTokenRepository.save(refreshTokenEntity) } - } - - val result = signInService.execute(signInDto) - then("토큰 값 비교") { - result.accessToken shouldBe accessToken - result.refreshToken shouldBe refreshToken - result.accessExp shouldBe accessExp - result.refreshExp shouldBe refreshExp - } - - } - - - `when`("signInDto가 주어지고 유저가 로그인 했던 유저라면") { - - every { - memberRepository.findByEmail(gAuthUserInfo.email) - } returns member - - every { - memberRepository.existsByEmail(gAuthUserInfo.email) - } returns true - - then("user insert 쿼리가 실행되지 않는다") { - verify { memberRepository.save(member) wasNot Called } - } - - then("refreshToken update 쿼리가 실행되어야 함") { - verify(exactly = 2) { refreshTokenRepository.save(refreshTokenEntity) } - } - - val result = signInService.execute(signInDto) - then("토큰 값 비교") { - result.accessToken shouldBe accessToken - result.refreshToken shouldBe refreshToken - result.accessExp shouldBe accessExp - result.refreshExp shouldBe refreshExp - result.roles shouldBe member.roles - result.expiresAt shouldBe expiresAt - } - } - - } - -}) \ No newline at end of file diff --git a/src/test/kotlin/com/dotori/v2/util/AuthDataUtil.kt b/src/test/kotlin/com/dotori/v2/util/AuthDataUtil.kt index df1e433c..697417e8 100644 --- a/src/test/kotlin/com/dotori/v2/util/AuthDataUtil.kt +++ b/src/test/kotlin/com/dotori/v2/util/AuthDataUtil.kt @@ -1,20 +1,11 @@ package com.dotori.v2.util import com.dotori.v2.domain.auth.domain.entity.RefreshToken -import com.dotori.v2.domain.auth.presentation.data.dto.SignInGAuthDto -import com.dotori.v2.domain.auth.presentation.data.req.SignInGAuthReqDto import com.dotori.v2.domain.auth.presentation.data.res.SignInResDto import com.dotori.v2.domain.member.enums.Role import java.time.ZonedDateTime object AuthDataUtil { - fun signInRequestDto(code: String) = SignInGAuthReqDto( - code = code - ) - - fun signInDto(code: String) = SignInGAuthDto( - code = code - ) fun signInResponseDto( accessToken: String,