Testing account-service, backend-api, balance-service, company-service.

This commit is contained in:
psemenkov 2023-02-14 14:51:03 +03:00
parent daa2e880ff
commit 71de170b00
66 changed files with 9863 additions and 796 deletions

View file

@ -60,6 +60,11 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

View file

@ -11,7 +11,6 @@ import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.BankAccount;
import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
@ -42,7 +41,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea
private final Imdg<Relation> relationMap;
private final IMessageResolver messageResolver;
// private final Imdg<User> userImdg;
// private final Imdg<User> userImdg;
// private final Imdg<UserRoleSession> userRoleSessionImdg;
private final Function<BankAccountNewRequest, IValidator> bankAccountNewRequestValidator;

View file

@ -52,7 +52,7 @@ public enum AccountValidationRule implements IValidationRule<ImdgValidationConte
public Optional<EnumMessage> validate(ImdgValidationContext<BankAccountNewRequest> context) {
BankAccountNewRequest accountReq = context.getValidatedObject();
if (StringUtils.isEmpty(accountReq.getCurrency())) {
return of(AccountError.WrongFieldValue, "Currency");
return of(AccountError.WrongFieldValue, "currency");
}
if (StringUtils.isEmpty(accountReq.getBankIdentificationCode())) {
return of(AccountError.WrongFieldValue, "bankIdentificationCode");

View file

@ -13,9 +13,11 @@ import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
@Configuration
public class HazelcastServiceTestConfiguration {
public static final AtomicLong currentID = new AtomicLong(0L);
private HazelcastInstance hazelcastInstance;
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
@ -40,7 +42,7 @@ public class HazelcastServiceTestConfiguration {
joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(true).setMembers(List.of("127.0.0.1")));
networkConfig.setJoin(joinConfig);
cfg.setNetworkConfig(networkConfig);
hazelcastInstance = Hazelcast.newHazelcastInstance(cfg);
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg);
HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance);
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
}

View file

@ -0,0 +1,44 @@
package ru.spcex.clearing.account.config;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
import org.apache.kafka.clients.producer.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
@Configuration
public class KafkaConfigTest {
@Autowired
@Bean(name = "kafkaSenderTest")
public KafkaSender kafkaSender(Producer<String, Object> kafkaProducer, @Qualifier("hazelcastServiceTest") ImdgProvider imdgProvider) {
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
return KafkaSender
.setup()
.producer(kafkaProducer)
.idGenerator(imdgIdGenerator::nextId)
.imdgProvider(s -> {
Imdg<RequestInfo> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
return imdg::insert;
})
.build();
}
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean(name = "mockConsumerTest")
public MockConsumer<String, Object> createConsumer() {
return new MockConsumer<>(OffsetResetStrategy.EARLIEST);
}
}

View file

@ -0,0 +1,146 @@
package ru.spcex.clearing.account.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.account.Account;
import ru.spcex.clearing.account.config.HazelcastServiceTestConfiguration;
import ru.spcex.clearing.account.config.KafkaConfigTest;
import ru.spcex.clearing.account.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.account.config.HazelcastServiceTestConfiguration.currentID;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.account.utils.TestUtils.addRecordToKafka;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
AccountService.class,
HazelcastServiceTestConfiguration.class,
KafkaConfigTest.class})
class AccountServiceTest {
public static final MatcherFactory.Matcher<Account> ACCOUNT_MATCHER = usingIgnoringFieldsComparator();
public static final MatcherFactory.Matcher<RequestInfo> REQUEST_INFO_MATCHER_MATCHER = usingIgnoringFieldsComparator("created");
private static final int PARTITION = 0;
private static final String TOPIC_ACCOUNT_NEW = Consts.ACCOUNT_NEW;
private static final String account = "123456789123";
@Autowired
AccountService accountService;
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@SpyBean
private MockProducer<String, Object> producer;
/**
* {@link AccountService#accountNew(BaseRequest)}<br>
* Тест проверяет создание сущности {@link BaseRequest} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link AccountSdf01Request}:<br>
* {@link AccountSdfRequestPart#setSdfId} - текущий Id<br>
* {@link AccountSdfRequestPart#setAccount} - 123456789123<br>
* {@link AccountSdfRequestPart#setCompanyId} - текущий Id<br>
* {@link AccountSdf01Request#setGroupingSdf01Id} - текущий Id<br>
* {@link AccountSdf01Request#setAccounts} - Collections.singletonList(AccountSdfRequestPart)<br>
*/
@Test
void accountNew() throws InterruptedException {
//ARRANGE
Long firstID = currentID.getAndIncrement();
Long secondID = currentID.getAndIncrement();
AccountSdfRequestPart accountSdfRequestPart = new AccountSdfRequestPart();
accountSdfRequestPart.setSdfId(firstID);
accountSdfRequestPart.setAccount(account);
accountSdfRequestPart.setCompanyId(firstID);
AccountSdf01Request accountSdf01Request = new AccountSdf01Request();
accountSdf01Request.setGroupingSdf01Id(firstID);
accountSdf01Request.setAccounts(Collections.singletonList(accountSdfRequestPart));
BaseRequest<AccountSdf01Request> baseNewRequest = new BaseRequest<>();
baseNewRequest.setRequestPayload(accountSdf01Request);
baseNewRequest.setId(firstID);
baseNewRequest.setActionType(ActionType.NEW);
String jsonBaseNewRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart();
responsePart.setSdfId(firstID);
responsePart.setErrorCode(null);
responsePart.setErrorText(null);
List<AccountSdfToStatementRequestPart> accountToStatement = Collections.singletonList(responsePart);
StatementRequest statementRequest = new StatementRequest();
statementRequest.setGroupId(firstID);
statementRequest.setAccountCreationResults(accountToStatement);
BaseRequest<Object> baseRequest = new BaseRequest<>();
baseRequest.setId(secondID);
baseRequest.setActionType(ActionType.SYSTEM);
baseRequest.setRequestPayload(statementRequest);
Account predictableAccount = new Account();
predictableAccount.setAccount(account);
predictableAccount.setId(firstID);
predictableAccount.setCompanyId(firstID);
RequestInfo predictableRequestInfo = new RequestInfo();
predictableRequestInfo.setId(secondID);
predictableRequestInfo.setStatus(Status.Processing);
//ACT
hazelcastServiceTest.waitTillReadyState();
//KAFKA
addRecordToKafka((MockConsumer) accountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, 0, jsonBaseNewRequest);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(1))
.send(producerRecord.capture());
BaseRequest<Object> baseRequestObject = (BaseRequest<Object>) producerRecord.getValue().value();
ImdgHazelcast<Account> accountImdg = (ImdgHazelcast<Account>) hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class);
ImdgHazelcast<RequestInfo> requestInfoImdg = (ImdgHazelcast<RequestInfo>) hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
//ASSERT
Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", account));
RequestInfo requestInfoResult = requestInfoImdg.getSingleObjectByID(baseRequestObject.getId());
assertEquals(Consts.STATEMENT_PROCESS, producerRecord.getValue().topic());
ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
REQUEST_INFO_MATCHER_MATCHER.assertMatch(requestInfoResult, predictableRequestInfo);
}
}

View file

@ -1,24 +1,24 @@
package ru.spcex.clearing.account.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.BankAccount;
import ru.clearing.classes.statics.data.company.Company;
import ru.spcex.clearing.account.config.ErrorResolverConfig;
import ru.spcex.clearing.account.config.HazelcastServiceTestConfiguration;
import ru.spcex.clearing.account.config.KafkaConfigTest;
import ru.spcex.clearing.account.config.ValidationConfig;
import ru.spcex.clearing.account.utils.MatcherFactory.Matcher;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
@ -28,43 +28,75 @@ import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.Allowed;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
import java.util.Collections;
import java.util.HashMap;
import java.util.function.Function;
import javax.annotation.PostConstruct;
import java.util.concurrent.atomic.AtomicInteger;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator;
import static ru.spcex.clearing.account.utils.TestUtils.*;
import static ru.spcex.clearing.platform.messaging.service.Status.Error;
import static ru.spcex.clearing.platform.messaging.service.Status.Success;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
HazelcastServiceTestConfiguration.class, ErrorResolverConfig.class,
ValidationConfig.class})
ErrorResolverConfig.class,
BankAccountService.class,
ValidationConfig.class,
HazelcastServiceTestConfiguration.class,
KafkaConfigTest.class})
public class BankAccountServiceTest {
public static final Matcher<BankAccount> BANK_ACCOUNT_MATCHER = usingIgnoringFieldsComparator();
public static final Matcher<Account> ACCOUNT_MATCHER = usingIgnoringFieldsComparator();
public static final Matcher<BaseRequest<Object>> BASE_REQUEST_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;
private static final String TOPIC_ACCOUNT_DELETE = Consts.DESTINATION_BANK_ACCOUNT_DELETE;
private static Long currentId = 0L;
private static final Long ID = 0L;
private static final AtomicInteger countRun = new AtomicInteger(1);
private static final Long accountId = 12L;
private static final String currency = "RUB";
private static final String bankIdentificationCode = "99999";
private static final String bankName = "ooo tinkoff";
private static final String destination = "OOO ROGA I KOPITA";
private static final String correspondentAccount = "9294189285498598598";
private static final String correspondentAccountName = "BIK OF TINKOFF";
private static final String taxpayerIdentificationNumber = "848484848484";
private static final String taxRegistrationReasonCode = "886886";
protected final Long addresseeIdNew = 2L;
protected final String deal = "111111111";
private final String acc = "0123456789";
protected Imdg<Company> companyImdg;
private Imdg<BankAccount> bankAccountImdg;
private Imdg<Account> accountImdg;
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
@Autowired
private IMessageResolver messageResolver;
private MockConsumer<String, Object> mockConsumer;
private MockProducer<String, Object> mockProducer;
@Autowired
private Function<BankAccountNewRequest, IValidator> bankAccountNewRequestValidator;
private BankAccountService bankAccountService;
@BeforeEach
void setUp() {
mockConsumer = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
mockProducer = new MockProducer<>();
@Captor
private ArgumentCaptor<ProducerRecord> producerRecord;
@SpyBean
private MockProducer<String, Object> producer;
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class);
bankAccountImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class);
accountImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class);
}
/**
@ -81,73 +113,159 @@ public class BankAccountServiceTest {
* {@link BankAccountNewRequest#taxRegistrationReasonCode} - 886886<br>
* {@link BankAccountNewRequest#account} - 123456789123<br>
*/
// @Test
public void bankAccountNew() throws InterruptedException {
//arrange
BankAccountNewRequest bankAccountNewRequest = new BankAccountNewRequest();
bankAccountNewRequest.setBankName("ooo tinkoff");
bankAccountNewRequest.setBankIdentificationCode("99999");
bankAccountNewRequest.setCorrespondentAccount("9294189285498598598");
bankAccountNewRequest.setCorrespondentAccountName("BIK OF TINKOFF");
bankAccountNewRequest.setCurrency("RUB");
bankAccountNewRequest.setDestination("OOO ROGA I KOPITA");
bankAccountNewRequest.setTaxpayerIdentificationNumber("848484848484");
bankAccountNewRequest.setTaxRegistrationReasonCode("886886");
bankAccountNewRequest.setAccount("123456789123");
@Test
public void bankAccountNew() {
//ARRANGE
BaseRequest<Object> predictableBaseRequest = new BaseRequest<>();
predictableBaseRequest.setId(ID);
predictableBaseRequest.setActionType(ActionType.SYSTEM);
RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate();
requestInfoUpdate.setId(ID);
requestInfoUpdate.setStatus(Success);
predictableBaseRequest.setRequestPayload(requestInfoUpdate);
BaseRequest<BankAccountNewRequest> baseNewRequest = new BaseRequest<>();
baseNewRequest.setRequestPayload(bankAccountNewRequest);
baseNewRequest.setId(currentId);
baseNewRequest.setActionType(ActionType.NEW);
String jsonBaseNewRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
BankAccount predictableResult = new BankAccount();
predictableResult.setBankName("ooo tinkoff");
predictableResult.setBankIdentificationCode("99999");
predictableResult.setCorrespondentAccount("9294189285498598598");
predictableResult.setCorrespondentAccountName("BIK OF TINKOFF");
predictableResult.setCurrency("RUB");
predictableResult.setDestination("OOO ROGA I KOPITA");
predictableResult.setTaxpayerIdentificationNumber("848484848484");
predictableResult.setTaxRegistrationReasonCode("886886");
predictableResult.setId(currentId);
//KAFKA
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC_ACCOUNT_NEW, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC_ACCOUNT_NEW, PARTITION, 0, "key", jsonBaseNewRequest));
});
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
TopicPartition tp = new TopicPartition(TOPIC_ACCOUNT_NEW, PARTITION);
startOffsets.put(tp, 0L);
mockConsumer.updateBeginningOffsets(startOffsets);
BankAccount predictableBankAccount = getBankAccount();
Company company = getTestCompany();
companyImdg.insert(company);
Account predictableAccount = getTestAccount(accountId, acc);
clearImdg(accountImdg);
BankAccountNewRequest bankAccountNewRequest = getBankAccountNewRequest(predictableBankAccount);
String jsonString = getJsonStringForNew(bankAccountNewRequest, ID);
//ACT
addRecordToKafka((MockConsumer) bankAccountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, 0, jsonString);
//service set up
BankAccountService bankAccountService = new BankAccountService(mockConsumer, mockProducer,
hazelcastServiceTest, messageResolver,
bankAccountNewRequestValidator);
Thread.sleep(10000);
//callbacks set up
bankAccountService.afterPropertiesSet();
Thread.sleep(10000);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(1))
.send(producerRecord.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", acc));
BankAccount bankAccountResult = bankAccountImdg.getSingleObjectBySQL(String.format("account = %s or companyId = %s", acc, addresseeIdNew));
predictableBankAccount.setAccountId(accountResult.getId());
predictableBankAccount.setId(bankAccountResult.getId());
setSameValueToField(accountResult, predictableAccount);
//ASSERT
IMap<Long, BankAccount> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_BankAccount);
BankAccount result = iMap.get(currentId);
assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic());
BANK_ACCOUNT_MATCHER.assertMatch(bankAccountResult, predictableBankAccount);
ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest);
}
BANK_ACCOUNT_MATCHER.assertMatch(result, predictableResult);
/**
* {@link BankAccountService#bankAccountNew(BaseRequest request)}<br>
* Тест проверяет валидацию.<br>
* Входной запрос {@link BankAccountNewRequest}:<br>
* {@link BankAccountNewRequest#bankIdentificationCode} - 99999<br>
* {@link BankAccountNewRequest#bankName} - ооо тинькофф<br>
* {@link BankAccountNewRequest#correspondentAccount} - 9294189285498598598<br>
* {@link BankAccountNewRequest#correspondentAccountName} - BIK OF<br>
* {@link BankAccountNewRequest#currency} - RUB<br>
* {@link BankAccountNewRequest#destination} - OOO ROGA I KOPITA<br>
* {@link BankAccountNewRequest#taxpayerIdentificationNumber} - 848484848484<br>
* {@link BankAccountNewRequest#taxRegistrationReasonCode} - 886886<br>
* {@link BankAccountNewRequest#account} - 123456789123<br>
*/
@Test
public void validatedBankAccountNew() {
clearImdg(accountImdg);
BankAccount predictableBankAccount = getBankAccount();
Company company = getTestCompany();
companyImdg.insert(company);
BankAccountNewRequest bankAccountNewRequest = getBankAccountNewRequest(predictableBankAccount);
//reset hazelcastService for next test
iMap.clear();
currentId++;
//AccountValidationRule.RequiredFields
//WrongFieldValue
bankAccountNewRequest.setCurrency(null);
checkError("(5004) args [currency]", bankAccountNewRequest);
bankAccountNewRequest.setCurrency(currency);
bankAccountNewRequest.setBankIdentificationCode(null);
checkError("(5004) args [bankIdentificationCode]", bankAccountNewRequest);
bankAccountNewRequest.setBankIdentificationCode(bankIdentificationCode);
bankAccountNewRequest.setBankName(null);
checkError("(5004) args [bankName]", bankAccountNewRequest);
bankAccountNewRequest.setBankName(bankName);
bankAccountNewRequest.setAccount(null);
checkError("(5004) args [account]", bankAccountNewRequest);
bankAccountNewRequest.setAccount(acc);
bankAccountNewRequest.setDestination(null);
checkError("(5004) args [destination]", bankAccountNewRequest);
bankAccountNewRequest.setDestination(destination);
bankAccountNewRequest.setCompanyId(null);
checkError("(5004) args [companyId]", bankAccountNewRequest);
bankAccountNewRequest.setCompanyId(addresseeIdNew);
//AccountValidationRule.RubRequiredFields
//WrongFieldValue
bankAccountNewRequest.setCorrespondentAccount(null);
checkError("(5004) args [correspondentAccount]", bankAccountNewRequest);
bankAccountNewRequest.setCorrespondentAccount(correspondentAccount);
bankAccountNewRequest.setCorrespondentAccountName(null);
checkError("(5004) args [correspondentAccountName]", bankAccountNewRequest);
bankAccountNewRequest.setCorrespondentAccountName(correspondentAccountName);
bankAccountNewRequest.setTaxpayerIdentificationNumber(null);
checkError("(5004) args [taxpayerIdentificationNumber]", bankAccountNewRequest);
bankAccountNewRequest.setTaxpayerIdentificationNumber(taxpayerIdentificationNumber);
bankAccountNewRequest.setTaxRegistrationReasonCode(null);
checkError("(5004) args [taxRegistrationReasonCode]", bankAccountNewRequest);
bankAccountNewRequest.setTaxRegistrationReasonCode(taxRegistrationReasonCode);
//AccountValidationRule.CompanyPresent
//CompanyNotFound
bankAccountNewRequest.setCompanyId(999924535239L);
checkError("(5013) args []", bankAccountNewRequest);
//CompanyNotActive
company.setWorkflowStatus(Status.Blocked.getKey());
companyImdg.insert(company);
bankAccountNewRequest.setCompanyId(company.getId());
checkError("(5014) args []", bankAccountNewRequest);
//AccountValidationRule.AccountIsNew
//AccountAlreadyExist
company.setWorkflowStatus(Status.Active.getKey());
companyImdg.insert(company);
Account existAccount = getTestAccount(accountId, acc);
accountImdg.insert(existAccount);
checkError("(5010) args []", bankAccountNewRequest);
accountImdg.delete(existAccount);
}
private void checkError(String errorMsg, BankAccountNewRequest bankAccountNewRequest) {
//ARRANGE
int currentTime = countRun.getAndIncrement();
long currentOffset = currentTime;
BaseRequest<Object> predictableBaseRequest = new BaseRequest<>();
predictableBaseRequest.setId(ID);
predictableBaseRequest.setActionType(ActionType.SYSTEM);
RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate();
requestInfoUpdate.setId(ID);
requestInfoUpdate.setStatus(Error);
requestInfoUpdate.setMessage(errorMsg);
predictableBaseRequest.setRequestPayload(requestInfoUpdate);
String jsonString = getJsonStringForNew(bankAccountNewRequest, ID);
//ACT
addRecordToKafka((MockConsumer) bankAccountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, currentOffset, jsonString);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(currentTime))
.send(producerRecord.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
//ASSERT
assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic());
BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest);
}
/**
@ -164,104 +282,72 @@ public class BankAccountServiceTest {
* {@link BankAccountUpdateRequest#taxRegistrationReasonCode} - 532137<br>
* {@link BankAccountUpdateRequest#account} - 326984656514<br>
*/
// @Test
void bankAccountUpdate() throws InterruptedException {
//arrange
BankAccountNewRequest bankAccountNewRequest = new BankAccountNewRequest();
bankAccountNewRequest.setBankName("ooo tinkoff");
bankAccountNewRequest.setBankIdentificationCode("99999");
bankAccountNewRequest.setCorrespondentAccount("9294189285498598598");
bankAccountNewRequest.setCorrespondentAccountName("BIK OF TINKOFF");
bankAccountNewRequest.setCurrency("RUB");
bankAccountNewRequest.setDestination("OOO ROGA I KOPITA");
bankAccountNewRequest.setTaxpayerIdentificationNumber("848484848484");
bankAccountNewRequest.setTaxRegistrationReasonCode("886886");
bankAccountNewRequest.setAccount("123456789123");
@Test
void bankAccountUpdate() {
//ARRANGE
BaseRequest<Object> predictableBaseRequest = new BaseRequest<>();
predictableBaseRequest.setId(ID);
predictableBaseRequest.setActionType(ActionType.SYSTEM);
RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate();
requestInfoUpdate.setId(ID);
requestInfoUpdate.setStatus(Success);
predictableBaseRequest.setRequestPayload(requestInfoUpdate);
// Company company = getTestCompany();
// companyImdg.insert(company);
Account predictableAccount = getTestAccount(accountId, acc);
accountImdg.insert(predictableAccount);
BankAccount bankAccountExists = getBankAccount();
bankAccountImdg.insert(bankAccountExists);
BankAccount predictableUpdateBankAccount = new BankAccount();
predictableUpdateBankAccount.setBankName("NEW BUNK NAME");
predictableUpdateBankAccount.setBankIdentificationCode("88888");
predictableUpdateBankAccount.setCorrespondentAccount("894984646541316");
predictableUpdateBankAccount.setCorrespondentAccountName("BIK OF NEW BUNK");
predictableUpdateBankAccount.setCurrency("EU");
predictableUpdateBankAccount.setDestination("OOO NEW BUNK");
predictableUpdateBankAccount.setTaxpayerIdentificationNumber("65468461321");
predictableUpdateBankAccount.setTaxRegistrationReasonCode("532137");
predictableUpdateBankAccount.setAccount(acc);
predictableUpdateBankAccount.setId(ID);
BaseRequest<BankAccountNewRequest> baseNewRequest = new BaseRequest<>();
baseNewRequest.setRequestPayload(bankAccountNewRequest);
baseNewRequest.setId(currentId);
baseNewRequest.setActionType(ActionType.NEW);
String jsonBaseNewRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
BankAccountUpdateRequest bankAccountUpdateRequest = new BankAccountUpdateRequest();
bankAccountUpdateRequest.setId(currentId);
bankAccountUpdateRequest.setBankName("NEW BUNK NAME");
bankAccountUpdateRequest.setBankIdentificationCode("88888");
bankAccountUpdateRequest.setCorrespondentAccount("894984646541316");
bankAccountUpdateRequest.setCorrespondentAccountName("BIK OF NEW BUNK");
bankAccountUpdateRequest.setCurrency("EU");
bankAccountUpdateRequest.setDestination("OOO NEW BUNK");
bankAccountUpdateRequest.setTaxpayerIdentificationNumber("65468461321");
bankAccountUpdateRequest.setTaxRegistrationReasonCode("532137");
bankAccountUpdateRequest.setAccount("326984656514");
bankAccountUpdateRequest.setId(predictableUpdateBankAccount.getId());
bankAccountUpdateRequest.setBankName(predictableUpdateBankAccount.getBankName());
bankAccountUpdateRequest.setBankIdentificationCode(predictableUpdateBankAccount.getBankIdentificationCode());
bankAccountUpdateRequest.setCorrespondentAccount(predictableUpdateBankAccount.getCorrespondentAccount());
bankAccountUpdateRequest.setCorrespondentAccountName(predictableUpdateBankAccount.getCorrespondentAccountName());
bankAccountUpdateRequest.setCurrency(predictableUpdateBankAccount.getCurrency());
bankAccountUpdateRequest.setDestination(predictableUpdateBankAccount.getDestination());
bankAccountUpdateRequest.setTaxpayerIdentificationNumber(predictableUpdateBankAccount.getTaxpayerIdentificationNumber());
bankAccountUpdateRequest.setTaxRegistrationReasonCode(predictableUpdateBankAccount.getTaxRegistrationReasonCode());
bankAccountUpdateRequest.setAccount(predictableUpdateBankAccount.getAccount());
BaseRequest<BankAccountUpdateRequest> baseUpdateRequest = new BaseRequest<>();
baseUpdateRequest.setRequestPayload(bankAccountUpdateRequest);
baseUpdateRequest.setId(currentId);
baseUpdateRequest.setActionType(ActionType.UPDATE);
String jsonBaseUpdateRequest;
try {
jsonBaseUpdateRequest = objectMapper.writeValueAsString(baseUpdateRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
BankAccount predictableUpdateResult = new BankAccount();
predictableUpdateResult.setBankName("NEW BUNK NAME");
predictableUpdateResult.setBankIdentificationCode("88888");
predictableUpdateResult.setCorrespondentAccount("894984646541316");
predictableUpdateResult.setCorrespondentAccountName("BIK OF NEW BUNK");
predictableUpdateResult.setCurrency("EU");
predictableUpdateResult.setDestination("OOO NEW BUNK");
predictableUpdateResult.setTaxpayerIdentificationNumber("65468461321");
predictableUpdateResult.setTaxRegistrationReasonCode("532137");
predictableUpdateResult.setId(currentId);
//KAFKA
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC_ACCOUNT_NEW, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC_ACCOUNT_NEW, PARTITION, 0, "key", jsonBaseNewRequest));
});
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
TopicPartition tp = new TopicPartition(TOPIC_ACCOUNT_NEW, PARTITION);
startOffsets.put(tp, 0L);
mockConsumer.updateBeginningOffsets(startOffsets);
String jsonString = getJsonStringForUPDATE(bankAccountUpdateRequest, ID);
//ACT
//service set up
BankAccountService bankAccountService = new BankAccountService(mockConsumer, mockProducer,
hazelcastServiceTest, messageResolver,
bankAccountNewRequestValidator);
Thread.sleep(10000);
//callbacks set up
bankAccountService.afterPropertiesSet();
Thread.sleep(10000);
addRecordToKafka((MockConsumer) bankAccountService.getConsumer(), TOPIC_ACCOUNT_UPDATE, PARTITION, 0, jsonString);
//KAFKA
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC_ACCOUNT_UPDATE, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC_ACCOUNT_UPDATE, PARTITION, 0, "key", jsonBaseUpdateRequest));
});
HashMap<TopicPartition, Long> startOffsetsUpdating = new HashMap<>();
TopicPartition tpUpdating = new TopicPartition(TOPIC_ACCOUNT_UPDATE, PARTITION);
startOffsetsUpdating.put(tpUpdating, 0L);
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(1))
.send(producerRecord.capture());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", acc));
BankAccount resultUpdating = bankAccountImdg.getSingleObjectBySQL(String.format("account = %s or companyId = %s", acc, addresseeIdNew));
predictableUpdateBankAccount.setAccountId(resultUpdating.getAccountId());
predictableUpdateBankAccount.setCompanyId(resultUpdating.getCompanyId());
predictableAccount.setUpdated(accountResult.getUpdated());
//ASSERT
Thread.sleep(10000);
IMap<Long, BankAccount> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_BankAccount);
BankAccount resultUpdating = iMap.get(currentId);
assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic());
BANK_ACCOUNT_MATCHER.assertMatch(resultUpdating, predictableUpdateResult);
//reset hazelcastService for next test
iMap.clear();
currentId++;
//ASSERT
assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic());
BANK_ACCOUNT_MATCHER.assertMatch(resultUpdating, predictableUpdateBankAccount);
ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount);
BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest);
}
/**
@ -271,80 +357,87 @@ public class BankAccountServiceTest {
* {@link CommonDeleteRequest#id} - Идентификатор записи
*/
@Test
void bankAccountDelete() throws InterruptedException {
//arrange
BankAccountNewRequest bankAccountNewRequest = new BankAccountNewRequest();
bankAccountNewRequest.setBankName("ooo tinkoff");
bankAccountNewRequest.setBankIdentificationCode("99999");
bankAccountNewRequest.setCorrespondentAccount("9294189285498598598");
bankAccountNewRequest.setCorrespondentAccountName("BIK OF TINKOFF");
bankAccountNewRequest.setCurrency("RUB");
bankAccountNewRequest.setDestination("OOO ROGA I KOPITA");
bankAccountNewRequest.setTaxpayerIdentificationNumber("848484848484");
bankAccountNewRequest.setTaxRegistrationReasonCode("886886");
bankAccountNewRequest.setAccount("123456789123");
BaseRequest<BankAccountNewRequest> baseNewRequest = new BaseRequest<>();
baseNewRequest.setRequestPayload(bankAccountNewRequest);
baseNewRequest.setId(currentId);
baseNewRequest.setActionType(ActionType.NEW);
String jsonBaseNewRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
void bankAccountDelete() {
//ARRANGE
BankAccount bankAccountExists = getBankAccount();
bankAccountImdg.insert(bankAccountExists);
Account account = new Account();
account.setId(accountId);
accountImdg.insert(account);
CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest();
commonDeleteRequest.setId(currentId);
BaseRequest<CommonDeleteRequest> baseDeleteRequest = new BaseRequest<>();
baseDeleteRequest.setRequestPayload(commonDeleteRequest);
baseDeleteRequest.setId(currentId);
baseDeleteRequest.setActionType(ActionType.DELETE);
String jsonDeleteNewRequest;
try {
jsonDeleteNewRequest = objectMapper.writeValueAsString(baseDeleteRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
//KAFKA
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC_ACCOUNT_NEW, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC_ACCOUNT_NEW, PARTITION, 0, "key", jsonBaseNewRequest));
});
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
TopicPartition tp = new TopicPartition(TOPIC_ACCOUNT_NEW, PARTITION);
startOffsets.put(tp, 0L);
mockConsumer.updateBeginningOffsets(startOffsets);
commonDeleteRequest.setId(ID);
String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID);
//ACT
//service set up
BankAccountService bankAccountService = new BankAccountService(mockConsumer, mockProducer,
hazelcastServiceTest, messageResolver,
bankAccountNewRequestValidator);
Thread.sleep(10000);
//callbacks set up
bankAccountService.afterPropertiesSet();
Thread.sleep(10000);
addRecordToKafka((MockConsumer) bankAccountService.getConsumer(), TOPIC_ACCOUNT_DELETE, PARTITION, 0, jsonString);
//KAFKA
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC_ACCOUNT_DELETE, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC_ACCOUNT_DELETE, PARTITION, 0, "key", jsonDeleteNewRequest));
});
HashMap<TopicPartition, Long> startOffsetsDeleting = new HashMap<>();
TopicPartition tpDeleting = new TopicPartition(TOPIC_ACCOUNT_DELETE, PARTITION);
startOffsetsDeleting.put(tpDeleting, 0L);
mockConsumer.updateBeginningOffsets(startOffsetsDeleting);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(1))
.send(producerRecord.capture());
//ASSERT
Thread.sleep(10000);
IMap<Long, BankAccount> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_BankAccount);
Assertions.assertEquals(0, iMap.size());
//reset hazelcastService for next test
iMap.clear();
currentId++;
BankAccount bankAccount = bankAccountImdg.getSingleObjectByID(ID);
Assertions.assertNull(bankAccount);
assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic());
}
private Company getTestCompany() {
Company company = new Company();
company.setId(addresseeIdNew);
company.setWorkflowStatus(Status.Active.getKey());
company.setTradingCode(deal);
company.setShortName("ShortName");
company.setFullName("FullName");
return company;
}
private Account getTestAccount(Long id, String acc) {
Account account = new Account();
account.setId(id);
account.setAccount(acc);
account.setAccountType(AccountType.Bank.getKey());
account.setAccountStatus(Status.Active.getKey());
account.setProcessingSign(Allowed.ALLOWED.getKey());
return account;
}
private void setSameValueToField(Account from, Account to) {
to.setCreated(from.getCreated());
to.setUpdated(from.getUpdated());
to.setId(from.getId());
}
private BankAccount getBankAccount() {
BankAccount bankAccount = new BankAccount();
bankAccount.setAccountId(accountId);
bankAccount.setAccount(acc);
bankAccount.setCompanyId(addresseeIdNew);
bankAccount.setId(ID);
bankAccount.setBankName(bankName);
bankAccount.setBankIdentificationCode(bankIdentificationCode);
bankAccount.setCorrespondentAccount(correspondentAccount);
bankAccount.setCorrespondentAccountName(correspondentAccountName);
bankAccount.setCurrency(currency);
bankAccount.setDestination(destination);
bankAccount.setTaxpayerIdentificationNumber(taxpayerIdentificationNumber);
bankAccount.setTaxRegistrationReasonCode(taxRegistrationReasonCode);
return bankAccount;
}
private BankAccountNewRequest getBankAccountNewRequest(BankAccount bankAccount) {
BankAccountNewRequest bankAccountNewRequest = new BankAccountNewRequest();
bankAccountNewRequest.setBankName(bankAccount.getBankName());
bankAccountNewRequest.setBankIdentificationCode(bankAccount.getBankIdentificationCode());
bankAccountNewRequest.setCorrespondentAccount(bankAccount.getCorrespondentAccount());
bankAccountNewRequest.setCorrespondentAccountName(bankAccount.getCorrespondentAccountName());
bankAccountNewRequest.setCurrency(bankAccount.getCurrency());
bankAccountNewRequest.setDestination(bankAccount.getDestination());
bankAccountNewRequest.setTaxpayerIdentificationNumber(bankAccount.getTaxpayerIdentificationNumber());
bankAccountNewRequest.setTaxRegistrationReasonCode(bankAccount.getTaxRegistrationReasonCode());
bankAccountNewRequest.setAccount(bankAccount.getAccount());
bankAccountNewRequest.setCompanyId(bankAccount.getCompanyId());
return bankAccountNewRequest;
}
}

View file

@ -0,0 +1,63 @@
package ru.spcex.clearing.account.utils;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
public class ImapEvent<T> {
private final IMap<Long, T> iMap;
private final String listenerAdding;
private final String listenerUpdating;
private final String listenerRemoving;
private final AtomicBoolean checkEventHappened = new AtomicBoolean(false);
public ImapEvent(IMap<Long, T> iMap) {
this.iMap = iMap;
listenerAdding = iMap.addEntryListener((EntryAddedListener<Long, T>) entryEvent -> {
synchronized (checkEventHappened) {
checkEventHappened.set(true);
checkEventHappened.notify();
}
}, false);
listenerUpdating = iMap.addEntryListener((EntryUpdatedListener<Long, T>) entryEvent -> {
synchronized (checkEventHappened) {
checkEventHappened.set(true);
checkEventHappened.notify();
}
}, false);
listenerRemoving = iMap.addEntryListener((EntryRemovedListener<Long, T>) entryEvent -> {
synchronized (checkEventHappened) {
checkEventHappened.set(true);
checkEventHappened.notify();
}
}, false);
}
public void waitWhenHappened() throws InterruptedException {
//running timer task as daemon thread
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
boolean secondRan;
@Override
public void run() {
checkEventHappened.set(secondRan);//если что-то пойдет не так не тормозить основной поток
secondRan = true;
}
}, 0, 30 * 1000);
synchronized (checkEventHappened) {
while (!checkEventHappened.get()) {
checkEventHappened.wait(100);
}
}
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerAdding);
iMap.removeEntryListener(listenerUpdating);
iMap.removeEntryListener(listenerRemoving);
}
}

View file

@ -0,0 +1,95 @@
package ru.spcex.clearing.account.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.TopicPartition;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class TestUtils {
private static final ObjectMapper objectMapper = new ObjectMapper();
public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) {
TopicPartition tp = new TopicPartition(topic, partition);
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
startOffsets.put(tp, 0L);
mockConsumer.updateBeginningOffsets(startOffsets);
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(tp));
mockConsumer.addRecord(new ConsumerRecord<>(topic, partition, offset, "key", jsonValue));
});
}
public static <T> String getJsonStringForNew(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.NEW);
}
public static <T> String getJsonStringForUPDATE(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.UPDATE);
}
public static <T> String getJsonStringForDELETE(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.DELETE);
}
private static <T> String getJsonBaseRequest(T accountRequest, long id, ActionType actionType) {
BaseRequest<T> baseRequest = new BaseRequest<>();
baseRequest.setRequestPayload(accountRequest);
baseRequest.setId(id);
baseRequest.setActionType(actionType);
String jsonBaseRequest;
try {
jsonBaseRequest = objectMapper.writeValueAsString(baseRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
return jsonBaseRequest;
}
public static <T extends SpcexObjectBase> void clearImdg(Imdg<T> imdg) {
Collection<T> values = imdg.getAllValues();
for (T val : values) {
imdg.delete(val);
}
}
public static class FutureRecordMetadata implements Future<RecordMetadata> {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
return false;
}
@Override
public RecordMetadata get() throws InterruptedException, ExecutionException {
return null;
}
@Override
public RecordMetadata get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return null;
}
}
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>backend-api</artifactId>
@ -8,12 +8,12 @@
<description>Clearing backend API module</description>
<packaging>jar</packaging>
<parent>
<artifactId>clearing-parent</artifactId>
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-1.0.0.0</version>
</parent>
<properties>
<keycloak-spring-boot-starter.version>17.0.1</keycloak-spring-boot-starter.version>
@ -25,9 +25,9 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
@ -87,17 +87,26 @@
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-autoconfigure</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>${keycloak-spring-boot-starter.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>${keycloak-spring-boot-starter.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.backendapi.controller.queue.config;
package ru.spcex.clearing.backendapi.controller.config;
import com.hazelcast.config.*;
import com.hazelcast.core.Hazelcast;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.backendapi.controller.queue.config;
package ru.spcex.clearing.backendapi.controller.config;
import org.apache.kafka.clients.producer.Producer;
import org.springframework.beans.factory.annotation.Autowired;
@ -10,14 +10,14 @@ import ru.spcex.clearing.backendapi.service.validation.ActionValidationProvider;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
public class IOperator {
public class IOperatorTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
@Autowired
@Bean
@Bean("iOperatorTest")
public OperatorImpl createIOperator(Producer<String, Object> kafka, ActionValidationProvider validationProvider) {
return new OperatorImpl(kafka, hazelcastServiceTest, validationProvider);
}

View file

@ -1,15 +1,17 @@
package ru.spcex.clearing.backendapi.controller.queue.config;
package ru.spcex.clearing.backendapi.controller.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
@Configuration
public class Jackson2HttpConverterConfig {
public class Jackson2HttpConverterTestConfig {
@Bean("customJsonHttpConverter")
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
return new MappingJackson2HttpMessageConverter(JacksonObjectMapper.getMapper());
@ -21,16 +23,13 @@ public class Jackson2HttpConverterConfig {
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 ActionType getActionType() у BankAccountNewAction
//модуль для корректной сериализации LocalDateTime в поля JSON - JavaTimeModule модуль библиотеки jackson-datatype-jsr310
registerModule(new JavaTimeModule());
configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//запрещаем доступ ко всем полям и методам класса и потом разрешаем доступ только к полям, нужны чтобы не было лишних полей из-за методов как: public ActionType getActionType() у BankAccountNewAction
setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
// не сериализуем null-поля
//не сериализуем null-поля
// setSerializationInclusion(JsonInclude.Include.NON_NULL);
}

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.backendapi.controller.queue.config;
package ru.spcex.clearing.backendapi.controller.config;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
@ -8,7 +8,7 @@ import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.platform.messaging.serialization.JsonSerializer;
@Configuration
public class KafkaConfig {
public class KafkaTestConfig {
@Bean
public Producer<String, Object> createProducer() {

View file

@ -0,0 +1,28 @@
package ru.spcex.clearing.backendapi.controller.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.enumeration.SpringPropertiesMessageResolver;
import java.util.Locale;
@Configuration
public class MessagesTestConfig {
@Bean("validation-error-messages-test")
public ResourceBundleMessageSource messages() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasenames("messages/error");
source.setUseCodeAsDefaultMessage(true);
source.setDefaultEncoding("utf8");
source.setDefaultLocale(Locale.ROOT);
return source;
}
@Bean("errorTestResolver")
public IMessageResolver errorResolver(@Qualifier("validation-error-messages-test") ResourceBundleMessageSource messageBundle) {
return new SpringPropertiesMessageResolver(messageBundle);
}
}

View file

@ -0,0 +1,32 @@
package ru.spcex.clearing.backendapi.controller.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import ru.spcex.clearing.backendapi.meta.GetResponseFactory;
import ru.spcex.clearing.backendapi.meta.GetResponseFactoryTestConfiguration;
import ru.spcex.clearing.backendapi.meta.MetaServer;
import ru.spcex.clearing.backendapi.service.impl.StateLoaderImpl;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
@Import({GetResponseFactoryTestConfiguration.class})
public class StateLoaderImplTestConfig {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
@Autowired
@Bean(name = "responseFactoryTest")
public GetResponseFactory getResponseFactory(@Qualifier("metaJsonTest") MetaServer meta) {
return new GetResponseFactory(meta);
}
@Bean(name = "stateLoaderImplTest")
public StateLoaderImpl createStateLoaderImpl(@Qualifier("responseFactoryTest") GetResponseFactory responseFactory) {
return new StateLoaderImpl(hazelcastServiceTest, responseFactory);
}
}

View file

@ -0,0 +1,41 @@
package ru.spcex.clearing.backendapi.controller.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class WebSecurityTestConfigurer {
@Bean
public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.withUsername("spring")
.password(passwordEncoder.encode("secret"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/task-runners/**")
.hasRole("USER")
.antMatchers("/**")
.permitAll()
.and()
.httpBasic();
return http.build();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

View file

@ -0,0 +1,34 @@
package ru.spcex.clearing.backendapi.controller.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import ru.spcex.clearing.backendapi.config.WebConfig;
import ru.spcex.clearing.backendapi.config.element.BackendApiSettings;
import ru.spcex.clearing.backendapi.security.element.SecuritySettings;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
@Configuration
@Import({BackendApiSettings.class})
public class WebTestConfig {
@Bean("webConfigTest")
public WebConfig createWebConfig(@Qualifier("customJsonHttpConverter") MappingJackson2HttpMessageConverter customJsonHttpConverter) throws IOException {
String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
String appConfigPath = rootPath + "application.properties";
Properties appProps = new Properties();
appProps.load(new FileInputStream(appConfigPath));
BackendApiSettings backendSettings = new BackendApiSettings();
backendSettings.setSecurity(new SecuritySettings());
backendSettings.getSecurity().setSameSite(appProps.getProperty("backend-api.security.same-site", "no"));
return new WebConfig(customJsonHttpConverter, backendSettings);
}
}

View file

@ -0,0 +1,119 @@
package ru.spcex.clearing.backendapi.controller.queue;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
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.config.*;
import ru.spcex.clearing.backendapi.controller.queue.account.AccountBalanceController;
import ru.spcex.clearing.backendapi.controller.queue.account.AccountController;
import ru.spcex.clearing.backendapi.controller.queue.account.BankAccountController;
import ru.spcex.clearing.backendapi.controller.queue.company.*;
import ru.spcex.clearing.backendapi.controller.queue.misc.NotificationController;
import ru.spcex.clearing.backendapi.controller.queue.misc.SessionController;
import ru.spcex.clearing.backendapi.controller.queue.payment.PaymentInstructionController;
import ru.spcex.clearing.backendapi.controller.queue.scheduler.ClearingCalendarController;
import ru.spcex.clearing.backendapi.controller.queue.scheduler.LauncherController;
import ru.spcex.clearing.backendapi.controller.queue.scheduler.PlannerAllTodayController;
import ru.spcex.clearing.backendapi.controller.utils.MatcherFactory;
import ru.spcex.clearing.backendapi.controller.utils.TestUtils;
import ru.spcex.clearing.backendapi.meta.GetResponseFactory;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import javax.annotation.PostConstruct;
import java.util.concurrent.atomic.AtomicLong;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.backendapi.controller.utils.MatcherFactory.usingIgnoringFieldsComparator;
@ContextConfiguration(classes = {
//account
AccountBalanceController.class,
AccountController.class,
BankAccountController.class,
//company
CompanyRoleSetController.class,
DeleteCompanyController.class,
EditClearingMemberCategoryController.class,
EditCompanyInfoController.class,
EditCompanySymbolController.class,
EditContactController.class,
ProfileDocumentController.class,
RelationController.class,
//misc
NotificationController.class,
SessionController.class,
//payment
PaymentInstructionController.class,
//scheduler
ClearingCalendarController.class,
PlannerAllTodayController.class,//PlanerAllTodayController
LauncherController.class,
//******* common configs *******
WebTestConfig.class,
IOperatorTest.class,
// KafkaTestConfig.class,
HazelcastServiceTestConfiguration.class,
StateLoaderImplTestConfig.class,
WebSecurityTestConfigurer.class,
MessagesTestConfig.class,
Jackson2HttpConverterTestConfig.class})
@ExtendWith(SpringExtension.class)
@WebMvcTest//(controllers = DeleteCompanyController.class)
@TestPropertySource(properties = "spring.config.location=D:/repo/mfd/clearing/clearing-parent/backend-api/src/main/resources/")
public abstract class AbstractControllerTest {
public static final MatcherFactory.Matcher<BaseRequest> BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator(BaseRequest.class);
protected static final AtomicLong currentId = new AtomicLong();
private static final CharacterEncodingFilter CHARACTER_ENCODING_FILTER = new CharacterEncodingFilter();
static {
CHARACTER_ENCODING_FILTER.setEncoding("UTF-8");
CHARACTER_ENCODING_FILTER.setForceEncoding(true);
}
@Autowired
@Qualifier("hazelcastServiceTest")
protected HazelcastService hazelcastServiceTest;
@Autowired
@Qualifier("responseFactoryTest")
protected GetResponseFactory responseFactory;
@Captor
protected ArgumentCaptor<ProducerRecord> producerRecord;
@MockBean
protected MockProducer<String, Object> producer;
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@PostConstruct
private void postConstruct() {
mockMvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.addFilter(CHARACTER_ENCODING_FILTER)
// .apply(springSecurity())
.build();
TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class);
doReturn(future).when(producer).send(producerRecord.capture());
}
protected ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception {
return mockMvc.perform(builder);
}
}

View file

@ -0,0 +1,53 @@
package ru.spcex.clearing.backendapi.controller.queue.account;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.imdg.api.Imdg;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class AccountBalanceControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/account-balances/";
/**
* {@link AccountBalanceController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_BankAccount.<br>
* Входной запрос /account-balances/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
AccountBalance existBankAccount = new AccountBalance();
existBankAccount.setAccountType("99");
existBankAccount.setAccount("123456789123");
existBankAccount.setId(currentId.get());
Imdg<AccountBalance> accountImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class);
accountImdg.insert(existBankAccount);
Collection<AccountBalance> values = accountImdg.getAllValues();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -0,0 +1,53 @@
package ru.spcex.clearing.backendapi.controller.queue.account;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.account.Account;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.imdg.api.Imdg;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class AccountControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/accounting/accounts/";
/**
* {@link AccountController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_BankAccount.<br>
* Входной запрос /securities/bank-accounts/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
Account existBankAccount = new Account();
existBankAccount.setAccountType("99");
existBankAccount.setAccount("123456789123");
existBankAccount.setId(currentId.get());
Imdg<Account> accountImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class);
accountImdg.insert(existBankAccount);
Collection<Account> values = accountImdg.getAllValues();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -1,68 +1,36 @@
package ru.spcex.clearing.backendapi.controller.queue.account;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.NestedExceptionUtils;
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.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.config.WebConfig;
import ru.spcex.clearing.backendapi.controller.queue.config.*;
import ru.spcex.clearing.backendapi.controller.queue.utils.MatcherFactory;
import ru.clearing.classes.statics.data.account.BankAccount;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountUpdateAction;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.account.BankAccountBackendGetById;
import ru.spcex.clearing.backendapi.controller.response.entity.account.BankAccountBackendGetFields;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest;
import javax.annotation.PostConstruct;
import java.util.concurrent.atomic.AtomicLong;
import java.util.Collection;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.queue.utils.JsonUtil.writeValue;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
@SpringJUnitWebConfig(classes = {
WebConfig.class,
IOperator.class,
BankAccountControllerConfig.class,
KafkaConfig.class,
HazelcastServiceTestConfiguration.class,
Jackson2HttpConverterConfig.class})
class BankAccountControllerTest {
public static final MatcherFactory.Matcher<CudResponse> CUD_RESPONSE_MATCHER = MatcherFactory.usingIgnoringFieldsComparator(CudResponse.class);
class BankAccountControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/securities/bank-accounts/";
private static final CharacterEncodingFilter CHARACTER_ENCODING_FILTER = new CharacterEncodingFilter();
private static final AtomicLong currentId = new AtomicLong();
static {
CHARACTER_ENCODING_FILTER.setEncoding("UTF-8");
CHARACTER_ENCODING_FILTER.setForceEncoding(true);
}
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@PostConstruct
private void postConstruct() {
mockMvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.addFilter(CHARACTER_ENCODING_FILTER)
// .apply(springSecurity())
.build();
}
/**
* {@link BankAccountController#add(BankAccountNewAction)}<br>
@ -92,19 +60,19 @@ class BankAccountControllerTest {
"01",
"11111222223333344444");
CudResponse extended = new CudResponse();
extended.setCode(0L);
extended.setMessage("success");
extended.setPayload(new QueueSuccessResponse(ActionType.NEW, currentId.getAndIncrement()));
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.NEW, currentId.getAndIncrement()));
//ACT
mockMvc.perform(MockMvcRequestBuilders.post(REST_URL)
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(bankAccountNewAction)))
perform(MockMvcRequestBuilders.post(REST_URL)
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(bankAccountNewAction)))
.andDo(print())//output to the log request and response
// ASSERT
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(extended)));
.andExpect(content().json(writeValue(expected)));
}
/**
@ -146,7 +114,6 @@ class BankAccountControllerTest {
* {@link BankAccountUpdateAction#destination} - destination<br>
* {@link BankAccountUpdateAction#taxpayerIdentificationNumber} - 3664011397<br>
* {@link BankAccountUpdateAction#taxRegistrationReasonCode} - 01<br>
* {@link BankAccountUpdateAction#account} - 11111222223333344444<br>
*/
@Test
void update() throws Exception {
@ -162,48 +129,129 @@ class BankAccountControllerTest {
"01",
"11111222223333344444");
CudResponse extended = new CudResponse();
extended.setCode(0L);
extended.setMessage("success");
extended.setPayload(new QueueSuccessResponse(ActionType.UPDATE, currentId.getAndIncrement()));
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.UPDATE, currentId.getAndIncrement()));
//ACT
mockMvc.perform(MockMvcRequestBuilders.put(REST_URL + "0")
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(bankAccountNewAction)))
perform(MockMvcRequestBuilders.put(REST_URL + "0")
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(bankAccountNewAction)))
.andDo(print())//output to the log request and response
// ASSERT
// ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(extended)));
.andExpect(content().json(writeValue(expected)));
}
/**
* {@link BankAccountController#delete(Long)} <br>
* Тест проверяет получение id сущности {@link Long} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link Long}: - 0L<br>
* Входной запрос /securities/bank-accounts/{@link Long}: - 0L<br>
*/
@Test
void delete() throws Exception {
//ARRANGE
CudResponse extended = new CudResponse();
extended.setCode(0L);
extended.setMessage("success");
extended.setPayload(new QueueSuccessResponse(ActionType.DELETE, currentId.getAndIncrement()));
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.DELETE, currentId.getAndIncrement()));
//ACT
mockMvc.perform(MockMvcRequestBuilders.delete(REST_URL + "0")
.contentType(MediaType.APPLICATION_JSON))
perform(MockMvcRequestBuilders.delete(REST_URL + "0")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
/**
* {@link BankAccountController#getById(Long)} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_BankAccount.<br>
* Входной запрос /securities/bank-accounts/{@link Long}: - 0L <br>
* Ответ BankAccountBackendGetById <br>
*/
@Test
void getById() throws Exception {
//ARRANGE
BankAccount existBankAccount = new BankAccount();
existBankAccount.setBankName("ooo tinkoff");
existBankAccount.setBankIdentificationCode("99999");
existBankAccount.setCorrespondentAccount("9294189285498598598");
existBankAccount.setCorrespondentAccountName("BIK OF TINKOFF");
existBankAccount.setCurrency("RUB");
existBankAccount.setDestination("OOO ROGA I KOPITA");
existBankAccount.setTaxpayerIdentificationNumber("848484848484");
existBankAccount.setTaxRegistrationReasonCode("886886");
existBankAccount.setId(currentId.get());
IMap<Long, BankAccount> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_BankAccount);
iMap.put(existBankAccount.getId(), existBankAccount);
BankAccountBackendGetById expected = new BankAccountBackendGetById();
BankAccountBackendGetFields payload = new BankAccountBackendGetFields();
payload.setBankName("ooo tinkoff");
payload.setBankIdentificationCode("99999");
payload.setCorrespondentAccount("9294189285498598598");
payload.setCorrespondentAccountName("BIK OF TINKOFF");
payload.setCurrency("RUB");
payload.setDestination("OOO ROGA I KOPITA");
payload.setTaxpayerIdentificationNumber("848484848484");
payload.setTaxRegistrationReasonCode("886886");
payload.setId(existBankAccount.getId());
expected.setPayload(payload);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL + existBankAccount.getId())
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
// ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(extended)));
.andExpect(content().json(writeValue(expected)));
}
/**
* {@link BankAccountController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_BankAccount.<br>
* Входной запрос /securities/bank-accounts/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
BankAccount existBankAccount = new BankAccount();
existBankAccount.setBankName("ooo tinkoff");
existBankAccount.setBankIdentificationCode("99999");
existBankAccount.setCorrespondentAccount("9294189285498598598");
existBankAccount.setCorrespondentAccountName("BIK OF TINKOFF");
existBankAccount.setCurrency("RUB");
existBankAccount.setDestination("OOO ROGA I KOPITA");
existBankAccount.setTaxpayerIdentificationNumber("848484848484");
existBankAccount.setTaxRegistrationReasonCode("886886");
existBankAccount.setId(currentId.get());
IMap<Long, BankAccount> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_BankAccount);
iMap.put(existBankAccount.getId(), existBankAccount);
Collection<BankAccount> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
private void assertThrowsFor(IAction<?> iAction) {
assertThrows(ActionValidationException.class, () -> {
try {
mockMvc.perform(MockMvcRequestBuilders.post(REST_URL).contentType(MediaType.APPLICATION_JSON).content(writeValue(iAction)));
perform(MockMvcRequestBuilders.post(REST_URL).contentType(MediaType.APPLICATION_JSON).content(writeValue(iAction)));
} catch (Exception e) {
Throwable rootCause = NestedExceptionUtils.getRootCause(e);
throw rootCause != null ? rootCause : e;
@ -239,7 +287,6 @@ class BankAccountControllerTest {
bankAccountUpdateAction.setDestination(Destination);
bankAccountUpdateAction.setTaxpayerIdentificationNumber(TaxpayerIdentificationNumber);
bankAccountUpdateAction.setTaxRegistrationReasonCode(TaxRegistrationReasonCode);
bankAccountUpdateAction.setAccount(Account);
return bankAccountUpdateAction;
}
}

View file

@ -0,0 +1,53 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.company.CompanyRoleSet;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.imdg.api.Imdg;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class CompanyRoleSetControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/company-role-sets/";
/**
* {@link CompanyRoleSetController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_BankAccount.<br>
* Входной запрос /company-role-sets/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
CompanyRoleSet existBankAccount = new CompanyRoleSet();
existBankAccount.setCompanyId(11L);
existBankAccount.setRoleId(12L);
existBankAccount.setId(currentId.get());
Imdg<CompanyRoleSet> accountImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class);
accountImdg.insert(existBankAccount);
Collection<CompanyRoleSet> values = accountImdg.getAllValues();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -0,0 +1,80 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.company.Company;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class DeleteCompanyControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/companies/";
/**
* {@link DeleteCompanyController#delete(Long)} <br>
* Тест проверяет получение id сущности {@link Long} по REST API и отправку в Apache Kafka.<br>
* Входной запрос /companies/{@link Long}: - 0L<br>
*/
@Test
void delete() throws Exception {
//ARRANGE
CudResponse extended = new CudResponse();
extended.setCode(0L);
extended.setMessage("success");
extended.setPayload(new QueueSuccessResponse(ActionType.DELETE, currentId.getAndIncrement()));
//ACT
perform(MockMvcRequestBuilders.delete(REST_URL + "0")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
// ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(extended)));
}
/**
* {@link DeleteCompanyController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_Company.<br>
* Входной запрос /companies <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
Company existCompany = new Company();
existCompany.setTradingCode("ooo tinkoff");
existCompany.setClearingCode("99999");
existCompany.setFullName("BIK OF TINKOFF");
existCompany.setShortName("OOO ROGA I KOPITA");
existCompany.setTradingCode("848484848484");
existCompany.setId(currentId.get());
IMap<Long, Company> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Company);
iMap.put(existCompany.getId(), existCompany);
Collection<Company> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -0,0 +1,173 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.request.cud.company.ClearingMemberCategoryNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.company.ClearingMemberCategoryUpdateAction;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import java.util.Collection;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class EditClearingMemberCategoryControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/clearing-member-categories/";
/**
* {@link EditClearingMemberCategoryController#add(ClearingMemberCategoryNewAction)}<br>
* Тест проверяет получение сущности {@link ClearingMemberCategoryNewAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link ClearingMemberCategoryNewAction}:<br>
* {@link ClearingMemberCategoryNewAction#clearingMemberCategory} - "Category"<br>
* {@link ClearingMemberCategoryNewAction#companyId} - currentId<br>
*/
@Test
void add() throws Exception {
//ARRANGE
ClearingMemberCategoryNewAction clearingMemberCategoryNewAction = new ClearingMemberCategoryNewAction();
clearingMemberCategoryNewAction.setClearingMemberCategory("Category");
clearingMemberCategoryNewAction.setCompanyId(0L);
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.NEW, currentId.getAndIncrement()));
//ACT
perform(MockMvcRequestBuilders.post(REST_URL)
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(clearingMemberCategoryNewAction)))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
/**
* {@link EditClearingMemberCategoryController#add(ClearingMemberCategoryNewAction)}<br>
* Тест проверяет получение сущности {@link ClearingMemberCategoryNewAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link ClearingMemberCategoryNewAction}:<br>
* {@link ClearingMemberCategoryNewAction#clearingMemberCategory} - "Category"<br>
* {@link ClearingMemberCategoryNewAction#companyId} - currentId<br>
*/
// @Test валидации пока нет
void addWithException() {
assertThrowsFor(getClearingMemberCategoryNewAction("Category", null));
assertThrowsFor(getClearingMemberCategoryNewAction("", 0L));
}
/**
* {@link EditClearingMemberCategoryController#update(Long, ClearingMemberCategoryUpdateAction)}<br>
* Тест проверяет получение сущности {@link ClearingMemberCategoryUpdateAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link ClearingMemberCategoryUpdateAction}:<br>
* {@link ClearingMemberCategoryUpdateAction#clearingMemberCategory} - Category<br>
* {@link ClearingMemberCategoryUpdateAction#id} - currentId<br>
*/
@Test
void update() throws Exception {
//ARRANGE
ClearingMemberCategoryUpdateAction clearingMemberCategoryUpdateAction = new ClearingMemberCategoryUpdateAction();
clearingMemberCategoryUpdateAction.setClearingMemberCategory("Category");
clearingMemberCategoryUpdateAction.setId(currentId.get());
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.UPDATE, currentId.getAndIncrement()));
//ACT
perform(MockMvcRequestBuilders.put(REST_URL + clearingMemberCategoryUpdateAction.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(clearingMemberCategoryUpdateAction)))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
/**
* {@link EditClearingMemberCategoryController#delete(Long)} <br>
* Тест проверяет получение id сущности {@link Long} по REST API и отправку в Apache Kafka.<br>
* Входной запрос /clearing-member-categories/{@link Long}: - currentId<br>
*/
@Test
void delete() throws Exception {
//ARRANGE
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.DELETE, currentId.getAndIncrement()));
//ACT
perform(MockMvcRequestBuilders.delete(REST_URL + expected.getPayload().getId())
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
/**
* {@link EditClearingMemberCategoryController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_ClearingMemberCategory.<br>
* Входной запрос /clearing-member-categories/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
ClearingMemberCategory clearingMemberCategory = new ClearingMemberCategory();
clearingMemberCategory.setClearingMemberCategory("Category");
clearingMemberCategory.setCompanyId(1000000L);
clearingMemberCategory.setId(currentId.get());
IMap<Long, ClearingMemberCategory> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_ClearingMemberCategory);
iMap.put(clearingMemberCategory.getId(), clearingMemberCategory);
Collection<ClearingMemberCategory> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
private void assertThrowsFor(IAction<?> iAction) {
assertThrows(ActionValidationException.class, () -> {
try {
perform(MockMvcRequestBuilders.post(REST_URL).contentType(MediaType.APPLICATION_JSON).content(writeValue(iAction)));
} catch (Exception e) {
Throwable rootCause = NestedExceptionUtils.getRootCause(e);
throw rootCause != null ? rootCause : e;
}
});
}
private ClearingMemberCategoryNewAction getClearingMemberCategoryNewAction(String category, Long companyId) {
ClearingMemberCategoryNewAction clearingMemberCategoryNewAction = new ClearingMemberCategoryNewAction();
clearingMemberCategoryNewAction.setClearingMemberCategory(category);
clearingMemberCategoryNewAction.setCompanyId(companyId);
return clearingMemberCategoryNewAction;
}
}

View file

@ -0,0 +1,126 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import org.junit.jupiter.api.Test;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.request.cud.company.ClearingMemberCategoryNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.company.CompanyInfoUpdateAction;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class EditCompanyInfoControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/company-infos/";
/**
* {@link EditCompanyInfoController#update(Long, CompanyInfoUpdateAction)}<br>
* Тест проверяет получение сущности {@link CompanyInfoUpdateAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link CompanyInfoUpdateAction}:<br>
* {@link CompanyInfoUpdateAction#clearingCode} - 11<br>
* {@link CompanyInfoUpdateAction#tradingCode} - 11<br>
* {@link CompanyInfoUpdateAction#corporationSoleType} - 0000<br>
* {@link CompanyInfoUpdateAction#countryCode} - 0000<br>
* {@link CompanyInfoUpdateAction#description} - exists description<br>
* {@link CompanyInfoUpdateAction#professionalSign} - 0000<br>
* {@link CompanyInfoUpdateAction#legalKind} - 0000<br>
* {@link CompanyInfoUpdateAction#organizationType} - 0000<br>
* {@link CompanyInfoUpdateAction#residence} - 0000<br>
* {@link CompanyInfoUpdateAction#shortNameEng} - exists shortNameEng<br>
* {@link CompanyInfoUpdateAction#fullNameEng} - exists fullNameEng<br>
* {@link CompanyInfoUpdateAction#shortName} - exists shortName<br>
* {@link CompanyInfoUpdateAction#fullName} - exists fullName<br>
* {@link CompanyInfoUpdateAction- Category<br>
* {@link CompanyInfoUpdateAction- Category<br>
* {@link CompanyInfoUpdateAction- Category<br>
* {@link CompanyInfoUpdateAction#id} - currentId<br>
*/
// @Test валидации пока нет
void addWithException() {
assertThrowsFor(getClearingMemberCategoryNewAction("Category", null));
assertThrowsFor(getClearingMemberCategoryNewAction("", 0L));
}
/**
* {@link EditCompanyInfoController#update(Long, CompanyInfoUpdateAction)}<br>
* Тест проверяет получение сущности {@link CompanyInfoUpdateAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link CompanyInfoUpdateAction}:<br>
* {@link CompanyInfoUpdateAction#clearingCode} - 11<br>
* {@link CompanyInfoUpdateAction#tradingCode} - 11<br>
* {@link CompanyInfoUpdateAction#corporationSoleType} - 0000<br>
* {@link CompanyInfoUpdateAction#countryCode} - 0000<br>
* {@link CompanyInfoUpdateAction#description} - exists description<br>
* {@link CompanyInfoUpdateAction#professionalSign} - 0000<br>
* {@link CompanyInfoUpdateAction#legalKind} - 0000<br>
* {@link CompanyInfoUpdateAction#organizationType} - 0000<br>
* {@link CompanyInfoUpdateAction#residence} - 0000<br>
* {@link CompanyInfoUpdateAction#shortNameEng} - exists shortNameEng<br>
* {@link CompanyInfoUpdateAction#fullNameEng} - exists fullNameEng<br>
* {@link CompanyInfoUpdateAction#shortName} - exists shortName<br>
* {@link CompanyInfoUpdateAction#fullName} - exists fullName<br>
* {@link CompanyInfoUpdateAction- Category<br>
* {@link CompanyInfoUpdateAction- Category<br>
* {@link CompanyInfoUpdateAction- Category<br>
* {@link CompanyInfoUpdateAction#id} - currentId<br>
*/
@Test
void update() throws Exception {
//ARRANGE
CompanyInfoUpdateAction companyInfoUpdateAction = new CompanyInfoUpdateAction();
companyInfoUpdateAction.setClearingCode("11");
companyInfoUpdateAction.setTradingCode("11");
companyInfoUpdateAction.setCorporationSoleType("0000");
companyInfoUpdateAction.setCountryCode("0000");
companyInfoUpdateAction.setDescription("exists description");
companyInfoUpdateAction.setProfessionalSign("0000");
companyInfoUpdateAction.setLegalKind("0000");
companyInfoUpdateAction.setOrganizationType("0000");
companyInfoUpdateAction.setResidence("0000");
companyInfoUpdateAction.setShortNameEng("exists shortNameEng");
companyInfoUpdateAction.setFullNameEng("exists fullNameEng");
companyInfoUpdateAction.setShortName("exists shortName");
companyInfoUpdateAction.setFullName("exists fullName");
companyInfoUpdateAction.setId(currentId.get());
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.UPDATE, currentId.getAndIncrement()));
//ACT
perform(MockMvcRequestBuilders.put(REST_URL + companyInfoUpdateAction.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(companyInfoUpdateAction)))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
private void assertThrowsFor(IAction<?> iAction) {
assertThrows(ActionValidationException.class, () -> {
try {
perform(MockMvcRequestBuilders.post(REST_URL).contentType(MediaType.APPLICATION_JSON).content(writeValue(iAction)));
} catch (Exception e) {
Throwable rootCause = NestedExceptionUtils.getRootCause(e);
throw rootCause != null ? rootCause : e;
}
});
}
private ClearingMemberCategoryNewAction getClearingMemberCategoryNewAction(String category, Long companyId) {
ClearingMemberCategoryNewAction clearingMemberCategoryNewAction = new ClearingMemberCategoryNewAction();
clearingMemberCategoryNewAction.setClearingMemberCategory(category);
clearingMemberCategoryNewAction.setCompanyId(companyId);
return clearingMemberCategoryNewAction;
}
}

View file

@ -0,0 +1,129 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.request.cud.company.ClearingMemberCategoryNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.company.CompanySymbolUpdateAction;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import java.util.Collection;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class EditCompanySymbolControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/company-symbols/";
/**
* {@link EditCompanySymbolController#update(Long, CompanySymbolUpdateAction)}<br>
* Тест проверяет получение сущности {@link CompanySymbolUpdateAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link CompanySymbolUpdateAction}:<br>
* {@link CompanySymbolUpdateAction#companyId} - 1000L<br>
* {@link CompanySymbolUpdateAction#companySymbol} - Symbol<br>
* {@link CompanySymbolUpdateAction#companySymbolValue} - SymbolValue<br>
* {@link CompanySymbolUpdateAction#id} - currentId<br>
*/
// @Test валидации пока нет
void addWithException() {
assertThrowsFor(getClearingMemberCategoryNewAction("Category", null));
assertThrowsFor(getClearingMemberCategoryNewAction("", 0L));
}
/**
* {@link EditCompanySymbolController#update(Long, CompanySymbolUpdateAction)}<br>
* Тест проверяет получение сущности {@link CompanySymbolUpdateAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link CompanySymbolUpdateAction}:<br>
* {@link CompanySymbolUpdateAction#companyId} - 1000L<br>
* {@link CompanySymbolUpdateAction#companySymbol} - Symbol<br>
* {@link CompanySymbolUpdateAction#companySymbolValue} - SymbolValue<br>
* {@link CompanySymbolUpdateAction#id} - currentId<br>
*/
@Test
void update() throws Exception {
//ARRANGE
CompanySymbolUpdateAction companySymbolUpdateAction = new CompanySymbolUpdateAction();
companySymbolUpdateAction.setCompanyId(1000L);
companySymbolUpdateAction.setCompanySymbol("Symbol");
companySymbolUpdateAction.setCompanySymbolValue("SymbolValue");
companySymbolUpdateAction.setId(currentId.get());
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.UPDATE, currentId.getAndIncrement()));
//ACT
perform(MockMvcRequestBuilders.put(REST_URL + companySymbolUpdateAction.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(companySymbolUpdateAction)))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
/**
* {@link EditCompanySymbolController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_CompanySymbols.<br>
* Входной запрос /clearing-member-categories/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
CompanySymbols companySymbols = new CompanySymbols();
companySymbols.setCompanyId(1000L);
companySymbols.setCompanySymbol("Symbol");
companySymbols.setCompanySymbolValue("SymbolValue");
companySymbols.setId(currentId.get());
IMap<Long, CompanySymbols> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_CompanySymbols);
iMap.put(companySymbols.getId(), companySymbols);
Collection<CompanySymbols> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
private void assertThrowsFor(IAction<?> iAction) {
assertThrows(ActionValidationException.class, () -> {
try {
perform(MockMvcRequestBuilders.post(REST_URL).contentType(MediaType.APPLICATION_JSON).content(writeValue(iAction)));
} catch (Exception e) {
Throwable rootCause = NestedExceptionUtils.getRootCause(e);
throw rootCause != null ? rootCause : e;
}
});
}
private ClearingMemberCategoryNewAction getClearingMemberCategoryNewAction(String category, Long companyId) {
ClearingMemberCategoryNewAction clearingMemberCategoryNewAction = new ClearingMemberCategoryNewAction();
clearingMemberCategoryNewAction.setClearingMemberCategory(category);
clearingMemberCategoryNewAction.setCompanyId(companyId);
return clearingMemberCategoryNewAction;
}
}

View file

@ -0,0 +1,130 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.profile.Contact;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.request.cud.company.ClearingMemberCategoryNewAction;
import ru.spcex.clearing.backendapi.controller.request.cud.company.CompanySymbolUpdateAction;
import ru.spcex.clearing.backendapi.controller.request.cud.company.ContactUpdateAction;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import java.util.Collection;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class EditContactControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/contacts/";
/**
* {@link EditCompanySymbolController#update(Long, CompanySymbolUpdateAction)}<br>
* Тест проверяет получение сущности {@link CompanySymbolUpdateAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link CompanySymbolUpdateAction}:<br>
* {@link CompanySymbolUpdateAction#companyId} - 1000L<br>
* {@link CompanySymbolUpdateAction#companySymbol} - Symbol<br>
* {@link CompanySymbolUpdateAction#companySymbolValue} - SymbolValue<br>
* {@link CompanySymbolUpdateAction#id} - currentId<br>
*/
// @Test валидации пока нет
void addWithException() {
assertThrowsFor(getClearingMemberCategoryNewAction("Category", null));
assertThrowsFor(getClearingMemberCategoryNewAction("", 0L));
}
/**
* {@link EditContactController#update(Long, ContactUpdateAction)}<br>
* Тест проверяет получение сущности {@link ContactUpdateAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link ContactUpdateAction}:<br>
* {@link ContactUpdateAction#companyId} - 1000L<br>
* {@link ContactUpdateAction#contactType} - ContactType<br>
* {@link ContactUpdateAction#contactValue} - ContactValue<br>
* {@link ContactUpdateAction#id} - currentId<br>
*/
@Test
void update() throws Exception {
//ARRANGE
ContactUpdateAction companySymbolUpdateAction = new ContactUpdateAction();
companySymbolUpdateAction.setCompanyId(1000L);
companySymbolUpdateAction.setContactType("ContactType");
companySymbolUpdateAction.setContactValue("ContactValue");
companySymbolUpdateAction.setId(currentId.get());
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.UPDATE, currentId.getAndIncrement()));
//ACT
perform(MockMvcRequestBuilders.put(REST_URL + companySymbolUpdateAction.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(companySymbolUpdateAction)))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
/**
* {@link EditContactController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_Contact.<br>
* Входной запрос /contacts/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
Contact companySymbolUpdateAction = new Contact();
companySymbolUpdateAction.setCompanyId(1000L);
companySymbolUpdateAction.setContactType("ContactType");
companySymbolUpdateAction.setContactValue("ContactValue");
companySymbolUpdateAction.setId(currentId.get());
IMap<Long, Contact> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Contact);
iMap.put(companySymbolUpdateAction.getId(), companySymbolUpdateAction);
Collection<Contact> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
private void assertThrowsFor(IAction<?> iAction) {
assertThrows(ActionValidationException.class, () -> {
try {
perform(MockMvcRequestBuilders.post(REST_URL).contentType(MediaType.APPLICATION_JSON).content(writeValue(iAction)));
} catch (Exception e) {
Throwable rootCause = NestedExceptionUtils.getRootCause(e);
throw rootCause != null ? rootCause : e;
}
});
}
private ClearingMemberCategoryNewAction getClearingMemberCategoryNewAction(String category, Long companyId) {
ClearingMemberCategoryNewAction clearingMemberCategoryNewAction = new ClearingMemberCategoryNewAction();
clearingMemberCategoryNewAction.setClearingMemberCategory(category);
clearingMemberCategoryNewAction.setCompanyId(companyId);
return clearingMemberCategoryNewAction;
}
}

View file

@ -0,0 +1,64 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.profile.ProfileDocument;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class ProfileDocumentControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/profile-documents/";
/**
* {@link ProfileDocumentController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_ProfileDocument.<br>
* Входной запрос /profile-documents/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
ProfileDocument profileDocument = new ProfileDocument();
profileDocument.setCompanyId(1000L);
profileDocument.setDocumentType("DocumentType");
profileDocument.setIssueDate(LocalDate.now());
profileDocument.setIssuePlace("IssuePlace");
profileDocument.setIssuer("Issuer");
profileDocument.setIssuerCode("IssuerCode");
profileDocument.setName("Name");
profileDocument.setNumber("Number");
profileDocument.setPlace("Place");
profileDocument.setValidFromDate(LocalDate.now());
profileDocument.setValidToDate(LocalDate.now());
profileDocument.setLink("Link");
profileDocument.setId(currentId.get());
IMap<Long, ProfileDocument> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_ProfileDocument);
iMap.put(profileDocument.getId(), profileDocument);
Collection<ProfileDocument> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -0,0 +1,138 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import org.junit.jupiter.api.Test;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.account.BankAccount;
import ru.clearing.classes.statics.data.company.relation.Relation;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.queue.account.BankAccountController;
import ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountUpdateAction;
import ru.spcex.clearing.backendapi.controller.request.cud.company.RelationUpdateAction;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.platform.imdg.api.Imdg;
import java.util.Collection;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class RelationControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/relations/";
/**
* {@link BankAccountController#update(Long, BankAccountUpdateAction)}<br>
* Тест проверяет получение сущности {@link BankAccountUpdateAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link BankAccountUpdateAction}:<br>
* {@link BankAccountUpdateAction#bankIdentificationCode} - 044525776<br>
* {@link BankAccountUpdateAction#bankName} - Beta Money Bank<br>
* {@link BankAccountUpdateAction#correspondentAccount} - 30101111111111111776<br>
* {@link BankAccountUpdateAction#correspondentAccountName} - correspondent<br>
* {@link BankAccountUpdateAction#currency} - RUB<br>
* {@link BankAccountUpdateAction#destination} - destination<br>
* {@link BankAccountUpdateAction#taxpayerIdentificationNumber} - 3664011397<br>
* {@link BankAccountUpdateAction#taxRegistrationReasonCode} - 01<br>
*/
@Test
void update() throws Exception {
//ARRANGE
Long existsId = 123L;
RelationUpdateAction relationUpdateAction = new RelationUpdateAction();
relationUpdateAction.setId(existsId);
relationUpdateAction.setServiceStatus("Ok");
relationUpdateAction.setComment("It`s good");
BaseRequest<Object> predictableBaseRequest = new BaseRequest<>();
predictableBaseRequest.setActionType(relationUpdateAction.getActionType());
predictableBaseRequest.setRequestPayload(relationUpdateAction.toRequest());
Relation relation = new Relation();
relation.setId(existsId);
Imdg<Relation> relationImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
relationImdg.insert(relation);
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.UPDATE, currentId.getAndIncrement()));
//ACT
perform(MockMvcRequestBuilders.put(REST_URL + existsId)
.contentType(MediaType.APPLICATION_JSON)
.content(writeValue(relationUpdateAction)))
.andDo(print())//output to the log request and response
// ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
assertEquals(Consts.DESTINATION_RELATION_UPDATE, producerRecord.getValue().topic());
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
predictableBaseRequest.setId(baseRequestResult.getId());
BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest);
}
/**
* {@link RelationController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_BankAccount.<br>
* Входной запрос /relations/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
Long existsId = 123L;
BankAccount existBankAccount = new BankAccount();
existBankAccount.setBankName("ooo tinkoff");
existBankAccount.setBankIdentificationCode("99999");
existBankAccount.setCorrespondentAccount("9294189285498598598");
existBankAccount.setCorrespondentAccountName("BIK OF TINKOFF");
existBankAccount.setCurrency("RUB");
existBankAccount.setDestination("OOO ROGA I KOPITA");
existBankAccount.setTaxpayerIdentificationNumber("848484848484");
existBankAccount.setTaxRegistrationReasonCode("886886");
existBankAccount.setId(currentId.get());
Relation relation = new Relation();
relation.setId(existsId);
Imdg<Relation> relationImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
relationImdg.insert(relation);
Collection<Relation> values = relationImdg.getAllValues();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
private void assertThrowsFor(IAction<?> iAction) {
assertThrows(ActionValidationException.class, () -> {
try {
perform(MockMvcRequestBuilders.post(REST_URL).contentType(MediaType.APPLICATION_JSON).content(writeValue(iAction)));
} catch (Exception e) {
Throwable rootCause = NestedExceptionUtils.getRootCause(e);
throw rootCause != null ? rootCause : e;
}
});
}
}

View file

@ -0,0 +1,59 @@
package ru.spcex.clearing.backendapi.controller.queue.misc;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.misc.Notification;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class NotificationControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/notifications/";
/**
* {@link NotificationController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_Notification.<br>
* Входной запрос /notifications/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
Notification profileDocument = new Notification();
profileDocument.setClearingDate(LocalDate.now());
profileDocument.setSenderId(1000L);
profileDocument.setAddresseeId(1000L);
profileDocument.setObjectType("ObjectType");
profileDocument.setObjectId(Instant.now());
profileDocument.setNotificationStatus("Status");
profileDocument.setId(currentId.get());
IMap<Long, Notification> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Notification);
iMap.put(profileDocument.getId(), profileDocument);
Collection<Notification> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -0,0 +1,54 @@
package ru.spcex.clearing.backendapi.controller.queue.misc;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.misc.Session;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class SessionControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/sessions/";
/**
* {@link SessionController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_Session.<br>
* Входной запрос /sessions/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
Session session = new Session();
session.setClearingDate(LocalDate.now());
session.setSessionStatus("Ok");
session.setId(currentId.get());
IMap<Long, Session> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Session);
iMap.put(session.getId(), session);
Collection<Session> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -0,0 +1,77 @@
package ru.spcex.clearing.backendapi.controller.queue.payment;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class PaymentInstructionControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/paymentInstructions/";
/**
* {@link PaymentInstructionController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_PaymentInstruction.<br>
* Входной запрос /paymentInstructions/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
PaymentInstruction paymentInstruction = new PaymentInstruction();
paymentInstruction.setSenderId(1010L);
paymentInstruction.setAddresseeId(1010L);
paymentInstruction.setAdresseeBic("123456789");
paymentInstruction.setPayeeBankName("BankName");
paymentInstruction.setPayeeBic("123456789");
paymentInstruction.setAddresseeBankName("BankName");
paymentInstruction.setPaymentDate(Instant.now());
paymentInstruction.setPaymentPurpose("Purpose");
paymentInstruction.setSettlementDate(LocalDate.now());
paymentInstruction.setCreditLegAmount(2020L);
paymentInstruction.setDebitLegAmount(2020L);
paymentInstruction.setCreditLegAccountId(2020L);
paymentInstruction.setCreditCsAccount("Ok");
paymentInstruction.setCreditLegAccount("123456789");
paymentInstruction.setDebitLegAccountId(3030L);
paymentInstruction.setDebitCsAccount("123456789");
paymentInstruction.setDebitLegAccount("123456789");
paymentInstruction.setCreditLegDirection(3030L);
paymentInstruction.setDebitLegDirection(3030L);
paymentInstruction.setCreditLegCurrencyCode("123456789");
paymentInstruction.setDebitLegCurrencyCode("123456789");
paymentInstruction.setClearingDate(LocalDate.now());
paymentInstruction.setTransactionStatus("Status");
paymentInstruction.setDocumentNumber("123456789");
paymentInstruction.setId(currentId.get());
IMap<Long, PaymentInstruction> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_PaymentInstruction);
iMap.put(paymentInstruction.getId(), paymentInstruction);
Collection<PaymentInstruction> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -0,0 +1,169 @@
package ru.spcex.clearing.backendapi.controller.queue.scheduler;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.spi.KeycloakAccount;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.keycloak.representations.AccessToken;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.MediaType;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.scheduler.Launcher;
import ru.clearing.classes.statics.data.user.User;
import ru.clearing.platform.dictionary.TaskDictionary;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.queue.account.BankAccountController;
import ru.spcex.clearing.backendapi.controller.request.cud.account.BankAccountNewAction;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.backendapi.domain.actions.IAction;
import ru.spcex.clearing.backendapi.errors.ActionValidationException;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest;
import java.util.Collection;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class LauncherControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/task-runners/";
/**
* {@link LauncherController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_TaskRunner.<br>
* Входной запрос /task-runners/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
Launcher taskRunner = new Launcher();
taskRunner.setTask("Task");
taskRunner.setSenderId(10210L);
taskRunner.setId(currentId.get());
IMap<Long, Launcher> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Launcher);
iMap.put(taskRunner.getId(), taskRunner);
Collection<Launcher> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
// @Test todo пока не работает (
void add() throws Exception {
//ARRANGE
TaskDictionary taskDictionary = new TaskDictionary();
IMap<Long, TaskDictionary> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_TaskDictionary);
iMap.put(taskDictionary.getId(), taskDictionary);
CudResponse expected = new CudResponse();
expected.setCode(0L);
expected.setMessage("success");
expected.setPayload(new QueueSuccessResponse(ActionType.NEW, currentId.getAndIncrement()));
setUserNameInMockSecurityContextAndMapUser("existUser");
//ACT
perform(MockMvcRequestBuilders.post(REST_URL + "ABLK")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
private void setUserNameInMockSecurityContextAndMapUser(String username) {
User user = new User();
user.setIdentifier(username);
user.setId(currentId.get());
IMap<Long, User> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_User);
iMap.put(user.getId(), user);
AccessToken accessToken = mock(AccessToken.class);
when(accessToken.getPreferredUsername()).thenReturn(username);
KeycloakSecurityContext keycloakSecurityContext = mock(KeycloakSecurityContext.class);
when(keycloakSecurityContext.getToken()).thenReturn(accessToken);
KeycloakPrincipal keycloakPrincipal = mock(KeycloakPrincipal.class);
when(keycloakPrincipal.getKeycloakSecurityContext()).thenReturn(keycloakSecurityContext);
KeycloakAccount details = mock(KeycloakAccount.class);
when(details.getPrincipal()).thenReturn(keycloakPrincipal);
KeycloakAuthenticationToken authentication = mock(KeycloakAuthenticationToken.class);
when(authentication.getDetails()).thenReturn(details);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
// @Test
// void testWithPostProcessor() выдает Exception {
// perform(MockMvcRequestBuilders.get("/greet").with(jwt().jwt(jwt -> {
// jwt.claim("preferred_username", "Tonton Pirate");
// }).authorities(List.of(new SimpleGrantedAuthority("NICE_GUY"), new SimpleGrantedAuthority("AUTHOR")))))
// .andExpect(status().isOk())
// .andExpect(content().string("Hi Tonton Pirate! You are granted with: [NICE_GUY, AUTHOR]."));
// }
/**
* {@link BankAccountController#add(BankAccountNewAction)}<br>
* Тест проверяет работу валидации сущности {@link BankAccountNewAction} принятой по REST API для отправку в Apache Kafka.<br>
* Входной запрос {@link BankAccountNewRequest}:<br>
* {@link BankAccountNewRequest#bankIdentificationCode} - 044525776 или ""<br>
* {@link BankAccountNewRequest#bankName} - Beta Money Bank или ""<br>
* {@link BankAccountNewRequest#correspondentAccount} - 30101111111111111776 или ""<br>
* {@link BankAccountNewRequest#correspondentAccountName} - correspondent или ""<br>
* {@link BankAccountNewRequest#currency} - RUB или ""<br>
* {@link BankAccountNewRequest#destination} - destinatio или ""n<br>
* {@link BankAccountNewRequest#taxpayerIdentificationNumber} - 3664011397 или ""<br>
* {@link BankAccountNewRequest#taxRegistrationReasonCode} - 01 или ""<br>
* {@link BankAccountNewRequest#account} - 11111222223333344444 или ""<br>
*/
@Test
void addWithException() {
// assertThrowsFor(getBankAccountNewAction("", "Beta Money Bank", "30101111111111111776", "correspondent", "RUB", "destination", "3664011397", "01", "11111222223333344444"));
// assertThrowsFor(getBankAccountNewAction("044525776", "", "30101111111111111776", "correspondent", "RUB", "destination", "3664011397", "01", "11111222223333344444"));
// assertThrowsFor(getBankAccountNewAction("044525776", "Beta Money Bank", "", "correspondent", "RUB", "destination", "3664011397", "01", "11111222223333344444"));
// assertThrowsFor(getBankAccountNewAction("044525776", "Beta Money Bank", "30101111111111111776", "", "RUB", "destination", "3664011397", "01", "11111222223333344444"));
// assertThrowsFor(getBankAccountNewAction("044525776", "Beta Money Bank", "30101111111111111776", "correspondent", "", "destination", "3664011397", "01", "11111222223333344444"));
// assertThrowsFor(getBankAccountNewAction("044525776", "Beta Money Bank", "30101111111111111776", "correspondent", "RUB", "", "3664011397", "01", "11111222223333344444"));
// assertThrowsFor(getBankAccountNewAction("044525776", "Beta Money Bank", "30101111111111111776", "correspondent", "RUB", "destination", "", "01", "11111222223333344444"));
// assertThrowsFor(getBankAccountNewAction("044525776", "Beta Money Bank", "30101111111111111776", "correspondent", "RUB", "destination", "3664011397", "", "11111222223333344444"));
// assertThrowsFor(getBankAccountNewAction("044525776", "Beta Money Bank", "30101111111111111776", "correspondent", "RUB", "destination", "3664011397", "01", ""));
}
private void assertThrowsFor(IAction<?> iAction) {
assertThrows(ActionValidationException.class, () -> {
try {
perform(MockMvcRequestBuilders.post(REST_URL).contentType(MediaType.APPLICATION_JSON).content(writeValue(iAction)));
} catch (Exception e) {
Throwable rootCause = NestedExceptionUtils.getRootCause(e);
throw rootCause != null ? rootCause : e;
}
});
}
}

View file

@ -0,0 +1,61 @@
package ru.spcex.clearing.backendapi.controller.queue.scheduler;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.scheduler.PlannerAllToday;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class PlannerAllTodayControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/schedule/schedulers-all-today/";
/**
* {@link PlannerAllTodayController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_SchedulerAllToday.<br>
* Входной запрос /schedule/schedulers-all-today/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
PlannerAllToday schedulerAllToday = new PlannerAllToday();
schedulerAllToday.setTask("Task");
schedulerAllToday.setTaskTime(LocalTime.now());
schedulerAllToday.setClearingDate(LocalDate.now());
schedulerAllToday.setMarket("Market");
schedulerAllToday.setTaskStatus("Ok");
schedulerAllToday.setSecurityId(10210L);
schedulerAllToday.setParent("Source");
schedulerAllToday.setParentId(1010L);
schedulerAllToday.setId(currentId.get());
IMap<Long, PlannerAllToday> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_PlannerAllToday);
iMap.put(schedulerAllToday.getId(), schedulerAllToday);
Collection<PlannerAllToday> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -0,0 +1,59 @@
package ru.spcex.clearing.backendapi.controller.queue.scheduler;
import com.hazelcast.core.IMap;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.clearing.classes.statics.data.scheduler.Planner;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Collection;
import java.util.Map;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue;
class PlannerControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/schedule/schedulers/";
/**
* {@link PlannerController#getAll()} <br>
* Тест проверяет получение запроса по REST API и отправку всех записей из таблицы hazelcast Map_Scheduler.<br>
* Входной запрос /schedule/schedulers/ <br>
* Ответ CommonGetAllResponse <br>
*/
@Test
void getAll() throws Exception {
//ARRANGE
Planner scheduler = new Planner();
scheduler.setTask("Task");
scheduler.setTaskTime(LocalTime.now());
scheduler.setClearingDate(LocalDate.now());
scheduler.setMarket("Market");
scheduler.setTaskStatus("Ok");
scheduler.setSecurityId(10210L);
scheduler.setId(currentId.get());
IMap<Long, Planner> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Planner);
iMap.put(scheduler.getId(), scheduler);
Collection<Planner> values = iMap.values();
Collection<Map<String, Object>> all = responseFactory.responseFromObjectCollection(values);
CommonGetAllResponse expected = new CommonGetAllResponse();
expected.fromEntity(all);
//ACT
perform(MockMvcRequestBuilders.get(REST_URL)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
//ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(expected)));
}
}

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.backendapi.controller.queue.utils;
package ru.spcex.clearing.backendapi.controller.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
@ -9,7 +9,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static ru.spcex.clearing.backendapi.controller.queue.config.Jackson2HttpConverterConfig.JacksonObjectMapper.getMapper;
import static ru.spcex.clearing.backendapi.controller.config.Jackson2HttpConverterTestConfig.JacksonObjectMapper.getMapper;
public class JsonUtil {

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.backendapi.controller.queue.utils;
package ru.spcex.clearing.backendapi.controller.utils;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;

View file

@ -0,0 +1,95 @@
package ru.spcex.clearing.backendapi.controller.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.TopicPartition;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class TestUtils {
private static final ObjectMapper objectMapper = new ObjectMapper();
public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) {
TopicPartition tp = new TopicPartition(topic, partition);
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
startOffsets.put(tp, 0L);
mockConsumer.updateBeginningOffsets(startOffsets);
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(tp));
mockConsumer.addRecord(new ConsumerRecord<>(topic, partition, offset, "key", jsonValue));
});
}
public static <T> String getJsonStringForNew(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.NEW);
}
public static <T> String getJsonStringForUPDATE(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.UPDATE);
}
public static <T> String getJsonStringForDELETE(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.DELETE);
}
private static <T> String getJsonBaseRequest(T accountRequest, long id, ActionType actionType) {
BaseRequest<T> baseRequest = new BaseRequest<>();
baseRequest.setRequestPayload(accountRequest);
baseRequest.setId(id);
baseRequest.setActionType(actionType);
String jsonBaseRequest;
try {
jsonBaseRequest = objectMapper.writeValueAsString(baseRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
return jsonBaseRequest;
}
public static <T extends SpcexObjectBase> void clearImdg(Imdg<T> imdg) {
Collection<T> values = imdg.getAllValues();
for (T val : values) {
imdg.delete(val);
}
}
public static class FutureRecordMetadata implements Future<RecordMetadata> {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
return false;
}
@Override
public RecordMetadata get() throws InterruptedException, ExecutionException {
return null;
}
@Override
public RecordMetadata get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return null;
}
}
}

View file

@ -24,7 +24,7 @@ public class GetResponseFactoryTestConfiguration {
return new PathResource(path);
}
// @Value("file:${spring.config.location}/meta.json")
// @Value("file:${spring.config.location}/meta.json")
// private Resource meta;
//
@Bean("metaJsonTestRaw")
@ -32,7 +32,8 @@ public class GetResponseFactoryTestConfiguration {
if (!meta.isReadable()) throw new IllegalStateException("cannot read meta.json from meta " + meta.getFile());
return Files.readString(meta.getFile().toPath());
}
//
//
@Autowired
@Bean("metaJsonTest")
public MetaServer metaServer(@Qualifier("metaJsonTestRaw") String metaJson) throws JsonProcessingException {

View file

@ -0,0 +1,51 @@
server.port=8080
server.servlet.context-path=/backend-api
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:keystore/client.p12
server.ssl.key-store-password=Aa123456
server.ssl.enabled=true
spring.main.web-application-type=servlet
backend-api.example-setting=test
backend-api.hazelcast.cluster-members=127.0.0.1:5701
backend-api.hazelcast.login=dev
backend-api.hazelcast.password=dev-pass
backend-api.kafka-producer.bootstrap-servers=localhost:9092
backend-api.kafka-producer.acks=all
backend-api.kafka-producer.retries=0
backend-api.kafka-producer.batch-size=16384
backend-api.kafka-producer.linger-ms=1
backend-api.kafka-producer.buffer-memory=33554432
backend-api.kafka-consumer.bootstrap-servers=localhost:9092
backend-api.kafka-consumer.group-id=dev-group-backend-api
backend-api.kafka-consumer.enable-auto-commit=true
backend-api.kafka-consumer.session-timeout-ms=30000
backend-api.kafka-consumer.auto-offset-reset=latest
backend-api.kafka-consumer.linger-ms=1
backend-api.kafka-consumer.buffer-memory=33554432
backend-api.security.authorization-disabled=false
##keycloak
##keycloak.auth-server-url=http://10.200.200.147:8080/
##keycloak.realm=master
##keycloak.resource=clearing
##keycloak.public-client=true
##keycloak.credentials.secret=WnOVCxcAmrUYc8IjiFHOuRif5Oesoyfr
##keycloak.security-constraints[0].authRoles[0]=admin
##keycloak.security-constraints[0].securityCollections[0].patterns[0]=/backend-api/users/*
#
#
##keycloak.policy-enforcer-config.paths[0].path=/*
##keycloak.policy-enforcer-config.paths[0].enforcementMode=ENFORCING
##keycloak.policy-enforcer-config.paths[1].path=/backend-api/anonymous/method1
##keycloak.policy-enforcer-config.paths[1].enforcementMode=DISABLED
##keycloak.security-constraints[1].auth-roles[0]=*
##keycloak.security-constraints[1].security-collections[0].patterns[0]=/backend-api/anonymous/method1
#
##keycloak.security-constraints[1].securityCollections[0].name=anonymous-methods
##keycloak.security-constraints[1].securityCollections[0].patterns[0]=/backend-api/anonymous/method1

File diff suppressed because it is too large Load diff

View file

@ -1,54 +0,0 @@
package ru.spcex.clearing.backendapi.controller.queue;
import org.springframework.beans.factory.annotation.Autowired;
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.MockHttpServletRequestBuilder;
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.config.WebConfig;
import ru.spcex.clearing.backendapi.controller.queue.company.DeleteCompanyController;
import ru.spcex.clearing.backendapi.controller.queue.config.*;
import javax.annotation.PostConstruct;
import java.util.concurrent.atomic.AtomicLong;
@SpringJUnitWebConfig(classes = {
WebConfig.class,
IOperator.class,
StateLoaderImplConfig.class,
DeleteCompanyController.class,
BankAccountControllerConfig.class,
KafkaConfig.class,
HazelcastServiceTestConfiguration.class,
Jackson2HttpConverterConfig.class})
public abstract class AbstractControllerTest {
protected static final AtomicLong currentId = new AtomicLong();
private static final CharacterEncodingFilter CHARACTER_ENCODING_FILTER = new CharacterEncodingFilter();
static {
CHARACTER_ENCODING_FILTER.setEncoding("UTF-8");
CHARACTER_ENCODING_FILTER.setForceEncoding(true);
}
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@PostConstruct
private void postConstruct() {
mockMvc = MockMvcBuilders
.webAppContextSetup(webApplicationContext)
.addFilter(CHARACTER_ENCODING_FILTER)
// .apply(springSecurity())
.build();
}
protected ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception {
return mockMvc.perform(builder);
}
}

View file

@ -1,40 +0,0 @@
package ru.spcex.clearing.backendapi.controller.queue.company;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest;
import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse;
import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static ru.spcex.clearing.backendapi.controller.queue.utils.JsonUtil.writeValue;
class DeleteCompanyControllerTest extends AbstractControllerTest {
private static final String REST_URL = "/companies/";
/**
* {@link DeleteCompanyController#delete(Long)} <br>
* Тест проверяет получение id сущности {@link Long} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link Long}: - 0L<br>
*/
@Test
void delete() throws Exception {
//ARRANGE
CudResponse extended = new CudResponse();
extended.setCode(0L);
extended.setMessage("success");
extended.setPayload(new QueueSuccessResponse(ActionType.DELETE, currentId.getAndIncrement()));
//ACT
perform(MockMvcRequestBuilders.delete(REST_URL + "0")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())//output to the log request and response
// ASSERT
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(content().json(writeValue(extended)));
}
}

View file

@ -1,28 +0,0 @@
package ru.spcex.clearing.backendapi.controller.queue.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.backendapi.controller.queue.account.BankAccountController;
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.impl.StateLoaderImpl;
@Configuration
public class BankAccountControllerConfig {
@Autowired
@Qualifier("iOperator")
private IOperator operator;
@Autowired
@Qualifier("stateLoaderImpl")
private StateLoaderImpl stateLoader;
@Bean
public BankAccountController createBankAccountController() {
return new BankAccountController(operator, stateLoader);
}
}

View file

@ -1,25 +0,0 @@
package ru.spcex.clearing.backendapi.controller.queue.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.backendapi.controller.queue.company.DeleteCompanyController;
import ru.spcex.clearing.backendapi.service.IOperator;
import ru.spcex.clearing.backendapi.service.impl.StateLoaderImpl;
@Configuration
public class DeleteCompanyControllerConfig {
@Autowired
@Qualifier("iOperator")
private IOperator operator;
@Autowired
@Qualifier("stateLoaderImpl")
private StateLoaderImpl stateLoader;
@Bean
public DeleteCompanyController createDeleteCompanyController() {
return new DeleteCompanyController(operator, stateLoader);
}
}

View file

@ -1,22 +0,0 @@
package ru.spcex.clearing.backendapi.controller.queue.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.backendapi.service.impl.StateLoaderImpl;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
public class StateLoaderImplConfig {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
@Bean(name = "stateLoaderImpl")
public StateLoaderImpl createIOperator() {
return new StateLoaderImpl(hazelcastServiceTest);
}
}

View file

@ -56,6 +56,16 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>

View file

@ -17,7 +17,7 @@ import java.util.List;
import java.util.Random;
@Configuration
public class BalanceImdgTestConfig {
public class ImdgTestConfig {
private HazelcastInstance hazelcastInstance;
@ -57,7 +57,7 @@ public class BalanceImdgTestConfig {
joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(true).setMembers(List.of("127.0.0.1")));
networkConfig.setJoin(joinConfig);
cfg.setNetworkConfig(networkConfig);
hazelcastInstance = Hazelcast.newHazelcastInstance(cfg);
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg);
HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance);
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
}

View file

@ -2,14 +2,13 @@ package ru.spcex.clearing.balance.config;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.serialization.JsonSerializer;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.platform.imdg.api.Imdg;
@ -19,20 +18,10 @@ import ru.spcex.platform.imdg.api.ImdgProvider;
@Configuration
public class KafkaTestConfig {
@Bean
public MockConsumer<String, Object> createTestConsumer() {
return new MockConsumer<>(OffsetResetStrategy.EARLIEST);
}
@Bean
public Producer<String, Object> createTestProducer() {
return new MockProducer<>(true, new StringSerializer(), new JsonSerializer());
}
@Autowired
@Bean
public KafkaSender kafkaSender(Producer<String, Object> kafkaProducer, ImdgProvider imdgProvider) {
public KafkaSender kafkaSender(Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider) {
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
return KafkaSender
.setup()
@ -44,4 +33,10 @@ public class KafkaTestConfig {
})
.build();
}
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public MockConsumer<String, Object> createTestConsumer() {
return new MockConsumer<>(OffsetResetStrategy.EARLIEST);
}
}

View file

@ -10,10 +10,7 @@ import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.sdf.SDf02;
import ru.clearing.classes.statics.data.sdf.SDf08;
import ru.clearing.classes.statics.data.sdf.SDf10;
import ru.clearing.classes.statics.data.sdf.SDf17;
import ru.clearing.classes.statics.data.sdf.*;
import ru.clearing.classes.statics.data.statement.Statement;
import ru.spcex.clearing.balance.config.*;
import ru.spcex.clearing.balance.utils.MatcherFactory;
@ -25,8 +22,11 @@ import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.concurrent.atomic.AtomicLong;
import static ru.spcex.clearing.balance.service.Sdf01ExecutorTest.acc;
import static ru.spcex.clearing.balance.service.Sdf01ExecutorTest.datFormatter;
import static ru.spcex.clearing.balance.utils.MatcherFactory.usingIgnoringFieldsComparator;
@ExtendWith(SpringExtension.class)
@ -41,12 +41,27 @@ import static ru.spcex.clearing.balance.utils.MatcherFactory.usingIgnoringFields
MessagesConfig.class,
ValidationConfig.class,
SdfExecutorsConfig.class,
BalanceImdgTestConfig.class,
ImdgTestConfig.class,
ImdgTestConfig.class,
KafkaTestConfig.class})
public abstract class AbstractServiceTest {
protected static final MatcherFactory.Matcher<AccountBalance> ACCOUNT_BALANCE_MATCHER = usingIgnoringFieldsComparator("created", "updated", "clearingDate", "id");
protected static final MatcherFactory.Matcher<Result> RESULT_MATCHER = usingIgnoringFieldsComparator("account.created", "account.updated", "account.clearingDate", "generationId");
protected static final MatcherFactory.Matcher<Statement> STATEMENT_MATCHER = usingIgnoringFieldsComparator("created", "comment", "outSDfId", "updated", "id");
protected static AtomicLong currentId = new AtomicLong(0L);
protected static IMap<Long, Company> companyMap;
protected static IMap<Long, CompanySymbols> companySymbolsMap;
protected static IMap<Long, Account> accountMap;
protected static ImdgHazelcast<Statement> statementImdg;
protected static ImdgHazelcast<RequestInfo> requestInfoImdg;
protected static ImdgHazelcast<SDf02> sdf02Imdg;
protected static ImdgHazelcast<SDf01> sdf01Imdg;
protected static ImdgHazelcast<SDf08> sdf08Imdg;
protected static ImdgHazelcast<SDf10> sdf10Imdg;
protected static ImdgHazelcast<SDf17> sdf17Imdg;
protected static ImdgHazelcast<AccountBalance> accountBalanceImdg;
protected static ImdgHazelcast<Company> companyImdg;
protected static ImdgHazelcast<Account> accountImdg;
protected final Long accountIdNew = 10L;
protected final Long addresseeIdNew = 2L;
protected final String deal = "111111111";
@ -54,28 +69,18 @@ public abstract class AbstractServiceTest {
protected final BigDecimal amountNew = new BigDecimal(1000);
protected final String cashMovementCurrencyCode = CurrencyCode.RUB.getKey();
protected AtomicLong currentId = new AtomicLong(0L);
protected IMap<Long, Company> companyMap;
protected IMap<Long, CompanySymbols> companySymbolsMap;
protected IMap<Long, Account> accountMap;
protected ImdgHazelcast<Statement> statementImdg;
protected ImdgHazelcast<RequestInfo> requestInfoImdg;
protected ImdgHazelcast<SDf02> sdf02Imdg;
protected ImdgHazelcast<SDf08> sdf08Imdg;
protected ImdgHazelcast<SDf10> sdf10Imdg;
protected ImdgHazelcast<SDf17> sdf17Imdg;
protected ImdgHazelcast<AccountBalance> accountBalanceImdg;
@Autowired
@Qualifier("hazelcastServiceTest")
private ImdgProvider hazelcast;
void init() {
hazelcast.waitAvailable();
ImdgHazelcast<Company> companyImdg = (ImdgHazelcast<Company>) hazelcast.getImdg(IMDGDistributedNames.Map_Company, Company.class);
companyImdg = (ImdgHazelcast<Company>) hazelcast.getImdg(IMDGDistributedNames.Map_Company, Company.class);
ImdgHazelcast<CompanySymbols> companySymbolsImdg = (ImdgHazelcast<CompanySymbols>) hazelcast.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
ImdgHazelcast<Account> accountImdg = (ImdgHazelcast<Account>) hazelcast.getImdg(IMDGDistributedNames.Map_Account, Account.class);
accountImdg = (ImdgHazelcast<Account>) hazelcast.getImdg(IMDGDistributedNames.Map_Account, Account.class);
requestInfoImdg = (ImdgHazelcast<RequestInfo>) hazelcast.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
statementImdg = (ImdgHazelcast<Statement>) hazelcast.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
sdf01Imdg = (ImdgHazelcast<SDf01>) hazelcast.getImdg(IMDGDistributedNames.Map_SDf01, SDf01.class);
sdf02Imdg = (ImdgHazelcast<SDf02>) hazelcast.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class);
sdf08Imdg = (ImdgHazelcast<SDf08>) hazelcast.getImdg(IMDGDistributedNames.Map_SDf08, SDf08.class);
sdf10Imdg = (ImdgHazelcast<SDf10>) hazelcast.getImdg(IMDGDistributedNames.Map_SDf10, SDf10.class);
@ -135,4 +140,19 @@ public abstract class AbstractServiceTest {
accountBalance.setFullName(company.getFullName());
return accountBalance;
}
protected SDf01 getTestSdf01(long id, long generationId) {
LocalDate date = LocalDate.now();
SDf01 sdf01 = new SDf01();
sdf01.setId(id);
sdf01.setGenerationId(generationId);
sdf01.setMarket("U");
sdf01.setDeal(deal);
sdf01.setAccount(acc);
sdf01.setCurr_code("RUR");
sdf01.setDat(date.format(datFormatter));
sdf01.setAcc_type("A");
sdf01.setRemainder(amountNew.toString());
return sdf01;
}
}

View file

@ -1,7 +1,9 @@
package ru.spcex.clearing.balance.service;
import org.apache.kafka.clients.producer.MockProducer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.company.Company;
@ -30,11 +32,14 @@ class AccountBalanceServiceTest extends AbstractServiceTest {
@Autowired
AccountBalanceService accountBalanceService;
@SpyBean
private MockProducer<String, Object> producer;
@PostConstruct
void init() {
super.init();
}
/**
* {@link AccountBalanceService#createAccountBalance(Long addresseeId, Long accountId, BigDecimal amount, String cashMovementCurrencyCode)}<br>
* Тест проверяет генерацию сущности {@link AccountResult}<br>
@ -47,9 +52,9 @@ class AccountBalanceServiceTest extends AbstractServiceTest {
@Test
void createAccountBalance() {
Company company = getTestCompany();
companyMap.put(addresseeIdNew, company);
companyImdg.insert(company);
Account account = getTestAccount(accountIdNew, acc);
accountMap.put(accountIdNew, account);
accountImdg.insert(account);
AccountResult predictableNewResult = getTestAccountResult(accountIdNew, account, company);
AccountResult resultNew = accountBalanceService.createAccountBalance(addresseeIdNew, accountIdNew, amountNew, cashMovementCurrencyCode);
@ -91,7 +96,8 @@ class AccountBalanceServiceTest extends AbstractServiceTest {
//CompanyNotFound
AccountResult predictableResult;
predictableResult = new AccountResult(new EnumMessage(BalanceError.CompanyNotFound));
companyMap.delete(addresseeIdNew);
Company company = getTestCompany();
companyImdg.delete(company);
AccountResult result = accountBalanceService.createAccountBalance(addresseeIdNew, accountIdNew, amountNew, cashMovementCurrencyCode);
ACCOUNT_BALANCE_MATCHER.assertMatch(result, predictableResult);
@ -100,11 +106,11 @@ class AccountBalanceServiceTest extends AbstractServiceTest {
ACCOUNT_BALANCE_MATCHER.assertMatch(result, predictableResult);
//AccountNotPresent accountType=null
companyMap.put(addresseeIdNew, getTestCompany());
companyImdg.insert(company);
Account account = new Account();
account.setId(accountIdNew);
account.setAccountStatus(Status.Active.getKey());
accountMap.put(accountIdNew, account);
accountImdg.insert(account);
predictableResult = new AccountResult(new EnumMessage(BalanceError.AccountNotPresent));
result = accountBalanceService.createAccountBalance(addresseeIdNew, accountIdNew, amountNew, cashMovementCurrencyCode);
@ -114,7 +120,7 @@ class AccountBalanceServiceTest extends AbstractServiceTest {
account.setId(null);
account.setAccountType(AccountType.Clrn.getKey());
account.setAccountStatus(Status.Active.getKey());
accountMap.put(accountIdNew, account);
accountImdg.insert(account);
predictableResult = new AccountResult(new EnumMessage(BalanceError.AccountNotPresent));
result = accountBalanceService.createAccountBalance(addresseeIdNew, accountIdNew, amountNew, cashMovementCurrencyCode);
@ -124,14 +130,14 @@ class AccountBalanceServiceTest extends AbstractServiceTest {
account.setId(accountIdNew);
account.setAccountType(AccountType.Clrn.getKey());
account.setAccountStatus(null);
accountMap.put(accountIdNew, account);
accountImdg.insert(account);
predictableResult = new AccountResult(new EnumMessage(BalanceError.AccountNotActive, account.getId()));
result = accountBalanceService.createAccountBalance(addresseeIdNew, accountIdNew, amountNew, cashMovementCurrencyCode);
ACCOUNT_BALANCE_MATCHER.assertMatch(result, predictableResult);
account.setAccountStatus(Status.Active.getKey());
accountMap.put(accountIdNew, account);
accountImdg.insert(account);
result = accountBalanceService.createAccountBalance(addresseeIdNew, null, amountNew, cashMovementCurrencyCode);
predictableResult = new AccountResult(new EnumMessage(BalanceError.AccountNotPresent));
ACCOUNT_BALANCE_MATCHER.assertMatch(result, predictableResult);

View file

@ -1,7 +1,9 @@
package ru.spcex.clearing.balance.service;
import org.apache.kafka.clients.producer.MockProducer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.company.Company;
@ -27,13 +29,15 @@ import java.util.Map;
import static ru.spcex.clearing.balance.utils.MatcherFactory.usingIgnoringFieldsComparator;
class Sdf01ExecutorTest extends AbstractServiceTest {
final static DateTimeFormatter datFormatter = DateTimeFormatter.ofPattern("dd.MM.yy");
public final static DateTimeFormatter datFormatter = DateTimeFormatter.ofPattern("dd.MM.yy");
public final static String acc = "123456789";
private static final MatcherFactory.Matcher<SDf02> SDF_02_MATCHER = usingIgnoringFieldsComparator("created", "comment", "outSDfId", "generationTime", "generationId", "id");
private final String acc = "123456789";
private final Long ID = 1L;
@Autowired
Sdf01Executor sdf01Executor;
private StatementRequest statementRequest;
@SpyBean
private MockProducer<String, Object> producer;
@PostConstruct
void init() {
@ -59,7 +63,7 @@ class Sdf01ExecutorTest extends AbstractServiceTest {
@Test
void execute() {
//check create statement, SDf02 and AccountBalance
SDf01 sdf01 = getTestSdf01();
SDf01 sdf01 = getTestSdf01(ID, 1L);
Company company = getTestCompany();
companyMap.put(addresseeIdNew, company);
@ -103,7 +107,7 @@ class Sdf01ExecutorTest extends AbstractServiceTest {
@Test
void validatedExecute() {
//CompanyNotFound
SDf01 sdf01 = getTestSdf01();
SDf01 sdf01 = getTestSdf01(ID, 1L);
companyMap.delete(addresseeIdNew);
checkError(new EnumMessage(BalanceError.CompanyNotFound), sdf01);
@ -206,20 +210,6 @@ class Sdf01ExecutorTest extends AbstractServiceTest {
return sDf02;
}
private SDf01 getTestSdf01() {
LocalDate date = LocalDate.now();
SDf01 sdf01 = new SDf01();
sdf01.setId(ID);
sdf01.setMarket("U");
sdf01.setDeal(deal);
sdf01.setAccount(acc);
sdf01.setCurr_code("RUR");
sdf01.setDat(date.format(datFormatter));
sdf01.setAcc_type("A");
sdf01.setRemainder(amountNew.toString());
return sdf01;
}
private Statement getTestStatement(Long id, Company company, Account account, SDf01 sdf01) {
Statement statement = new Statement();
statement.setId(id);

View file

@ -2,43 +2,46 @@ package ru.spcex.clearing.balance.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import ru.clearing.classes.statics.data.sdf.SDf08;
import ru.spcex.clearing.balance.utils.ImapEvent;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.platform.enumeration.Task;
import javax.annotation.PostConstruct;
import java.time.Instant;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.balance.utils.MockKafkaUtils.addRecordToKafka;
class Sdf08ServiceTest extends AbstractServiceTest {
// private static final MatcherFactory.Matcher<SDf08> SDF_08_MATCHER = usingIgnoringFieldsComparator("created", "comment", "outSDfId", "generationTime", "generationId", "id");
private static final String TOPIC = Task.getAllBalance.topic();
private static final int PARTITION = 1;
private static final Long limit = 300L;
@Autowired
Sdf08Service sdf08Service;
@Autowired
@Captor
ArgumentCaptor<ProducerRecord> producerRecord;
private MockConsumer<String, Object> mockConsumer;
@SpyBean
private MockProducer<String, Object> producer;
@PostConstruct
void init() {
super.init();
mockConsumer = (MockConsumer<String, Object>) sdf08Service.getConsumer();
}
/**
@ -60,30 +63,21 @@ class Sdf08ServiceTest extends AbstractServiceTest {
throw new RuntimeException(e);
}
IMap<Long, SDf08> sdf08Map = sdf08Imdg.getMap();
IMap<Long, RequestInfo> resultsRequestMap = requestInfoImdg.getMap();
ImapEvent imapEvent = new ImapEvent(resultsRequestMap);
int count = sdf08Map.size();
long timeNow = Instant.now().toEpochMilli();
//KAFKA
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonBaseNewRequest));
});
addRecordToKafka(mockConsumer, TOPIC, PARTITION, 0, jsonBaseNewRequest);
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
TopicPartition tp = new TopicPartition(TOPIC, PARTITION);
startOffsets.put(tp, 0L);
mockConsumer.updateBeginningOffsets(startOffsets);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(1))
.send(producerRecord.capture());
//waiting for hazelcast map item updates
imapEvent.waitWhenHappened();
assertEquals(Consts.EXPORT_PROCESS, producerRecord.getValue().topic());
BaseRequest<Object> baseRequest = (BaseRequest<Object>) producerRecord.getValue().value();
Collection<RequestInfo> resultsRequestInfo = requestInfoImdg.getCollectionObjectsByFieldValues(Map.of("status", Status.Processing));
RequestInfo requestInfo = resultsRequestInfo.stream().max((entry1, entry2) -> entry1.getId() > entry2.getId() ? 1 : -1).get();
Long diffRequestInfo = requestInfo.getCreated().toEpochMilli() - timeNow;
ExportToFileRequest exportToFileRequest = (ExportToFileRequest) baseRequest.getRequestPayload();
SDf08 resultsSDf08 = sdf08Imdg.getSingleObjectBySQL(String.format("generationId = %s and id != null", exportToFileRequest.getSdfGroupId()));
RequestInfo resultRequestInfo = requestInfoImdg.getSingleObjectByID(baseRequest.getId());
assertEquals(1, sdf08Map.size() - count);
assertTrue(limit.compareTo(diffRequestInfo) > 0);
assertNotNull(baseRequest);
assertNotNull(resultsSDf08);
assertNotNull(resultRequestInfo);
}
}

View file

@ -1,7 +1,9 @@
package ru.spcex.clearing.balance.service;
import org.apache.kafka.clients.producer.MockProducer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.company.Company;
@ -34,6 +36,8 @@ class Sdf09ExecutorTest extends AbstractServiceTest {
Sdf09Executor sdf09Executor;
private SDf09 sdf09;
private StatementRequest statementRequest;
@SpyBean
private MockProducer<String, Object> producer;
@PostConstruct
void init() {

View file

@ -1,7 +1,12 @@
package ru.spcex.clearing.balance.service;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.account.AccountBalance;
import ru.clearing.classes.statics.data.company.Company;
@ -11,8 +16,12 @@ import ru.clearing.classes.statics.data.sdf.SDf17;
import ru.clearing.classes.statics.data.statement.Statement;
import ru.spcex.clearing.balance.errors.BalanceError;
import ru.spcex.clearing.balance.utils.MatcherFactory;
import ru.spcex.clearing.balance.utils.MockKafkaUtils;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationNewRequest;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.utils.enumeration.EnumMessage;
@ -24,6 +33,9 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static ru.spcex.clearing.balance.utils.MatcherFactory.usingIgnoringFieldsComparator;
class Sdf16ExecutorTest extends AbstractServiceTest {
@ -32,9 +44,14 @@ class Sdf16ExecutorTest extends AbstractServiceTest {
private final String acc = "323456789";
@Autowired
Sdf16Executor sdf16Executor;
@Captor
ArgumentCaptor<ProducerRecord> producerRecord;
private SDf16 sdf16;
private StatementRequest statementRequest;
@MockBean
private MockProducer<String, Object> producer;
@PostConstruct
void init() {
super.init();
@ -78,11 +95,18 @@ class Sdf16ExecutorTest extends AbstractServiceTest {
predictableStatement.setOutSDfId(predictableSdf17.getId());
AccountResult predictableNewResult = getTestAccountResult(currentId.getAndIncrement(), account, company);
MockKafkaUtils.FutureRecordMetadata future = spy(MockKafkaUtils.FutureRecordMetadata.class);
doReturn(future).when(producer).send(producerRecord.capture());
Result result = sdf16Executor.execute(Collections.singletonList(sdf16), statementRequest);
BaseRequest<Object> baseRequest = (BaseRequest<Object>) producerRecord.getValue().value();
NotificationNewRequest notificationNewRequest = (NotificationNewRequest) baseRequest.getRequestPayload();
Statement resultStatement = statementImdg.getSingleObjectByFieldValues(Map.of("account", acc));
SDf17 resultSdf17 = sdf17Imdg.getSingleObjectByFieldValues(Map.of("account", acc));
AccountBalance resultAccountBalance = accountBalanceImdg.getSingleObjectByFieldValues(Map.of("account", acc));
assertEquals(Consts.NOTIFICATION_NEW, producerRecord.getValue().topic());
assertEquals(notificationNewRequest.getObjectId(), resultStatement.getId());
RESULT_MATCHER.assertMatch(result, predictableResult);
STATEMENT_MATCHER.assertMatch(resultStatement, predictableStatement);
SDF_17_MATCHER.assertMatch(resultSdf17, predictableSdf17);

View file

@ -2,44 +2,54 @@ package ru.spcex.clearing.balance.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.clients.producer.MockProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.springframework.beans.factory.annotation.Autowired;
import ru.spcex.clearing.balance.utils.ImapEvent;
import org.springframework.boot.test.mock.mockito.SpyBean;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.sdf.SDf01;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
import ru.spcex.clearing.platform.messaging.service.Status;
import javax.annotation.PostConstruct;
import java.time.Instant;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static ru.spcex.clearing.balance.utils.MockKafkaUtils.addRecordToKafka;
import static ru.spcex.platform.enumeration.SdfTable.SDF_01;
class StatementServiceServiceTest extends AbstractServiceTest {
// private static final MatcherFactory.Matcher<SDf08> SDF_08_MATCHER = usingIgnoringFieldsComparator("created", "comment", "outSDfId", "generationTime", "generationId", "id");
private static final String TOPIC = Consts.STATEMENT_PROCESS;
private static final int PARTITION = 1;
private static final Long groupId = 111L;
private static final Long limit = 300L;
private final static AtomicLong cuurentOffset = new AtomicLong(1L);
private final Long ID = 11L;
@Autowired
StatementService statementService;
@Autowired
@Captor
ArgumentCaptor<ProducerRecord> producerRecord;
private MockConsumer<String, Object> mockConsumer;
private SDf01 sDf01;
private Company company;
@SpyBean
private MockProducer<String, Object> producer;
@PostConstruct
void init() {
super.init();
mockConsumer = (MockConsumer<String, Object>) statementService.getConsumer();
sDf01 = getTestSdf01(ID, groupId);
company = getTestCompany();
}
/**
@ -50,43 +60,78 @@ class StatementServiceServiceTest extends AbstractServiceTest {
* {@link StatementRequest#table} - SDF_01<br>
*/
@Test
void process() throws InterruptedException {
void processEXPORT_PROCESS() {
sdf01Imdg.delete(sDf01);
companyImdg.delete(company);
companyImdg.delete(company);
StatementRequest statementRequest = new StatementRequest();
statementRequest.setGroupId(groupId);
statementRequest.setTable(SDF_01);
BaseRequest<StatementRequest> baseRequest = new BaseRequest<>();
baseRequest.setRequestPayload(statementRequest);
baseRequest.setId(currentId.getAndIncrement());
baseRequest.setActionType(ActionType.NEW);
BaseRequest<StatementRequest> baseNewRequest = new BaseRequest<>();
baseNewRequest.setRequestPayload(statementRequest);
baseNewRequest.setId(currentId.getAndIncrement());
baseNewRequest.setActionType(ActionType.NEW);
String jsonBaseNewRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseNewRequest = objectMapper.writeValueAsString(baseRequest);
jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
IMap<Long, RequestInfo> resultsRequestMap = requestInfoImdg.getMap();
ImapEvent imapEvent = new ImapEvent(resultsRequestMap);
long timeNow = Instant.now().toEpochMilli();
//KAFKA
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonBaseNewRequest));
});
addRecordToKafka(mockConsumer, TOPIC, PARTITION, cuurentOffset.getAndIncrement(), jsonBaseNewRequest);
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
TopicPartition tp = new TopicPartition(TOPIC, PARTITION);
startOffsets.put(tp, 0L);
mockConsumer.updateBeginningOffsets(startOffsets);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(1))
.send(producerRecord.capture());
//waiting for hazelcast map item updates
imapEvent.waitWhenHappened();
BaseRequest<Object> baseRequest = (BaseRequest<Object>) producerRecord.getValue().value();
RequestInfo resultRequestInfo = requestInfoImdg.getSingleObjectByID(baseRequest.getId());
Collection<RequestInfo> resultsRequestInfo = requestInfoImdg.getCollectionObjectsByFieldValues(Map.of("status", Status.Processing));
RequestInfo requestInfo = resultsRequestInfo.stream().max((entry1, entry2) -> entry1.getId() > entry2.getId() ? 1 : -1).get();
Long diffRequestInfo = requestInfo.getCreated().toEpochMilli() - timeNow;
assertEquals(Consts.EXPORT_PROCESS, producerRecord.getValue().topic());
assertNotNull(baseRequest);
assertNotNull(resultRequestInfo);
}
assertTrue(limit.compareTo(diffRequestInfo) > 0);
/**
* {@link StatementService}<br>
* Тест проверяет генерацию сущностей {@link RequestInfo}<br>
* Входные параметры:<br>
* {@link StatementRequest}: new StatementRequest()<br>
* {@link StatementRequest#table} - SDF_01<br>
*/
@Test
void processACCOUNT_NEW() {
sdf01Imdg.insert(sDf01);
companyImdg.insert(company);
StatementRequest statementRequest = new StatementRequest();
statementRequest.setGroupId(groupId);
statementRequest.setTable(SDF_01);
BaseRequest<StatementRequest> baseNewRequest = new BaseRequest<>();
baseNewRequest.setRequestPayload(statementRequest);
baseNewRequest.setId(currentId.getAndIncrement());
baseNewRequest.setActionType(ActionType.NEW);
String jsonBaseNewRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
addRecordToKafka(mockConsumer, TOPIC, PARTITION, cuurentOffset.getAndIncrement(), jsonBaseNewRequest);
//waiting for kafka producer send message (finale event)
verify(producer, timeout(30_000L).times(1))
.send(producerRecord.capture());
BaseRequest<Object> baseRequest = (BaseRequest<Object>) producerRecord.getValue().value();
RequestInfo resultRequestInfo = requestInfoImdg.getSingleObjectByID(baseRequest.getId());
assertEquals(Consts.ACCOUNT_NEW, producerRecord.getValue().topic());
assertNotNull(baseRequest);
assertNotNull(resultRequestInfo);
}
}

View file

@ -0,0 +1,54 @@
package ru.spcex.clearing.balance.utils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.apache.kafka.common.TopicPartition;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class MockKafkaUtils {
public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) {
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(topic, partition)));
mockConsumer.addRecord(new ConsumerRecord<>(topic, partition, offset, "key", jsonValue));
});
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
TopicPartition tp = new TopicPartition(topic, partition);
startOffsets.put(tp, 0L);
mockConsumer.updateBeginningOffsets(startOffsets);
}
public static class FutureRecordMetadata implements Future<RecordMetadata> {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
return false;
}
@Override
public RecordMetadata get() throws InterruptedException, ExecutionException {
return null;
}
@Override
public RecordMetadata get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return null;
}
}
}

View file

@ -13,9 +13,12 @@ import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
@Configuration
public class HazelcastServiceTestConfiguration {
public static final AtomicLong currentID = new AtomicLong(0L);
private HazelcastInstance hazelcastInstance;
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {

View file

@ -3,8 +3,6 @@ package ru.spcex.clearing.company.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
@ -19,20 +17,22 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
import ru.clearing.classes.statics.data.profile.Contact;
import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration;
import ru.spcex.clearing.company.utils.ImapEvent;
import ru.spcex.clearing.company.utils.MatcherFactory.Matcher;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import java.util.Collections;
import java.util.HashMap;
import static ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration.currentID;
import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator;
@ExtendWith(SpringExtension.class)
@ -42,9 +42,10 @@ class ClearingMemberCategoryServiceTest {
public static final Matcher<ClearingMemberCategory> MEMBER_CATEGORY_MATCHER = usingIgnoringFieldsComparator();
private static final int PARTITION = 0;
private static final String TOPIC_MEMBER_CATEGORY_NEW = Consts.DESTINATION_CLEARING_MEMBER_CATEGORY_NEW;
private static final String TOPIC_MEMBER_CATEGORY_UPDATE = Consts.DESTINATION_CLEARING_MEMBER_CATEGORY_UPDATE;
private static final String TOPIC_MEMBER_CATEGORY_DELETE = Consts.DESTINATION_CLEARING_MEMBER_CATEGORY_DELETE;
private static final Long ID = 0L;
private static final Long ID = currentID.getAndIncrement();
@Autowired
@Qualifier("hazelcastServiceTest")
@ -58,6 +59,56 @@ class ClearingMemberCategoryServiceTest {
mockProducer = new MockProducer<>();
}
@Test
void clearingMemberCategoryNew() throws InterruptedException {
//ARRANGE
ClearingMemberCategoryNewRequest memberCategoryNewRequest = new ClearingMemberCategoryNewRequest();
memberCategoryNewRequest.setClearingMemberCategory("1234");
BaseRequest<ClearingMemberCategoryNewRequest> baseUpdateRequest = new BaseRequest<>();
baseUpdateRequest.setRequestPayload(memberCategoryNewRequest);
baseUpdateRequest.setId(ID);
baseUpdateRequest.setActionType(ActionType.NEW);
String jsonBaseForNewRequest;
ObjectMapper objectMapper = new ObjectMapper();
try {
jsonBaseForNewRequest = objectMapper.writeValueAsString(baseUpdateRequest);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
ClearingMemberCategory predictableClearingMemberCategory = new ClearingMemberCategory();
predictableClearingMemberCategory.setId(ID);
predictableClearingMemberCategory.setClearingMemberCategory("1234");
//ACT
//service set up
ClearingMemberCategoryService clearingMemberCategoryService = new ClearingMemberCategoryService(mockConsumer, mockProducer, hazelcastServiceTest);
//callbacks set up
clearingMemberCategoryService.afterPropertiesSet();
IMap<Long, ClearingMemberCategory> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_ClearingMemberCategory);
ImapEvent imapEvent = new ImapEvent(iMap);
//KAFKA
mockConsumer.schedulePollTask(() -> {
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC_MEMBER_CATEGORY_NEW, PARTITION)));
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC_MEMBER_CATEGORY_NEW, PARTITION, 0, "key", jsonBaseForNewRequest));
});
HashMap<TopicPartition, Long> startOffsetsUpdating = new HashMap<>();
TopicPartition tpUpdating = new TopicPartition(TOPIC_MEMBER_CATEGORY_NEW, PARTITION);
startOffsetsUpdating.put(tpUpdating, 0L);
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
//waiting for hazelcast map item updates
imapEvent.waitWhenHappened();
//ASSERT
ClearingMemberCategory resultUpdating = iMap.get(ID);
MEMBER_CATEGORY_MATCHER.assertMatch(resultUpdating, predictableClearingMemberCategory);
}
/**
* {@link ClearingMemberCategoryService#clearingMemberCategoryUpdate(BaseRequest)}<br>
* Тест проверяет обновление сущности {@link ClearingMemberCategory} в Hazelcast при передаче из Apache Kafka.<br>
@ -100,6 +151,7 @@ class ClearingMemberCategoryServiceTest {
IMap<Long, ClearingMemberCategory> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_ClearingMemberCategory);
iMap.put(ID, existsСlearingMemberCategory);
ImapEvent imapEvent = new ImapEvent(iMap);
//KAFKA
mockConsumer.schedulePollTask(() -> {
@ -112,30 +164,11 @@ class ClearingMemberCategoryServiceTest {
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
//waiting for hazelcast map item updates
Object waiter = new Object();
String listenerID = iMap.addEntryListener((EntryUpdatedListener<Long, Contact>) entryEvent -> {
System.out.println("Checking If removed..");
synchronized (waiter) {
try {
waiter.wait(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
waiter.notify();
}
}, false);
synchronized (waiter) {
waiter.wait(100);
}
imapEvent.waitWhenHappened();
//ASSERT
ClearingMemberCategory resultUpdating = iMap.get(ID);
MEMBER_CATEGORY_MATCHER.assertMatch(resultUpdating, predictableClearingMemberCategory);
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerID);
}
/**
@ -175,6 +208,7 @@ class ClearingMemberCategoryServiceTest {
IMap<Long, ClearingMemberCategory> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_ClearingMemberCategory);
iMap.put(ID, existsСlearingMemberCategory);
ImapEvent imapEvent = new ImapEvent(iMap);
//KAFKA
mockConsumer.schedulePollTask(() -> {
@ -187,28 +221,9 @@ class ClearingMemberCategoryServiceTest {
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
//waiting for hazelcast map item removes
Object waiter = new Object();
String listenerID = iMap.addEntryListener((EntryRemovedListener<Long, Contact>) entryEvent -> {
System.out.println("Checking If removed..");
try {
waiter.wait(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (waiter) {
waiter.notify();
}
}, false);
synchronized (waiter) {
waiter.wait(100);
}
imapEvent.waitWhenHappened();
//ASSERT
Assertions.assertEquals(0, iMap.size());
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerID);
}
}

View file

@ -3,7 +3,6 @@ package ru.spcex.clearing.company.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryUpdatedListener;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
@ -16,9 +15,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.profile.CompanyInfo;
import ru.clearing.classes.statics.data.profile.Contact;
import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration;
import ru.spcex.clearing.company.utils.ImapEvent;
import ru.spcex.clearing.company.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
@ -88,6 +88,9 @@ class CompanyInfoServiceTest {
existsCompanyInfo.setFullNameEng("exists fullNameEng");
existsCompanyInfo.setShortName("exists shortName");
existsCompanyInfo.setFullName("exists fullName");
Company existsCompany = new Company();
existsCompany.setId(ID);
existsCompany.setProfile(existsCompanyInfo);
CompanyInfoUpdateRequest companyInfoUpdateRequest = new CompanyInfoUpdateRequest();
companyInfoUpdateRequest.setId(ID);
@ -137,8 +140,9 @@ class CompanyInfoServiceTest {
//callbacks set up
clearingMemberCategoryService.afterPropertiesSet();
IMap<Long, CompanyInfo> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Company);
iMap.put(ID, existsCompanyInfo);
IMap<Long, Company> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Company);
iMap.put(ID, existsCompany);
ImapEvent imapEvent = new ImapEvent(iMap);
//KAFKA
mockConsumer.schedulePollTask(() -> {
@ -151,29 +155,10 @@ class CompanyInfoServiceTest {
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
//waiting for hazelcast map updates
Object waiter = new Object();
String listenerID = iMap.addEntryListener((EntryUpdatedListener<Long, Contact>) entryEvent -> {
System.out.println("Checking If removed..");
try {
waiter.wait(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (waiter) {
waiter.notify();
}
}, false);
synchronized (waiter) {
waiter.wait(100);
}
imapEvent.waitWhenHappened();
//ASSERT
CompanyInfo resultUpdating = iMap.get(ID);
COMPANY_INFO_MATCHER.assertMatch(resultUpdating, predictableCompanyInfo);
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerID);
Company resultUpdating = iMap.get(ID);
COMPANY_INFO_MATCHER.assertMatch(resultUpdating.getProfile(), predictableCompanyInfo);
}
}

View file

@ -3,7 +3,6 @@ package ru.spcex.clearing.company.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryRemovedListener;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
@ -19,8 +18,8 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
import ru.clearing.classes.statics.data.profile.Contact;
import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration;
import ru.spcex.clearing.company.utils.ImapEvent;
import ru.spcex.clearing.company.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
@ -92,6 +91,7 @@ class CompanyServiceTest {
IMap<Long, Company> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Company);
iMap.put(ID, existsCompany);
ImapEvent imapEvent = new ImapEvent(iMap);
//KAFKA
mockConsumer.schedulePollTask(() -> {
@ -104,28 +104,9 @@ class CompanyServiceTest {
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
//waiting for hazelcast map item removes
Object waiter = new Object();
String listenerID = iMap.addEntryListener((EntryRemovedListener<Long, Contact>) entryEvent -> {
System.out.println("Checking If removed..");
try {
waiter.wait(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (waiter) {
waiter.notify();
}
}, false);
synchronized (waiter) {
waiter.wait(100);
}
imapEvent.waitWhenHappened();
//ASSERT
Assertions.assertEquals(0, iMap.size());
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerID);
}
}

View file

@ -3,7 +3,6 @@ package ru.spcex.clearing.company.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryUpdatedListener;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
@ -17,8 +16,8 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.profile.Contact;
import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration;
import ru.spcex.clearing.company.utils.ImapEvent;
import ru.spcex.clearing.company.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
@ -105,6 +104,7 @@ class CompanySymbolServiceTest {
IMap<Long, CompanySymbols> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_CompanySymbols);
iMap.put(ID, existsCompanySymbols);
ImapEvent imapEvent = new ImapEvent(iMap);
//KAFKA
mockConsumer.schedulePollTask(() -> {
@ -117,29 +117,10 @@ class CompanySymbolServiceTest {
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
//waiting for hazelcast map item updates
Object waiter = new Object();
String listenerID = iMap.addEntryListener((EntryUpdatedListener<Long, Contact>) entryEvent -> {
System.out.println("Checking If removed..");
try {
waiter.wait(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (waiter) {
waiter.notify();
}
}, false);
synchronized (waiter) {
waiter.wait(100);
}
imapEvent.waitWhenHappened();
//ASSERT
CompanySymbols resultUpdating = iMap.get(ID);
COMPANY_SYMBOL_MATCHER.assertMatch(resultUpdating, predictableCompanySymbols);
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerID);
}
}

View file

@ -3,7 +3,6 @@ package ru.spcex.clearing.company.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryUpdatedListener;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.MockConsumer;
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
@ -18,6 +17,7 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.clearing.classes.statics.data.profile.Contact;
import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration;
import ru.spcex.clearing.company.utils.ImapEvent;
import ru.spcex.clearing.company.utils.MatcherFactory;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
@ -103,6 +103,7 @@ class ContactServiceTest {
//callbacks set up
IMap<Long, Contact> iMap = hazelcastServiceTest.getHazelcast().getMap(IMDGDistributedNames.Map_Contact);
iMap.put(ID, existsContact);
ImapEvent imapEvent = new ImapEvent(iMap);
//KAFKA
mockConsumer.schedulePollTask(() -> {
@ -115,29 +116,10 @@ class ContactServiceTest {
mockConsumer.updateBeginningOffsets(startOffsetsUpdating);
//waiting for hazelcast map updates
Object waiter = new Object();
String listenerID = iMap.addEntryListener((EntryUpdatedListener<Long, Contact>) entryEvent -> {
System.out.println("Checking If removed..");
try {
waiter.wait(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (waiter) {
waiter.notify();
}
}, false);
synchronized (waiter) {
waiter.wait(100);
}
imapEvent.waitWhenHappened();
//ASSERT
Contact resultUpdating = iMap.get(ID);
CONTACT_MATCHER.assertMatch(resultUpdating, predictableContact);
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerID);
}
}

View file

@ -0,0 +1,63 @@
package ru.spcex.clearing.company.utils;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.map.listener.EntryRemovedListener;
import com.hazelcast.map.listener.EntryUpdatedListener;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
public class ImapEvent<T> {
private final IMap<Long, T> iMap;
private final String listenerAdding;
private final String listenerUpdating;
private final String listenerRemoving;
private final AtomicBoolean checkEventHappened = new AtomicBoolean(false);
public ImapEvent(IMap<Long, T> iMap) {
this.iMap = iMap;
listenerAdding = iMap.addEntryListener((EntryAddedListener<Long, T>) entryEvent -> {
synchronized (checkEventHappened) {
checkEventHappened.set(true);
checkEventHappened.notify();
}
}, false);
listenerUpdating = iMap.addEntryListener((EntryUpdatedListener<Long, T>) entryEvent -> {
synchronized (checkEventHappened) {
checkEventHappened.set(true);
checkEventHappened.notify();
}
}, false);
listenerRemoving = iMap.addEntryListener((EntryRemovedListener<Long, T>) entryEvent -> {
synchronized (checkEventHappened) {
checkEventHappened.set(true);
checkEventHappened.notify();
}
}, false);
}
public void waitWhenHappened() throws InterruptedException {
//running timer task as daemon thread
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
boolean secondRan;
@Override
public void run() {
checkEventHappened.set(secondRan);//если что-то пойдет не так не тормозить основной поток
secondRan = true;
}
}, 0, 30 * 1000);
synchronized (checkEventHappened) {
while (!checkEventHappened.get()) {
checkEventHappened.wait(100);
}
}
//preparing hazelcastImdgProvider for next test
iMap.removeEntryListener(listenerAdding);
iMap.removeEntryListener(listenerUpdating);
iMap.removeEntryListener(listenerRemoving);
}
}

View file

@ -36,15 +36,15 @@ import java.util.function.Function;
* утилитный класс для обработки сообщений из очереди
*/
public class QueueConsumer implements AutoCloseable {
protected final Map<String, ConsumerSpecificClass<?>> callbacks;
private final Logger log = LoggerFactory.getLogger(getClass());
private final AtomicBoolean closed = new AtomicBoolean(false);
private final Consumer<String, Object> consumer;
private Producer<String, Object> producer;
private final ExecutorService inputExecutor;
private final ExecutorService outputExecutor;
protected final Map<String, ConsumerSpecificClass<?>> callbacks;
private final ObjectMapper json;
protected boolean supportStartOffsetTimeWindow;
private Producer<String, Object> producer;
public QueueConsumer(Consumer<String, Object> kafkaQueue) {
this.consumer = kafkaQueue;
@ -58,6 +58,7 @@ public class QueueConsumer implements AutoCloseable {
/**
* используем этот конструктор, если хотим класть
* в кафку "ответ" - информацию о статусе обработки команд
*
* @param kafkaQueue
* @param kafkaResponseQueue
*/
@ -96,7 +97,7 @@ public class QueueConsumer implements AutoCloseable {
}
} catch (Throwable e) {
log.error(ExceptionUtils.getStackTrace(e));
if (producer != null) {
if (producer != null && o != null) {
sendErrorResponse((BaseRequest<?>) o);
}
}
@ -166,12 +167,13 @@ public class QueueConsumer implements AutoCloseable {
/**
* Валидация запроса
*
* @param <R> Класс проверяемого запроса
* @return null если ошибок нет
*/
public <R> RequestInfoUpdate validate(BaseRequest<R> userRequest,
Function<R, IValidator> validatorBuilder,
IMessageResolver messageResolver) {
Function<R, IValidator> validatorBuilder,
IMessageResolver messageResolver) {
if (validatorBuilder != null) {
R req = userRequest.getRequestPayload();
IValidator validator = validatorBuilder.apply(req);
@ -197,5 +199,8 @@ public class QueueConsumer implements AutoCloseable {
outputExecutor.shutdown();
}
// нужен для тестов поскольку у каждого сервиса свой consumer
public Consumer getConsumer() {
return consumer;
}
}