diff --git a/src/main/java/com/modoospace/common/GlobalExceptionHandler.java b/src/main/java/com/modoospace/common/GlobalExceptionHandler.java index b4df0aa..66e5538 100644 --- a/src/main/java/com/modoospace/common/GlobalExceptionHandler.java +++ b/src/main/java/com/modoospace/common/GlobalExceptionHandler.java @@ -49,6 +49,11 @@ public ResponseEntity handleNotFoundEntityException(NotFoundEntityExcept return new ResponseEntity<>(exception.getMessage(), HttpStatus.NOT_FOUND); } + @ExceptionHandler(EmptyResponseException.class) + public ResponseEntity handleEmptyResponseException(EmptyResponseException exception) { + return new ResponseEntity<>(exception.getMessage(), HttpStatus.NOT_FOUND); + } + @ExceptionHandler(InvalidTimeRangeException.class) public ResponseEntity handleInvalidTimeRangeException(InvalidTimeRangeException exception) { return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST); diff --git a/src/main/java/com/modoospace/common/exception/EmptyResponseException.java b/src/main/java/com/modoospace/common/exception/EmptyResponseException.java new file mode 100644 index 0000000..9c3480e --- /dev/null +++ b/src/main/java/com/modoospace/common/exception/EmptyResponseException.java @@ -0,0 +1,7 @@ +package com.modoospace.common.exception; + +public class EmptyResponseException extends RuntimeException { + public EmptyResponseException(String response, String identifier) { + super(response+"("+identifier+")응답 값이 비었습니다."); + } +} diff --git a/src/main/java/com/modoospace/config/auth/SecurityConfiguration.java b/src/main/java/com/modoospace/config/auth/SecurityConfiguration.java index fad162d..923a383 100644 --- a/src/main/java/com/modoospace/config/auth/SecurityConfiguration.java +++ b/src/main/java/com/modoospace/config/auth/SecurityConfiguration.java @@ -22,6 +22,7 @@ protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .authorizeHttpRequests(request -> request .antMatchers(HttpMethod.GET, "/", "/error", "/api/v1/spaces/**", "/api/v1/spaces/*/facilities/**", + "/api/v1/test/**", "/api/v1/facilities/*/schedules/**", "/api/v1/visitors/reservations/facilities/*/availability/**").permitAll() .antMatchers(HttpMethod.POST, "/api/v1/alarms/send/**").permitAll() diff --git a/src/main/java/com/modoospace/mockData/controller/MockDataController.java b/src/main/java/com/modoospace/mockData/controller/MockDataController.java new file mode 100644 index 0000000..0b951e4 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/MockDataController.java @@ -0,0 +1,83 @@ +package com.modoospace.mockData.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.modoospace.common.exception.EmptyResponseException; +import com.modoospace.config.auth.LoginEmail; +import com.modoospace.mockData.controller.dto.MockAddressResponse; +import com.modoospace.mockData.controller.dto.MockSpaceResponse; +import com.modoospace.mockData.service.MockDataService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.net.URI; +import java.net.URLEncoder; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/mock-data") +@Slf4j +public class MockDataController { + + private final ObjectMapper objectMapper = new ObjectMapper(); + private final HttpClient client = HttpClient.newHttpClient(); + + private final MockDataService mockDataService; + + @Value("${spring.kakao.apikey}") + private String key; + + @GetMapping("/space/{spaceId}") + public ResponseEntity getSpace(@PathVariable String spaceId) throws IOException, InterruptedException { + return ResponseEntity.ok(getMockSpace(spaceId)); + } + + private MockSpaceResponse getMockSpace(String spaceId) throws IOException, InterruptedException { + HttpRequest spaceRequest = HttpRequest.newBuilder() + .uri(URI.create("https://new-api.spacecloud.kr/spaces/" + spaceId)) + .build(); + HttpResponse httpSpaceResponse = client.send(spaceRequest, HttpResponse.BodyHandlers.ofString()); + if (isResponseSpaceEmpty(httpSpaceResponse.body())) { + throw new EmptyResponseException("Space", spaceId); + } + return objectMapper.readValue(httpSpaceResponse.body(), MockSpaceResponse.class); + } + + private boolean isResponseSpaceEmpty(String responseBody) { + return "{}".equals(responseBody.trim()); + } + + @GetMapping("/address") + public ResponseEntity getAddress(String address) throws IOException, InterruptedException { + return ResponseEntity.ok(getMockAddress(address)); + } + + private MockAddressResponse getMockAddress(String address) throws IOException, InterruptedException { + String encodedAddress = URLEncoder.encode(address, StandardCharsets.UTF_8); + HttpRequest addressRequest = HttpRequest.newBuilder() + .uri(URI.create("https://dapi.kakao.com/v2/local/search/address?query=" + encodedAddress)) + .header("Authorization", "KakaoAK " + key) + .build(); + HttpResponse httpAddressResponse = client.send(addressRequest, HttpResponse.BodyHandlers.ofString()); + MockAddressResponse addressResponse = objectMapper.readValue(httpAddressResponse.body(), MockAddressResponse.class); + if (addressResponse.getDocuments().isEmpty()) { + throw new EmptyResponseException("Address", address); + } + return addressResponse; + } + + @PostMapping("/space/{spaceId}") + public ResponseEntity saveSpace(@PathVariable String spaceId, @LoginEmail String email) throws IOException, InterruptedException { + MockSpaceResponse spaceResponse = getMockSpace(spaceId); + MockAddressResponse addressResponse = getMockAddress(spaceResponse.getLocation().getAddress()); + Long entitySpaceId = mockDataService.saveEntity(spaceResponse, addressResponse, email); + return ResponseEntity.created(URI.create("/api/v1/spaces/" + entitySpaceId)).build(); + } +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/MockAddressResponse.java b/src/main/java/com/modoospace/mockData/controller/dto/MockAddressResponse.java new file mode 100644 index 0000000..4fb0d19 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/MockAddressResponse.java @@ -0,0 +1,33 @@ +package com.modoospace.mockData.controller.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.modoospace.mockData.controller.dto.address.Document; +import com.modoospace.space.domain.Address; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class MockAddressResponse { + + List documents = new ArrayList<>(); + + public Address toAddress(String detailAddress) { + Document document = documents.get(0); + return Address.builder() + .depthFirst(document.getAddress().getDepthFirst()) + .depthSecond(document.getAddress().getDepthSecond()) + .depthThird(document.getAddress().getDepthThird()) + .addressNo(document.getAddress().getFullAddressNo()) + .roadName(document.getRoadAddress().getRoadName()) + .buildingNo(document.getRoadAddress().getFullBuildingNo()) + .detailAddress(detailAddress) + .x(document.getX()) + .y(document.getY()) + .build(); + } +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/MockSpaceResponse.java b/src/main/java/com/modoospace/mockData/controller/dto/MockSpaceResponse.java new file mode 100644 index 0000000..f4311d2 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/MockSpaceResponse.java @@ -0,0 +1,93 @@ +package com.modoospace.mockData.controller.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.modoospace.member.domain.Member; +import com.modoospace.mockData.controller.dto.space.*; +import com.modoospace.space.domain.*; +import lombok.Getter; +import lombok.Setter; + +import java.time.DayOfWeek; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class MockSpaceResponse { + + @JsonProperty("products") + private List facilityResponses = new ArrayList<>(); + + @JsonProperty("info") + private SpaceInfo spaceInfo; + + private Location location; + + @JsonProperty("break_days") + private List breakDays = new ArrayList<>(); + + @JsonProperty("break_holidays") + private List breakHolidays = new ArrayList<>(); + + @JsonProperty("break_times") + private List breakTimes = new ArrayList<>(); + + public String getCategoryName() { + return facilityResponses.stream() + .findFirst() + .flatMap(p -> p.getCategories().stream().findFirst()) + .map(FacilityCategory::getName).orElse("스터디룸"); + } + + public Space toSpace(Address address, Category category, Member member) { + return Space.builder() + .name(spaceInfo.getName()) + .description(spaceInfo.getDescription()) + .address(address) + .category(category) + .host(member) + .build(); + } + + public WeekdaySettings getWeekdaySettings() { + List weekdaySettings = new ArrayList<>(Arrays.asList( + new WeekdaySetting(DayOfWeek.MONDAY), + new WeekdaySetting(DayOfWeek.TUESDAY), + new WeekdaySetting(DayOfWeek.WEDNESDAY), + new WeekdaySetting(DayOfWeek.THURSDAY), + new WeekdaySetting(DayOfWeek.FRIDAY)) + ); + + if (breakDays.isEmpty() && breakHolidays.isEmpty()) { + weekdaySettings.add(new WeekdaySetting(DayOfWeek.SATURDAY)); + weekdaySettings.add(new WeekdaySetting(DayOfWeek.SUNDAY)); + } + + return new WeekdaySettings(weekdaySettings); + } + + public TimeSettings getTimeSettings() { + List timeSettings = breakTimes.stream() + .flatMap(breakTime -> makeTimeRangeFromBreakTime(breakTime).stream()) + .map(TimeSetting::new) + .collect(Collectors.toList()); + + return new TimeSettings(timeSettings); + } + + // end 10 ~ start 2 + private static List makeTimeRangeFromBreakTime(BreakTime breakTime) { + List list = new ArrayList<>(); + if (breakTime.getEndHour() > breakTime.getStartHour()) { + list.add(new TimeRange(breakTime.getEndHour(), 24)); + list.add(new TimeRange(0, breakTime.getStartHour())); + } else { + list.add(new TimeRange(breakTime.getEndHour(), breakTime.getStartHour())); + } + return list; + } +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/address/Document.java b/src/main/java/com/modoospace/mockData/controller/dto/address/Document.java new file mode 100644 index 0000000..31e5114 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/address/Document.java @@ -0,0 +1,20 @@ +package com.modoospace.mockData.controller.dto.address; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class Document { + + JibunAddress address; + + @JsonProperty("road_address") + RoadAddress roadAddress; + + String x; + String y; +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/address/JibunAddress.java b/src/main/java/com/modoospace/mockData/controller/dto/address/JibunAddress.java new file mode 100644 index 0000000..eb632d0 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/address/JibunAddress.java @@ -0,0 +1,31 @@ +package com.modoospace.mockData.controller.dto.address; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class JibunAddress { + + @JsonProperty("region_1depth_name") + String depthFirst; + + @JsonProperty("region_2depth_name") + String depthSecond; + + @JsonProperty("region_3depth_name") + String depthThird; + + @JsonProperty("main_address_no") + String addressNo; + + @JsonProperty("sub_address_no") + String subAddressNo; + + public String getFullAddressNo() { + return subAddressNo == null || subAddressNo.isBlank() ? addressNo : addressNo + "-" + subAddressNo; + } +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/address/RoadAddress.java b/src/main/java/com/modoospace/mockData/controller/dto/address/RoadAddress.java new file mode 100644 index 0000000..185d814 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/address/RoadAddress.java @@ -0,0 +1,25 @@ +package com.modoospace.mockData.controller.dto.address; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class RoadAddress { + + @JsonProperty("road_name") + String roadName; + + @JsonProperty("main_building_no") + String buildingNo; + + @JsonProperty("sub_building_no") + String subBuildingNo; + + public String getFullBuildingNo() { + return subBuildingNo == null || subBuildingNo.isBlank() ? buildingNo : buildingNo + "-" + subBuildingNo; + } +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/space/BreakDay.java b/src/main/java/com/modoospace/mockData/controller/dto/space/BreakDay.java new file mode 100644 index 0000000..bc77a13 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/space/BreakDay.java @@ -0,0 +1,18 @@ +package com.modoospace.mockData.controller.dto.space; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class BreakDay { + + @JsonProperty("BRK_DAY_TP_CD") + String breakDayCd; + + @JsonProperty("DAYW_CD") + String dayCd; +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/space/BreakHoliday.java b/src/main/java/com/modoospace/mockData/controller/dto/space/BreakHoliday.java new file mode 100644 index 0000000..04a9260 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/space/BreakHoliday.java @@ -0,0 +1,18 @@ +package com.modoospace.mockData.controller.dto.space; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class BreakHoliday { + + @JsonProperty("BRK_DAY_TP_CD") + String breakDayCd; + + @JsonProperty("DAYW_CD") + String dayCd; +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/space/BreakTime.java b/src/main/java/com/modoospace/mockData/controller/dto/space/BreakTime.java new file mode 100644 index 0000000..d4ef88d --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/space/BreakTime.java @@ -0,0 +1,18 @@ +package com.modoospace.mockData.controller.dto.space; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class BreakTime { + + @JsonProperty("start_time") + Integer startHour; + + @JsonProperty("end_time") + Integer endHour; +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/space/FacilityCategory.java b/src/main/java/com/modoospace/mockData/controller/dto/space/FacilityCategory.java new file mode 100644 index 0000000..25fa39f --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/space/FacilityCategory.java @@ -0,0 +1,13 @@ +package com.modoospace.mockData.controller.dto.space; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class FacilityCategory { + + String name; +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/space/FacilityInfo.java b/src/main/java/com/modoospace/mockData/controller/dto/space/FacilityInfo.java new file mode 100644 index 0000000..6e63f6c --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/space/FacilityInfo.java @@ -0,0 +1,23 @@ +package com.modoospace.mockData.controller.dto.space; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class FacilityInfo { + + String name; + + @JsonProperty("desc") + String description; + + @JsonProperty("min_guest_policy") + Integer minUser = 1; + + @JsonProperty("max_guest_capacity") + Integer maxUser = 10; +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/space/FacilityResponse.java b/src/main/java/com/modoospace/mockData/controller/dto/space/FacilityResponse.java new file mode 100644 index 0000000..89caa7f --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/space/FacilityResponse.java @@ -0,0 +1,34 @@ +package com.modoospace.mockData.controller.dto.space; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.modoospace.space.domain.Facility; +import com.modoospace.space.domain.Space; +import com.modoospace.space.domain.TimeSettings; +import com.modoospace.space.domain.WeekdaySettings; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class FacilityResponse { + + FacilityInfo info; + List categories = new ArrayList<>(); + + public Facility toFacility(TimeSettings timeSettings, WeekdaySettings weekdaySettings, Space space) { + return Facility.builder() + .name(info.getName()) + .reservationEnable(true) + .minUser(info.getMinUser()) + .maxUser(info.getMaxUser()) + .description(info.getDescription()) + .space(space) + .timeSettings(timeSettings) + .weekdaySettings(weekdaySettings) + .build(); + } +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/space/Location.java b/src/main/java/com/modoospace/mockData/controller/dto/space/Location.java new file mode 100644 index 0000000..62ef607 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/space/Location.java @@ -0,0 +1,18 @@ +package com.modoospace.mockData.controller.dto.space; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class Location { + + @JsonProperty("addr") + String address; + + @JsonProperty("addr_detail") + String detailAddress; +} diff --git a/src/main/java/com/modoospace/mockData/controller/dto/space/SpaceInfo.java b/src/main/java/com/modoospace/mockData/controller/dto/space/SpaceInfo.java new file mode 100644 index 0000000..e586619 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/controller/dto/space/SpaceInfo.java @@ -0,0 +1,17 @@ +package com.modoospace.mockData.controller.dto.space; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonIgnoreProperties(ignoreUnknown = true) +public class SpaceInfo { + + String name; + + @JsonProperty("desc") + String description; +} diff --git a/src/main/java/com/modoospace/mockData/service/MockDataService.java b/src/main/java/com/modoospace/mockData/service/MockDataService.java new file mode 100644 index 0000000..bdc00a1 --- /dev/null +++ b/src/main/java/com/modoospace/mockData/service/MockDataService.java @@ -0,0 +1,47 @@ +package com.modoospace.mockData.service; + +import com.modoospace.member.domain.Member; +import com.modoospace.member.service.MemberService; +import com.modoospace.mockData.controller.dto.MockAddressResponse; +import com.modoospace.mockData.controller.dto.MockSpaceResponse; +import com.modoospace.space.domain.*; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class MockDataService { + + private final MemberService memberService; + private final CategoryRepository categoryRepository; + private final SpaceRepository spaceRepository; + private final SpaceIndexRepository spaceIndexRepository; + private final FacilityRepository facilityRepository; + + public Long saveEntity(MockSpaceResponse spaceResponse, MockAddressResponse addressResponse, String email) { + Space space = makeSpace(spaceResponse, addressResponse, email); + spaceIndexRepository.save(SpaceIndex.of(space)); + makeFacility(spaceResponse, space); + return space.getId(); + } + + private Space makeSpace(MockSpaceResponse spaceResponse, MockAddressResponse addressResponse, String email) { + Member member = memberService.findMemberByEmail(email); + Address address = addressResponse.toAddress(spaceResponse.getLocation().getDetailAddress()); + Category category = findCategory(spaceResponse.getCategoryName()); + + return spaceRepository.save(spaceResponse.toSpace(address, category, member)); + } + + private Category findCategory(String name) { + Optional optionalCategory = categoryRepository.findByName(name); + return optionalCategory.orElseGet(() -> categoryRepository.save(new Category(name))); + } + + private void makeFacility(MockSpaceResponse spaceResponse, Space space) { + spaceResponse.getFacilityResponses() + .forEach(product -> facilityRepository.save(product.toFacility(spaceResponse.getTimeSettings(), spaceResponse.getWeekdaySettings(), space))); + } +} diff --git a/src/main/java/com/modoospace/space/domain/CategoryRepository.java b/src/main/java/com/modoospace/space/domain/CategoryRepository.java index 4f0c5b3..346455e 100644 --- a/src/main/java/com/modoospace/space/domain/CategoryRepository.java +++ b/src/main/java/com/modoospace/space/domain/CategoryRepository.java @@ -2,6 +2,9 @@ import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface CategoryRepository extends JpaRepository { + Optional findByName(String name); } diff --git a/src/main/java/com/modoospace/space/repository/SpaceIndexQueryRepository.java b/src/main/java/com/modoospace/space/repository/SpaceIndexQueryRepository.java index 70db1b6..b2cb501 100644 --- a/src/main/java/com/modoospace/space/repository/SpaceIndexQueryRepository.java +++ b/src/main/java/com/modoospace/space/repository/SpaceIndexQueryRepository.java @@ -1,11 +1,14 @@ package com.modoospace.space.repository; import com.modoospace.space.domain.SpaceIndex; + import java.util.List; import java.util.stream.Collectors; + import lombok.RequiredArgsConstructor; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; +import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; @@ -21,13 +24,14 @@ public List findIdByQuery(String queryString) { BoolQueryBuilder queryBuilder = makeQuery(queryString); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() - .withQuery(queryBuilder) - .build(); + .withQuery(queryBuilder) + .withPageable(PageRequest.of(0, 1000)) + .build(); return elasticsearchOperations.search(searchQuery, SpaceIndex.class) - .stream() - .map(searchHit -> searchHit.getContent().getId()) - .collect(Collectors.toList()); + .stream() + .map(searchHit -> searchHit.getContent().getId()) + .collect(Collectors.toList()); } /** @@ -39,8 +43,8 @@ private BoolQueryBuilder makeQuery(String queryString) { BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); for (String term : terms) { queryBuilder = queryBuilder.must( - QueryBuilders.queryStringQuery("*" + term + "*") - .field("name").field("description").field("categoryName").field("address") + QueryBuilders.queryStringQuery("*" + term + "*") + .field("name").field("description").field("categoryName").field("address") ); } return queryBuilder; diff --git a/src/main/java/com/modoospace/space/repository/SpaceQueryRepository.java b/src/main/java/com/modoospace/space/repository/SpaceQueryRepository.java index 4ce94c4..8b97178 100644 --- a/src/main/java/com/modoospace/space/repository/SpaceQueryRepository.java +++ b/src/main/java/com/modoospace/space/repository/SpaceQueryRepository.java @@ -34,12 +34,14 @@ public class SpaceQueryRepository { private final SpaceIndexQueryRepository spaceIndexQueryRepository; public Page searchSpace(SpaceSearchRequest searchRequest, Pageable pageable) { + + BooleanExpression spaceIdInExpression = spaceIdInQueryResult(searchRequest.getQuery()); List content = jpaQueryFactory .selectFrom(space) .join(space.host, member).fetchJoin() .join(space.category, category).fetchJoin() .where( - spaceIdInQueryResult(searchRequest.getQuery()) + spaceIdInExpression , eqDepthFirst(searchRequest.getDepthFirst()) , eqDepthSecond(searchRequest.getDepthSecond()) , eqDepthThird(searchRequest.getDepthThird()) @@ -54,7 +56,7 @@ public Page searchSpace(SpaceSearchRequest searchRequest, Pageable pageab JPAQuery countQuery = jpaQueryFactory .selectFrom(space) .where( - spaceIdInQueryResult(searchRequest.getQuery()) + spaceIdInExpression , eqDepthFirst(searchRequest.getDepthFirst()) , eqDepthSecond(searchRequest.getDepthSecond()) , eqDepthThird(searchRequest.getDepthThird()) diff --git a/src/test/java/com/modoospace/mockData/controller/MockDataControllerTest.java b/src/test/java/com/modoospace/mockData/controller/MockDataControllerTest.java new file mode 100644 index 0000000..b8bc0e2 --- /dev/null +++ b/src/test/java/com/modoospace/mockData/controller/MockDataControllerTest.java @@ -0,0 +1,112 @@ +package com.modoospace.mockData.controller; + +import com.modoospace.AbstractIntegrationContainerBaseTest; +import com.modoospace.common.exception.EmptyResponseException; +import com.modoospace.member.domain.Member; +import com.modoospace.member.domain.MemberRepository; +import com.modoospace.member.domain.Role; +import com.modoospace.mockData.controller.dto.MockAddressResponse; +import com.modoospace.mockData.controller.dto.MockSpaceResponse; +import com.modoospace.space.domain.Category; +import com.modoospace.space.domain.CategoryRepository; +import com.modoospace.space.domain.Space; +import com.modoospace.space.domain.SpaceRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; +import java.net.URI; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@Transactional +class MockDataControllerTest extends AbstractIntegrationContainerBaseTest { + + @Autowired + private MockDataController mockDataController; + + @Autowired + private MemberRepository memberRepository; + + @Autowired + private SpaceRepository spaceRepository; + + @Autowired + private CategoryRepository categoryRepository; + + private Member member; + + @BeforeEach + public void setUp() { + member = Member.builder() + .name("허정화") + .email("wjdghkwhdl@jr.naver.com") + .role(Role.HOST) + .build(); + memberRepository.save(member); + Category category = new Category("스터디룸"); + categoryRepository.save(category); + } + + @DisplayName("외부api로 받아온 공간데이터가 비어있을 경우 Exception을 던진다.") + @Test + public void getSpace_throwException_ifEmptyResponse() { + assertThatThrownBy(() -> mockDataController.getSpace("1")) + .isInstanceOf(EmptyResponseException.class); + } + + @DisplayName("외부Api로 받아온 데이터를 반환한다.") + @Test + public void getSpace() throws IOException, InterruptedException { + MockSpaceResponse space = mockDataController.getSpace("58861").getBody(); + + assertThat(space).isNotNull(); + assertThat(space.getSpaceInfo().getName()).isEqualTo("감성공간 아르떼부암 "); + } + + @DisplayName("KakaoApi로 받아온 주소데이터가 비어있을 경우 Exception을 던진다.") + @Test + public void getAddress_throwException_ifEmptyResponse() { + assertThatThrownBy(() -> mockDataController.getAddress("address")) + .isInstanceOf(EmptyResponseException.class); + } + + @DisplayName("KakaoApi로 받아온 데이터를 반환한다.") + @Test + public void getAddress() throws IOException, InterruptedException { + MockAddressResponse address = mockDataController.getAddress("서울 종로구 자하문로 254").getBody(); + + assertThat(address).isNotNull(); + assertThat(address.getDocuments().get(0).getX()).isEqualTo("126.963964049851"); + assertThat(address.getDocuments().get(0).getY()).isEqualTo("37.5969625614596"); + } + + @DisplayName("외부api로 받아온 공간데이터가 비어있을 경우 변환하지 않고 Exception을 던진다.") + @Test + public void saveSpace_throwException_ifEmptyResponse() { + assertThatThrownBy(() -> mockDataController.saveSpace("2", member.getEmail())) + .isInstanceOf(EmptyResponseException.class); + } + + @DisplayName("외부Api로 받아온 데이터를 모두스페이스 엔티티로 변환 후 저장하여 반환한다.") + @Test + public void saveSpace() throws IOException, InterruptedException { + URI location = mockDataController.saveSpace("58861", member.getEmail()).getHeaders().getLocation(); + assertThat(location).isNotNull(); + + Optional space = spaceRepository.findById(extractId(location)); + assertThat(space).isPresent(); + assertThat(space.get().getName()).isEqualTo("감성공간 아르떼부암 "); + } + + private Long extractId(URI location) { + String path = location.getPath(); + String id = path.substring(path.lastIndexOf("/") + 1); + return Long.parseLong(id); + } +} \ No newline at end of file