Some ValidatorRule and PlannerNewRequest validator

This commit is contained in:
akulikov 2023-01-17 13:35:13 +03:00
parent a6100aca8f
commit 299cbb1abe
18 changed files with 599 additions and 93 deletions

View file

@ -2,11 +2,17 @@ package ru.spcex.clearing.scheduler.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.security.Security;
import ru.clearing.platform.dictionary.TaskDictionary;
import ru.clearing.platform.dictionary.TaskStatusDictionary;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
import ru.spcex.clearing.scheduler.validation.rules.DictionaryPresentRule;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.clearing.scheduler.validation.rules.common.*;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.Market;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
@ -27,11 +33,11 @@ public class ValidationConfig {
this.imdgs = new HashMap<>();
BiConsumer<String, Class<? extends SpcexObjectBase>> addImdg = (s, aClass) -> imdgs.put(s, imdgProvider.getImdg(s, aClass));
addImdg.accept(IMDGDistributedNames.Map_TaskDictionary, TaskDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary, TaskStatusDictionary.class);
addImdg.accept(IMDGDistributedNames.Map_Company, Company.class);
addImdg.accept(IMDGDistributedNames.Map_Security, Security.class);
}
/**
* чтобы во всех валидаторах был один экземпляр Imdg
*/
private Imdg<?> getImdg(String key) {
return imdgs.get(key);
}
@ -47,8 +53,31 @@ public class ValidationConfig {
DictionaryPresentRule.instance("task",
PlannerNewRequest::getTask,
IMDGDistributedNames.Map_TaskDictionary,
TaskDictionary.class,
true)
TaskDictionary.class),
TimeNotBeforeRule.instance("taskTime",
PlannerNewRequest::getTaskTime),
DateNotBeforeRule.instance("clearingDate",
PlannerNewRequest::getClearingDate),
EnumPresentRule.instance("market",
PlannerNewRequest::getMarket,
Market.values(),
false),
DictionaryPresentRule.instance("taskStatus",
PlannerNewRequest::getTaskStatus,
IMDGDistributedNames.Map_TaskStatusDictionary,
TaskStatusDictionary.class),
IdPresentRule.instance("companyId",
PlannerNewRequest::getCompanyId,
IMDGDistributedNames.Map_Company,
Company.class,
ValidationError.CompanyNotFound,
company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive),
IdPresentRule.instance("securityId",
PlannerNewRequest::getSecurityId,
IMDGDistributedNames.Map_Security,
Security.class,
ValidationError.SecurityNotFound,
security -> WorkflowStatus.Active.getKey().equals(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive)
);
};
}

View file

@ -1,21 +0,0 @@
package ru.spcex.clearing.scheduler.error;
import ru.spcex.platform.utils.enumeration.IEnumId;
public enum PlannerErrors implements IEnumId {
WrongEnumValue(10003L),
EmptyRequiredValue(10002L)
;
private final Long id;
PlannerErrors(Long id) {
this.id = id;
}
@Override
public Long getId() {
return null;
}
}

View file

@ -0,0 +1,28 @@
package ru.spcex.clearing.scheduler.error;
import ru.spcex.platform.utils.enumeration.IEnumId;
public enum ValidationError implements IEnumId {
WrongDictionaryValue(10003L),
EmptyRequiredValue(10002L),
WrongEnumValue(777L), //todo set code
TaskForPastDate(7010L),
TaskForPastTime(7011L),
CompanyNotFound(7014L),
SecurityNotFound(7012L),
CompanyNotActive(7015L),
SecurityNotActive(7013L)
;
private final Long id;
ValidationError(Long id) {
this.id = id;
}
@Override
public Long getId() {
return null;
}
}

View file

@ -18,7 +18,6 @@ import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerUpdateReq
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.scheduler.error.PlannerErrors;
import ru.spcex.clearing.scheduler.validation.IRequestValidator;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -74,7 +73,7 @@ public class PlannerService extends QueueConsumer implements InitializingBean {
IValidator validator = validationFactory.apply(req);
Optional<EnumMessage> validationError = validator.tillFirstError();
if (validationError.isPresent()) {
String errorMsg = messageResolver.resolve(new EnumMessage(PlannerErrors.WrongEnumValue));
String errorMsg = messageResolver.resolve(validationError.get());
log.error("cannot process PlannerNewRequest id={}: {}", userRequest.getId(), errorMsg);
return new RequestInfoUpdate()
.setId(userRequest.getId())

View file

@ -225,7 +225,7 @@ public interface IRequestValidator<T> {
*/
static boolean checkErrorList(List<IRequestValidator.ValidationError> errors, Logger log) {
if (!errors.isEmpty()) {
log.error("Validation error: [{}]",
log.error("Validation idNotPresentError: [{}]",
errors.stream().map(IRequestValidator.ValidationError::toString).collect(Collectors.joining(", "))
);
return true;

View file

@ -0,0 +1,30 @@
package ru.spcex.clearing.scheduler.validation.rules.common;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.time.LocalDate;
import java.util.Optional;
import java.util.function.Function;
public record DateNotBeforeRule<R>(String fieldName, Function<R, LocalDate> getter, boolean required) implements IValidationRule<ImdgValidationContext<R>> {
public static <R> DateNotBeforeRule<R> instance(String fieldName, Function<R, LocalDate> getter, boolean required) {
return new DateNotBeforeRule<>(fieldName, getter, required);
}
public static <R> DateNotBeforeRule<R> instance(String fieldName, Function<R, LocalDate> getter) {
return new DateNotBeforeRule<>(fieldName, getter, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
LocalDate date = getter.apply(validatedObject);
if (date == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : Optional.empty();
if (date.isBefore(LocalDate.now())) return of(ValidationError.TaskForPastDate, fieldName);
return Optional.empty();
}
}

View file

@ -1,7 +1,7 @@
package ru.spcex.clearing.scheduler.validation.rules;
package ru.spcex.clearing.scheduler.validation.rules.common;
import ru.clearing.platform.dictionary.AbstractDictionary;
import ru.spcex.clearing.scheduler.error.PlannerErrors;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
@ -12,33 +12,38 @@ import java.util.Optional;
import java.util.function.Function;
public record DictionaryPresentRule<R, D extends AbstractDictionary>(String fieldName,
Function<R, String> getEnumCode,
Function<R, String> getter,
String dictionaryName,
Class<D> enumClass,
Class<D> dictionaryClass,
boolean required) implements IValidationRule<ImdgValidationContext<R>> {
public static <R, D extends AbstractDictionary> DictionaryPresentRule<R, D> instance(String fieldName,
Function<R, String> getEnumCode,
Function<R, String> getter,
String dictionaryName,
Class<D> enumClass,
Class<D> dictionaryClass,
boolean required) {
return new DictionaryPresentRule<>(fieldName, getEnumCode, dictionaryName, enumClass, required);
return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, dictionaryClass, required);
}
public static <R, D extends AbstractDictionary> DictionaryPresentRule<R, D> instance(String fieldName,
Function<R, String> getter,
String dictionaryName,
Class<D> dictionaryClass) {
return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, dictionaryClass, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
String enumCode = getEnumCode.apply(validatedObject);
if (enumCode == null) {
return required ? of(PlannerErrors.EmptyRequiredValue, fieldName) : empty();
}
String enumCode = getter.apply(validatedObject);
if (enumCode == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : empty();
Imdg<D> dictImdg = context.obtainMap(
dictionaryName,
enumClass
dictionaryClass
);
D dictionaryFromMap = dictImdg.getSingleObjectByFieldValues(Map.of("code", enumCode));
if (dictionaryFromMap == null) {
return of(PlannerErrors.WrongEnumValue, fieldName);
return of(ValidationError.WrongDictionaryValue, fieldName);
}
return empty();
}

View file

@ -0,0 +1,40 @@
package ru.spcex.clearing.scheduler.validation.rules.common;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Optional;
import java.util.function.Function;
public record EnumPresentRule<R, E extends IEnumKey>(String fieldName,
Function<R, String> getter,
E[] enumValues,
boolean required) implements IValidationRule<ImdgValidationContext<R>> {
public static <R, E extends IEnumKey> EnumPresentRule<R, E> instance(String fieldName,
Function<R, String> getter,
E[] enumValues,
boolean required) {
return new EnumPresentRule<>(fieldName, getter, enumValues, required);
}
public static <R, E extends IEnumKey> EnumPresentRule<R, E> instance(String fieldName,
Function<R, String> getter,
E[] enumValues) {
return new EnumPresentRule<>(fieldName, getter, enumValues, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
String enumCode = getter.apply(validatedObject);
if (enumCode == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : empty();
for (E enumValue : enumValues) {
if (enumValue.getKey().equals(enumCode)) return empty();
}
return of(ValidationError.WrongEnumValue, fieldName);
}
}

View file

@ -1,6 +1,6 @@
package ru.spcex.clearing.scheduler.validation.rules;
package ru.spcex.clearing.scheduler.validation.rules.common;
import ru.spcex.clearing.scheduler.error.PlannerErrors;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
@ -18,7 +18,7 @@ public record FieldRequiredRule<R, V>(String fieldName, Function<R, V> getter) i
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
V value = getter.apply(validatedObject);
if (value == null) return of(PlannerErrors.EmptyRequiredValue, fieldName);
if (value == null) return of(ValidationError.EmptyRequiredValue, fieldName);
return empty();
}
}

View file

@ -0,0 +1,62 @@
package ru.spcex.clearing.scheduler.validation.rules.common;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
public record IdPresentRule<R, V extends SpcexObjectBase>(
String fieldName,
Function<R, Long> idGetter,
Function<V, ValidationError>[] additionalChecks,
String mapName,
Class<V> mapClass,
ValidationError idNotPresentError,
boolean required
) implements IValidationRule<ImdgValidationContext<R>> {
@SafeVarargs
public static <R, V extends SpcexObjectBase> IdPresentRule<R, V> instance(String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
ValidationError idNotPresentError,
boolean required,
Function<V, ValidationError> ... additionalChecks) {
return new IdPresentRule<>(fieldName, idGetter, additionalChecks, mapName, mapClass, idNotPresentError, required);
}
@SafeVarargs
public static <R, V extends SpcexObjectBase> IdPresentRule<R, V> instance(String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
ValidationError idNotPresentError,
Function<V, ValidationError> ... additionalChecks) {
return new IdPresentRule<>(fieldName, idGetter, additionalChecks, mapName, mapClass, idNotPresentError, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
Long id = idGetter.apply(validatedObject);
if (id == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : empty();
Imdg<V> imdg = context.obtainMap(mapName, mapClass);
V fromMap = imdg.getSingleObjectByFieldValues(Map.of("id", id));
if (fromMap == null) {
return of(idNotPresentError, fieldName);
}
for (Function<V, ValidationError> additionalCheck : additionalChecks) {
ValidationError validationError = additionalCheck.apply(fromMap);
if (validationError != null)
return of(validationError, fieldName);
}
return empty();
}
}

View file

@ -0,0 +1,30 @@
package ru.spcex.clearing.scheduler.validation.rules.common;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.time.LocalTime;
import java.util.Optional;
import java.util.function.Function;
public record TimeNotBeforeRule<R>(String fieldName, Function<R, LocalTime> getter, boolean required) implements IValidationRule<ImdgValidationContext<R>> {
public static <R> TimeNotBeforeRule<R> instance(String fieldName, Function<R, LocalTime> getter, boolean required) {
return new TimeNotBeforeRule<>(fieldName, getter, required);
}
public static <R> TimeNotBeforeRule<R> instance(String fieldName, Function<R, LocalTime> getter) {
return new TimeNotBeforeRule<>(fieldName, getter, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
LocalTime date = getter.apply(validatedObject);
if (date == null) return required ? of(ValidationError.EmptyRequiredValue, fieldName) : Optional.empty();
if (date.isBefore(LocalTime.now())) return of(ValidationError.TaskForPastTime, fieldName);
return Optional.empty();
}
}

View file

@ -0,0 +1,49 @@
package ru.specx.clearing.scheduler.validation;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
import ru.spcex.clearing.scheduler.validation.rules.common.DateNotBeforeRule;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.time.LocalDate;
import java.util.Collection;
import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ExtendWith(SpringExtension.class)
class DateNotBeforeRuleTest {
@Test
public void dateNotBeforeRuleTest() {
Function<PlannerNewRequest, IValidator> validatorBuilder = plannerNewRequest -> {
ImdgValidationContext<PlannerNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerNewRequest);
return new ValidatorImpl<>(context,
DateNotBeforeRule.instance("clearingDate", PlannerNewRequest::getClearingDate));
};
PlannerNewRequest plannerNewRequest = new PlannerNewRequest();
plannerNewRequest.setClearingDate(LocalDate.now().plusDays(1));
IValidator validator = validatorBuilder.apply(plannerNewRequest);
Collection<EnumMessage> enumMessages = validator.validateAll();
assertTrue(enumMessages.isEmpty());
plannerNewRequest.setClearingDate(LocalDate.now());
validator = validatorBuilder.apply(plannerNewRequest);
enumMessages = validator.validateAll();
assertTrue(enumMessages.isEmpty());
plannerNewRequest.setClearingDate(LocalDate.now().minusDays(1));
validator = validatorBuilder.apply(plannerNewRequest);
enumMessages = validator.validateAll();
assertEquals(1, enumMessages.size());
}
}

View file

@ -13,12 +13,16 @@ import ru.clearing.platform.dictionary.TaskStatusDictionary;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
import ru.spcex.clearing.scheduler.error.PlannerErrors;
import ru.spcex.clearing.scheduler.validation.rules.DictionaryPresentRule;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.clearing.scheduler.validation.rules.common.DictionaryPresentRule;
import ru.spcex.platform.enumeration.DayStatus;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.enumeration.Task;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import ru.specx.clearing.scheduler.config.HazelcastServiceTestConfiguration;
@ -26,7 +30,6 @@ import ru.specx.clearing.scheduler.config.HazelcastServiceTestConfiguration;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -46,85 +49,67 @@ class DictionaryPresentRuleTest {
TaskDictionary.class,
PlannerNewRequest.class,
"task",
Task.values(),
PlannerNewRequest::getTask,
PlannerNewRequest::setTask);
testDictionary(IMDGDistributedNames.Map_TaskStatusDictionary,
TaskStatusDictionary.class,
PlannerNewRequest.class,
"taskStatus",
Status.values(),
PlannerNewRequest::getTaskStatus,
PlannerNewRequest::setTaskStatus);
testDictionary(IMDGDistributedNames.Map_TaskDictionary,
TaskDictionary.class,
PlannerNewRequest.class,
"task",
PlannerNewRequest::getTask,
PlannerNewRequest::setTask);
testDictionary(IMDGDistributedNames.Map_DayStatusDictionary,
DayStatusDictionary.class,
ClearingCalendarNewRequest.class,
"dayStatus",
DayStatus.values(),
ClearingCalendarNewRequest::getDayStatus,
ClearingCalendarNewRequest::setDayStatus);
}
private <D extends AbstractDictionary, R> void testDictionary(String dictionaryKey,
private <D extends AbstractDictionary, R, E extends IEnumKey> void testDictionary(String dictionaryKey,
Class<D> dictionaryClass,
Class<R> recordClass,
String fieldName,
E[] enumValues,
Function<R, String> getter,
BiConsumer<R, String> setter) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Imdg<D> dictionaryImdg = hazelcastServiceTest.getImdg(dictionaryKey, dictionaryClass);
D td1 = dictionaryClass.getConstructor().newInstance();
td1.setId(1L);
td1.setCode("CSD1");
td1.setName("TEST NAME 1");
dictionaryImdg.insert(td1);
D td2 = dictionaryClass.getConstructor().newInstance();
td2.setId(2L);
td2.setCode("CSD2");
td2.setName("TEST NAME 2");
dictionaryImdg.insert(td2);
long idIdx = 0;
for (E enumValue : enumValues) {
D td = dictionaryClass.getConstructor().newInstance();
td.setId(idIdx++);
td.setCode(enumValue.getKey());
dictionaryImdg.insert(td);
}
BiFunction<R, Boolean, IValidator> validatorBuilder = (plannerNewRequest, required) -> {
Function<R, IValidator> validatorBuilder = request -> {
ImdgValidationContext<R> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerNewRequest);
context.setValidatedObject(request);
context.addImdg(dictionaryKey, dictionaryImdg);
return new ValidatorImpl<>(context,
DictionaryPresentRule.instance(fieldName,
getter,
dictionaryKey,
dictionaryClass,
required)
dictionaryClass)
);
};
R record = recordClass.getConstructor().newInstance();
IValidator strictValidator = validatorBuilder.apply(record, true);
IValidator lazyValidator = validatorBuilder.apply(record, false);
IValidator validator = validatorBuilder.apply(record);
setter.accept(record, "CSD1");
Collection<EnumMessage> enumMessages = strictValidator.validateAll();
assertTrue(enumMessages.isEmpty());
Collection<EnumMessage> enumMessages;
for (E enumValue : enumValues) {
setter.accept(record, enumValue.getKey());
enumMessages = validator.validateAll();
assertTrue(enumMessages.isEmpty());
}
setter.accept(record, "CSD2");
enumMessages = strictValidator.validateAll();
assertTrue(enumMessages.isEmpty());
setter.accept(record, null);
enumMessages = strictValidator.validateAll();
setter.accept(record, "BAD_VALUE");
enumMessages = validator.validateAll();
assertEquals(1, enumMessages.size());
assertEquals(PlannerErrors.EmptyRequiredValue, enumMessages.iterator().next().getSubject());
enumMessages = lazyValidator.validateAll();
assertTrue(enumMessages.isEmpty());
setter.accept(record, "NOT_CSD");
enumMessages = strictValidator.validateAll();
assertEquals(1, enumMessages.size());
assertEquals(PlannerErrors.WrongEnumValue, enumMessages.iterator().next().getSubject());
enumMessages = lazyValidator.validateAll();
assertEquals(1, enumMessages.size());
assertEquals(PlannerErrors.WrongEnumValue, enumMessages.iterator().next().getSubject());
assertEquals(ValidationError.WrongDictionaryValue, enumMessages.iterator().next().getSubject());
}
}

View file

@ -0,0 +1,97 @@
package ru.specx.clearing.scheduler.validation;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.platform.dictionary.AbstractDictionary;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.clearing.scheduler.validation.rules.common.EnumPresentRule;
import ru.spcex.platform.enumeration.DayStatus;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.enumeration.Task;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import ru.specx.clearing.scheduler.config.HazelcastServiceTestConfiguration;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
HazelcastServiceTestConfiguration.class})
class EnumPresentRuleTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
@Test
public void enumPresentRuleTest() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
testEnum(
PlannerNewRequest.class,
"task",
Task.values(),
PlannerNewRequest::getTask,
PlannerNewRequest::setTask);
testEnum(
PlannerNewRequest.class,
"taskStatus",
Status.values(),
PlannerNewRequest::getTaskStatus,
PlannerNewRequest::setTaskStatus);
testEnum(
ClearingCalendarNewRequest.class,
"dayStatus",
DayStatus.values(),
ClearingCalendarNewRequest::getDayStatus,
ClearingCalendarNewRequest::setDayStatus);
}
private <D extends AbstractDictionary, R, E extends IEnumKey> void testEnum(Class<R> recordClass,
String fieldName,
E[] enumValues,
Function<R, String> getter,
BiConsumer<R, String> setter) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
BiFunction<R, Boolean, IValidator> validatorBuilder = (request, required) -> {
ImdgValidationContext<R> context = new ImdgValidationContext<>();
context.setValidatedObject(request);
return new ValidatorImpl<>(context,
EnumPresentRule.instance(fieldName,
getter,
enumValues,
required)
);
};
R record = recordClass.getConstructor().newInstance();
IValidator strictValidator = validatorBuilder.apply(record, true);
Collection<EnumMessage> enumMessages;
for (E enumValue : enumValues) {
setter.accept(record, enumValue.getKey());
enumMessages = strictValidator.validateAll();
assertTrue(enumMessages.isEmpty());
}
setter.accept(record, "BAD_VALUE");
enumMessages = strictValidator.validateAll();
assertEquals(1, enumMessages.size());
assertEquals(ValidationError.WrongEnumValue, enumMessages.iterator().next().getSubject());
}
}

View file

@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
import ru.spcex.clearing.scheduler.validation.rules.FieldRequiredRule;
import ru.spcex.clearing.scheduler.validation.rules.common.FieldRequiredRule;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator;

View file

@ -0,0 +1,105 @@
package ru.specx.clearing.scheduler.validation;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.security.Security;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
import ru.spcex.clearing.scheduler.error.ValidationError;
import ru.spcex.clearing.scheduler.validation.rules.common.IdPresentRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import ru.specx.clearing.scheduler.config.HazelcastServiceTestConfiguration;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
HazelcastServiceTestConfiguration.class})
class IdPresentRuleTest {
private final static Long TEST_ID = 777L;
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
@Test
public void idPresentRuleTest() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
testIdPresentRule(
"companyId",
PlannerNewRequest::getCompanyId,
PlannerNewRequest::setCompanyId,
IMDGDistributedNames.Map_Company,
Company.class,
PlannerNewRequest.class,
ValidationError.CompanyNotFound,
ValidationError.CompanyNotActive
);
testIdPresentRule(
"securityId",
PlannerNewRequest::getSecurityId,
PlannerNewRequest::setSecurityId,
IMDGDistributedNames.Map_Security,
Security.class,
PlannerNewRequest.class,
ValidationError.SecurityNotFound,
ValidationError.SecurityNotActive
);
}
private <R, D extends SpcexObjectBase> void testIdPresentRule(String fieldName,
Function<R, Long> getter,
BiConsumer<R, Long> setter,
String mapName,
Class<D> mapClass,
Class<R> objClass,
ValidationError notFoundExpectedError,
ValidationError notActiveExpectedError) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Imdg<D> imdg = hazelcastServiceTest.getImdg(mapName, mapClass);
Function<R, IValidator> validatorBuilder = request -> {
ImdgValidationContext<R> context = new ImdgValidationContext<>();
context.setValidatedObject(request);
context.addImdg(mapName, imdg);
return new ValidatorImpl<>(context, IdPresentRule.instance(fieldName,
getter,
mapName,
mapClass,
notFoundExpectedError,
true,
company -> company.getId().equals(TEST_ID) ? null : notActiveExpectedError
));
};
R obj = objClass.getConstructor().newInstance();
setter.accept(obj, TEST_ID);
IValidator validator = validatorBuilder.apply(obj);
Collection<EnumMessage> enumMessages = validator.validateAll();
assertEquals(1, enumMessages.size());
assertEquals(notFoundExpectedError, enumMessages.iterator().next().getSubject());
D map = mapClass.getConstructor().newInstance();
map.setId(TEST_ID);
imdg.insert(map);
enumMessages = validator.validateAll();
assertTrue(enumMessages.isEmpty());
}
}

View file

@ -0,0 +1,49 @@
package ru.specx.clearing.scheduler.validation;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
import ru.spcex.clearing.scheduler.validation.rules.common.TimeNotBeforeRule;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
import java.time.LocalTime;
import java.util.Collection;
import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ExtendWith(SpringExtension.class)
class TimeNotBeforeRuleTest {
@Test
public void timeNotBeforeRuleTest() {
Function<PlannerNewRequest, IValidator> validatorBuilder = plannerNewRequest -> {
ImdgValidationContext<PlannerNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerNewRequest);
return new ValidatorImpl<>(context,
TimeNotBeforeRule.instance("taskTime", PlannerNewRequest::getTaskTime));
};
PlannerNewRequest plannerNewRequest = new PlannerNewRequest();
plannerNewRequest.setTaskTime(LocalTime.now().plusMinutes(1));
IValidator validator = validatorBuilder.apply(plannerNewRequest);
Collection<EnumMessage> enumMessages = validator.validateAll();
assertTrue(enumMessages.isEmpty());
plannerNewRequest.setTaskTime(LocalTime.now().plusSeconds(1));
validator = validatorBuilder.apply(plannerNewRequest);
enumMessages = validator.validateAll();
assertTrue(enumMessages.isEmpty());
plannerNewRequest.setTaskTime(LocalTime.now().minusMinutes(1));
validator = validatorBuilder.apply(plannerNewRequest);
enumMessages = validator.validateAll();
assertEquals(1, enumMessages.size());
}
}

View file

@ -0,0 +1,19 @@
package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum WorkflowStatus implements IEnumKey {
Active("ACTV"),
Blocked("BLKD");
private final String key;
WorkflowStatus(String key) {
this.key = key;
}
@Override
public String getKey() {
return key;
}
}