Skip to content

Commit

Permalink
Merge pull request #81 from KUSITMS-29th-TEAM-B/feat/flight-78
Browse files Browse the repository at this point in the history
feat : JD 공고 조회 필터링 기능 추가
  • Loading branch information
isprogrammingfun authored May 19, 2024
2 parents 7ffcd45 + 486d16a commit 73d5014
Show file tree
Hide file tree
Showing 21 changed files with 223 additions and 147 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.bamyanggang.apimodule.common.dto

import com.bamyanggang.domainmodule.common.pagination.PageDomain

data class PageResponse<T>(
val content: List<T>,
val page: Int,
val size: Int,
val totalPage: Int,
val hasNext: Boolean
) {
companion object {
fun <T> from(page: PageDomain<T>): PageResponse<T> {
return PageResponse(
content = page.content,
page = page.pageNumber,
size = page.pageSize,
totalPage = page.totalPage,
hasNext = page.hasNext
)
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
package com.bamyanggang.apimodule.domain.jobDescription.application.service

import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateApply
import com.bamyanggang.domainmodule.domain.jobDescription.enums.WriteStatus
import com.bamyanggang.domainmodule.domain.jobDescription.service.ApplyAppender
import com.bamyanggang.domainmodule.domain.jobDescription.service.ApplyContentAppender
import com.bamyanggang.domainmodule.domain.jobDescription.service.JobDescriptionModifier
import com.bamyanggang.domainmodule.domain.jobDescription.service.JobDescriptionReader
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.*

@Service
class ApplyCreateService(
private val applyAppender: ApplyAppender,
private val applyContentAppender: ApplyContentAppender
private val applyContentAppender: ApplyContentAppender,
private val jobDescriptionReader: JobDescriptionReader,
private val jobDescriptionModifier: JobDescriptionModifier
) {
@Transactional
fun createApply(request: CreateApply.Request, jobDescriptionId: UUID) {
applyAppender.appendApply(
jobDescriptionId = jobDescriptionId,
).also { apply ->
request.contents.forEach { content ->
applyContentAppender.appendApplyContent(
applyId = apply.id,
question = content.question,
answer = content.answer
)
jobDescriptionReader.readJobDescriptionById(jobDescriptionId).also {
jobDescriptionModifier.modifyWriteStatus(it, WriteStatus.WRITING)
applyAppender.appendApply(it.id).also { apply ->
request.contents.forEach { content ->
applyContentAppender.appendApplyContent(
applyId = apply.id,
question = content.question,
answer = content.answer
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,43 @@
package com.bamyanggang.apimodule.domain.jobDescription.application.service

import com.bamyanggang.apimodule.common.dto.SliceResponse
import com.bamyanggang.apimodule.common.dto.PageResponse
import com.bamyanggang.apimodule.common.getAuthenticationPrincipal
import com.bamyanggang.apimodule.domain.jobDescription.application.dto.GetJobDescriptionInfo
import com.bamyanggang.domainmodule.common.pagination.SliceDomain
import com.bamyanggang.domainmodule.common.pagination.PageDomain
import com.bamyanggang.domainmodule.domain.jobDescription.enums.SortType
import com.bamyanggang.domainmodule.domain.jobDescription.enums.WriteStatus
import com.bamyanggang.domainmodule.domain.jobDescription.service.ApplyReader
import com.bamyanggang.domainmodule.domain.jobDescription.service.JobDescriptionReader
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.SliceImpl
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional


@Service
class JobDescriptionInfoGetService(
private val jobDescriptionReader: JobDescriptionReader,
private val applyReader: ApplyReader
) {

@Transactional(readOnly = true)
fun getJobDescriptionInfo(pageable: Pageable, writeStatus: WriteStatus?, sortType: SortType?): SliceResponse<GetJobDescriptionInfo.Response> {
fun getJobDescriptionInfo(pageable: Pageable, writeStatus: WriteStatus?, sortType: SortType?): PageResponse<GetJobDescriptionInfo.Response> {
return getAuthenticationPrincipal().let{ userId ->
val jobDescriptions = jobDescriptionReader.readJobDescriptionByUserIdAndSortType(userId, pageable.pageNumber, pageable.pageSize, sortType)
val jobDescriptions = jobDescriptionReader.readJobDescriptionByUserIdAndSortType(userId, pageable.pageNumber, pageable.pageSize, sortType, writeStatus)

val jobDescriptionInfoResponses = jobDescriptions.content.map{ jobDescription ->
val apply = applyReader.readApplyByJobDescriptionId(jobDescription.id)
GetJobDescriptionInfo.Response(
jobDescription.id,
jobDescription.getRemainingDate(),
jobDescription.enterpriseName,
jobDescription.title,
apply?.writeStatus?: WriteStatus.NOT_APPLIED,
jobDescription.writeStatus,
jobDescription.createdAt,
jobDescription.startedAt,
jobDescription.endedAt
)
}

val jobDescriptionsSlice = SliceDomain(jobDescriptionInfoResponses, jobDescriptions.pageNumber, jobDescriptions.pageSize, jobDescriptions.hasNext)
SliceResponse.from(jobDescriptionsSlice)
val jobDescriptionsSlice = PageDomain(jobDescriptionInfoResponses, jobDescriptions.pageNumber, jobDescriptions.pageSize, jobDescriptions.totalPage,
jobDescriptions.hasNext)
PageResponse.from(jobDescriptionsSlice)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.bamyanggang.apimodule.domain.jobDescription.presentation

import com.bamyanggang.apimodule.common.dto.SliceResponse
import com.bamyanggang.apimodule.common.dto.PageResponse
import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateApply
import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateJobDescription
import com.bamyanggang.apimodule.domain.jobDescription.application.dto.GetJobDescriptionInfo
Expand Down Expand Up @@ -41,7 +41,7 @@ class JobDescriptionController(
pageable: Pageable,
@RequestParam writeStatus: WriteStatus?,
@RequestParam sortType: SortType?
): SliceResponse<GetJobDescriptionInfo.Response> {
): PageResponse<GetJobDescriptionInfo.Response> {
return jobDescriptionInfoGetService.getJobDescriptionInfo(pageable, writeStatus, sortType)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,69 @@ import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateApp
import com.bamyanggang.apimodule.domain.jobDescription.application.service.ApplyCreateService
import com.bamyanggang.commonmodule.fixture.generateFixture
import com.bamyanggang.domainmodule.domain.jobDescription.aggregate.Apply
import com.bamyanggang.domainmodule.domain.jobDescription.aggregate.JobDescription
import com.bamyanggang.domainmodule.domain.jobDescription.enums.WriteStatus
import com.bamyanggang.domainmodule.domain.jobDescription.service.ApplyAppender
import com.bamyanggang.domainmodule.domain.jobDescription.service.ApplyContentAppender
import com.bamyanggang.domainmodule.domain.jobDescription.service.JobDescriptionModifier
import com.bamyanggang.domainmodule.domain.jobDescription.service.JobDescriptionReader
import io.kotest.core.spec.style.BehaviorSpec
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import java.time.LocalDateTime
import java.util.*



class ApplyCreateServiceTest : BehaviorSpec({
val applyAppender = mockk<ApplyAppender>()
val applyContentAppender = mockk<ApplyContentAppender>()
val applyCreateService = ApplyCreateService(applyAppender, applyContentAppender)
val jobDescriptionReader = mockk<JobDescriptionReader>()
val jobDescriptionModifier = mockk<JobDescriptionModifier>()
val applyCreateService = ApplyCreateService(applyAppender, applyContentAppender, jobDescriptionReader, jobDescriptionModifier)

Given("CreateApply.Request 와 jobDescriptionId이 들어온 경우") {
val request = generateFixture<CreateApply.Request>()
val jobDescriptionId = UUID.randomUUID()
val jobDescription : JobDescription = generateFixture{
it.set("id", jobDescriptionId)
it.set("enterpriseName", "기업 이름")
it.set("title", "직무 공고 제목")
it.set("content", "직무 공고 내용")
it.set("link", "직무 공고 링크")
it.set("startedAt", LocalDateTime.now())
it.set("endedAt", LocalDateTime.now().plusDays(1))
}
val apply = generateFixture<Apply>()

given("ApplyCreateService.createApply") {
`when`("request가 주어지면") {
val request: CreateApply.Request = generateFixture()
val jobDescriptionId: UUID = generateFixture()
val apply: Apply = generateFixture()
every { applyAppender.appendApply(any()) } returns apply
every { applyContentAppender.appendApplyContent(any(), any(), any()) } returns Unit
every { jobDescriptionReader.readJobDescriptionById(jobDescriptionId) } returns jobDescription
every { applyAppender.appendApply(jobDescriptionId) } returns apply
every { applyContentAppender.appendApplyContent(any(), any(), any()) } returns Unit
every { jobDescriptionModifier.modifyWriteStatus(any(), any()) } returns Unit

When("createApply가 호출된다") {
applyCreateService.createApply(request, jobDescriptionId)

then("appendApply가 호출된다.") {
verify { applyAppender.appendApply( jobDescriptionId) }
Then("applyAppender.appendApply가 호출된다") {
verify { applyAppender.appendApply(jobDescriptionId) }
}

then("appendApplyContent가 호출된다.") {
Then("applyContentAppender.appendApplyContent가 호출된다") {
request.contents.forEach { content ->
verify { applyContentAppender.appendApplyContent(apply.id, content.question, content.answer) }
verify {
applyContentAppender.appendApplyContent(
applyId = apply.id,
question = content.question,
answer = content.answer
)
}
}
}

Then("jobDescriptionModifier.modifyWriteStatus 가 호출된다") {
verify { jobDescriptionModifier.modifyWriteStatus(jobDescription, WriteStatus.WRITING) }
}
}
}
})
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.bamyanggang.apimodule.domain.jobDescription.presentation

import com.bamyanggang.apimodule.BaseRestDocsTest
import com.bamyanggang.apimodule.common.dto.SliceResponse
import com.bamyanggang.apimodule.common.dto.PageResponse
import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateApply
import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateApplyContent
import com.bamyanggang.apimodule.domain.jobDescription.application.dto.CreateJobDescription
Expand All @@ -11,19 +11,16 @@ import com.bamyanggang.apimodule.domain.jobDescription.application.service.JobDe
import com.bamyanggang.apimodule.domain.jobDescription.application.service.JobDescriptionInfoGetService
import com.bamyanggang.commonmodule.exception.ExceptionHandler
import com.bamyanggang.commonmodule.fixture.generateFixture
import com.bamyanggang.domainmodule.common.pagination.SliceDomain
import com.bamyanggang.domainmodule.common.pagination.PageDomain
import com.bamyanggang.domainmodule.domain.jobDescription.enums.SortType
import com.bamyanggang.domainmodule.domain.jobDescription.enums.WriteStatus
import io.kotest.assertions.print.printWithType
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.mockito.BDDMockito.given
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.context.annotation.Import
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Slice
import org.springframework.data.domain.SliceImpl
import org.springframework.http.MediaType
import org.springframework.restdocs.headers.HeaderDocumentation.headerWithName
import org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders
Expand Down Expand Up @@ -260,9 +257,9 @@ class JobDescriptionControllerTest : BaseRestDocsTest() {
it.set("startedAt", LocalDateTime.now())
it.set("endedAt", LocalDateTime.now()) }

val slice = SliceDomain(listOf(getJobDescriptionInfoResponse), 0, 1, true)
val sliceResponse = SliceResponse.from(slice)
given(jobDescriptionInfoGetService.getJobDescriptionInfo(pageRequest, WriteStatus.WRITING, SortType.ENDED)).willReturn(sliceResponse)
val slice = PageDomain(listOf(getJobDescriptionInfoResponse), 0, 1, 5, true)
val pageResponse = PageResponse.from(slice)
given(jobDescriptionInfoGetService.getJobDescriptionInfo(pageRequest, WriteStatus.WRITING, SortType.ENDED)).willReturn(pageResponse)


val request = RestDocumentationRequestBuilders.get(JobDescriptionApi.BASE_URL)
Expand Down Expand Up @@ -302,6 +299,7 @@ class JobDescriptionControllerTest : BaseRestDocsTest() {
fieldWithPath("content[].endedAt").description("종료일"),
fieldWithPath("page").description("요청 페이지"),
fieldWithPath("size").description("요청 사이즈"),
fieldWithPath("totalPage").description("전체 페이지 수"),
fieldWithPath("hasNext").description("다음 데이터 존재 여부")
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,32 @@ inline fun <reified T> generateFixture(propertyBuilder: (ArbitraryBuilder<T>) ->

// 특정 속성 없는 임의 객체 생성
inline fun <reified T> generateFixture(): T {
return generateFixture { it }
}

// 기본 타입의 임의의 객체
inline fun <reified T> generateBasicTypeFixture(length: Int): T {
return FixtureMonkey.builder()
.defaultNotNull(true)
.plugin(KotlinPlugin())
.build()
.giveMeBuilder<T>()
.sample()
}

// 기본 타입의 임의의 객체
inline fun <reified T> generateBasicTypeFixture(length: Int): T {
return if (T::class == String::class) {
FixtureMonkey.builder()
.defaultNotNull(true)
.plugin(KotlinPlugin())
.build()
.giveMeBuilder<T>()
.sample()
.toString()
.take(length) as T
} else {
FixtureMonkey.builder()
.defaultNotNull(true)
.plugin(KotlinPlugin())
.build()
.giveMeBuilder<T>()
.sample()
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.bamyanggang.domainmodule.common.pagination

data class SliceDomain<T>(
data class PageDomain<T>(
val content: List<T>,
val pageNumber: Int,
val pageSize: Int,
val totalPage: Int,
val hasNext: Boolean
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import java.util.UUID

data class Apply(
override val id : UUID = UuidCreator.create(),
val writeStatus: WriteStatus = WriteStatus.WRITING,
val createdAt: LocalDateTime,
val updatedAt: LocalDateTime,
val jobDescriptionId: UUID,
Expand All @@ -27,14 +26,12 @@ data class Apply(

fun toDomain(
id: UUID,
writeStatus: WriteStatus,
createdAt: LocalDateTime,
updatedAt: LocalDateTime,
jobDescriptionId: UUID
): Apply {
return Apply(
id = id,
writeStatus = writeStatus,
createdAt = createdAt,
updatedAt = updatedAt,
jobDescriptionId = jobDescriptionId
Expand Down
Loading

0 comments on commit 73d5014

Please sign in to comment.