From b97c01a0cf82ce2fe7587a7c529868917b5439fd Mon Sep 17 00:00:00 2001 From: be-student Date: Wed, 19 Jul 2023 18:07:10 +0900 Subject: [PATCH] =?UTF-8?q?wip:=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#21] --- .../congestion/CongestionController.java | 23 +++ .../congestion/CongestionControllerTest.java | 135 ++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 backend/src/main/java/com/carffeine/carffeine/controller/congestion/CongestionController.java create mode 100644 backend/src/test/java/com/carffeine/carffeine/controller/congestion/CongestionControllerTest.java diff --git a/backend/src/main/java/com/carffeine/carffeine/controller/congestion/CongestionController.java b/backend/src/main/java/com/carffeine/carffeine/controller/congestion/CongestionController.java new file mode 100644 index 000000000..a728de7bd --- /dev/null +++ b/backend/src/main/java/com/carffeine/carffeine/controller/congestion/CongestionController.java @@ -0,0 +1,23 @@ +package com.carffeine.carffeine.controller.congestion; + +import com.carffeine.carffeine.controller.chargerStation.dto.StatisticsResponse; +import com.carffeine.carffeine.service.chargerstation.CongestionService; +import com.carffeine.carffeine.service.chargerstation.dto.StatisticsRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RestController +public class CongestionController { + + private final CongestionService congestionService; + + @GetMapping("/api/stations/{stationId}/statistics") + public ResponseEntity showCongestionStatistics(@PathVariable String stationId) { + StatisticsResponse statisticsResponse = congestionService.calculateCongestion(new StatisticsRequest(stationId)); + return ResponseEntity.ok(statisticsResponse); + } +} diff --git a/backend/src/test/java/com/carffeine/carffeine/controller/congestion/CongestionControllerTest.java b/backend/src/test/java/com/carffeine/carffeine/controller/congestion/CongestionControllerTest.java new file mode 100644 index 000000000..eab02e228 --- /dev/null +++ b/backend/src/test/java/com/carffeine/carffeine/controller/congestion/CongestionControllerTest.java @@ -0,0 +1,135 @@ +package com.carffeine.carffeine.controller.congestion; + +import com.carffeine.carffeine.controller.chargerStation.dto.CongestionInfoResponse; +import com.carffeine.carffeine.controller.chargerStation.dto.CongestionResponse; +import com.carffeine.carffeine.controller.chargerStation.dto.StatisticsResponse; +import com.carffeine.carffeine.service.chargerstation.CongestionService; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.carffeine.carffeine.helper.RestDocsHelper.customDocument; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@DisplayNameGeneration(ReplaceUnderscores.class) +@SuppressWarnings("NonAsciiCharacters") +@WebMvcTest(CongestionController.class) +@AutoConfigureRestDocs +class CongestionControllerTest { + + @MockBean + private CongestionService congestionService; + + @Autowired + private MockMvc mockMvc; + + @Test + void 혼잡도를_계산하여_반환한다() throws Exception { + // given + String stationId = "1"; + + given(congestionService.calculateCongestion(any())) + .willReturn( + new StatisticsResponse( + "1", + getExpected()) + ); + + mockMvc.perform(get("/api/stations/{stationId}/statistics", stationId)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.stationId").value("1")) + .andDo(customDocument("statistics", + pathParameters( + parameterWithName("stationId").description("충전소 ID") + ), + responseFields( + fieldWithPath("stationId").type(JsonFieldType.STRING).description("충전소 ID"), + fieldWithPath("congestion").type(JsonFieldType.OBJECT).description("혼잡도 정보"), + fieldWithPath("congestion.standard").type(JsonFieldType.OBJECT).description("표준 충전기 혼잡도 정보"), + fieldWithPath("congestion.standard.MON").type(JsonFieldType.ARRAY).description("월요일 혼잡도 정보"), + fieldWithPath("congestion.standard.MON[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.standard.MON[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.standard.TUE").type(JsonFieldType.ARRAY).description("화요일 혼잡도 정보"), + fieldWithPath("congestion.standard.TUE[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.standard.TUE[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.standard.WED").type(JsonFieldType.ARRAY).description("수요일 혼잡도 정보"), + fieldWithPath("congestion.standard.WED[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.standard.WED[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.standard.THU").type(JsonFieldType.ARRAY).description("목요일 혼잡도 정보"), + fieldWithPath("congestion.standard.THU[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.standard.THU[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.standard.FRI").type(JsonFieldType.ARRAY).description("금요일 혼잡도 정보"), + fieldWithPath("congestion.standard.FRI[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.standard.FRI[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.standard.SAT").type(JsonFieldType.ARRAY).description("토요일 혼잡도 정보"), + fieldWithPath("congestion.standard.SAT[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.standard.SAT[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.standard.SUN").type(JsonFieldType.ARRAY).description("일요일 혼잡도 정보"), + fieldWithPath("congestion.standard.SUN[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.standard.SUN[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.quick").type(JsonFieldType.OBJECT).description("급속 충전기 혼잡도 정보"), + fieldWithPath("congestion.quick.MON").type(JsonFieldType.ARRAY).description("월요일 혼잡도 정보"), + fieldWithPath("congestion.quick.MON[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.quick.MON[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.quick.TUE").type(JsonFieldType.ARRAY).description("화요일 혼잡도 정보"), + fieldWithPath("congestion.quick.TUE[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.quick.TUE[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.quick.WED").type(JsonFieldType.ARRAY).description("수요일 혼잡도 정보"), + fieldWithPath("congestion.quick.WED[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.quick.WED[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.quick.THU").type(JsonFieldType.ARRAY).description("목요일 혼잡도 정보"), + fieldWithPath("congestion.quick.THU[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.quick.THU[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.quick.FRI").type(JsonFieldType.ARRAY).description("금요일 혼잡도 정보"), + fieldWithPath("congestion.quick.FRI[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.quick.FRI[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.quick.SAT").type(JsonFieldType.ARRAY).description("토요일 혼잡도 정보"), + fieldWithPath("congestion.quick.SAT[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.quick.SAT[].ratio").type(JsonFieldType.NUMBER).description("혼잡도"), + fieldWithPath("congestion.quick.SUN").type(JsonFieldType.ARRAY).description("일요일 혼잡도 정보"), + fieldWithPath("congestion.quick.SUN[].hour").type(JsonFieldType.NUMBER).description("시간"), + fieldWithPath("congestion.quick.SUN[].ratio").type(JsonFieldType.NUMBER).description("혼잡도") + ))); + } + + private CongestionResponse getExpected() { + List dailyCongestion = new ArrayList<>(); + for (int i = 0; i < 24; i++) { + dailyCongestion.add(new CongestionInfoResponse(i, -1)); + } + return new CongestionResponse( + Map.of("MON", dailyCongestion, + "TUE", dailyCongestion, + "WED", dailyCongestion, + "THU", dailyCongestion, + "FRI", dailyCongestion, + "SAT", dailyCongestion, + "SUN", dailyCongestion), + Map.of("MON", dailyCongestion, + "TUE", dailyCongestion, + "WED", dailyCongestion, + "THU", dailyCongestion, + "FRI", dailyCongestion, + "SAT", dailyCongestion, + "SUN", dailyCongestion) + ); + } +}