diff --git a/server/src/main/kotlin/com/fone/filmone/config/SwaggerConfig.kt b/server/src/main/kotlin/com/fone/filmone/config/SwaggerConfig.kt index f325ba57..c96409a1 100644 --- a/server/src/main/kotlin/com/fone/filmone/config/SwaggerConfig.kt +++ b/server/src/main/kotlin/com/fone/filmone/config/SwaggerConfig.kt @@ -5,8 +5,6 @@ import com.fone.competition.presentation.dto.RegisterCompetitionDto.RegisterComp import com.fone.competition.presentation.dto.RetrieveCompetitionDto.RetrieveCompetitionResponse import com.fone.competition.presentation.dto.RetrieveCompetitionDto.RetrieveCompetitionsResponse import com.fone.competition.presentation.dto.RetrieveCompetitionScrapDto.RetrieveCompetitionScrapResponse -import com.fone.jobOpening.presentation.dto.LocationDto.RetrieveDistrictsResponse -import com.fone.jobOpening.presentation.dto.LocationDto.RetrieveRegionsResponse import com.fone.jobOpening.presentation.dto.RegisterJobOpeningDto.RegisterJobOpeningResponse import com.fone.jobOpening.presentation.dto.RetrieveJobOpeningDto.RetrieveJobOpeningResponse import com.fone.jobOpening.presentation.dto.RetrieveJobOpeningDto.RetrieveJobOpeningsResponse @@ -14,6 +12,8 @@ import com.fone.jobOpening.presentation.dto.RetrieveJobOpeningMyRegistrationDto. import com.fone.jobOpening.presentation.dto.RetrieveJobOpeningScrapDto.RetrieveJobOpeningScrapResponse import com.fone.jobOpening.presentation.dto.RetrieveMySimilarJobOpeningDto.RetrieveMySimilarJobOpeningResponse import com.fone.jobOpening.presentation.dto.ScrapJobOpeningDto.ScrapJobOpeningResponse +import com.fone.jobOpening.presentation.dto.common.LocationDto.RetrieveDistrictsResponse +import com.fone.jobOpening.presentation.dto.common.LocationDto.RetrieveRegionsResponse import com.fone.profile.presentation.dto.RegisterProfileDto.RegisterProfileResponse import com.fone.profile.presentation.dto.RetrieveProfileMyRegistrationDto.RetrieveProfileMyRegistrationResponse import com.fone.profile.presentation.dto.RetrieveProfileWantDto.RetrieveProfileWantResponse diff --git a/server/src/main/kotlin/com/fone/jobOpening/domain/service/LocationService.kt b/server/src/main/kotlin/com/fone/jobOpening/domain/service/LocationService.kt index 1224abcb..4e707c26 100644 --- a/server/src/main/kotlin/com/fone/jobOpening/domain/service/LocationService.kt +++ b/server/src/main/kotlin/com/fone/jobOpening/domain/service/LocationService.kt @@ -1,8 +1,8 @@ package com.fone.jobOpening.domain.service import com.fone.jobOpening.domain.repository.LocationRepository -import com.fone.jobOpening.presentation.dto.LocationDto.RetrieveDistrictsResponse -import com.fone.jobOpening.presentation.dto.LocationDto.RetrieveRegionsResponse +import com.fone.jobOpening.presentation.dto.common.LocationDto.RetrieveDistrictsResponse +import com.fone.jobOpening.presentation.dto.common.LocationDto.RetrieveRegionsResponse import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional diff --git a/server/src/main/kotlin/com/fone/jobOpening/domain/service/ValidateJobOpeningService.kt b/server/src/main/kotlin/com/fone/jobOpening/domain/service/ValidateJobOpeningService.kt index c2ecc412..67e270de 100644 --- a/server/src/main/kotlin/com/fone/jobOpening/domain/service/ValidateJobOpeningService.kt +++ b/server/src/main/kotlin/com/fone/jobOpening/domain/service/ValidateJobOpeningService.kt @@ -38,7 +38,7 @@ class ValidateJobOpeningService( throw RequestValidationException("최소 1개 이상 작품의 성격을 선택해주세요.") } - validateDate(request.recruitmentStartDate, request.recruitmentEndDate) + validateDate(request.recruitmentStartDate, request.recruitmentEndDate, "모집기간") } suspend fun validateRolePage(request: ValidateJobOpeningDto.ThirdPage) { @@ -97,7 +97,7 @@ class ValidateJobOpeningService( locationRepository.findLocation(request.workingCity, request.workingDistrict) ?: throw RequestValidationException("'시', '구'가 유효하지 않습니다.") - validateDate(request.workingStartDate, request.workingEndDate) + validateDate(request.workingStartDate, request.workingEndDate, "근무시간") if (request.workingStartTime != null && request.workingEndTime != null) { return @@ -106,14 +106,6 @@ class ValidateJobOpeningService( if (request.workingStartTime == null && request.workingEndTime == null) { return } - - if (request.workingStartTime == null) { - throw RequestValidationException("근무시간의 시작과 마감 값을 올바르게 입력해 주세요.") - } - - if (request.workingEndTime == null) { - throw RequestValidationException("근무시간의 시작과 마감 값을 올바르게 입력해 주세요.") - } } suspend fun validateSummaryPage(request: ValidateJobOpeningDto.SixthPage) { @@ -134,6 +126,7 @@ class ValidateJobOpeningService( private fun validateDate( recruitmentStartDate: LocalDate?, recruitmentEndDate: LocalDate?, + displayName: String, ) { if (recruitmentStartDate == null && recruitmentEndDate == null) { // 상시모집이여서 아래 검증 로직 필요 없음 @@ -141,18 +134,18 @@ class ValidateJobOpeningService( } if (recruitmentStartDate == null) { - throw RequestValidationException("모집기간의 시작과 끝 값을 모두 입력해 주세요.") + throw RequestValidationException(displayName + "의 시작과 끝 값을 모두 입력해 주세요.") } if (recruitmentEndDate == null) { - throw RequestValidationException("모집기간의 시작과 끝 값을 모두 입력해 주세요.") + throw RequestValidationException(displayName + "의 시작과 끝 값을 모두 입력해 주세요.") } if (recruitmentStartDate.isAfter(recruitmentEndDate)) { throw RequestValidationException("마감일을 시작일보다 앞날로 입력해 주세요.") } - if (!recruitmentStartDate.isAfter(LocalDate.now())) { + if (recruitmentStartDate.isBefore(LocalDate.now())) { throw RequestValidationException("시작일은 과거의 날짜로 설정될 수 없어요.") } } diff --git a/server/src/main/kotlin/com/fone/jobOpening/infrastructure/JobOpeningRepositoryImpl.kt b/server/src/main/kotlin/com/fone/jobOpening/infrastructure/JobOpeningRepositoryImpl.kt index d6c8cfa5..17be98f1 100644 --- a/server/src/main/kotlin/com/fone/jobOpening/infrastructure/JobOpeningRepositoryImpl.kt +++ b/server/src/main/kotlin/com/fone/jobOpening/infrastructure/JobOpeningRepositoryImpl.kt @@ -16,7 +16,6 @@ import com.linecorp.kotlinjdsl.spring.data.reactive.query.SpringDataHibernateMut import com.linecorp.kotlinjdsl.spring.reactive.listQuery import com.linecorp.kotlinjdsl.spring.reactive.pageQuery import com.linecorp.kotlinjdsl.spring.reactive.querydsl.SpringDataReactiveCriteriaQueryDsl -import com.linecorp.kotlinjdsl.spring.reactive.querydsl.SpringDataReactivePageableQueryDsl import com.linecorp.kotlinjdsl.spring.reactive.singleQueryOrNull import io.smallrye.mutiny.coroutines.awaitSuspending import org.hibernate.reactive.mutiny.Mutiny @@ -262,11 +261,6 @@ class JobOpeningRepositoryImpl( return col(JobOpening::type).equal(type) } - private fun SpringDataReactivePageableQueryDsl.typeEq(type: Type?): EqualValueSpec? { - type ?: return null - return col(JobOpening::type).equal(type) - } - private fun SpringDataReactiveCriteriaQueryDsl.orderSpec(sort: Sort): List { val recruitmentEndDateIsNull = case( diff --git a/server/src/main/kotlin/com/fone/jobOpening/presentation/controller/LocationController.kt b/server/src/main/kotlin/com/fone/jobOpening/presentation/controller/LocationController.kt index 2488ee17..fe64363a 100644 --- a/server/src/main/kotlin/com/fone/jobOpening/presentation/controller/LocationController.kt +++ b/server/src/main/kotlin/com/fone/jobOpening/presentation/controller/LocationController.kt @@ -2,8 +2,8 @@ package com.fone.jobOpening.presentation.controller import com.fone.common.response.CommonResponse import com.fone.jobOpening.application.LocationFacade -import com.fone.jobOpening.presentation.dto.LocationDto.RetrieveDistrictsResponse -import com.fone.jobOpening.presentation.dto.LocationDto.RetrieveRegionsResponse +import com.fone.jobOpening.presentation.dto.common.LocationDto.RetrieveDistrictsResponse +import com.fone.jobOpening.presentation.dto.common.LocationDto.RetrieveRegionsResponse import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.v3.oas.annotations.media.Content diff --git a/server/src/main/kotlin/com/fone/jobOpening/presentation/dto/LocationDto.kt b/server/src/main/kotlin/com/fone/jobOpening/presentation/dto/common/LocationDto.kt similarity index 54% rename from server/src/main/kotlin/com/fone/jobOpening/presentation/dto/LocationDto.kt rename to server/src/main/kotlin/com/fone/jobOpening/presentation/dto/common/LocationDto.kt index bf217dba..c80e73f9 100644 --- a/server/src/main/kotlin/com/fone/jobOpening/presentation/dto/LocationDto.kt +++ b/server/src/main/kotlin/com/fone/jobOpening/presentation/dto/common/LocationDto.kt @@ -1,15 +1,15 @@ -package com.fone.jobOpening.presentation.dto +package com.fone.jobOpening.presentation.dto.common import io.swagger.v3.oas.annotations.media.Schema class LocationDto { data class RetrieveRegionsResponse( - @Schema(description = "지역", example = "서울특별시") + @Schema(description = "지역", example = "[\"서울특별시\"]") val regions: List, ) data class RetrieveDistrictsResponse( - @Schema(description = "시군구", example = "강남구") + @Schema(description = "시군구", example = "[\"강남구\"]") val districts: List, ) } diff --git a/server/src/test/kotlin/com/fone/jobOpening/infrastructure/JobOpeningRepositoryImplTest.kt b/server/src/test/kotlin/com/fone/jobOpening/infrastructure/JobOpeningRepositoryImplTest.kt new file mode 100644 index 00000000..5b745f14 --- /dev/null +++ b/server/src/test/kotlin/com/fone/jobOpening/infrastructure/JobOpeningRepositoryImplTest.kt @@ -0,0 +1,50 @@ +package com.fone.jobOpening.infrastructure + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fone.common.CommonJobOpeningCallApi +import com.fone.common.CommonUserCallApi +import com.fone.common.CustomDescribeSpec +import com.fone.common.IntegrationTest +import com.fone.common.entity.Type +import com.fone.jobOpening.domain.repository.JobOpeningRepository +import com.fone.jobOpening.presentation.dto.RetrieveJobOpeningDto +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe +import org.springframework.test.web.reactive.server.WebTestClient + +@IntegrationTest +class JobOpeningRepositoryImplTest( + client: WebTestClient, + private val objectMapper: ObjectMapper, + private val jobOpeningRepository: JobOpeningRepository, +) : + CustomDescribeSpec() { + + init { + describe("#findByFilters") { + context("빈 구인구직 리스트를 조회하면") { + it("성공한다") { + val jobOpenings = jobOpeningRepository.findByFilters( + org.springframework.data.domain.Pageable.unpaged(), + RetrieveJobOpeningDto.RetrieveJobOpeningsRequest(type = Type.ACTOR) + ) + + jobOpenings.size shouldBe 0 + } + } + } + + describe("#findById") { + context("존재하는 구인구직을 상세 조회하면") { + val (accessToken, _) = CommonUserCallApi.getAccessToken(client) + val jobOpeningId = CommonJobOpeningCallApi.register(client, accessToken) + + it("성공한다") { + val jobOpening = jobOpeningRepository.findById(1) + jobOpening shouldNotBe null + jobOpening?.id shouldBe 1 + } + } + } + } +} diff --git a/server/src/test/kotlin/com/fone/jobOpening/presentation/controller/RetrieveJobOpeningControllerTest.kt b/server/src/test/kotlin/com/fone/jobOpening/presentation/controller/RetrieveJobOpeningControllerTest.kt index c3ae0c97..b765a5b2 100644 --- a/server/src/test/kotlin/com/fone/jobOpening/presentation/controller/RetrieveJobOpeningControllerTest.kt +++ b/server/src/test/kotlin/com/fone/jobOpening/presentation/controller/RetrieveJobOpeningControllerTest.kt @@ -9,6 +9,8 @@ import com.fone.common.CustomDescribeSpec import com.fone.common.IntegrationTest import com.fone.common.PageDeserializer import com.fone.common.doGet +import com.fone.common.entity.CategoryType +import com.fone.common.entity.DomainType import com.fone.common.response.CommonResponse import com.fone.jobOpening.presentation.dto.RetrieveJobOpeningDto.RetrieveJobOpeningResponse import com.fone.jobOpening.presentation.dto.RetrieveJobOpeningDto.RetrieveJobOpeningsResponse @@ -94,5 +96,69 @@ class RetrieveJobOpeningControllerTest(client: WebTestClient, private val object } } } + describe("#retrieve jobOpenings with filters") { + context("조건에 맞는 구인구직 리스트를 조회하면") { + it("성공한다") { + val filterParams = mapOf( + "type" to "ACTOR", + "ageMin" to "20", + "ageMax" to "30" + ) + client.doGet(retrieveUrl, accessToken, filterParams) + .expectStatus().isOk.expectBody().consumeWith { println(it) } + .jsonPath("$.result").isEqualTo("SUCCESS") + } + } + } + describe("#retrieve jobOpenings sorted by viewCount") { + context("조회수(viewCount)로 정렬된 구인구직 리스트를 조회하면") { + it("성공한다") { + client.doGet(retrieveUrl, accessToken, mapOf("type" to "ACTOR", "sort" to "viewCount,desc")) + .expectStatus().isOk.expectBody().consumeWith { println(it) } + .jsonPath("$.result").isEqualTo("SUCCESS") + } + } + } + describe("#retrieve jobOpenings sorted by createdAt") { + context("생성일(createdAt)로 정렬된 구인구직 리스트를 조회하면") { + it("성공한다") { + client.doGet(retrieveUrl, accessToken, mapOf("type" to "ACTOR", "sort" to "createdAt,asc")) + .expectStatus().isOk.expectBody().consumeWith { println(it) } + .jsonPath("$.result").isEqualTo("SUCCESS") + } + } + } + describe("#retrieve jobOpenings sorted by scrapCount") { + context("스크랩수(scrapCount)로 정렬된 구인구직 리스트를 조회하면") { + it("성공한다") { + client.doGet(retrieveUrl, accessToken, mapOf("type" to "ACTOR", "sort" to "scrapCount,desc")) + .expectStatus().isOk.expectBody().consumeWith { println(it) } + .jsonPath("$.result").isEqualTo("SUCCESS") + } + } + } + describe("#retrieve jobOpenings sorted by recruitmentEndDate") { + context("모집 종료일(recruitmentEndDate)로 정렬된 구인구직 리스트를 조회하면") { + it("성공한다") { + client.doGet(retrieveUrl, accessToken, mapOf("type" to "ACTOR", "sort" to "recruitmentEndDate,asc")) + .expectStatus().isOk.expectBody().consumeWith { println(it) } + .jsonPath("$.result").isEqualTo("SUCCESS") + } + } + } + describe("#retrieve jobOpenings with domains and categories") { + context("특정 분야(domains)와 카테고리(categories)로 필터링된 구인구직 리스트를 조회하면") { + it("성공한다") { + val params = mapOf( + "type" to "ACTOR", + "domains" to listOf(DomainType.SCENARIO).joinToString(","), + "categories" to listOf(CategoryType.WEB_DRAMA).joinToString(",") + ) + client.doGet(retrieveUrl, accessToken, params) + .expectStatus().isOk.expectBody().consumeWith { println(it) } + .jsonPath("$.result").isEqualTo("SUCCESS") + } + } + } } } diff --git a/server/src/test/kotlin/com/fone/jobOpening/presentation/controller/ValidateJobOpeningControllerTest.kt b/server/src/test/kotlin/com/fone/jobOpening/presentation/controller/ValidateJobOpeningControllerTest.kt index fcd01d5c..daa1fb32 100644 --- a/server/src/test/kotlin/com/fone/jobOpening/presentation/controller/ValidateJobOpeningControllerTest.kt +++ b/server/src/test/kotlin/com/fone/jobOpening/presentation/controller/ValidateJobOpeningControllerTest.kt @@ -4,9 +4,15 @@ import com.fone.common.CommonUserCallApi import com.fone.common.CustomDescribeSpec import com.fone.common.IntegrationTest import com.fone.common.doPost +import com.fone.common.entity.Career import com.fone.common.entity.CategoryType +import com.fone.common.entity.ContactMethod +import com.fone.common.entity.DomainType +import com.fone.common.entity.Gender +import com.fone.common.entity.Genre import com.fone.common.entity.Salary import com.fone.common.entity.Weekday +import com.fone.jobOpening.presentation.dto.ValidateJobOpeningDto import com.fone.jobOpening.presentation.dto.ValidateJobOpeningDto.FifthPage import com.fone.jobOpening.presentation.dto.ValidateJobOpeningDto.SecondPage import org.springframework.test.web.reactive.server.WebTestClient @@ -18,13 +24,71 @@ class ValidateJobOpeningControllerTest(client: WebTestClient) : CustomDescribeSp val url = "/api/v1/job-openings/validate" val (accessToken, _) = CommonUserCallApi.getAccessToken(client) describe("#JobOpening 검증 API") { + context("contact 페이지") { + it("EMAIL 케이스 성공한다") { + val request = ValidateJobOpeningDto.FirstPage( + contactMethod = ContactMethod.EMAIL, + contact = "test@test.com" + ) + client.doPost("$url/contact", request, accessToken) + .expectStatus().isOk.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") + } + + it("KAKAO 케이스 성공한다") { + val request = ValidateJobOpeningDto.FirstPage( + contactMethod = ContactMethod.KAKAO, + contact = "https://open.kakao.com/test" + ) + client.doPost("$url/contact", request, accessToken) + .expectStatus().isOk.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") + } + + it("FORM 케이스 성공한다") { + val request = ValidateJobOpeningDto.FirstPage( + contactMethod = ContactMethod.GOOGLE_FORM, + contact = "https://docs.google.com/forms/test" + ) + client.doPost("$url/contact", request, accessToken) + .expectStatus().isOk.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") + } + + it("이메일 케이스 실패한다") { + val request = ValidateJobOpeningDto.FirstPage( + contactMethod = ContactMethod.EMAIL, + contact = "test" + ) + client.doPost("$url/contact", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + + it("카카오 케이스 실패한다") { + val request = ValidateJobOpeningDto.FirstPage( + contactMethod = ContactMethod.KAKAO, + contact = "https://open.kakao.co" + ) + client.doPost("$url/contact", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + + it("구글폼 케이스 실패한다") { + val request = ValidateJobOpeningDto.FirstPage( + contactMethod = ContactMethod.GOOGLE_FORM, + contact = "https://docs.google.com/form" + ) + client.doPost("$url/contact", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + } context("title 페이지") { it("성공한다") { val request = SecondPage( "제목", listOf(CategoryType.ETC), - null, - null, + LocalDate.now(), + LocalDate.now(), listOf(""), "" ) @@ -32,7 +96,7 @@ class ValidateJobOpeningControllerTest(client: WebTestClient) : CustomDescribeSp .expectStatus().isOk.expectBody() .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") } - it("실패한다") { + it("타이틀 케이스 실패한다") { val request = SecondPage( "", listOf(CategoryType.ETC), @@ -44,6 +108,207 @@ class ValidateJobOpeningControllerTest(client: WebTestClient) : CustomDescribeSp client.doPost("$url/title", request, accessToken).expectStatus().isBadRequest.expectBody() .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") } + it("카테고리 케이스 실패한다") { + val request = SecondPage( + "제목", + listOf(), + LocalDate.now(), + LocalDate.now(), + listOf(""), + "" + ) + client.doPost("$url/title", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("모집기간 마감일 시작일 유효성 실패한다") { + val request = SecondPage( + "제목", + listOf(CategoryType.ETC), + LocalDate.now(), + LocalDate.now().minusDays(1), + listOf(""), + "" + ) + client.doPost("$url/title", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("모집기간 시작일 유효성 실패한다") { + val request = SecondPage( + "제목", + listOf(CategoryType.ETC), + LocalDate.now().minusDays(1), + LocalDate.now().minusDays(1), + listOf(""), + "" + ) + client.doPost("$url/title", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + } + context("role 페이지") { + it("성공한다") { + val request = ValidateJobOpeningDto.ThirdPage( + casting = "모집배역", + domains = listOf(DomainType.ETC), + numberOfRecruits = 1, + careers = listOf(Career.NEWCOMER), + ageMin = 0, + ageMax = 100, + gender = Gender.MAN + ) + client.doPost("$url/role", request, accessToken) + .expectStatus().isOk.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") + } + it("모집배역 케이스 실패한다") { + val request = ValidateJobOpeningDto.ThirdPage( + casting = "", + domains = listOf(DomainType.ETC), + numberOfRecruits = 1, + careers = listOf(Career.NEWCOMER), + ageMin = 0, + ageMax = 100, + gender = Gender.MAN + ) + client.doPost("$url/role", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("모집분야 케이스 실패한다") { + val request = ValidateJobOpeningDto.ThirdPage( + casting = "모집배역", + domains = listOf(), + numberOfRecruits = 1, + careers = listOf(Career.NEWCOMER), + ageMin = 0, + ageMax = 100, + gender = Gender.MAN + ) + client.doPost("$url/role", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("모집인원 케이스 실패한다") { + val request = ValidateJobOpeningDto.ThirdPage( + casting = "모집배역", + domains = listOf(DomainType.ETC), + numberOfRecruits = -1, + careers = listOf(Career.NEWCOMER), + ageMin = 0, + ageMax = 100, + gender = Gender.MAN + ) + client.doPost("$url/role", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("경력 케이스 실패한다") { + val request = ValidateJobOpeningDto.ThirdPage( + casting = "모집배역", + domains = listOf(DomainType.ETC), + numberOfRecruits = 1, + careers = listOf(), + ageMin = 0, + ageMax = 100, + gender = Gender.MAN + ) + client.doPost("$url/role", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("나이 케이스 실패한다1") { + val request = ValidateJobOpeningDto.ThirdPage( + casting = "모집배역", + domains = listOf(DomainType.ETC), + numberOfRecruits = 1, + careers = listOf(Career.NEWCOMER), + ageMin = 100, + ageMax = 0, + gender = Gender.MAN + ) + client.doPost("$url/role", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("나이 케이스 실패한다2") { + val request = ValidateJobOpeningDto.ThirdPage( + casting = "모집배역", + domains = listOf(DomainType.ETC), + numberOfRecruits = 1, + careers = listOf(Career.NEWCOMER), + ageMin = -1, + ageMax = -1, + gender = Gender.MAN + ) + client.doPost("$url/role", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("나이 케이스 실패한다3") { + val request = ValidateJobOpeningDto.ThirdPage( + casting = "모집배역", + domains = listOf(DomainType.ETC), + numberOfRecruits = 1, + careers = listOf(Career.NEWCOMER), + ageMin = 300, + ageMax = 300, + gender = Gender.MAN + ) + client.doPost("$url/role", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + } + context("project 페이지") { + it("성공한다") { + val request = ValidateJobOpeningDto.FourthPage( + produce = "제작", + workTitle = "작품 제목", + director = "이하은", + genres = setOf(Genre.ACTION), + logline = "로그라인" + ) + client.doPost("$url/project", request, accessToken) + .expectStatus().isOk.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") + } + it("제작 케이스 실패한다") { + val request = ValidateJobOpeningDto.FourthPage( + produce = "", + workTitle = "작품 제목", + director = "이하은", + genres = setOf(Genre.ACTION), + logline = "로그라인" + ) + client.doPost("$url/project", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("작품 제목 케이스 실패한다") { + val request = ValidateJobOpeningDto.FourthPage( + produce = "제작", + workTitle = "", + director = "이하은", + genres = setOf(Genre.ACTION), + logline = "로그라인" + ) + client.doPost("$url/project", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("연출자 케이스 실패한다") { + val request = ValidateJobOpeningDto.FourthPage( + produce = "제작", + workTitle = "작품 제목", + director = "", + genres = setOf(Genre.ACTION), + logline = "로그라인" + ) + client.doPost("$url/project", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("장르 케이스 실패한다") { + val request = ValidateJobOpeningDto.FourthPage( + produce = "제작", + workTitle = "작품 제목", + director = "이하은", + genres = setOf(), + logline = "로그라인" + ) + client.doPost("$url/project", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } } context("ProjectDetails 페이지") { it("성공한다") { @@ -62,10 +327,25 @@ class ValidateJobOpeningControllerTest(client: WebTestClient) : CustomDescribeSp .expectStatus().isOk.expectBody() .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") } - it("실패한다") { + it("촬영위치 케이스 실패한다") { + val request = FifthPage( + "", + "강남구", + null, + null, + setOf(Weekday.MON), + null, + null, + Salary.HOURLY, + -2 + ) + client.doPost("$url/project-details", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("촬영위치 케이스 실패한다") { val request = FifthPage( "서울특별시", - "상상구", + "", null, null, setOf(Weekday.MON), @@ -77,34 +357,81 @@ class ValidateJobOpeningControllerTest(client: WebTestClient) : CustomDescribeSp client.doPost("$url/project-details", request, accessToken).expectStatus().isBadRequest.expectBody() .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") } + it("근무시간 endDate 케이스 실패한다") { + val request = FifthPage( + "서울특별시", + "강남구", + LocalDate.now(), + null, + setOf(Weekday.MON), + null, + null, + Salary.HOURLY, + -2 + ) + client.doPost("$url/project-details", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("근무시간 startDate 케이스 실패한다") { + val request = FifthPage( + "서울특별시", + "강남구", + null, + LocalDate.now(), + setOf(Weekday.MON), + null, + null, + Salary.HOURLY, + -2 + ) + client.doPost("$url/project-details", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + } + context("Summary 페이지") { + it("성공한다") { + val request = ValidateJobOpeningDto.SixthPage( + "상세 요강입니다." + ) + client.doPost("$url/summary", request, accessToken) + .expectStatus().isOk.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") + } + it("상세 요강 케이스 실패한다") { + val request = ValidateJobOpeningDto.SixthPage( + "상세" + ) + client.doPost("$url/summary", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + } + context("Manager 페이지") { + it("성공한다") { + val request = ValidateJobOpeningDto.SeventhPage( + "이하은", + "test@test.com" + ) + client.doPost("$url/manager", request, accessToken) + .expectStatus().isOk.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") + } + it("담당자 케이스 실패한다") { + val request = ValidateJobOpeningDto.SeventhPage( + "", + "test@test.com" + ) + client.doPost("$url/manager", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } + it("이메일 케이스 실패한다") { + val request = ValidateJobOpeningDto.SeventhPage( + "이하은", + "test" + ) + client.doPost("$url/manager", request, accessToken).expectStatus().isBadRequest.expectBody() + .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") + } } - // context("role 페이지") { - // it("성공한다") { - // val request = RolePageValidation( - // "역할", - // 1, - // Gender.MAN, - // 88, - // 0, - // Career.NEWCOMER - // ) - // client.doPost("$url/role", request, accessToken) - // .expectStatus().isOk.expectBody() - // .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("SUCCESS") - // } - // it("실패한다") { - // val request = RolePageValidation( - // "역할", - // null, - // Gender.MAN, - // 88, - // 0, - // Career.NEWCOMER - // ) - // client.doPost("$url/role", request, accessToken).expectStatus().isBadRequest.expectBody() - // .consumeWith { println(it) }.jsonPath("$.result").isEqualTo("FAIL") - // } - // } } } } diff --git a/server/src/test/kotlin/com/fone/jobOpening/presentation/dto/common/LocationDtoTest.kt b/server/src/test/kotlin/com/fone/jobOpening/presentation/dto/common/LocationDtoTest.kt new file mode 100644 index 00000000..bdc106da --- /dev/null +++ b/server/src/test/kotlin/com/fone/jobOpening/presentation/dto/common/LocationDtoTest.kt @@ -0,0 +1,26 @@ +package com.fone.jobOpening.presentation.dto.common + +import io.kotest.core.spec.style.DescribeSpec +import io.kotest.matchers.shouldBe + +class LocationDtoTest : DescribeSpec({ + describe("LocationDto") { + context("RetrieveRegionsResponse") { + it("should correctly store regions") { + val regions = listOf("서울특별시", "부산광역시") + val response = LocationDto.RetrieveRegionsResponse(regions) + + response.regions shouldBe regions + } + } + + context("RetrieveDistrictsResponse") { + it("should correctly store districts") { + val districts = listOf("강남구", "서초구") + val response = LocationDto.RetrieveDistrictsResponse(districts) + + response.districts shouldBe districts + } + } + } +})