diff --git a/server-profile-submodule b/server-profile-submodule index 3d2f82a9..eb24cd1e 160000 --- a/server-profile-submodule +++ b/server-profile-submodule @@ -1 +1 @@ -Subproject commit 3d2f82a9632cd0aed47eee6137f58f918f79aeda +Subproject commit eb24cd1e7c9385e121c77eaf0e775e9ea493832b diff --git a/src/main/kotlin/com/celuveat/celeb/adapter/out/persistence/InterestedCelebrityPersistenceAdapter.kt b/src/main/kotlin/com/celuveat/celeb/adapter/out/persistence/InterestedCelebrityPersistenceAdapter.kt index 3d462d60..973ea732 100644 --- a/src/main/kotlin/com/celuveat/celeb/adapter/out/persistence/InterestedCelebrityPersistenceAdapter.kt +++ b/src/main/kotlin/com/celuveat/celeb/adapter/out/persistence/InterestedCelebrityPersistenceAdapter.kt @@ -66,4 +66,8 @@ class InterestedCelebrityPersistenceAdapter( ): Boolean { return interestedCelebrityJpaRepository.existsByMemberIdAndCelebrityId(memberId, celebrityId) } + + override fun countByMemberId(memberId: Long): Int { + return interestedCelebrityJpaRepository.countByMemberId(memberId).toInt() + } } diff --git a/src/main/kotlin/com/celuveat/celeb/adapter/out/persistence/entity/InterestedCelebrityJpaRepository.kt b/src/main/kotlin/com/celuveat/celeb/adapter/out/persistence/entity/InterestedCelebrityJpaRepository.kt index 889c85d9..517bf285 100644 --- a/src/main/kotlin/com/celuveat/celeb/adapter/out/persistence/entity/InterestedCelebrityJpaRepository.kt +++ b/src/main/kotlin/com/celuveat/celeb/adapter/out/persistence/entity/InterestedCelebrityJpaRepository.kt @@ -16,4 +16,6 @@ interface InterestedCelebrityJpaRepository : JpaRepository, ): List + + fun countByMemberId(memberId: Long): Long } diff --git a/src/main/kotlin/com/celuveat/restaurant/application/port/out/ReadInterestedRestaurantPort.kt b/src/main/kotlin/com/celuveat/restaurant/application/port/out/ReadInterestedRestaurantPort.kt index 5f184d66..36cd1b31 100644 --- a/src/main/kotlin/com/celuveat/restaurant/application/port/out/ReadInterestedRestaurantPort.kt +++ b/src/main/kotlin/com/celuveat/restaurant/application/port/out/ReadInterestedRestaurantPort.kt @@ -19,4 +19,6 @@ interface ReadInterestedRestaurantPort { memberId: Long, restaurantIds: List, ): List + + fun countByMemberId(memberId: Long): Int } diff --git a/src/main/kotlin/com/celuveat/review/adapter/out/persistence/ReviewPersistenceAdapter.kt b/src/main/kotlin/com/celuveat/review/adapter/out/persistence/ReviewPersistenceAdapter.kt index f78b62e9..1f4046f1 100644 --- a/src/main/kotlin/com/celuveat/review/adapter/out/persistence/ReviewPersistenceAdapter.kt +++ b/src/main/kotlin/com/celuveat/review/adapter/out/persistence/ReviewPersistenceAdapter.kt @@ -62,6 +62,10 @@ class ReviewPersistenceAdapter( ) } + override fun countByWriterId(memberId: Long): Int { + return reviewJpaRepository.countByWriterId(memberId).toInt() + } + companion object { val LATEST_SORTER = Sort.by("createdAt").descending() } diff --git a/src/main/kotlin/com/celuveat/review/adapter/out/persistence/entity/ReviewJpaRepository.kt b/src/main/kotlin/com/celuveat/review/adapter/out/persistence/entity/ReviewJpaRepository.kt index 71abec8b..31d52778 100644 --- a/src/main/kotlin/com/celuveat/review/adapter/out/persistence/entity/ReviewJpaRepository.kt +++ b/src/main/kotlin/com/celuveat/review/adapter/out/persistence/entity/ReviewJpaRepository.kt @@ -15,4 +15,6 @@ interface ReviewJpaRepository : JpaRepository { restaurantsId: Long, page: Pageable, ): Slice + + fun countByWriterId(writerId: Long): Long } diff --git a/src/main/kotlin/com/celuveat/review/application/port/out/ReadReviewPort.kt b/src/main/kotlin/com/celuveat/review/application/port/out/ReadReviewPort.kt index f1a8dc32..4718cdf1 100644 --- a/src/main/kotlin/com/celuveat/review/application/port/out/ReadReviewPort.kt +++ b/src/main/kotlin/com/celuveat/review/application/port/out/ReadReviewPort.kt @@ -11,4 +11,6 @@ interface ReadReviewPort { page: Int, size: Int, ): SliceResult + + fun countByWriterId(memberId: Long): Int } diff --git a/src/test/kotlin/com/celuveat/member/adapter/in/rest/MemberControllerTest.kt b/src/test/kotlin/com/celuveat/member/adapter/in/rest/MemberControllerTest.kt new file mode 100644 index 00000000..777050fe --- /dev/null +++ b/src/test/kotlin/com/celuveat/member/adapter/in/rest/MemberControllerTest.kt @@ -0,0 +1,101 @@ +package com.celuveat.member.adapter.`in`.rest + +import com.celuveat.auth.application.port.`in`.ExtractMemberIdUseCase +import com.celuveat.member.adapter.`in`.rest.request.UpdateProfileRequest +import com.celuveat.member.adapter.`in`.rest.response.MemberProfileResponse +import com.celuveat.member.application.port.`in`.ReadMemberUseCase +import com.celuveat.member.application.port.`in`.UpdateProfileUseCase +import com.celuveat.member.application.port.`in`.result.MemberProfileResult +import com.celuveat.support.sut +import com.fasterxml.jackson.databind.ObjectMapper +import com.navercorp.fixturemonkey.kotlin.giveMeBuilder +import com.navercorp.fixturemonkey.kotlin.setNotNullExp +import com.ninjasquad.springmockk.MockkBean +import io.kotest.core.spec.style.FunSpec +import io.kotest.core.test.TestCase +import io.kotest.core.test.TestResult +import io.mockk.Runs +import io.mockk.clearAllMocks +import io.mockk.every +import io.mockk.just +import io.mockk.unmockkAll +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.get +import org.springframework.test.web.servlet.patch + +@WebMvcTest(MemberController::class) +class MemberControllerTest( + @Autowired val mockMvc: MockMvc, + @Autowired val mapper: ObjectMapper, + @MockkBean val readMemberUseCase: ReadMemberUseCase, + @MockkBean val updateProfileUseCase: UpdateProfileUseCase, + // for AuthMemberArgumentResolver + @MockkBean val extractMemberIdUseCase: ExtractMemberIdUseCase, +) : FunSpec({ + + context("회원 정보를 조회한다") { + val memberId = 1L + val accessToken = "celuveatAccessToken" + val result = sut.giveMeOne(MemberProfileResult::class.java) + val response = MemberProfileResponse.from(result) + + test("회원 정보 조회 성공") { + every { readMemberUseCase.readMember(memberId) } returns result + every { extractMemberIdUseCase.extract(accessToken) } returns memberId + + mockMvc.get("/members/profile") { + header("Authorization", "Bearer $accessToken") + }.andExpect { + status { isOk() } + content { json(mapper.writeValueAsString(response)) } + }.andDo { + print() + } + } + + test("비회원인 경우 실패") { + mockMvc.get("/members/profile") { + }.andExpect { + status { isUnauthorized() } + }.andDo { + print() + } + } + } + + context("회원 정보를 수정한다") { + val memberId = 1L + val accessToken = "celuveatAccessToken" + val request = sut.giveMeBuilder() + .setNotNullExp(UpdateProfileRequest::nickname) + .setNotNullExp(UpdateProfileRequest::profileImageUrl) + .sample() + val command = request.toCommand(memberId) + + test("회원 정보 수정 성공") { + every { updateProfileUseCase.updateProfile(command) } just Runs + every { extractMemberIdUseCase.extract(accessToken) } returns memberId + + mockMvc.patch("/members/profile") { + header("Authorization", "Bearer $accessToken") + contentType = MediaType.APPLICATION_JSON + content = mapper.writeValueAsString(request) + }.andExpect { + status { isOk() } + }.andDo { + print() + } + } + } +}) { + override suspend fun afterEach( + testCase: TestCase, + result: TestResult, + ) { + clearAllMocks() + unmockkAll() + } +} diff --git a/src/test/kotlin/com/celuveat/member/application/SocialLoginServiceTest.kt b/src/test/kotlin/com/celuveat/member/application/SocialLoginServiceTest.kt index f487fb28..3952f1f7 100644 --- a/src/test/kotlin/com/celuveat/member/application/SocialLoginServiceTest.kt +++ b/src/test/kotlin/com/celuveat/member/application/SocialLoginServiceTest.kt @@ -53,7 +53,9 @@ class SocialLoginServiceTest : BehaviorSpec({ .set(Member::id, 0L) .set(Member::socialIdentifier, socialIdentifier) .sample() - val savedMember = member.copy(id = 1L) + val savedMember = sut.giveMeBuilder(member) + .set(Member::id, 1L) + .sample() When("최초 회원인 경우") { every { fetchSocialMemberPort.fetchMember(serverType, authCode, redirectUrl) } returns member