Skip to content

Commit

Permalink
feat: 사전 식물 검색기능 구현 (#69)
Browse files Browse the repository at this point in the history
* feat: 사전 식물 검색기능 구현

* style: 사전 식물 검색기능 구현

* style: final 키워드 제거로 컨벤션 통일

* style: 컬렉션 리스트변환 toList() 메소드로 변경

* style: 체이닝 메소드 컨벤션 적용

* style: 리스트 길이 테스트 메소드 hasSize 적용

* refactor: 검색 결과가 존재하지 않을 시 에러가 아닌 빈 배열 반환

* style: 메소드 공백 추가

* style: 테스트 메소드 네이밍 구체화

* style: 미사용 bean 제거

* style: 테스트 변수 네이밍 수정

* style: 테스트 메소드 네이밍 수정 및 공백 구분
  • Loading branch information
rawfishthelgh authored Jul 18, 2023
1 parent 2fa5834 commit 07ad085
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.official.pium.controller;

import com.official.pium.service.dto.DataResponse;
import com.official.pium.service.dto.DictionaryPlantSearchResponse;
import com.official.pium.service.DictionaryPlantService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/dictionary-plants")
public class DictionaryPlantController {

private final DictionaryPlantService dictionaryPlantService;

@GetMapping
public ResponseEntity<DataResponse<List<DictionaryPlantSearchResponse>>> searchDictionaryPlants(@RequestParam("name") String name) {
return ResponseEntity.ok(dictionaryPlantService.search(name));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.official.pium.mapper;

import com.official.pium.service.dto.DictionaryPlantSearchResponse;
import com.official.pium.domain.DictionaryPlant;

public class DictionaryPlantMapper {

public static DictionaryPlantSearchResponse toDictionaryPlantSearchResponse(DictionaryPlant dictionaryPlant) {
return DictionaryPlantSearchResponse.builder()
.id(dictionaryPlant.getId())
.name(dictionaryPlant.getName())
.image(dictionaryPlant.getImageUrl())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@
import com.official.pium.domain.DictionaryPlant;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface DictionaryPlantRepository extends JpaRepository<DictionaryPlant, Long> {

List<DictionaryPlant> findDictionaryPlantsByNameContains(String name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.official.pium.service;

import com.official.pium.domain.DictionaryPlant;
import com.official.pium.mapper.DictionaryPlantMapper;
import com.official.pium.repository.DictionaryPlantRepository;
import com.official.pium.service.dto.DataResponse;
import com.official.pium.service.dto.DictionaryPlantSearchResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class DictionaryPlantService {

private final DictionaryPlantRepository dictionaryPlantRepository;

public DataResponse<List<DictionaryPlantSearchResponse>> search(String name) {
List<DictionaryPlant> dictionaryPlants = dictionaryPlantRepository.findDictionaryPlantsByNameContains(name);

List<DictionaryPlantSearchResponse> dictionaryPlantSearchResponses = dictionaryPlants.stream()
.map(DictionaryPlantMapper::toDictionaryPlantSearchResponse)
.toList();

return DataResponse.<List<DictionaryPlantSearchResponse>>builder()
.data(dictionaryPlantSearchResponses)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.official.pium.service.dto;

import lombok.*;

@Getter
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DataResponse<T> {

private T data;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.official.pium.service.dto;

import lombok.*;

@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class DictionaryPlantSearchResponse {

private Long id;
private String name;
private String image;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.official.pium.controller;

import com.official.pium.service.dto.DataResponse;
import com.official.pium.service.dto.DictionaryPlantSearchResponse;
import com.official.pium.fixture.DictionaryPlantFixture;
import com.official.pium.service.DictionaryPlantService;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;

import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@SuppressWarnings("NonAsciiCharacters")
@WebMvcTest(controllers = DictionaryPlantController.class)
public class DictionaryPlantControllerTest {

@Autowired
private MockMvc mockMvc;

@MockBean
private DictionaryPlantService dictionaryPlantService;

@Test
void 사전_식물_검색이_성공하면_OK_반환한다() throws Exception {
DataResponse<List<DictionaryPlantSearchResponse>> 식물들 = DictionaryPlantFixture.RESPONSE.식물들;

given(
dictionaryPlantService.search(any())
).willReturn(식물들);

mockMvc.perform(get("/dictionary-plants?name=스투키"))
.andExpect(status().isOk())
.andDo(print());
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.official.pium.fixture;

import com.official.pium.service.dto.DataResponse;
import com.official.pium.service.dto.DictionaryPlantSearchResponse;
import com.official.pium.domain.DictionaryPlant;
import com.official.pium.domain.WaterCycle;

import java.util.List;

@SuppressWarnings("NonAsciiCharacters")
public class DictionaryPlantFixture {

Expand All @@ -28,4 +32,21 @@ public class DictionaryPlantFixture {
.winter("겉흙이 마르면 촉촉하게")
.build()
).build();

public static class RESPONSE {
public static DataResponse<List<DictionaryPlantSearchResponse>> 식물들 =
DataResponse.<List<DictionaryPlantSearchResponse>>builder()
.data(
List.of(
DictionaryPlantSearchResponse.builder()
.id(1L)
.name("스투키")
.image("image")
.build()
)
)
.build();


}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.official.pium.service;

import com.official.pium.IntegrationTest;
import com.official.pium.domain.DictionaryPlant;
import com.official.pium.service.dto.DataResponse;
import com.official.pium.service.dto.DictionaryPlantSearchResponse;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;

@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@SuppressWarnings("NonAsciiCharacters")
public class DictionaryPlantServiceTest extends IntegrationTest {

@Autowired
DictionaryPlantService dictionaryPlantService;

@Test
void 사전식물_검색시_검색명이_포함된_사전식물을_반환한다() {
DictionaryPlant 스투키1 = dictionaryPlantSupport.builder().build();
DictionaryPlant 스투키2 = dictionaryPlantSupport.builder().build();

DataResponse<List<DictionaryPlantSearchResponse>> searchResultsContainsParamName = dictionaryPlantService.search("스투");

assertAll(
() -> assertThat(searchResultsContainsParamName.getData()).hasSize(2),
() -> assertThat(searchResultsContainsParamName.getData().get(0).getId()).isEqualTo(스투키1.getId()),
() -> assertThat(searchResultsContainsParamName.getData().get(1).getId()).isEqualTo(스투키2.getId())
);
}

@Test
void 사전식물_검색시_검색명이_포함된_사전식물이_없으면__리스트를_반환한다() {
DataResponse<List<DictionaryPlantSearchResponse>> search = dictionaryPlantService.search("스투");

assertThat(search.getData()).isEmpty();
}
}

0 comments on commit 07ad085

Please sign in to comment.