package jnpf.limsService.impl;
|
|
import jnpf.base.ActionResult;
|
import jnpf.base.UserInfo;
|
import jnpf.eln.RecordFreezeApi;
|
import jnpf.eln.RecordFreezeCheckBatch;
|
import jnpf.eln.RecordFreezeCheckRequest;
|
import jnpf.eln.RecordFreezeCheckResult;
|
import jnpf.eln.RecordFreezeReleaseRequest;
|
import jnpf.exception.DataException;
|
import jnpf.limsEntity.JianyanStatus;
|
import jnpf.limsEntity.LimsJianyanXiangEntity;
|
import org.junit.After;
|
import org.junit.Test;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
import java.util.Collections;
|
import java.util.HashMap;
|
import java.util.Map;
|
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicReference;
|
import java.nio.charset.StandardCharsets;
|
import java.nio.file.Files;
|
import java.nio.file.Paths;
|
|
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.fail;
|
|
public class LimsElnRecordFreezeGateTest {
|
|
@After
|
public void clearSynchronization() {
|
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
TransactionSynchronizationManager.clearSynchronization();
|
}
|
}
|
|
@Test
|
public void allowsItemsWithoutElnRecordAndReleasesNoLease() {
|
AtomicInteger releaseCalls = new AtomicInteger();
|
LimsElnRecordFreezeGate gate = new LimsElnRecordFreezeGate(api(request -> batch("item-1",
|
RecordFreezeCheckResult.NOT_APPLICABLE, null), releaseCalls));
|
TransactionSynchronizationManager.initSynchronization();
|
|
gate.prepareAndReleaseAfterCompletion("tenant-1", user(), Collections.singletonList("item-1"), rows());
|
|
assertEquals(1, TransactionSynchronizationManager.getSynchronizations().size());
|
TransactionSynchronizationManager.getSynchronizations().get(0).afterCompletion(0);
|
assertEquals(1, releaseCalls.get());
|
}
|
|
@Test
|
public void returnsElnReadySubmissionValuesWithoutExposingFieldCatalog() {
|
LimsElnRecordFreezeGate gate = new LimsElnRecordFreezeGate(api(request -> batch("item-1",
|
RecordFreezeCheckResult.READY, "lease-1"), new AtomicInteger()));
|
TransactionSynchronizationManager.initSynchronization();
|
|
Map<String, LimsElnRecordFreezeGate.SubmissionValues> values =
|
gate.prepareAndReleaseAfterCompletion("tenant-1", user(),
|
Collections.singletonList("item-1"), rows());
|
|
assertEquals("ELN 检验结果", values.get("item-1").getTestResult());
|
assertEquals("compliant", values.get("item-1").getTestConclusion());
|
}
|
|
@Test
|
public void usesSingleTenantIdWhenLoginContextHasNoTenant() {
|
AtomicReference<String> preparedTenant = new AtomicReference<>();
|
AtomicReference<String> releasedTenant = new AtomicReference<>();
|
RecordFreezeApi api = new RecordFreezeApi() {
|
@Override
|
public ActionResult<RecordFreezeCheckBatch> prepare(RecordFreezeCheckRequest request) {
|
preparedTenant.set(request.getTenantId());
|
return response(batch("item-1", RecordFreezeCheckResult.NOT_APPLICABLE, null));
|
}
|
|
@Override
|
public ActionResult<Boolean> release(RecordFreezeReleaseRequest request) {
|
releasedTenant.set(request.getTenantId());
|
return response(true);
|
}
|
};
|
TransactionSynchronizationManager.initSynchronization();
|
|
new LimsElnRecordFreezeGate(api).prepareAndReleaseAfterCompletion(
|
"", user(), Collections.singletonList("item-1"), rows());
|
TransactionSynchronizationManager.getSynchronizations().get(0).afterCompletion(0);
|
|
assertEquals("0", preparedTenant.get());
|
assertEquals("0", releasedTenant.get());
|
}
|
|
@Test
|
public void rejectsBlockingDiagnosticsBeforeAnyCallerUpdate() {
|
LimsElnRecordFreezeGate gate = new LimsElnRecordFreezeGate(api(request -> batch("item-1",
|
RecordFreezeCheckResult.BLOCKED, null), new AtomicInteger()));
|
TransactionSynchronizationManager.initSynchronization();
|
try {
|
gate.prepareAndReleaseAfterCompletion("tenant-1", user(), Collections.singletonList("item-1"), rows());
|
fail("expected DataException");
|
} catch (DataException expected) {
|
org.junit.Assert.assertTrue(expected.getMessage().contains("ELN 可冻结校验失败"));
|
}
|
}
|
|
@Test
|
public void failsClosedForRemoteExceptionAndMissingItemResponse() {
|
AtomicInteger releases = new AtomicInteger();
|
LimsElnRecordFreezeGate unavailable = new LimsElnRecordFreezeGate(api(request -> {
|
throw new IllegalStateException("network");
|
}, releases));
|
assertRejected(unavailable, "服务调用失败");
|
assertEquals(1, releases.get());
|
TransactionSynchronizationManager.clearSynchronization();
|
|
LimsElnRecordFreezeGate missing = new LimsElnRecordFreezeGate(api(request -> new RecordFreezeCheckBatch(), new AtomicInteger()));
|
assertRejected(missing, "响应缺少检验项");
|
}
|
|
@Test
|
public void rejectsLostPrepareResponseWithoutRepeatingAuthoritativeCalculation() {
|
AtomicInteger prepares = new AtomicInteger();
|
AtomicInteger releases = new AtomicInteger();
|
RecordFreezeApi api = new RecordFreezeApi() {
|
@Override
|
public ActionResult<RecordFreezeCheckBatch> prepare(RecordFreezeCheckRequest request) {
|
prepares.incrementAndGet();
|
throw new IllegalStateException("timeout");
|
}
|
|
@Override
|
public ActionResult<Boolean> release(RecordFreezeReleaseRequest request) {
|
releases.incrementAndGet();
|
return response(true);
|
}
|
};
|
assertRejected(new LimsElnRecordFreezeGate(api), "服务调用失败");
|
|
assertEquals(1, prepares.get());
|
assertEquals(1, releases.get());
|
}
|
|
@Test
|
public void sourceKeepsFreezeGateBeforeLimsUpdateAndMarksCaughtBusinessErrorsForRollback() throws Exception {
|
String service = new String(Files.readAllBytes(Paths.get(
|
"src/main/java/jnpf/limsService/impl/LimsJianceTaskServiceImpl.java")), StandardCharsets.UTF_8);
|
String submit = service.substring(service.indexOf("public LimsSubmitResultOutcome submitJianyanResult"));
|
assertTrue(submit.indexOf("elnRecordFreezeGate.prepareAndReleaseAfterCompletion")
|
< submit.indexOf("limsJianyanXiangMapper.submitResult("));
|
String controller = new String(Files.readAllBytes(Paths.get(
|
"../jnpf-lims-controller/src/main/java/jnpf/limsController/LimsJianceTaskController.java")), StandardCharsets.UTF_8);
|
assertTrue(controller.contains("TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()"));
|
}
|
|
private void assertRejected(LimsElnRecordFreezeGate gate, String expected) {
|
TransactionSynchronizationManager.initSynchronization();
|
try {
|
gate.prepareAndReleaseAfterCompletion("tenant-1", user(), Collections.singletonList("item-1"), rows());
|
fail("expected DataException");
|
} catch (DataException e) {
|
org.junit.Assert.assertTrue(e.getMessage().contains(expected));
|
}
|
}
|
|
private static RecordFreezeApi api(final PrepareResponder responder, final AtomicInteger releases) {
|
return new RecordFreezeApi() {
|
@Override
|
public ActionResult<RecordFreezeCheckBatch> prepare(RecordFreezeCheckRequest request) {
|
return response(responder.respond(request));
|
}
|
|
@Override
|
public ActionResult<Boolean> release(RecordFreezeReleaseRequest request) {
|
releases.incrementAndGet();
|
return response(true);
|
}
|
};
|
}
|
|
private static <T> ActionResult<T> response(T body) {
|
ActionResult<T> response = new ActionResult<>();
|
response.setCode(200);
|
response.setData(body);
|
return response;
|
}
|
|
private static RecordFreezeCheckBatch batch(String id, String status, String token) {
|
RecordFreezeCheckResult item = new RecordFreezeCheckResult();
|
item.setTestWorkItemId(id);
|
item.setStatus(status);
|
item.setReleaseToken(token);
|
if (RecordFreezeCheckResult.READY.equals(status)) {
|
item.setTestResult("ELN 检验结果");
|
item.setTestConclusion("compliant");
|
}
|
if (RecordFreezeCheckResult.BLOCKED.equals(status)) {
|
jnpf.eln.RecordFreezeIssue issue = new jnpf.eln.RecordFreezeIssue();
|
issue.setCategory("FORMULA");
|
issue.setCode("FREEZE_FORMULA");
|
issue.setMessage("公式未成功");
|
item.getDiagnostics().add(issue);
|
}
|
RecordFreezeCheckBatch batch = new RecordFreezeCheckBatch();
|
batch.getItems().add(item);
|
return batch;
|
}
|
|
private static UserInfo user() {
|
UserInfo user = new UserInfo();
|
user.setUserId("user-1");
|
return user;
|
}
|
|
private static Map<String, LimsJianyanXiangEntity> rows() {
|
LimsJianyanXiangEntity row = new LimsJianyanXiangEntity();
|
row.setId("item-1");
|
row.setJianyanZhuangtai(JianyanStatus.PENDING_TEST.getCode());
|
row.setJianchaRen("user-1");
|
Map<String, LimsJianyanXiangEntity> rows = new HashMap<>();
|
rows.put(row.getId(), row);
|
return rows;
|
}
|
|
@FunctionalInterface
|
private interface PrepareResponder {
|
RecordFreezeCheckBatch respond(RecordFreezeCheckRequest request);
|
}
|
}
|