diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/BankAccountServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/BankAccountServiceTest.java index cbc7952d1..027c1d3e6 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/BankAccountServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/BankAccountServiceTest.java @@ -36,7 +36,7 @@ import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFields @ContextConfiguration(classes = { HazelcastServiceTestConfiguration.class}) public class BankAccountServiceTest { - public static final Matcher BANK_ACCOUNT_MATCHER = usingIgnoringFieldsComparator("id"); + public static final Matcher BANK_ACCOUNT_MATCHER = usingIgnoringFieldsComparator(); private static final int PARTITION = 0; private static final String TOPIC_ACCOUNT_NEW = Consts.DESTINATION_BANK_ACCOUNT_NEW; private static final String TOPIC_ACCOUNT_UPDATE = Consts.DESTINATION_BANK_ACCOUNT_UPDATE; diff --git a/clearing-parent/backend-api/pom.xml b/clearing-parent/backend-api/pom.xml index 18b29f7d1..96503e90f 100644 --- a/clearing-parent/backend-api/pom.xml +++ b/clearing-parent/backend-api/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 backend-api @@ -8,12 +8,12 @@ Clearing backend API module jar - - clearing-parent + + clearing-parent ru.spcex.clearing SPCEX-1.0.0.0 - + 17.0.1 @@ -25,9 +25,9 @@ spring-boot-starter-web - org.springframework.boot - spring-boot-starter-security - + org.springframework.boot + spring-boot-starter-security + org.keycloak keycloak-spring-boot-starter @@ -53,17 +53,38 @@ ru.spcex.clearing classes + + + org.springframework + spring-test + test + + + org.mockito + mockito-core + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + - org.keycloak.bom - keycloak-adapter-bom - ${keycloak-spring-boot-starter.version} - pom - import - + org.keycloak.bom + keycloak-adapter-bom + ${keycloak-spring-boot-starter.version} + pom + import + diff --git a/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java b/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java new file mode 100644 index 000000000..4c4e2cc34 --- /dev/null +++ b/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java @@ -0,0 +1,72 @@ +package ru.spcex.clearing.backendapi.controller.queue.account; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.CharacterEncodingFilter; +import ru.spcex.clearing.backendapi.controller.queue.config.Jackson2HttpConverterConfig; +import ru.spcex.clearing.backendapi.controller.queue.utils.JsonUtil; +import ru.spcex.clearing.backendapi.controller.queue.utils.MatcherFactory; +import ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction; +import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse; + +import javax.annotation.PostConstruct; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringJUnitWebConfig(classes = { + Jackson2HttpConverterConfig.class}) +class BankAccountControllerTest { + + public static final MatcherFactory.Matcher CUD_RESPONSE_MATCHER = MatcherFactory.usingIgnoringFieldsComparator(CudResponse.class); + private static final String REST_URL = "/securities/bank-accounts/"; + private static final CharacterEncodingFilter CHARACTER_ENCODING_FILTER = new CharacterEncodingFilter(); + + static { + CHARACTER_ENCODING_FILTER.setEncoding("UTF-8"); + CHARACTER_ENCODING_FILTER.setForceEncoding(true); + } + + @Autowired + public Environment env; + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext webApplicationContext; + + @PostConstruct + private void postConstruct() { + mockMvc = MockMvcBuilders + .webAppContextSetup(webApplicationContext) + .addFilter(CHARACTER_ENCODING_FILTER) +// .apply(springSecurity()) + .build(); + } + + @Test + void add() throws Exception { + BankAccountNewAction bankAccountNewAction = new BankAccountNewAction(); + ResultActions action = mockMvc.perform(MockMvcRequestBuilders.post(REST_URL) + .contentType(MediaType.APPLICATION_JSON) +// .with(userHttpBasic(admin)) + .content(JsonUtil.writeValue(bankAccountNewAction))) + .andExpect(status().isCreated()); + + CudResponse created = CUD_RESPONSE_MATCHER.readFromJson(action); + } + + @Test + void update() { + } + + @Test + void delete() { + } +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/config/Jackson2HttpConverterConfig.java b/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/config/Jackson2HttpConverterConfig.java new file mode 100644 index 000000000..c6d557d21 --- /dev/null +++ b/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/config/Jackson2HttpConverterConfig.java @@ -0,0 +1,39 @@ +package ru.spcex.clearing.backendapi.controller.queue.config; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +@Configuration +public class Jackson2HttpConverterConfig { + @Bean("customJsonHttpConverter") + public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { + return new MappingJackson2HttpMessageConverter(JacksonObjectMapper.getMapper()); + } + + public static class JacksonObjectMapper extends ObjectMapper { + private static final ObjectMapper MAPPER = new JacksonObjectMapper(); + + private JacksonObjectMapper() { + //настройки Ильи + configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); + + //настройки какие были на курсе пока не нужны.. +// модуль для корректной сериализации LocalDateTime в поля JSON - JavaTimeModule модуль библиотеки jackson-datatype-jsr310 +// registerModule(new JavaTimeModule()); +// configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + +// запрещаем доступ ко всем полям и методам класса и потом разрешаем доступ только к полям, нужны чтобы не было лишних полей из-за методов как: public boolean isExcess() +// setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); +// setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); +// не сериализуем null-поля +// setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + + public static ObjectMapper getMapper() { + return MAPPER; + } + } +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/utils/JsonUtil.java b/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/utils/JsonUtil.java new file mode 100644 index 000000000..fb20fe457 --- /dev/null +++ b/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/utils/JsonUtil.java @@ -0,0 +1,38 @@ +package ru.spcex.clearing.backendapi.controller.queue.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectReader; + +import java.io.IOException; +import java.util.List; + +import static ru.spcex.clearing.backendapi.controller.queue.config.Jackson2HttpConverterConfig.JacksonObjectMapper.getMapper; + +public class JsonUtil { + + public static List readValues(String json, Class clazz) { + ObjectReader reader = getMapper().readerFor(clazz); + try { + return reader.readValues(json).readAll(); + } catch (IOException e) { + throw new IllegalArgumentException("Invalid read array from JSON:\n'" + json + "'", e); + } + } + + public static T readValue(String json, Class clazz) { + try { + return getMapper().readValue(json, clazz); + } catch (IOException e) { + throw new IllegalArgumentException("Invalid read from JSON:\n'" + json + "'", e); + } + } + + public static String writeValue(T obj) { + try { + return getMapper().writeValueAsString(obj); + } catch (JsonProcessingException e) { + throw new IllegalStateException("Invalid write to JSON:\n'" + obj + "'", e); + } + } + +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/utils/MatcherFactory.java b/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/utils/MatcherFactory.java new file mode 100644 index 000000000..1143b031a --- /dev/null +++ b/clearing-parent/backend-api/src/test/ru/spcex/clearing/backendapi/controller/queue/utils/MatcherFactory.java @@ -0,0 +1,82 @@ +package ru.spcex.clearing.backendapi.controller.queue.utils; + +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.ResultMatcher; + +import java.io.UnsupportedEncodingException; +import java.util.List; +import java.util.function.BiConsumer; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Factory for creating test matchers. + *

+ * Comparing actual and expected objects via AssertJ + * Support converting json MvcResult to objects for comparation. + */ +public class MatcherFactory { + + public static Matcher usingAssertions(Class clazz, BiConsumer assertion, BiConsumer, Iterable> iterableAssertion) { + return new Matcher<>(clazz, assertion, iterableAssertion); + } + + public static Matcher usingEqualsComparator(Class clazz) { + return usingAssertions(clazz, + (a, e) -> assertThat(a).isEqualTo(e), + (a, e) -> assertThat(a).isEqualTo(e)); + } + + public static Matcher usingIgnoringFieldsComparator(Class clazz, String... fieldsToIgnore) { + return usingAssertions(clazz, + (a, e) -> assertThat(a).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(e), + (a, e) -> assertThat(a).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(e)); + } + + public static class Matcher { + private final Class clazz; + private final BiConsumer assertion; + private final BiConsumer, Iterable> iterableAssertion; + + private Matcher(Class clazz, BiConsumer assertion, BiConsumer, Iterable> iterableAssertion) { + this.clazz = clazz; + this.assertion = assertion; + this.iterableAssertion = iterableAssertion; + } + + private static String getContent(MvcResult result) throws UnsupportedEncodingException { + return result.getResponse().getContentAsString(); + } + + public void assertMatch(T actual, T expected) { + assertion.accept(actual, expected); + } + + @SafeVarargs + public final void assertMatch(Iterable actual, T... expected) { + assertMatch(actual, List.of(expected)); + } + + public void assertMatch(Iterable actual, Iterable expected) { + iterableAssertion.accept(actual, expected); + } + + public ResultMatcher contentJson(T expected) { + return result -> assertMatch(JsonUtil.readValue(getContent(result), clazz), expected); + } + + @SafeVarargs + public final ResultMatcher contentJson(T... expected) { + return contentJson(List.of(expected)); + } + + public ResultMatcher contentJson(Iterable expected) { + return result -> assertMatch(JsonUtil.readValues(getContent(result), clazz), expected); + } + + public T readFromJson(ResultActions action) throws UnsupportedEncodingException { + return JsonUtil.readValue(getContent(action.andReturn()), clazz); + } + } +} diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractUpdateMapService.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractUpdateMapService.java index 24a5bc55b..f90e5ee06 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractUpdateMapService.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractUpdateMapService.java @@ -15,13 +15,11 @@ import java.time.Instant; public abstract class AbstractUpdateMapService implements InitializingBean, EntryAddedListener, EntryUpdatedListener, EntryRemovedListener { - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - protected final String EVENT_CREATE="CREATE"; - protected final String EVENT_UPDATE="UPDATE"; - protected final String EVENT_DELETE="DELETE"; - + protected final String EVENT_CREATE = "CREATE"; + protected final String EVENT_UPDATE = "UPDATE"; + protected final String EVENT_DELETE = "DELETE"; protected final HazelcastInstance hazelcastServerInstance; + private final Logger log = LoggerFactory.getLogger(this.getClass()); public AbstractUpdateMapService(HazelcastInstance hazelcastServerInstance) { this.hazelcastServerInstance = hazelcastServerInstance;