diff --git a/.editorconfig b/.editorconfig index 54a8570..72a7d08 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,5 +6,5 @@ indent_size = 4 insert_final_newline = true trim_trailing_whitespace = true -[{*.yaml,*.json}] +[*.yaml] indent_size = 2 diff --git a/pom.xml b/pom.xml index 3756469..5cbeab4 100644 --- a/pom.xml +++ b/pom.xml @@ -27,10 +27,8 @@ ${java.version} - 3.5.4 - 1.2.1 @@ -79,12 +77,6 @@ org.assertj assertj-core - - org.wiremock - wiremock-standalone - ${wiremock.version} - test - @@ -93,22 +85,6 @@ org.springframework.boot spring-boot-maven-plugin - - org.jsonschema2pojo - jsonschema2pojo-maven-plugin - ${jsonschema2pojo.version} - - ${basedir}/src/main/resources/schema - eu.ztsh.wymiana.model - - - - - generate - - - - diff --git a/src/main/java/eu/ztsh/wymiana/config/ClockConfiguration.java b/src/main/java/eu/ztsh/wymiana/config/ClockConfiguration.java deleted file mode 100644 index eea21a3..0000000 --- a/src/main/java/eu/ztsh/wymiana/config/ClockConfiguration.java +++ /dev/null @@ -1,16 +0,0 @@ -package eu.ztsh.wymiana.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.time.Clock; - -@Configuration -public class ClockConfiguration { - - @Bean - public Clock clock() { - return Clock.systemDefaultZone(); - } - -} diff --git a/src/main/java/eu/ztsh/wymiana/config/RestClientConfiguration.java b/src/main/java/eu/ztsh/wymiana/config/RestClientConfiguration.java deleted file mode 100644 index 74ee47b..0000000 --- a/src/main/java/eu/ztsh/wymiana/config/RestClientConfiguration.java +++ /dev/null @@ -1,18 +0,0 @@ -package eu.ztsh.wymiana.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.RestClient; - -@Configuration -public class RestClientConfiguration { - - @Bean - public RestClient restClient() { - return RestClient.builder() - .baseUrl("http://api.nbp.pl") - .defaultHeader("Accept", "application/json") - .build(); - } - -} diff --git a/src/main/java/eu/ztsh/wymiana/exception/NoDataException.java b/src/main/java/eu/ztsh/wymiana/exception/NoDataException.java deleted file mode 100644 index 8da9ad6..0000000 --- a/src/main/java/eu/ztsh/wymiana/exception/NoDataException.java +++ /dev/null @@ -1,9 +0,0 @@ -package eu.ztsh.wymiana.exception; - -public class NoDataException extends RuntimeException { - - public NoDataException(String code, String date) { - super("No data for code %s and date %s".formatted(code, date)); - } - -} diff --git a/src/main/java/eu/ztsh/wymiana/service/NbpService.java b/src/main/java/eu/ztsh/wymiana/service/NbpService.java deleted file mode 100644 index da26238..0000000 --- a/src/main/java/eu/ztsh/wymiana/service/NbpService.java +++ /dev/null @@ -1,89 +0,0 @@ -package eu.ztsh.wymiana.service; - -import eu.ztsh.wymiana.exception.NoDataException; -import eu.ztsh.wymiana.model.Rates; -import lombok.RequiredArgsConstructor; -import org.assertj.core.util.VisibleForTesting; -import org.springframework.http.HttpStatusCode; -import org.springframework.stereotype.Service; -import org.springframework.web.client.RestClient; - -import java.time.Clock; -import java.time.DayOfWeek; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.temporal.TemporalAdjusters; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * NBP exchange rates service - */ -@Service -@RequiredArgsConstructor -public class NbpService { - - private final Clock clock; - private final RestClient restClient; - private static final String URI_PATTERN = "/api/exchangerates/rates/c/{code}/{date}/"; - private final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - - private final ConcurrentMap cache = new ConcurrentHashMap<>(1); - - public double getSellRate(String currency) { - return getCurrency(currency).sell(); - } - - public double getBuyRate(String currency) { - return getCurrency(currency).buy(); - } - - private synchronized RatesCache getCurrency(String currency) { - var today = getFetchDate(); - var cacheObject = cache.get(currency); - if (cacheObject == null || cacheObject.date().isBefore(today)) { - var fresh = fetchData(currency, dtf.format(today)); - var rate = fresh.getRates().get(0); - cacheObject = new RatesCache( - LocalDate.parse(rate.getEffectiveDate(), dtf), - rate.getBid(), - rate.getAsk() - ); - cache.put(fresh.getCode(), cacheObject); - } - return cacheObject; - } - - /** - * Calculates date for data fetch. - *

- * Usually this would be today, but as rates are set only Mon-Fri, during weekends it is needed to fetch last friday rates. - * - * @return date for data fetch - */ - @VisibleForTesting - LocalDate getFetchDate() { - var today = LocalDate.now(clock); - return isWeekend(today) ? today.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)) : today; - } - - @VisibleForTesting - Rates fetchData(String code, String date) { - return restClient.get().uri(URI_PATTERN, code.toLowerCase(), date) - .retrieve() - .onStatus(HttpStatusCode::is4xxClientError, ((request, response) -> { - throw new NoDataException(code, date); - })) - .body(Rates.class); - } - - private static boolean isWeekend(LocalDate today) { - return today.getDayOfWeek() == DayOfWeek.SATURDAY - || today.getDayOfWeek() == DayOfWeek.SUNDAY; - } - - private record RatesCache(LocalDate date, double buy, double sell) { - - } - -} diff --git a/src/main/java/eu/ztsh/wymiana/validation/ValidExchangeRequest.java b/src/main/java/eu/ztsh/wymiana/validation/ValidExchangeRequest.java deleted file mode 100644 index 608bc3c..0000000 --- a/src/main/java/eu/ztsh/wymiana/validation/ValidExchangeRequest.java +++ /dev/null @@ -1,24 +0,0 @@ -package eu.ztsh.wymiana.validation; - -import jakarta.validation.Constraint; -import jakarta.validation.Payload; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.TYPE_USE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - - -@Retention(RUNTIME) -@Target({ TYPE_USE }) -@Documented -@Constraint(validatedBy = {ValidExchangeRequestValidator.class }) -public @interface ValidExchangeRequest { - - String message() default "Exchange request is not valid"; - Class[] groups() default { }; - Class[] payload() default { }; - -} diff --git a/src/main/java/eu/ztsh/wymiana/validation/ValidExchangeRequestValidator.java b/src/main/java/eu/ztsh/wymiana/validation/ValidExchangeRequestValidator.java deleted file mode 100644 index 0895d92..0000000 --- a/src/main/java/eu/ztsh/wymiana/validation/ValidExchangeRequestValidator.java +++ /dev/null @@ -1,24 +0,0 @@ -package eu.ztsh.wymiana.validation; - -import eu.ztsh.wymiana.web.model.CurrencyExchangeRequest; -import jakarta.validation.ConstraintValidator; -import jakarta.validation.ConstraintValidatorContext; - -public class ValidExchangeRequestValidator implements - ConstraintValidator { - - @Override - public boolean isValid(CurrencyExchangeRequest request, - ConstraintValidatorContext constraintValidatorContext) { - if (request == null) { - return false; - } - - return !request.from().equals(request.to()) - && !((request.toBuy() == null && request.toSell() == null) - || (request.toBuy() != null && request.toSell() != null)) - && ((request.toBuy() != null && request.toBuy() >= 0) - || (request.toSell() != null && request.toSell() >= 0)); - } - -} diff --git a/src/main/java/eu/ztsh/wymiana/web/model/CurrencyExchangeRequest.java b/src/main/java/eu/ztsh/wymiana/web/model/CurrencyExchangeRequest.java deleted file mode 100644 index 54f192e..0000000 --- a/src/main/java/eu/ztsh/wymiana/web/model/CurrencyExchangeRequest.java +++ /dev/null @@ -1,18 +0,0 @@ -package eu.ztsh.wymiana.web.model; - -import eu.ztsh.wymiana.validation.ValidExchangeRequest; -import jakarta.validation.constraints.NotNull; -import lombok.Builder; -import org.hibernate.validator.constraints.pl.PESEL; - -@Builder -@ValidExchangeRequest -public record CurrencyExchangeRequest( - @PESEL String pesel, - @NotNull String from, - @NotNull String to, - Double toBuy, - Double toSell -) { - -} diff --git a/src/main/resources/schema/rates.json b/src/main/resources/schema/rates.json deleted file mode 100644 index 2ed42d0..0000000 --- a/src/main/resources/schema/rates.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "$id": "https://api.nbp.pl/c/rates.json", - "$schema": "http://json-schema.org/draft/2020-12/schema", - "type": "object", - "def": { - "rate": { - "type": "object", - "properties": { - "no": { - "type": "string" - }, - "effectiveDate": { - "type": "string" - }, - "bid": { - "type": "number" - }, - "ask": { - "type": "number" - } - }, - "required": [ - "no", - "effectiveDate", - "bid", - "ask" - ] - } - }, - "properties": { - "table": { - "type": "string" - }, - "currency": { - "type": "string" - }, - "code": { - "type": "string" - }, - "rates": { - "type": "array", - "items": { - "$ref": "#/def/rate" - } - } - }, - "required": [ - "table", - "currency", - "code", - "rates" - ] -} diff --git a/src/test/java/eu/ztsh/wymiana/EntityCreator.java b/src/test/java/eu/ztsh/wymiana/EntityCreator.java index df78b20..4f7fcd7 100644 --- a/src/test/java/eu/ztsh/wymiana/EntityCreator.java +++ b/src/test/java/eu/ztsh/wymiana/EntityCreator.java @@ -2,9 +2,6 @@ package eu.ztsh.wymiana; import eu.ztsh.wymiana.data.entity.CurrencyEntity; import eu.ztsh.wymiana.data.entity.UserEntity; -import eu.ztsh.wymiana.model.Rate; -import eu.ztsh.wymiana.model.Rates; -import eu.ztsh.wymiana.web.model.CurrencyExchangeRequest; import eu.ztsh.wymiana.web.model.UserCreateRequest; import java.util.ArrayList; @@ -19,12 +16,6 @@ public class EntityCreator { public static String NAME = "Janina"; public static String SURNAME = "Kowalska"; public static double PLN = 20.10; - public static double USD_SELL = 5.18; - public static double USD_BUY = 5.08; - public static String PLN_SYMBOL = "PLN"; - public static String USD_SYMBOL = "USD"; - public static double BUY_RATE = 3.8804; - public static double SELL_RATE = 3.9572; } @@ -39,24 +30,6 @@ public class EntityCreator { .pln(Constants.PLN); } - public static CurrencyExchangeRequest.CurrencyExchangeRequestBuilder exchangeRequest() { - return CurrencyExchangeRequest.builder().pesel(Constants.PESEL); - } - - public static Rates rates(String date) { - var rates = new Rates(); - rates.setTable("C"); - rates.setCurrency("dolar amerykaƄski"); - rates.setCode("USD"); - var rate = new Rate(); - rate.setNo("096/C/NBP/2024"); - rate.setEffectiveDate(date); - rate.setBid(Constants.BUY_RATE); - rate.setAsk(Constants.SELL_RATE); - rates.setRates(List.of(rate)); - return rates; - } - public static class UserEntityBuilder { String name; diff --git a/src/test/java/eu/ztsh/wymiana/WireMockExtension.java b/src/test/java/eu/ztsh/wymiana/WireMockExtension.java deleted file mode 100644 index 99ebc73..0000000 --- a/src/test/java/eu/ztsh/wymiana/WireMockExtension.java +++ /dev/null @@ -1,50 +0,0 @@ -package eu.ztsh.wymiana; - -import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.client.WireMock; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeAllCallback; -import org.junit.jupiter.api.extension.ExtensionContext; - -import static com.github.tomakehurst.wiremock.client.WireMock.*; - -public class WireMockExtension implements BeforeAllCallback, AfterEachCallback, ExtensionContext.Store.CloseableResource { - - public static final String baseUrl = "http://localhost:38080"; - - public static void response(String endpoint, int status, String body) { - configureFor(38080); - stubFor(get(urlEqualTo(endpoint)) - .willReturn(WireMock.status(status) - .withHeader("Content-Type", "application/json") - .withBody(body))); - } - - public static void verifyGet(int count, String url) { - verify(exactly(count), getRequestedFor(urlEqualTo(url))); - } - - private static final WireMockServer wireMockServer = new WireMockServer(38080); - private boolean started; - - @Override - public void beforeAll(ExtensionContext extensionContext) throws Exception { - if (!started) { - wireMockServer.start(); - started = true; - } - } - @Override - public void afterEach(ExtensionContext extensionContext) throws Exception { - wireMockServer.listAllStubMappings().getMappings().forEach(wireMockServer::removeStub); - wireMockServer.findAllUnmatchedRequests().forEach(System.out::println); - wireMockServer.resetRequests(); - } - - @Override - public void close() throws Throwable { - wireMockServer.stop(); - } - - -} diff --git a/src/test/java/eu/ztsh/wymiana/service/NbpServiceTest.java b/src/test/java/eu/ztsh/wymiana/service/NbpServiceTest.java deleted file mode 100644 index 7424fbe..0000000 --- a/src/test/java/eu/ztsh/wymiana/service/NbpServiceTest.java +++ /dev/null @@ -1,117 +0,0 @@ -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); - } - -} diff --git a/src/test/java/eu/ztsh/wymiana/validation/AdultValidatorTest.java b/src/test/java/eu/ztsh/wymiana/validation/AdultValidatorTest.java index d4a2ed1..ca24718 100644 --- a/src/test/java/eu/ztsh/wymiana/validation/AdultValidatorTest.java +++ b/src/test/java/eu/ztsh/wymiana/validation/AdultValidatorTest.java @@ -1,42 +1,58 @@ package eu.ztsh.wymiana.validation; +import jakarta.validation.ConstraintValidatorContext; +import org.hibernate.validator.internal.engine.DefaultClockProvider; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; -class AdultValidatorTest extends ValidatorTest { +import static org.assertj.core.api.Assertions.assertThat; - protected AdultValidatorTest() { - super(new AdultValidator()); +class AdultValidatorTest { + + private static AdultValidator validator; + private static ConstraintValidatorContext validatorContext; + + @BeforeAll + static void prepare() { + validator = new AdultValidator(); + validatorContext = Mockito.mock(ConstraintValidatorContext.class); + Mockito.when(validatorContext.getClockProvider()).thenReturn(DefaultClockProvider.INSTANCE); } @Test @DisplayName("No digits in PESEL") void invalidPatternTest() { - assertThatValidation("notAPesel").isFalse(); + assertThat(call("notAPesel")).isFalse(); } @Test @DisplayName("Not an adult") void notAnAdultTest() { - assertThatValidation("24242400000").isFalse(); + assertThat(call("24242400000")).isFalse(); } @Test @DisplayName("Adult") void adultTest() { - assertThatValidation("88010100000").isTrue(); + assertThat(call("88010100000")).isTrue(); } @Test @DisplayName("Elderly person") void seniorTest() { - assertThatValidation("00010100000").isTrue(); + assertThat(call("00010100000")).isTrue(); } @Test @DisplayName("Invalid date") void notAValidDateTest() { - assertThatValidation("00919100000").isFalse(); + assertThat(call("00919100000")).isFalse(); + } + + private boolean call(String value) { + return validator.isValid(value, validatorContext); } } diff --git a/src/test/java/eu/ztsh/wymiana/validation/ValidExchangeRequestValidatorTest.java b/src/test/java/eu/ztsh/wymiana/validation/ValidExchangeRequestValidatorTest.java deleted file mode 100644 index 85161e6..0000000 --- a/src/test/java/eu/ztsh/wymiana/validation/ValidExchangeRequestValidatorTest.java +++ /dev/null @@ -1,128 +0,0 @@ -package eu.ztsh.wymiana.validation; - -import eu.ztsh.wymiana.EntityCreator; -import eu.ztsh.wymiana.web.model.CurrencyExchangeRequest; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -import static eu.ztsh.wymiana.EntityCreator.Constants.*; - -class ValidExchangeRequestValidatorTest extends ValidatorTest { - - protected ValidExchangeRequestValidatorTest() { - super(new ValidExchangeRequestValidator()); - } - - @Test - @DisplayName("Valid request with buy value specified") - void validRequestWithBuyTest() { - assertThatValidation(EntityCreator.exchangeRequest() - .from(PLN_SYMBOL) - .to(USD_SYMBOL) - .toBuy(USD_BUY) - .build()).isTrue(); - } - - @Test - @DisplayName("Valid request with sell value specified") - void validRequestWithSellTest() { - assertThatValidation(EntityCreator.exchangeRequest() - .from(PLN_SYMBOL) - .to(USD_SYMBOL) - .toSell(USD_SELL) - .build()).isTrue(); - } - - @Disabled("Already validated (has field annotation)") - @DisplayName("Invalid PESEL value") - @ParameterizedTest - @MethodSource - void invalidPeselTest(String pesel) { - assertThatValidation(EntityCreator.exchangeRequest() - .pesel(pesel) - .from(PLN_SYMBOL) - .to(USD_SYMBOL) - .toSell(USD_SELL) - .build()).isFalse(); - } - - @Test - @DisplayName("From and To have same value") - void sameFromToTest() { - assertThatValidation(EntityCreator.exchangeRequest() - .from(USD_SYMBOL) - .to(USD_SYMBOL) - .toSell(USD_SELL) - .build()).isFalse(); - } - - @Test - @DisplayName("Empty amounts") - void emptyBuySellTest() { - assertThatValidation(EntityCreator.exchangeRequest() - .from(PLN_SYMBOL) - .to(USD_SYMBOL) - .build()).isFalse(); - } - - @Disabled("Already validated (has field annotation)") - @Test - @DisplayName("Empty 'from' value") - void emptyFromTest() { - assertThatValidation(EntityCreator.exchangeRequest() - .to(USD_SYMBOL) - .toSell(USD_SELL) - .build()).isFalse(); - } - - @Disabled("Already validated (has field annotation)") - @Test - @DisplayName("Empty 'to' value") - void emptyToTest() { - assertThatValidation(EntityCreator.exchangeRequest() - .from(PLN_SYMBOL) - .toSell(USD_SELL) - .build()).isFalse(); - } - - @Test - @DisplayName("Both Buy and Sell params filled in") - void bothFilledBuySellTest() { - assertThatValidation(EntityCreator.exchangeRequest() - .from(PLN_SYMBOL) - .to(USD_SYMBOL) - .toBuy(USD_BUY) - .toSell(USD_SELL) - .build()).isFalse(); - } - - @Test - @DisplayName("Negative buy amount value") - void negativeBuyAmountTest() { - assertThatValidation(EntityCreator.exchangeRequest() - .from(PLN_SYMBOL) - .to(USD_SYMBOL) - .toBuy(-1.0) - .build()).isFalse(); - } - - @Test - @DisplayName("Negative sell amount value") - void negativeSellAmountTest() { - assertThatValidation(EntityCreator.exchangeRequest() - .from(PLN_SYMBOL) - .to(USD_SYMBOL) - .toSell(-1.0) - .build()).isFalse(); - } - - private static Stream invalidPeselTest() { - return Stream.of("INVALID", PESEL.replace('6', '7')); - } - -} diff --git a/src/test/java/eu/ztsh/wymiana/validation/ValidatorTest.java b/src/test/java/eu/ztsh/wymiana/validation/ValidatorTest.java deleted file mode 100644 index 7dc4bd8..0000000 --- a/src/test/java/eu/ztsh/wymiana/validation/ValidatorTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package eu.ztsh.wymiana.validation; - -import jakarta.validation.ConstraintValidator; -import jakarta.validation.ConstraintValidatorContext; -import org.assertj.core.api.AbstractBooleanAssert; -import org.hibernate.validator.internal.engine.DefaultClockProvider; -import org.junit.jupiter.api.BeforeAll; -import org.mockito.Mockito; - -import static org.assertj.core.api.Assertions.assertThat; - -public abstract class ValidatorTest, C> { - - private final V validator; - private static ConstraintValidatorContext validatorContext; - - protected ValidatorTest(V validator) { - this.validator = validator; - } - - @BeforeAll - static void prepare() { - validatorContext = Mockito.mock(ConstraintValidatorContext.class); - Mockito.when(validatorContext.getClockProvider()).thenReturn(DefaultClockProvider.INSTANCE); - } - - protected AbstractBooleanAssert assertThatValidation(C value) { - return assertThat(validator.isValid(value, validatorContext)); - } - -}