package jnpf.elnService.impl;
|
|
import jnpf.elnEntity.runtime.ElnRecordEntity;
|
import jnpf.elnEntity.runtime.ElnRecordFieldValueEntity;
|
import jnpf.elnEntity.runtime.ElnRecordFormulaCalculationResult;
|
import jnpf.elnEntity.runtime.ElnRecordRepeatValueEntity;
|
import jnpf.elnEntity.runtime.ElnRecordForms;
|
import jnpf.elnEntity.runtime.ElnRecordRevisionEntity;
|
import jnpf.elnEntity.runtime.ElnRecordVos;
|
import jnpf.elnMapper.ElnRecordFieldValueMapper;
|
import jnpf.elnMapper.ElnRecordMapper;
|
import jnpf.elnMapper.ElnRecordRepeatValueMapper;
|
import jnpf.elnMapper.ElnRecordRevisionMapper;
|
import jnpf.elnService.ElnRecordFormulaCalculationService;
|
import jnpf.lims.api.model.TestWorkItemSnapshotBatch;
|
import jnpf.lims.api.model.TestWorkItemSnapshot;
|
import org.junit.Test;
|
|
import java.lang.reflect.Proxy;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import static org.junit.Assert.assertEquals;
|
|
public class ElnRecordRecalculationServiceImplTest {
|
|
@Test
|
public void protectsFullRecalculationWithTaskAccessAndRecordVersion() {
|
ElnRecordEntity record = new ElnRecordEntity();
|
record.setId("record-1");
|
record.setJianyanXiangId("item-1");
|
record.setDangqianXiudingId("revision-1");
|
record.setFVersion(7);
|
ElnRecordRevisionEntity revision = new ElnRecordRevisionEntity();
|
revision.setId("revision-1");
|
revision.setDianziJiluId("record-1");
|
revision.setBizStatus("DRAFT");
|
List<ElnRecordFieldValueEntity> values = Arrays.asList(
|
calculated("result-a", "SUCCESS"),
|
calculated("result-b", "MISSING_INPUT"),
|
calculated("result-c", "ERROR"));
|
AtomicInteger casCalls = new AtomicInteger();
|
AtomicInteger updates = new AtomicInteger();
|
AtomicInteger repeatUpdates = new AtomicInteger();
|
ElnRecordMapper recordMapper = proxy(ElnRecordMapper.class, (method, args) -> {
|
if ("selectOne".equals(method)) return record;
|
if ("advanceVersion".equals(method)) {
|
assertEquals(7, args[2]);
|
casCalls.incrementAndGet();
|
return 1;
|
}
|
return null;
|
});
|
ElnRecordRevisionMapper revisionMapper = proxy(
|
ElnRecordRevisionMapper.class,
|
(method, args) -> "selectOne".equals(method) ? revision : null);
|
ElnRecordFieldValueMapper valueMapper = proxy(
|
ElnRecordFieldValueMapper.class, (method, args) -> {
|
if ("selectList".equals(method)) return new ArrayList<>(values);
|
if ("updateById".equals(method)) {
|
updates.incrementAndGet();
|
return 1;
|
}
|
return null;
|
});
|
ElnRecordFormulaCalculationService calculation =
|
new ElnRecordFormulaCalculationService() {
|
@Override
|
public List<ElnRecordFieldValueEntity> recalculateAffected(
|
String tenantId, ElnRecordEntity record,
|
ElnRecordRevisionEntity revision,
|
List<ElnRecordFieldValueEntity> values,
|
java.util.Set<String> changedBindingIds,
|
String operationCode, String operatorUserId) {
|
return Collections.emptyList();
|
}
|
|
@Override
|
public List<ElnRecordFieldValueEntity> recalculateAll(
|
String tenantId, ElnRecordEntity actualRecord,
|
ElnRecordRevisionEntity actualRevision,
|
List<ElnRecordFieldValueEntity> actualValues,
|
String operationCode, String operatorUserId) {
|
assertEquals("tenant-a", tenantId);
|
assertEquals("operation-1", operationCode);
|
assertEquals("user-1", operatorUserId);
|
return actualValues;
|
}
|
|
@Override
|
public ElnRecordFormulaCalculationResult recalculateAllWithRepeats(
|
String tenantId, ElnRecordEntity actualRecord,
|
ElnRecordRevisionEntity actualRevision,
|
List<ElnRecordFieldValueEntity> actualValues,
|
String operationCode, String operatorUserId) {
|
ElnRecordFormulaCalculationResult result =
|
new ElnRecordFormulaCalculationResult();
|
result.setFieldValues(actualValues);
|
ElnRecordRepeatValueEntity repeat = new ElnRecordRepeatValueEntity();
|
repeat.setJisuanZhuangtai("SUCCESS");
|
result.setRepeatValues(Collections.singletonList(repeat));
|
return result;
|
}
|
};
|
ElnRecordRepeatValueMapper repeatValueMapper = proxy(
|
ElnRecordRepeatValueMapper.class, (method, args) -> {
|
if ("updateById".equals(method)) {
|
repeatUpdates.incrementAndGet();
|
return 1;
|
}
|
return null;
|
});
|
ElnRecordRecalculationServiceImpl service =
|
new ElnRecordRecalculationServiceImpl(
|
recordMapper, revisionMapper, valueMapper, repeatValueMapper,
|
(itemIds, properties) -> successfulTask(), calculation,
|
() -> new ElnRecordRecalculationServiceImpl.UserContext(
|
"tenant-a", "user-1"));
|
ElnRecordForms.Recalculate command = new ElnRecordForms.Recalculate();
|
command.setExpectedRecordVersion(7);
|
command.setOperationCode("operation-1");
|
|
ElnRecordVos.Recalculated result = service.recalculateAll("record-1", command);
|
|
assertEquals(Integer.valueOf(8), result.getRecordVersion());
|
assertEquals(2, result.getSuccessCount());
|
assertEquals(1, result.getMissingInputCount());
|
assertEquals(1, result.getErrorCount());
|
assertEquals(1, casCalls.get());
|
assertEquals(3, updates.get());
|
assertEquals(1, repeatUpdates.get());
|
}
|
|
private static ElnRecordFieldValueEntity calculated(String bindingId, String status) {
|
ElnRecordFieldValueEntity value = new ElnRecordFieldValueEntity();
|
value.setMubanBangdingId(bindingId);
|
value.setJisuanZhuangtai(status);
|
return value;
|
}
|
|
private static TestWorkItemSnapshotBatch successfulTask() {
|
TestWorkItemSnapshot item = new TestWorkItemSnapshot();
|
item.setTestWorkItemId("item-1");
|
item.setOutcomeCode("SUCCESS");
|
TestWorkItemSnapshotBatch batch = new TestWorkItemSnapshotBatch();
|
batch.setItems(Collections.singletonList(item));
|
return batch;
|
}
|
|
@SuppressWarnings("unchecked")
|
private static <T> T proxy(Class<T> type, Invocation invocation) {
|
return (T) Proxy.newProxyInstance(type.getClassLoader(), new Class<?>[]{type},
|
(target, method, args) -> {
|
if (method.getDeclaringClass() == Object.class) {
|
if ("toString".equals(method.getName())) return type.getSimpleName();
|
if ("hashCode".equals(method.getName())) return System.identityHashCode(target);
|
if ("equals".equals(method.getName())) return target == args[0];
|
}
|
Object result = invocation.invoke(method.getName(), args);
|
if (result != null || !method.getReturnType().isPrimitive()) return result;
|
if (method.getReturnType() == boolean.class) return false;
|
return 0;
|
});
|
}
|
|
@FunctionalInterface
|
private interface Invocation {
|
Object invoke(String method, Object[] args);
|
}
|
}
|