Skip to content

Commit

Permalink
✨ [Feature] 공고 전체 조회 API (#797)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kimhan-nah authored Mar 30, 2024
1 parent 1a10bc1 commit 22748cc
Show file tree
Hide file tree
Showing 13 changed files with 249 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package gg.admin.repo.recruit;

import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.JpaRepository;

import gg.data.recruit.recruitment.Recruitment;

public interface RecruitmentAdminRepository extends JpaRepository<Recruitment, Long> {
Slice<Recruitment> findAllByOrderByEndTimeDesc(Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package gg.recruit.api.admin.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -14,8 +19,11 @@
import gg.data.recruit.recruitment.Recruitment;
import gg.recruit.api.admin.controller.request.RecruitmentCreateReqDto;
import gg.recruit.api.admin.controller.request.UpdateStatusRequestDto;
import gg.recruit.api.admin.controller.response.CreatedRecruitmentResponse;
import gg.recruit.api.admin.controller.response.RecruitmentsResponse;
import gg.recruit.api.admin.service.RecruitmentAdminService;
import gg.recruit.api.admin.service.dto.UpdateRecruitStatusParam;
import gg.utils.dto.PageRequestDto;
import lombok.RequiredArgsConstructor;

@RestController
Expand All @@ -25,10 +33,12 @@ public class RecruitmentAdminController {
private final RecruitmentAdminService recruitmentAdminService;

@PostMapping
public ResponseEntity<Void> createRecruitment(@RequestBody @Valid RecruitmentCreateReqDto recruitmentDto) {
public ResponseEntity<CreatedRecruitmentResponse> createRecruitment(
@RequestBody @Valid RecruitmentCreateReqDto recruitmentDto) {
Recruitment recruitment = recruitmentDto.toRecruitment();
recruitmentAdminService.createRecruitment(recruitment, recruitmentDto.getForm());
return ResponseEntity.status(HttpStatus.CREATED).build();
Long recruitmentId = recruitmentAdminService.createRecruitment(recruitment, recruitmentDto.getForm()).getId();
CreatedRecruitmentResponse createdRecruitmentResponse = new CreatedRecruitmentResponse(recruitmentId);
return ResponseEntity.status(HttpStatus.CREATED).body(createdRecruitmentResponse);
}

@PatchMapping("/{recruitId}/status")
Expand All @@ -39,4 +49,11 @@ public ResponseEntity<Void> updateRecruitStatus(@PathVariable Long recruitId,
new UpdateRecruitStatusParam(recruitId, requestDto.getFinish()));
return ResponseEntity.noContent().build();
}

@GetMapping
public ResponseEntity<RecruitmentsResponse> getRecruitments(PageRequestDto pageRequestDto) {
Pageable pageable = PageRequest.of(pageRequestDto.getPage() - 1, pageRequestDto.getSize());
List<Recruitment> recruitments = recruitmentAdminService.getAllRecruitments(pageable);
return ResponseEntity.ok(new RecruitmentsResponse(recruitments));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package gg.recruit.api.admin.controller.response;

import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class CreatedRecruitmentResponse {
private Long id;

public CreatedRecruitmentResponse(Long id) {
this.id = id;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package gg.recruit.api.admin.controller.response;

import java.time.LocalDateTime;

import gg.data.recruit.recruitment.Recruitment;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class RecruitmentDto {
private Long id;
private String title;
private String status;
private String generation;
private LocalDateTime startDate;
private LocalDateTime endDate;

@Builder
public RecruitmentDto(Long id, String title, String status, String generation, LocalDateTime startDate,
LocalDateTime endDate) {
this.id = id;
this.title = title;
this.status = status;
this.generation = generation;
this.startDate = startDate;
this.endDate = endDate;
}

public static RecruitmentDto toRecruitmentDto(Recruitment recruitment) {
return RecruitmentDto.builder()
.id(recruitment.getId())
.title(recruitment.getTitle())
.generation(recruitment.getGeneration())
.startDate(recruitment.getStartTime())
.endDate(recruitment.getEndTime())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package gg.recruit.api.admin.controller.response;

import java.util.ArrayList;
import java.util.List;

import gg.data.recruit.recruitment.Recruitment;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class RecruitmentsResponse {
private List<RecruitmentDto> recruitmentDtoList = new ArrayList<>();

public RecruitmentsResponse(List<Recruitment> recruitments) {
for (Recruitment recruitment : recruitments) {
recruitmentDtoList.add(RecruitmentDto.toRecruitmentDto(recruitment));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

import java.util.List;

import javax.transaction.Transactional;

import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import gg.admin.repo.recruit.RecruitmentAdminRepository;
import gg.data.recruit.recruitment.CheckList;
Expand Down Expand Up @@ -43,6 +44,24 @@ public Recruitment createRecruitment(Recruitment recruitment, List<Form> forms)
return recruitmentAdminRepository.save(recruitment);
}

@Transactional
public void updateRecruitStatus(UpdateRecruitStatusParam updateRecruitStatusParam) {
Recruitment recruitments = recruitmentAdminRepository.findById(updateRecruitStatusParam.getRecruitId())
.orElseThrow(() -> new NotExistException("Recruitment not found."));
recruitments.setFinish(updateRecruitStatusParam.getFinish());
}

/**
* 공고 종료 날짜 기준으로 내림차순(최근순) 정렬하여 채용 공고를 조회한다.
* @param pageable
* @return 조회된 채용 공고 리스트
*/
@Transactional(readOnly = true)
public List<Recruitment> getAllRecruitments(Pageable pageable) {
Slice<Recruitment> allByOrderByEndDateDesc = recruitmentAdminRepository.findAllByOrderByEndTimeDesc(pageable);
return allByOrderByEndDateDesc.getContent();
}

/**
* @param question 질문
* @param checkList 선택지
Expand All @@ -56,11 +75,4 @@ private void addCheckList(Question question, List<String> checkList) {
new CheckList(question, content);
}
}

@Transactional
public void updateRecruitStatus(UpdateRecruitStatusParam updateRecruitStatusParam) {
Recruitment recruitments = recruitmentAdminRepository.findById(updateRecruitStatusParam.getRecruitId())
.orElseThrow(() -> new NotExistException("Recruitment not found."));
recruitments.setFinish(updateRecruitStatusParam.getFinish());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package gg.recruit.api.user;
package gg.recruit.api;

import java.time.LocalDateTime;
import java.util.List;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

import gg.data.recruit.recruitment.Recruitment;
import gg.data.user.User;
import gg.recruit.api.RecruitMockData;
import gg.recruit.api.admin.controller.request.UpdateStatusRequestDto;
import gg.recruit.api.user.RecruitMockData;
import gg.repo.recruit.recruitment.RecruitmentRepository;
import gg.utils.TestDataUtils;
import gg.utils.annotation.IntegrationTest;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package gg.recruit.api.admin.integration;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Stream;

import javax.transaction.Transactional;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.test.web.servlet.MockMvc;
import org.testcontainers.shaded.com.google.common.net.HttpHeaders;

import com.fasterxml.jackson.databind.ObjectMapper;

import gg.admin.repo.recruit.RecruitmentAdminRepository;
import gg.data.recruit.recruitment.Recruitment;
import gg.recruit.api.RecruitMockData;
import gg.utils.TestDataUtils;
import gg.utils.annotation.IntegrationTest;

@IntegrationTest
@Transactional
@AutoConfigureMockMvc
public class RecruitmentAdminIntegrationTest {
@Autowired
private MockMvc mockMvc;

@Autowired
private ObjectMapper objectMapper;

@Autowired
private TestDataUtils testDataUtils;

@Autowired
private RecruitMockData recruitMockData;

@Autowired
private RecruitmentAdminRepository recruitmentAdminRepository;

@Nested
@DisplayName("공고 전체 조회 시 - POST /admin/recruitments")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class PostRecruitment {

@DisplayName("공고 종료 날짜 기준 최신순으로 조회된다.")
@ParameterizedTest
@MethodSource("getRecruitments")
void getAllRecruitments(List<Recruitment> recruitments) throws Exception {
// given
int page = 1;
int size = 10;
String url = String.format("/admin/recruitments?page=%d&size=%d", page, size);
String accessToken = testDataUtils.getAdminLoginAccessToken();
recruitmentAdminRepository.saveAll(recruitments);

// when
String response = mockMvc.perform(get(url)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();

System.out.println(response);
}

/**
* parameterized test에 사용할 List<Recruitment>를 반환하는 메소드
* @return 종료 날짜가 서로 다른 3개의 공고 리스트, empty list
*/
private Stream<List<Recruitment>> getRecruitments() {
LocalDateTime startDate = LocalDateTime.of(2021, 1, 1, 0, 0, 0);
return Stream.of(List.of(
new Recruitment("title", "contents", "generation", startDate, startDate.plusDays(1)),
new Recruitment("title", "contents", "generation", startDate, startDate.plusDays(2)),
new Recruitment("title", "contents", "generation", startDate, startDate.plusDays(3))
),
List.of());
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package gg.recruit.api.admin.service;

import static org.mockito.BDDMockito.*;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

import gg.admin.repo.recruit.RecruitmentAdminRepository;
import gg.data.recruit.recruitment.Recruitment;
import gg.utils.annotation.UnitTest;

@UnitTest
class RecruitmentAdminServiceUnitTest {
@InjectMocks
private RecruitmentAdminService recruitmentAdminService;

@Mock
private RecruitmentAdminRepository recruitmentAdminRepository;

@Test
@DisplayName("공고 조회")
void getAllRecruitments() {
// given
Slice<Recruitment> mock = mock(Slice.class);
Pageable mockPageable = mock(Pageable.class);
given(recruitmentAdminRepository.findAllByOrderByEndTimeDesc(mockPageable)).willReturn(mock);

// when
recruitmentAdminService.getAllRecruitments(mockPageable);

// then
verify(recruitmentAdminRepository, times(1)).findAllByOrderByEndTimeDesc(mockPageable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -26,7 +24,7 @@
import gg.data.recruit.recruitment.Recruitment;
import gg.data.recruit.recruitment.enums.InputType;
import gg.data.user.User;
import gg.recruit.api.user.RecruitMockData;
import gg.recruit.api.RecruitMockData;
import gg.recruit.api.user.controller.request.CheckListFormRequest;
import gg.recruit.api.user.controller.request.FormPatchRequestDto;
import gg.recruit.api.user.controller.request.FormRequest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import gg.data.recruit.application.Application;
import gg.data.recruit.recruitment.Recruitment;
import gg.data.user.User;
import gg.recruit.api.user.RecruitMockData;
import gg.recruit.api.RecruitMockData;
import gg.recruit.api.user.controller.response.ActiveRecruitmentListResDto;
import gg.recruit.api.user.controller.response.RecruitmentDetailResDto;
import gg.utils.TestDataUtils;
Expand Down

0 comments on commit 22748cc

Please sign in to comment.