FieldRequiredRule, tests for DictionaryPresentRule

This commit is contained in:
akulikov 2023-01-17 12:45:31 +03:00
parent 5167eb45f0
commit a6100aca8f
11 changed files with 252 additions and 55 deletions

View file

@ -5,7 +5,7 @@ import org.springframework.context.annotation.Configuration;
import ru.clearing.platform.dictionary.TaskDictionary;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerNewRequest;
import ru.spcex.clearing.scheduler.validation.rules.EnumPresentRule;
import ru.spcex.clearing.scheduler.validation.rules.DictionaryPresentRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -44,10 +44,11 @@ public class ValidationConfig {
Consumer<String> addImdg = (s) -> context.addImdg(s, getImdg(s));
addImdg.accept(IMDGDistributedNames.Map_TaskDictionary);
return new ValidatorImpl<>(context,
EnumPresentRule.instance("task",
DictionaryPresentRule.instance("task",
PlannerNewRequest::getTask,
IMDGDistributedNames.Map_TaskDictionary,
TaskDictionary.class)
TaskDictionary.class,
true)
);
};
}

View file

@ -4,6 +4,7 @@ import ru.spcex.platform.utils.enumeration.IEnumId;
public enum PlannerErrors implements IEnumId {
WrongEnumValue(10003L),
EmptyRequiredValue(10002L)
;
private final Long id;

View file

@ -15,7 +15,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteReques
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.ClearingCalendarUpdateRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.scheduler.IRequestValidator;
import ru.spcex.clearing.scheduler.validation.IRequestValidator;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;

View file

@ -18,8 +18,8 @@ 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.IRequestValidator;
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;
import ru.spcex.platform.utils.enumeration.EnumMessage;

View file

@ -15,7 +15,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteReques
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateUpdateRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.scheduler.IRequestValidator;
import ru.spcex.clearing.scheduler.validation.IRequestValidator;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;

View file

@ -1,4 +1,4 @@
package ru.spcex.clearing.scheduler;
package ru.spcex.clearing.scheduler.validation;
import org.slf4j.Logger;
import ru.clearing.platform.dictionary.AbstractDictionary;

View file

@ -0,0 +1,45 @@
package ru.spcex.clearing.scheduler.validation.rules;
import ru.clearing.platform.dictionary.AbstractDictionary;
import ru.spcex.clearing.scheduler.error.PlannerErrors;
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 DictionaryPresentRule<R, D extends AbstractDictionary>(String fieldName,
Function<R, String> getEnumCode,
String dictionaryName,
Class<D> enumClass,
boolean required) implements IValidationRule<ImdgValidationContext<R>> {
public static <R, D extends AbstractDictionary> DictionaryPresentRule<R, D> instance(String fieldName,
Function<R, String> getEnumCode,
String dictionaryName,
Class<D> enumClass,
boolean required) {
return new DictionaryPresentRule<>(fieldName, getEnumCode, dictionaryName, enumClass, required);
}
@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();
}
Imdg<D> dictImdg = context.obtainMap(
dictionaryName,
enumClass
);
D dictionaryFromMap = dictImdg.getSingleObjectByFieldValues(Map.of("code", enumCode));
if (dictionaryFromMap == null) {
return of(PlannerErrors.WrongEnumValue, fieldName);
}
return empty();
}
}

View file

@ -1,48 +0,0 @@
package ru.spcex.clearing.scheduler.validation.rules;
import ru.spcex.clearing.scheduler.error.PlannerErrors;
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 class EnumPresentRule<T, D extends SpcexObjectBase> implements IValidationRule<ImdgValidationContext<T>> {
protected final Function<T, String> getEnumCode;
protected final String dictionaryName;
protected final String fieldName;
protected final Class<D> enumClass;
public EnumPresentRule(String fieldName, Function<T, String> getEnumCode, String dictionaryName, Class<D> enumClass) {
this.fieldName = fieldName;
this.getEnumCode = getEnumCode;
this.dictionaryName = dictionaryName;
this.enumClass = enumClass;
}
public static <T1, D1 extends SpcexObjectBase> EnumPresentRule<T1, D1> instance(String fieldName,
Function<T1, String> getEnumCode,
String dictionaryName,
Class<D1> enumClass) {
return new EnumPresentRule<>(fieldName, getEnumCode, dictionaryName, enumClass);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<T> context) {
T validatedObject = context.getValidatedObject();
String enumCode = getEnumCode.apply(validatedObject);
Imdg<D> dictImdg = context.obtainMap(
dictionaryName,
enumClass
);
D taskFromMap = dictImdg.getSingleObjectByFieldValues(Map.of("code", enumCode));
if (taskFromMap == null) {
return of(PlannerErrors.WrongEnumValue, fieldName);
}
return empty();
}
}

View file

@ -0,0 +1,24 @@
package ru.spcex.clearing.scheduler.validation.rules;
import ru.spcex.clearing.scheduler.error.PlannerErrors;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Optional;
import java.util.function.Function;
public record FieldRequiredRule<R, V>(String fieldName, Function<R, V> getter) implements IValidationRule<ImdgValidationContext<R>> {
public static <R, V> FieldRequiredRule<R, V> instance(String fieldName, Function<R, V> getter) {
return new FieldRequiredRule<>(fieldName, getter);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
V value = getter.apply(validatedObject);
if (value == null) return of(PlannerErrors.EmptyRequiredValue, fieldName);
return empty();
}
}

View file

@ -0,0 +1,130 @@
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.clearing.platform.dictionary.DayStatusDictionary;
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.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.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.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 DictionaryPresentRuleTest {
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
@Test
public void dictionaryPresentRuleTest() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
testDictionary(IMDGDistributedNames.Map_TaskDictionary,
TaskDictionary.class,
PlannerNewRequest.class,
"task",
PlannerNewRequest::getTask,
PlannerNewRequest::setTask);
testDictionary(IMDGDistributedNames.Map_TaskStatusDictionary,
TaskStatusDictionary.class,
PlannerNewRequest.class,
"taskStatus",
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",
ClearingCalendarNewRequest::getDayStatus,
ClearingCalendarNewRequest::setDayStatus);
}
private <D extends AbstractDictionary, R> void testDictionary(String dictionaryKey,
Class<D> dictionaryClass,
Class<R> recordClass,
String fieldName,
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);
BiFunction<R, Boolean, IValidator> validatorBuilder = (plannerNewRequest, required) -> {
ImdgValidationContext<R> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerNewRequest);
context.addImdg(dictionaryKey, dictionaryImdg);
return new ValidatorImpl<>(context,
DictionaryPresentRule.instance(fieldName,
getter,
dictionaryKey,
dictionaryClass,
required)
);
};
R record = recordClass.getConstructor().newInstance();
IValidator strictValidator = validatorBuilder.apply(record, true);
IValidator lazyValidator = validatorBuilder.apply(record, false);
setter.accept(record, "CSD1");
Collection<EnumMessage> enumMessages = strictValidator.validateAll();
assertTrue(enumMessages.isEmpty());
setter.accept(record, "CSD2");
enumMessages = strictValidator.validateAll();
assertTrue(enumMessages.isEmpty());
setter.accept(record, null);
enumMessages = strictValidator.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());
}
}

View file

@ -0,0 +1,44 @@
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.FieldRequiredRule;
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.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 FieldRequiredRuleTest {
@Test
public void fieldRequiredRuleTest() {
Function<PlannerNewRequest, IValidator> validatorBuilder = plannerNewRequest -> {
ImdgValidationContext<PlannerNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(plannerNewRequest);
return new ValidatorImpl<>(context,
new FieldRequiredRule<>("task", PlannerNewRequest::getTask)
);
};
PlannerNewRequest plannerNewRequest = new PlannerNewRequest();
plannerNewRequest.setTask("test");
IValidator validator = validatorBuilder.apply(plannerNewRequest);
Collection<EnumMessage> enumMessages = validator.validateAll();
assertTrue(enumMessages.isEmpty());
plannerNewRequest.setTask(null);
validator = validatorBuilder.apply(plannerNewRequest);
enumMessages = validator.validateAll();
assertEquals(1, enumMessages.size());
}
}