diff --git a/.run/ApplicationTest.run.xml b/.run/ApplicationTest.run.xml new file mode 100644 index 0000000..2d103aa --- /dev/null +++ b/.run/ApplicationTest.run.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index c285df7..e7128bb 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,6 @@ org.springframework.modulith spring-modulith-starter-core - org.projectlombok lombok @@ -64,6 +63,16 @@ org.springframework.boot spring-boot-starter-actuator + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.platform + junit-platform-runner + test + diff --git a/src/main/java/dev/mars3142/fhq/timezone_service/config/AppConfig.java b/src/main/java/dev/mars3142/fhq/timezone_service/config/AppConfig.java index 6654ad2..4ede083 100644 --- a/src/main/java/dev/mars3142/fhq/timezone_service/config/AppConfig.java +++ b/src/main/java/dev/mars3142/fhq/timezone_service/config/AppConfig.java @@ -12,8 +12,8 @@ import org.springframework.web.client.RestClient; public class AppConfig { @Bean - public RestClient restClient() { - return RestClient.create(); + public RestClient.Builder restClientBuilder() { + return RestClient.builder(); } @Bean diff --git a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimeZoneServiceImpl.java b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimeZoneServiceImpl.java index c52ec2b..c6a18a2 100644 --- a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimeZoneServiceImpl.java +++ b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimeZoneServiceImpl.java @@ -5,14 +5,6 @@ import dev.mars3142.fhq.timezone_service.timezone.domain.entities.response.Ipify import dev.mars3142.fhq.timezone_service.timezone.domain.entities.response.TimeApiTimezoneZoneResponse; import dev.mars3142.fhq.timezone_service.timezone.domain.entities.response.WorldTimeApiIpResponse; import dev.mars3142.fhq.timezone_service.timezone.service.TimeZoneService; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.Objects; -import java.util.stream.Stream; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import lombok.val; import org.springframework.cache.annotation.Cacheable; @@ -20,13 +12,24 @@ import org.springframework.http.HttpStatusCode; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClient; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; + @Service -@RequiredArgsConstructor @Slf4j public class TimeZoneServiceImpl implements TimeZoneService { private final RestClient restClient; + public TimeZoneServiceImpl(RestClient.Builder restClientBuilder) { + restClient = restClientBuilder.build(); + } + @Override public String getExternalIp(String ip) { var result = ip; diff --git a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/web/controllers/TimeZoneController.java b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/web/controllers/TimeZoneController.java index 21a6b6d..546f5c8 100644 --- a/src/main/java/dev/mars3142/fhq/timezone_service/timezone/web/controllers/TimeZoneController.java +++ b/src/main/java/dev/mars3142/fhq/timezone_service/timezone/web/controllers/TimeZoneController.java @@ -36,7 +36,7 @@ public class TimeZoneController { } @GetMapping("{area}/{location}") - public TimeZoneResponse getTimeZone(@PathVariable String area, @PathVariable String location) { + public TimeZoneResponse getTimeZoneForLocation(@PathVariable String area, @PathVariable String location) { val timezone = area + "/" + location; val timezoneInfo = timeZoneService.getTimeZoneInfo(timezone); val abbreviation = Objects.requireNonNullElse(timezoneInfo.dstInterval(), new TimeApiTimezoneZoneResponse.Interval(null)).dstName(); diff --git a/src/test/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimeZoneServiceImplTest.java b/src/test/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimeZoneServiceImplTest.java new file mode 100644 index 0000000..bc26f57 --- /dev/null +++ b/src/test/java/dev/mars3142/fhq/timezone_service/timezone/service/impl/TimeZoneServiceImplTest.java @@ -0,0 +1,67 @@ +package dev.mars3142.fhq.timezone_service.timezone.service.impl; + +import lombok.val; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.client.RestClientTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.client.MockRestServiceServer; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; + +@DisplayName("Testing Timezone Service Default Implementation") +@RunWith(SpringRunner.class) +@RestClientTest(TimeZoneServiceImpl.class) +class TimeZoneServiceImplTest { + + @Autowired + private TimeZoneServiceImpl timeZoneService; + + @Autowired + private MockRestServiceServer server; + + @BeforeEach + public void setUp() { + server.reset(); + } + + @Test + @DisplayName("Return same ip") + void getSameIp() { + val ip = timeZoneService.getExternalIp("8.8.8.8"); + assertThat(ip).isEqualTo("8.8.8.8"); + } + + @Test + @DisplayName("Return custom ip") + void getCustomIp() { + server.expect(requestTo("https://api.ipify.org?format=json")) + .andRespond(withSuccess(""" + {"ip":"8.8.8.8"} + """, MediaType.APPLICATION_JSON)); + val ip = timeZoneService.getExternalIp("127.0.0.1"); + assertThat(ip).isEqualTo("8.8.8.8"); + } + + @Test + void getTimeZoneInfoByIp() { + } + + @Test + void getTimeZoneInfo() { + } + + @Test + void getPosixTimeZone() { + } + + @Test + void getLocations() { + } +} diff --git a/src/test/java/dev/mars3142/fhq/timezone_service/timezone/web/controllers/TimeZoneControllerTest.java b/src/test/java/dev/mars3142/fhq/timezone_service/timezone/web/controllers/TimeZoneControllerTest.java new file mode 100644 index 0000000..ce82552 --- /dev/null +++ b/src/test/java/dev/mars3142/fhq/timezone_service/timezone/web/controllers/TimeZoneControllerTest.java @@ -0,0 +1,58 @@ +package dev.mars3142.fhq.timezone_service.timezone.web.controllers; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@DisplayName("Testing Timezone RestController") +public class TimeZoneControllerTest { + + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate restTemplate; + + @Disabled + @Test + @DisplayName("local timezone is Europe/Berlin") + void getTimeZone() throws Exception { + assertThat(restTemplate.getForObject("http://localhost:" + port + "/v1/timezone", String.class)) + .contains("Europe/Berlin"); + } + + @Test + @DisplayName("Europe/Moscow is in European timezone list") + void checkLocationMoscow() throws Exception { + assertThat(restTemplate.getForObject("http://localhost:" + port + "/v1/timezone/Europe", String.class)) + .contains("Europe/Moscow").contains("64"); + } + + @Test + @DisplayName("Europe/Hamburg is not in European timezone list") + void checkLocationHamburg() throws Exception { + assertThat(restTemplate.getForObject("http://localhost:" + port + "/v1/timezone/Europe", String.class)) + .doesNotContain("Europe/Hamburg"); + } + + @Test + @DisplayName("Hawaii is not a valide timezone list") + void checkLocationHawaii() throws Exception { + assertThat(restTemplate.getForObject("http://localhost:" + port + "/v1/timezone/Hawaii", String.class)) + .contains("Not Found"); + } + + @Test + @DisplayName("Europe/Paris has a valid timezone") + void getTimeZoneForLocation() throws Exception { + assertThat(restTemplate.getForObject("http://localhost:" + port + "/v1/timezone/Europe/Paris", String.class)) + .contains("Europe/Paris"); + } +}