Skip to content
Closed
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
2 changes: 2 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ name: Sarang Backend CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
ci:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package gomushin.backend.schedule.domain.facade

import gomushin.backend.core.CustomUserDetails
import gomushin.backend.core.common.support.SpringContextHolder
import gomushin.backend.core.configuration.env.AppEnv
import gomushin.backend.core.infrastructure.exception.BadRequestException
import gomushin.backend.member.domain.entity.Member
import gomushin.backend.member.domain.service.MemberService
import gomushin.backend.schedule.domain.entity.Comment
Expand All @@ -9,90 +12,182 @@ import gomushin.backend.schedule.domain.service.CommentService
import gomushin.backend.schedule.domain.service.LetterService
import gomushin.backend.schedule.dto.request.UpsertCommentRequest
import gomushin.backend.schedule.facade.UpsertAndDeleteCommentFacade
import io.mockk.every
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.verify
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.junit.jupiter.MockitoExtension
import kotlin.test.Test
import kotlin.test.assertEquals

@ExtendWith(MockitoExtension::class)
@ExtendWith(MockKExtension::class)
class UpsertAndDeleteCommentFacadeTest {

@Mock
@MockK
private lateinit var commentService: CommentService

@Mock
@MockK
private lateinit var letterService: LetterService

@Mock
@MockK
private lateinit var memberService: MemberService

@InjectMocks
@InjectMockKs
private lateinit var upsertAndDeleteCommentFacade: UpsertAndDeleteCommentFacade

private val customUserDetails = mockk<CustomUserDetails>()

@BeforeEach
fun setUp() {
mockkObject(SpringContextHolder)
val mockAppEnv = mockk<AppEnv>()
every { SpringContextHolder.getBean(AppEnv::class.java) } returns mockAppEnv
every { mockAppEnv.getId() } returns "test"
}

init {
every { customUserDetails.getId() } returns 1L
}

@DisplayName("댓글 생성 또는 수정 성공")
@Test
fun upsert_success() {
// given
val customUserDetails = mock(CustomUserDetails::class.java)
val letterId = 1L
val letter = mockk<Letter>()
val memberId = 1L
val upsertCommentRequest = UpsertCommentRequest(
commentId = null,
content = "댓글 내용"
val member = mockk<Member>()
val commentId = 1L
val upsertCommentRequest = mockk<UpsertCommentRequest>()

every { upsertCommentRequest.commentId } returns commentId
every { memberService.getById(memberId) } returns member
every { letterService.getById(letterId) } returns letter
every { letter.id } returns letterId
every { member.id } returns memberId
every { member.nickname } returns "작성자"
every {
commentService.upsert(
id = eq(commentId),
letterId = eq(letterId),
authorId = eq(memberId),
nickname = eq("작성자"),
upsertCommentRequest = eq(upsertCommentRequest)
)
} returns Unit

// when
upsertAndDeleteCommentFacade.upsert(
customUserDetails,
letterId,
upsertCommentRequest
)

val mockMember = mock(Member::class.java).apply {
`when`(id).thenReturn(memberId)
`when`(nickname).thenReturn("테스트유저")
}
val mockLetter = mock(Letter::class.java).apply {
`when`(id).thenReturn(letterId)
// then
verify(exactly = 1) {
memberService.getById(memberId)
letterService.getById(letterId)
commentService.upsert(
id = eq(commentId),
letterId = eq(letterId),
authorId = eq(memberId),
nickname = eq("작성자"),
upsertCommentRequest = eq(upsertCommentRequest)
)
}
}

`when`(customUserDetails.getId()).thenReturn(memberId)
`when`(memberService.getById(memberId)).thenReturn(mockMember)
`when`(letterService.getById(letterId)).thenReturn(mockLetter)
@DisplayName("delete 성공")
@Test
fun delete() {
// given
val letterId = 1L
val commentId = 1L
val member = mockk<Member>()
val comment = mockk<Comment>()
every { memberService.getById(1L) } returns member
every { commentService.getById(commentId) } returns comment
every { member.id } returns 1L
every { comment.authorId } returns 1L
every { comment.letterId } returns letterId
every { commentService.delete(commentId) } returns Unit

// when
upsertAndDeleteCommentFacade.upsert(customUserDetails, letterId, upsertCommentRequest)
upsertAndDeleteCommentFacade.delete(
customUserDetails,
letterId,
commentId
)

// then
verify(commentService, times(1)).upsert(
id = upsertCommentRequest.commentId,
letterId = mockLetter.id,
authorId = mockMember.id,
nickname = "테스트유저",
upsertCommentRequest = upsertCommentRequest
)
verify(exactly = 1) {
memberService.getById(1L)
commentService.getById(commentId)
commentService.delete(commentId)
}
}

@DisplayName("댓글 삭제 성공")
@DisplayName("delete 실패 - 작성자가 아닌 경우")
@Test
fun delete_success() {
fun delete_fail_not_author() {
// given
val customUserDetails = mock(CustomUserDetails::class.java)
val letterId = 1L
val commentId = 1L
val mockMember = mock(Member::class.java)
val mockComment = mock(Comment::class.java)
val member = mockk<Member>()
val comment = mockk<Comment>()
every { memberService.getById(1L) } returns member
every { commentService.getById(commentId) } returns comment
every { member.id } returns 2L
every { comment.authorId } returns 1L
every { comment.letterId } returns letterId

// when
`when`(customUserDetails.getId()).thenReturn(1L)
`when`(memberService.getById(customUserDetails.getId())).thenReturn(mockMember)
`when`(commentService.getById(commentId)).thenReturn(mockComment)
`when`(mockMember.id).thenReturn(1L)
`when`(mockComment.authorId).thenReturn(1L)
`when`(mockComment.letterId).thenReturn(letterId)
`when`(mockComment.letterId).thenReturn(letterId)
// when & then
val exception = assertThrows<BadRequestException> {
upsertAndDeleteCommentFacade.delete(
customUserDetails,
letterId,
commentId
)
}

upsertAndDeleteCommentFacade.delete(customUserDetails, letterId, commentId)
val message = exception.error.element.message.resolved

// then
verify(memberService, times(1)).getById(customUserDetails.getId())
verify(commentService, times(1)).getById(commentId)
verify(commentService, times(1)).delete(commentId)
assertEquals("댓글은 작성자만 삭제하거나 업데이트 할 수 있어요.", message)
}

@DisplayName("delete 실패 - letterId가 일치하지 않는 경우")
@Test
fun delete_fail_invalid_letter() {
// given
val letterId = 1L
val commentId = 1L
val member = mockk<Member>()
val comment = mockk<Comment>()
every { memberService.getById(1L) } returns member
every { commentService.getById(commentId) } returns comment
every { member.id } returns 1L
every { comment.authorId } returns 1L
every { comment.letterId } returns 2L

// when & then
val exception = assertThrows<BadRequestException> {
upsertAndDeleteCommentFacade.delete(
customUserDetails,
letterId,
commentId
)
}

val message = exception.error.element.message.resolved

assertEquals("편지에 해당하는 댓글이 아니에요.", message)
}


}
Loading
Loading