117 lines
4.8 KiB
Java
117 lines
4.8 KiB
Java
package eu.ztsh.wymiana.service;
|
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import eu.ztsh.wymiana.EntityCreator;
|
|
import eu.ztsh.wymiana.WireMockExtension;
|
|
import eu.ztsh.wymiana.exception.NoDataException;
|
|
import org.junit.jupiter.api.BeforeAll;
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.DisplayName;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.extension.ExtendWith;
|
|
import org.junit.jupiter.params.ParameterizedTest;
|
|
import org.junit.jupiter.params.provider.EnumSource;
|
|
import org.mockito.Mockito;
|
|
import org.springframework.web.client.RestClient;
|
|
|
|
import java.time.Clock;
|
|
import java.time.DayOfWeek;
|
|
import java.time.LocalDate;
|
|
import java.time.Month;
|
|
import java.time.ZoneId;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.temporal.TemporalAdjusters;
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
|
|
@ExtendWith(WireMockExtension.class)
|
|
class NbpServiceTest {
|
|
|
|
private static final ZoneId zone = ZoneId.of("Europe/Warsaw");
|
|
private static final LocalDate today = LocalDate.of(2024, Month.MAY, 12); // Sunday
|
|
private static Clock clock;
|
|
private final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
private final RestClient restClient = RestClient.builder().baseUrl(WireMockExtension.baseUrl).build();
|
|
private NbpService nbpService;
|
|
|
|
@BeforeAll
|
|
static void prepare() {
|
|
clock = Mockito.mock(Clock.class);
|
|
Mockito.when(clock.getZone()).thenReturn(zone);
|
|
}
|
|
|
|
@BeforeEach
|
|
void prepareTest() {
|
|
nbpService = new NbpService(clock, restClient);
|
|
}
|
|
|
|
@DisplayName("Check if fetch date is calculated properly: weekdays")
|
|
@ParameterizedTest
|
|
@EnumSource(value = DayOfWeek.class, names = {"SATURDAY", "SUNDAY"}, mode = EnumSource.Mode.EXCLUDE)
|
|
void getFetchDateOnWorkingDayTest(DayOfWeek dayOfWeek) {
|
|
updateClock(dayOfWeek);
|
|
assertThat(nbpService.getFetchDate()).isEqualTo(
|
|
switch (dayOfWeek) {
|
|
case MONDAY -> LocalDate.of(2024, Month.MAY, 6);
|
|
case TUESDAY -> LocalDate.of(2024, Month.MAY, 7);
|
|
case WEDNESDAY -> LocalDate.of(2024, Month.MAY, 8);
|
|
case THURSDAY -> LocalDate.of(2024, Month.MAY, 9);
|
|
case FRIDAY -> LocalDate.of(2024, Month.MAY, 10);
|
|
default -> null;
|
|
}
|
|
);
|
|
}
|
|
|
|
@DisplayName("Check if fetch date is calculated properly: weekends")
|
|
@ParameterizedTest
|
|
@EnumSource(value = DayOfWeek.class, names = {"SATURDAY", "SUNDAY"})
|
|
void getFetchDateOnWeekendTest(DayOfWeek dayOfWeek) {
|
|
updateClock(dayOfWeek);
|
|
assertThat(nbpService.getFetchDate()).isEqualTo(LocalDate.of(2024, Month.MAY, 10));
|
|
}
|
|
|
|
@DisplayName("Fetch rates straight from server")
|
|
@Test
|
|
void getWithoutCacheTest() throws JsonProcessingException {
|
|
var date = dtf.format(updateClock(DayOfWeek.FRIDAY));
|
|
var url = "/api/exchangerates/rates/c/usd/%s/".formatted(date);
|
|
WireMockExtension.response(url, 200, new ObjectMapper().writeValueAsString(EntityCreator.rates(date)));
|
|
try {
|
|
assertThat(nbpService.getSellRate(EntityCreator.Constants.USD_SYMBOL)).isEqualTo(EntityCreator.Constants.SELL_RATE);
|
|
} finally {
|
|
WireMockExtension.verifyGet(1, url);
|
|
}
|
|
}
|
|
|
|
@DisplayName("Fetch rates from cache")
|
|
@Test
|
|
void getWithCacheTest() throws JsonProcessingException {
|
|
var date = dtf.format(updateClock(DayOfWeek.FRIDAY));
|
|
var url = "/api/exchangerates/rates/c/usd/%s/".formatted(date);
|
|
WireMockExtension.response(url, 200, new ObjectMapper().writeValueAsString(EntityCreator.rates(date)));
|
|
// save to cache
|
|
assertThat(nbpService.getSellRate(EntityCreator.Constants.USD_SYMBOL)).isEqualTo(EntityCreator.Constants.SELL_RATE);
|
|
// get from cache
|
|
assertThat(nbpService.getBuyRate(EntityCreator.Constants.USD_SYMBOL)).isEqualTo(EntityCreator.Constants.BUY_RATE);
|
|
WireMockExtension.verifyGet(1, url);
|
|
}
|
|
|
|
@DisplayName("Support 404: invalid currency or no data")
|
|
@Test
|
|
void getInvalidCurrencyTest() {
|
|
var date = dtf.format(updateClock(DayOfWeek.FRIDAY));
|
|
var url = "/api/exchangerates/rates/c/usb/%s/".formatted(date);
|
|
WireMockExtension.response(url, 404, "404 NotFound - Not Found - Brak danych");
|
|
assertThatThrownBy(() -> nbpService.getSellRate("usb")).isInstanceOf(NoDataException.class);
|
|
WireMockExtension.verifyGet(1, url);
|
|
}
|
|
|
|
private LocalDate updateClock(DayOfWeek dayOfWeek) {
|
|
var date = today.with(TemporalAdjusters.previousOrSame(dayOfWeek));
|
|
Mockito.when(clock.instant()).thenReturn(date.atStartOfDay(zone).toInstant());
|
|
return LocalDate.from(date);
|
|
}
|
|
|
|
}
|