|
|
|
|
@ -54,11 +54,13 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
"/api/v1/institution-identifiers/transaction-information-identifiers";
|
|
|
|
|
private static final String QUOTA_BASE_PATH =
|
|
|
|
|
"/api/v1/institution-identifiers/quota-requests";
|
|
|
|
|
private static final String CENTRAL_QUOTA_REQUEST_BASE_PATH =
|
|
|
|
|
"/api/v1/institution-identifiers/central-bank/quota-requests";
|
|
|
|
|
private static final String VERIFICATION_BASE_PATH =
|
|
|
|
|
"/api/v1/institution-identifiers/quota-verifications";
|
|
|
|
|
private static final String CONTROL_SIGNATURE_BASE_PATH =
|
|
|
|
|
"/api/v1/institution-identifiers/control-system-signatures";
|
|
|
|
|
private static final String BANK_CONTROL_SIGNATURE_BASE_PATH =
|
|
|
|
|
private static final String COMMERCIAL_BANK_CONTROL_SIGNATURE_BASE_PATH =
|
|
|
|
|
"/api/v1/institution-identifiers/commercial-bank/control-system-signatures";
|
|
|
|
|
private static final String QUOTA_CONTROL_BASE_PATH =
|
|
|
|
|
"/api/v1/institution-identifiers/quota-control-bits";
|
|
|
|
|
@ -111,8 +113,12 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void rejectsModuleFourWhenStepThreeHasNotReturnedResponse() throws Exception {
|
|
|
|
|
void rejectsDigestWhenStepThreeHasNotReturnedResponseAndPrepareRouteIsRemoved() throws Exception {
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/prepare").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isNotFound());
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"1589.85|ORG_3A4B5C6D7E8F|20260730153330\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString(
|
|
|
|
|
"步骤三尚未完成确认报文返回")));
|
|
|
|
|
@ -120,43 +126,50 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void flowsCompletedPreviousDataAndPersistsEveryModuleFourStep() throws Exception {
|
|
|
|
|
PrecedingData preceding = insertCompletedPrecedingData();
|
|
|
|
|
void recordsEveryConcatenationErrorAndReturnsFixedMessage() throws Exception {
|
|
|
|
|
insertCompletedPrecedingData();
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"1589.85[ORG_3A4B5C6D7E8F|20260730153330\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value("数据拼接错误"));
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"999.00|ORG_3A4B5C6D7E8F|20260730153330\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value("数据拼接错误"));
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/prepare").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("PREPARED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.verificationId").value(preceding.verificationId))
|
|
|
|
|
.andExpect(jsonPath("$.data.requestId").value(preceding.requestId))
|
|
|
|
|
.andExpect(jsonPath("$.data.identifierApplicationId").value(preceding.applicationId))
|
|
|
|
|
.andExpect(jsonPath("$.data.amount").value(1589.85))
|
|
|
|
|
.andExpect(jsonPath("$.data.institutionIdentifier").value("ORG_3A4B5C6D7E8F"))
|
|
|
|
|
.andExpect(jsonPath("$.data.transactionTimestamp")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("\\d{14}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.originalText")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern(
|
|
|
|
|
"1589\\.85\\|ORG_3A4B5C6D7E8F\\|\\d{14}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.digest").value(org.hamcrest.Matchers.nullValue()))
|
|
|
|
|
.andExpect(jsonPath("$.data.transactionIdentifier")
|
|
|
|
|
.value(org.hamcrest.Matchers.nullValue()));
|
|
|
|
|
assertThat(transactionMapper.selectList(null)).isEmpty();
|
|
|
|
|
StuModuleScoreDetailsEntity score = scoreMapper.selectOne(
|
|
|
|
|
new LambdaQueryWrapper<StuModuleScoreDetailsEntity>()
|
|
|
|
|
.eq(StuModuleScoreDetailsEntity::getUserId, USER_ID)
|
|
|
|
|
.eq(StuModuleScoreDetailsEntity::getSerialNumber, 3));
|
|
|
|
|
assertThat(score).isNotNull();
|
|
|
|
|
assertThat(score.getCompletionStatus()).isEqualTo("2");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/assemble").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString(
|
|
|
|
|
"请先使用SM3生成摘要")));
|
|
|
|
|
@Test
|
|
|
|
|
void flowsCompletedPreviousDataAndPersistsEveryModuleFourStep() throws Exception {
|
|
|
|
|
PrecedingData preceding = insertCompletedPrecedingData();
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization))
|
|
|
|
|
String originalText = "1589.85|ORG_3A4B5C6D7E8F|20260730153330";
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"" + originalText + "\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("DIGESTED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.digestAlgorithm").value("SM3"))
|
|
|
|
|
.andExpect(jsonPath("$.data.digest")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")));
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.originalText").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.transactionTimestamp").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.digestAlgorithm").doesNotExist());
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/assemble").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("ASSEMBLED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.transactionIdentifier")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("TXN_[0-9A-F]{64}")));
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("TXN_[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.digest").doesNotExist());
|
|
|
|
|
|
|
|
|
|
mvc.perform(get(BASE_PATH).header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
@ -172,15 +185,15 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
assertThat(persisted.getIdentifierApplicationId()).isEqualTo(preceding.applicationId);
|
|
|
|
|
assertThat(persisted.getAmount()).isEqualByComparingTo("1589.85");
|
|
|
|
|
assertThat(persisted.getInstitutionIdentifier()).isEqualTo("ORG_3A4B5C6D7E8F");
|
|
|
|
|
assertThat(persisted.getOriginalText()).isEqualTo("1589.85|ORG_3A4B5C6D7E8F|"
|
|
|
|
|
+ persisted.getTransactionTimestamp());
|
|
|
|
|
assertThat(persisted.getDigest()).matches("[0-9A-F]{64}");
|
|
|
|
|
assertThat(persisted.getOriginalText()).isEqualTo(originalText);
|
|
|
|
|
assertThat(persisted.getTransactionTimestamp()).isEqualTo("20260730153330");
|
|
|
|
|
assertThat(persisted.getDigest()).isEqualTo(cryptography.sm3(originalText));
|
|
|
|
|
assertThat(persisted.getTransactionIdentifier()).isEqualTo("TXN_" + persisted.getDigest());
|
|
|
|
|
assertThat(persisted.getStatus()).isEqualTo("ASSEMBLED");
|
|
|
|
|
|
|
|
|
|
assertThat(transactionLogMapper.selectList(null))
|
|
|
|
|
.extracting(TransactionInformationIdentifierOperationLogEntity::getOperation)
|
|
|
|
|
.containsExactly("PREPARE", "DIGEST", "ASSEMBLE");
|
|
|
|
|
.containsExactly("DIGEST", "ASSEMBLE");
|
|
|
|
|
|
|
|
|
|
StuModuleScoreDetailsEntity score = scoreMapper.selectOne(
|
|
|
|
|
new LambdaQueryWrapper<StuModuleScoreDetailsEntity>()
|
|
|
|
|
@ -192,11 +205,11 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void flowsModuleFourOutputIntoCompleteQuotaRequestWorkflow() throws Exception {
|
|
|
|
|
void flowsCompleteStepFiveFromSourceDataThroughCentralBankReceive() throws Exception {
|
|
|
|
|
insertCompletedPrecedingData();
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/prepare").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization))
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"1589.85|ORG_3A4B5C6D7E8F|20260730153330\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/assemble").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
@ -207,126 +220,240 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
.andExpect(jsonPath("$.data.institutionIdentifier").value("ORG_3A4B5C6D7E8F"))
|
|
|
|
|
.andExpect(jsonPath("$.data.transactionIdentifier")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("TXN_[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaRequestId").doesNotExist());
|
|
|
|
|
TransactionInformationIdentifierEntity sourceDataRecord = transactionMapper.selectList(null).get(0);
|
|
|
|
|
assertThat(sourceDataRecord.getStatus()).isEqualTo("ASSEMBLED");
|
|
|
|
|
assertThat(sourceDataRecord.getQuotaRequestId()).isNull();
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(3))
|
|
|
|
|
.andExpect(jsonPath("$.data.transactionIdentifierExists").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.conclusion").doesNotExist());
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/prepare").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isNotFound());
|
|
|
|
|
String quotaOriginalText = "1589.85|ORG_3A4B5C6D7E8F|"
|
|
|
|
|
+ transactionMapper.selectList(null).get(0).getTransactionIdentifier();
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"" + quotaOriginalText + "\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("QUOTA_PREPARED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.amount").value(1589.85))
|
|
|
|
|
.andExpect(jsonPath("$.data.institutionIdentifier").value("ORG_3A4B5C6D7E8F"))
|
|
|
|
|
.andExpect(jsonPath("$.data.transactionIdentifier")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("TXN_[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaRequestId")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("QR_\\d{8}_\\d{3}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaOriginalText")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern(
|
|
|
|
|
"1589\\.85\\|ORG_3A4B5C6D7E8F\\|TXN_[0-9A-F]{64}")));
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/digest").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("QUOTA_DIGESTED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaDigest")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")));
|
|
|
|
|
|
|
|
|
|
com.yau.digitalrmb.institutionidentity.application.InstitutionKeyPairResult bankKey =
|
|
|
|
|
keyService.commercialBankKey(
|
|
|
|
|
new InstitutionKeySubject(USER_ID, SCHOOL_ID, CLASS_ID), "module-four-tester");
|
|
|
|
|
String bankPublicKey = bankKey.getPublicKey();
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/sign")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.andExpect(jsonPath("$.data.digest").value(
|
|
|
|
|
org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1))
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaRequestId").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaOriginalText").doesNotExist());
|
|
|
|
|
|
|
|
|
|
InstitutionKeySubject subject = new InstitutionKeySubject(USER_ID, SCHOOL_ID, CLASS_ID);
|
|
|
|
|
String bankPrivateKey = keyService.commercialBankKey(subject, "module-four-tester").getPrivateKey();
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/sign").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"WRONG_BANK_PRIVATE_KEY\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("第1次错误")));
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/sign")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.content("{\"privateKey\":\"" + bankPrivateKey + "\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.signature").value(
|
|
|
|
|
org.hamcrest.Matchers.matchesPattern("[0-9A-F]+")))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1))
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaSigningKeyId").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaSignature").doesNotExist());
|
|
|
|
|
long stepFiveRecordId = transactionMapper.selectList(null).get(0).getId();
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"" + bankKey.getPrivateKey() + "\"}"))
|
|
|
|
|
.content("{\"originalText\":\"" + quotaOriginalText + "\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("QUOTA_SIGNED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaSigningKeyId").value("BANK_SECOND_SM2_KEY"))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaSignature")
|
|
|
|
|
.value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]+")));
|
|
|
|
|
|
|
|
|
|
.andExpect(jsonPath("$.data.digest").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")));
|
|
|
|
|
assertThat(transactionMapper.selectList(null)).hasSize(1);
|
|
|
|
|
assertThat(transactionMapper.selectList(null).get(0).getId()).isEqualTo(stepFiveRecordId);
|
|
|
|
|
assertThat(transactionMapper.selectList(null).get(0).getQuotaSignature()).isNull();
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/sign").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"" + bankPrivateKey + "\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/sign").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"" + bankPrivateKey + "\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.signature").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]+")));
|
|
|
|
|
assertThat(transactionMapper.selectList(null)).hasSize(1);
|
|
|
|
|
assertThat(transactionMapper.selectList(null).get(0).getId()).isEqualTo(stepFiveRecordId);
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/package").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("QUOTA_PACKAGED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaRequestMessage")
|
|
|
|
|
.value(org.hamcrest.Matchers.containsString("\"quotaRequestId\"")))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaRequestMessage")
|
|
|
|
|
.value(org.hamcrest.Matchers.containsString("\"txnId\"")));
|
|
|
|
|
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(6))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaRequestId").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.amount").value(1589.85))
|
|
|
|
|
.andExpect(jsonPath("$.data.orgId").value("ORG_3A4B5C6D7E8F"))
|
|
|
|
|
.andExpect(jsonPath("$.data.txnId").value(org.hamcrest.Matchers.startsWith("TXN_")))
|
|
|
|
|
.andExpect(jsonPath("$.data.digest").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.signature").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaRequestMessage").doesNotExist());
|
|
|
|
|
mvc.perform(get(CENTRAL_QUOTA_REQUEST_BASE_PATH).header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value(1))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(7));
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/send").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("QUOTA_RECEIVED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.centralBankReceiveStatus").value("RECEIVED"));
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/verify")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"publicKey\":\"WRONG_BANK_PUBLIC_KEY\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("第2次错误")));
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/verify")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"publicKey\":\"" + bankPublicKey + "\"}"))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(6))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaRequestId").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.amount").value(1589.85))
|
|
|
|
|
.andExpect(jsonPath("$.data.orgId").value("ORG_3A4B5C6D7E8F"))
|
|
|
|
|
.andExpect(jsonPath("$.data.txnId").value(org.hamcrest.Matchers.startsWith("TXN_")))
|
|
|
|
|
.andExpect(jsonPath("$.data.digest").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.signature").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.centralBankReceiveStatus").doesNotExist());
|
|
|
|
|
mvc.perform(get(QUOTA_BASE_PATH).header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("QUOTA_VERIFIED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.signatureValid").value(true))
|
|
|
|
|
.andExpect(jsonPath("$.data.h1EqualsH2").value(true))
|
|
|
|
|
.andExpect(jsonPath("$.data.h1").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.h2").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.conclusion").value("一致,验签通过"));
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(6));
|
|
|
|
|
mvc.perform(get(CENTRAL_QUOTA_REQUEST_BASE_PATH).header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value(2))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaRequestId").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.amount").value(1589.85))
|
|
|
|
|
.andExpect(jsonPath("$.data.orgId").value("ORG_3A4B5C6D7E8F"))
|
|
|
|
|
.andExpect(jsonPath("$.data.txnId").value(org.hamcrest.Matchers.startsWith("TXN_")))
|
|
|
|
|
.andExpect(jsonPath("$.data.digest").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.signature").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(7))
|
|
|
|
|
.andExpect(jsonPath("$.data.requestMessage").doesNotExist());
|
|
|
|
|
mvc.perform(post(CENTRAL_QUOTA_REQUEST_BASE_PATH + "/steps/receive")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isNotFound());
|
|
|
|
|
|
|
|
|
|
TransactionInformationIdentifierEntity persisted = transactionMapper.selectList(null).get(0);
|
|
|
|
|
assertThat(persisted.getQuotaOriginalText()).isEqualTo(persisted.getAmount().toPlainString() + "|"
|
|
|
|
|
+ persisted.getInstitutionIdentifier() + "|" + persisted.getTransactionIdentifier());
|
|
|
|
|
assertThat(persisted.getQuotaDigest()).matches("[0-9A-F]{64}");
|
|
|
|
|
assertThat(persisted.getQuotaSigningKeyId()).isEqualTo(InstitutionKeyService.BANK_SECOND_KEY);
|
|
|
|
|
assertThat(persisted.getStatus()).isEqualTo("QUOTA_RECEIVED");
|
|
|
|
|
assertThat(persisted.getQuotaDigest()).isEqualTo(cryptography.sm3(persisted.getQuotaOriginalText()));
|
|
|
|
|
assertThat(cryptography.verify(keyService.commercialBankKey(subject, "module-four-tester").getPublicKey(),
|
|
|
|
|
persisted.getQuotaDigest(), persisted.getQuotaSignature())).isTrue();
|
|
|
|
|
assertThat(persisted.getQuotaRequestMessage()).contains(persisted.getQuotaRequestId(),
|
|
|
|
|
persisted.getTransactionIdentifier(), persisted.getQuotaDigest(), persisted.getQuotaSignature());
|
|
|
|
|
assertThat(persisted.getQuotaRecomputedDigest()).isEqualTo(persisted.getQuotaDigest());
|
|
|
|
|
assertThat(persisted.getQuotaSignatureDigest()).isEqualTo(persisted.getQuotaDigest());
|
|
|
|
|
assertThat(persisted.getQuotaSignatureValid()).isTrue();
|
|
|
|
|
assertThat(persisted.getQuotaDigestMatches()).isTrue();
|
|
|
|
|
assertThat(persisted.getStatus()).isEqualTo("QUOTA_VERIFIED");
|
|
|
|
|
|
|
|
|
|
persisted.getQuotaDigest(), persisted.getQuotaSignature());
|
|
|
|
|
assertThat(transactionLogMapper.selectList(null))
|
|
|
|
|
.extracting(TransactionInformationIdentifierOperationLogEntity::getOperation)
|
|
|
|
|
.containsExactly("PREPARE", "DIGEST", "ASSEMBLE", "QUOTA_PREPARE", "QUOTA_DIGEST",
|
|
|
|
|
"QUOTA_SIGN", "QUOTA_PACKAGE", "QUOTA_SEND", "QUOTA_RECEIVE", "QUOTA_VERIFY");
|
|
|
|
|
.containsExactly("DIGEST", "ASSEMBLE", "QUOTA_DIGEST", "QUOTA_SIGN",
|
|
|
|
|
"QUOTA_DIGEST", "QUOTA_SIGN", "QUOTA_SIGN",
|
|
|
|
|
"QUOTA_PACKAGE", "QUOTA_SEND");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void flowsStepSixDataThroughCentralBankSignatureAndCommercialBankReceive() throws Exception {
|
|
|
|
|
flowsModuleFourOutputIntoCompleteQuotaRequestWorkflow();
|
|
|
|
|
flowsCompleteStepFiveFromSourceDataThroughCentralBankReceive();
|
|
|
|
|
InstitutionKeySubject subject = new InstitutionKeySubject(USER_ID, SCHOOL_ID, CLASS_ID);
|
|
|
|
|
String bankPublicKey = keyService.commercialBankKey(subject, "module-four-tester").getPublicKey();
|
|
|
|
|
String centralPrivateKey = keyService.centralBankKey(subject, "module-four-tester").getPrivateKey();
|
|
|
|
|
|
|
|
|
|
String firstPrepare = mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/prepare")
|
|
|
|
|
String verificationOriginalText = transactionMapper.selectList(null).get(0).getQuotaOriginalText();
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/concatenate-original-text")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("PREPARED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.amount").value(1589.85))
|
|
|
|
|
.andExpect(jsonPath("$.data.institutionIdentifier").value("ORG_3A4B5C6D7E8F"))
|
|
|
|
|
.andExpect(jsonPath("$.data.controlId").value(org.hamcrest.Matchers.matchesPattern(
|
|
|
|
|
"CTRL_\\d{8}_\\d{3}")))
|
|
|
|
|
.andReturn().getResponse().getContentAsString();
|
|
|
|
|
String repeatedPrepare = mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/prepare")
|
|
|
|
|
.andExpect(jsonPath("$.data.originalText").value(verificationOriginalText))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1));
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/hash")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"" + verificationOriginalText + "\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.h1").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.h2").doesNotExist());
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/recover-signature-digest")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"publicKey\":\"WRONG_BANK_SECOND_PUBLIC_KEY\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("第1次错误")));
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/recover-signature-digest")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"publicKey\":\"" + bankPublicKey + "\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.h2").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.h1").doesNotExist());
|
|
|
|
|
long stepSixRecordId = transactionMapper.selectList(null).get(0).getId();
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/hash")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"" + verificationOriginalText + "\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
assertThat(transactionMapper.selectList(null)).hasSize(1);
|
|
|
|
|
assertThat(transactionMapper.selectList(null).get(0).getId()).isEqualTo(stepSixRecordId);
|
|
|
|
|
assertThat(transactionMapper.selectList(null).get(0).getQuotaSignatureDigest()).isNull();
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/recover-signature-digest")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"publicKey\":\"" + bankPublicKey + "\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/recover-signature-digest")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"publicKey\":\"" + bankPublicKey + "\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
assertThat(transactionMapper.selectList(null)).hasSize(1);
|
|
|
|
|
assertThat(transactionMapper.selectList(null).get(0).getId()).isEqualTo(stepSixRecordId);
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/compare-digests")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
|
|
|
|
|
assertThat(com.jayway.jsonpath.JsonPath.<Number>read(repeatedPrepare, "$.data.id").longValue())
|
|
|
|
|
.isEqualTo(com.jayway.jsonpath.JsonPath.<Number>read(firstPrepare, "$.data.id").longValue());
|
|
|
|
|
assertThat(controlSignatureMapper.selectList(null)).hasSize(1);
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.h1EqualsH2").value(true))
|
|
|
|
|
.andExpect(jsonPath("$.data.conclusion").value("一致,验签通过"));
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/digest").header("Authorization", authorization))
|
|
|
|
|
TransactionInformationIdentifierEntity verified = transactionMapper.selectList(null).get(0);
|
|
|
|
|
assertThat(verified.getStatus()).isEqualTo("QUOTA_VERIFIED");
|
|
|
|
|
assertThat(verified.getQuotaRecomputedDigest()).isEqualTo(
|
|
|
|
|
cryptography.sm3(verified.getQuotaOriginalText()));
|
|
|
|
|
assertThat(verified.getQuotaSignatureDigest()).isEqualTo(verified.getQuotaDigest());
|
|
|
|
|
assertThat(verified.getQuotaSignatureValid()).isTrue();
|
|
|
|
|
assertThat(verified.getQuotaDigestMatches()).isTrue();
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/concatenate-original-text")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("DIGESTED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.digest").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]{64}")));
|
|
|
|
|
.andExpect(jsonPath("$.data.originalText").value(verificationOriginalText));
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/hash")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"" + verificationOriginalText + "\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
assertThat(transactionMapper.selectList(null).get(0).getQuotaSignatureDigest()).isNull();
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/recover-signature-digest")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"publicKey\":\"" + bankPublicKey + "\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/compare-digests")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.h1EqualsH2").value(true));
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/compare-digests")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.h1EqualsH2").value(true));
|
|
|
|
|
assertThat(transactionMapper.selectList(null)).hasSize(1);
|
|
|
|
|
assertThat(transactionMapper.selectList(null).get(0).getId()).isEqualTo(stepSixRecordId);
|
|
|
|
|
verified = transactionMapper.selectList(null).get(0);
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/prepare")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isNotFound());
|
|
|
|
|
String controlOriginalText = verified.getAmount().setScale(2).toPlainString() + "|"
|
|
|
|
|
+ verified.getInstitutionIdentifier() + "|" + verified.getTransactionIdentifier();
|
|
|
|
|
mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/digest")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"999.00|"
|
|
|
|
|
+ verified.getInstitutionIdentifier() + "|" + verified.getTransactionIdentifier()
|
|
|
|
|
+ "\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.allOf(
|
|
|
|
|
org.hamcrest.Matchers.containsString("与当前用户前序数据不一致"),
|
|
|
|
|
org.hamcrest.Matchers.containsString("第2次错误"))));
|
|
|
|
|
assertThat(controlSignatureMapper.selectList(null)).isEmpty();
|
|
|
|
|
String firstDigest = mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/digest")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"" + controlOriginalText + "\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.digest").value(cryptography.sm3(controlOriginalText)))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1))
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.originalText").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.controlId").doesNotExist())
|
|
|
|
|
.andReturn().getResponse().getContentAsString();
|
|
|
|
|
String repeatedDigest = mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/digest")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"" + controlOriginalText + "\"}"))
|
|
|
|
|
.andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
|
|
|
|
|
assertThat(com.jayway.jsonpath.JsonPath.<String>read(repeatedDigest, "$.data.digest"))
|
|
|
|
|
.isEqualTo(com.jayway.jsonpath.JsonPath.<String>read(firstDigest, "$.data.digest"));
|
|
|
|
|
assertThat(controlSignatureMapper.selectList(null)).hasSize(1);
|
|
|
|
|
mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/sign")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
@ -338,32 +465,47 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"" + centralPrivateKey + "\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("SIGNED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.signingKeyId").value(InstitutionKeyService.CENTRAL_FIRST_KEY))
|
|
|
|
|
.andExpect(jsonPath("$.data.signature").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]+")));
|
|
|
|
|
.andExpect(jsonPath("$.data.signature").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]+")))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1));
|
|
|
|
|
mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/package").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("PACKAGED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.responseMessage").value(org.hamcrest.Matchers.containsString(
|
|
|
|
|
"\"cbCtrlSignature\"")));
|
|
|
|
|
mvc.perform(get(COMMERCIAL_BANK_CONTROL_SIGNATURE_BASE_PATH).header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value(1))
|
|
|
|
|
.andExpect(jsonPath("$.data.ctrlId").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.amount").value(1589.85))
|
|
|
|
|
.andExpect(jsonPath("$.data.orgId").value("ORG_3A4B5C6D7E8F"))
|
|
|
|
|
.andExpect(jsonPath("$.data.txnId").value(org.hamcrest.Matchers.startsWith("TXN_")))
|
|
|
|
|
.andExpect(jsonPath("$.data.cbCtrlSignature").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(6));
|
|
|
|
|
mvc.perform(post(CONTROL_SIGNATURE_BASE_PATH + "/steps/send").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk()).andExpect(jsonPath("$.data.status").value("SENT"));
|
|
|
|
|
mvc.perform(post(BANK_CONTROL_SIGNATURE_BASE_PATH + "/steps/receive")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk()).andExpect(jsonPath("$.data.status").value("RECEIVED"));
|
|
|
|
|
mvc.perform(get(COMMERCIAL_BANK_CONTROL_SIGNATURE_BASE_PATH).header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value(2))
|
|
|
|
|
.andExpect(jsonPath("$.data.ctrlId").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.amount").value(1589.85))
|
|
|
|
|
.andExpect(jsonPath("$.data.orgId").value("ORG_3A4B5C6D7E8F"))
|
|
|
|
|
.andExpect(jsonPath("$.data.txnId").value(org.hamcrest.Matchers.startsWith("TXN_")))
|
|
|
|
|
.andExpect(jsonPath("$.data.cbCtrlSignature").isNotEmpty())
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(6));
|
|
|
|
|
|
|
|
|
|
ControlSystemSignatureEntity persisted = controlSignatureMapper.selectList(null).get(0);
|
|
|
|
|
TransactionInformationIdentifierEntity transaction = transactionMapper.selectList(null).get(0);
|
|
|
|
|
assertThat(persisted.getTransactionIdentifierId()).isEqualTo(transaction.getId());
|
|
|
|
|
assertThat(persisted.getOriginalText()).isEqualTo(persisted.getControlId() + "|"
|
|
|
|
|
+ transaction.getAmount().setScale(2).toPlainString() + "|"
|
|
|
|
|
+ transaction.getInstitutionIdentifier() + "|" + transaction.getTransactionIdentifier());
|
|
|
|
|
assertThat(persisted.getOriginalText()).isEqualTo(
|
|
|
|
|
transaction.getAmount().setScale(2).toPlainString() + "|"
|
|
|
|
|
+ transaction.getInstitutionIdentifier() + "|" + transaction.getTransactionIdentifier());
|
|
|
|
|
assertThat(persisted.getDigest()).isEqualTo(cryptography.sm3(persisted.getOriginalText()));
|
|
|
|
|
assertThat(persisted.getControlSignature()).isEqualTo(persisted.getSignature());
|
|
|
|
|
assertThat(cryptography.verify(keyService.centralBankKey(
|
|
|
|
|
new InstitutionKeySubject(USER_ID, SCHOOL_ID, CLASS_ID), "module-four-tester").getPublicKey(),
|
|
|
|
|
persisted.getDigest(), persisted.getControlSignature())).isTrue();
|
|
|
|
|
assertThat(persisted.getResponseMessage()).contains(persisted.getControlId(), persisted.getControlSignature());
|
|
|
|
|
assertThat(persisted.getStatus()).isEqualTo("RECEIVED");
|
|
|
|
|
assertThat(persisted.getStatus()).isEqualTo("SENT");
|
|
|
|
|
StuModuleScoreDetailsEntity score = scoreMapper.selectOne(
|
|
|
|
|
new LambdaQueryWrapper<StuModuleScoreDetailsEntity>()
|
|
|
|
|
.eq(StuModuleScoreDetailsEntity::getUserId, USER_ID)
|
|
|
|
|
@ -376,64 +518,155 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
flowsStepSixDataThroughCentralBankSignatureAndCommercialBankReceive();
|
|
|
|
|
InstitutionKeySubject subject = new InstitutionKeySubject(USER_ID, SCHOOL_ID, CLASS_ID);
|
|
|
|
|
String bankPrivateKey = keyService.commercialBankKey(subject, "module-four-tester").getPrivateKey();
|
|
|
|
|
String transactionIdentifier = transactionMapper.selectList(null).get(0).getTransactionIdentifier();
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/static-segment")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"amount\":1590.85,\"institutionIdentifier\":\"ORG_3A4B5C6D7E8F\"," +
|
|
|
|
|
"\"transactionIdentifier\":\"" + transactionIdentifier + "\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("第4次错误")));
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/static-segment")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"amount\":1589.85,\"institutionIdentifier\":\"ORG_3A4B5C6D7E8F\"," +
|
|
|
|
|
"\"transactionIdentifier\":\"" + transactionIdentifier + "\"}"))
|
|
|
|
|
mvc.perform(get(CENTRAL_QUOTA_CONTROL_BASE_PATH).header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value(1))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaId").value(org.hamcrest.Matchers.nullValue()))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(6));
|
|
|
|
|
mvc.perform(get(QUOTA_CONTROL_BASE_PATH + "/segments/static")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isNotFound())
|
|
|
|
|
.andExpect(jsonPath("$.message").value("当前没有步骤八额度控制位记录"));
|
|
|
|
|
mvc.perform(get(QUOTA_CONTROL_BASE_PATH + "/segments/dynamic")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isNotFound())
|
|
|
|
|
.andExpect(jsonPath("$.message").value("当前没有步骤八额度控制位记录"));
|
|
|
|
|
String staticSegmentResponse = mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/static-segment")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("STATIC_READY"))
|
|
|
|
|
.andExpect(jsonPath("$.data.staticSegment").value(
|
|
|
|
|
org.hamcrest.Matchers.matchesPattern("STATIC_[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.receiveStatus").value(1));
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/dynamic-segment")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"randomValue\":\"7G8H9I0J\",\"timestamp\":\"20260730153600\"}"))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1))
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andReturn().getResponse().getContentAsString();
|
|
|
|
|
String staticSegment = com.jayway.jsonpath.JsonPath.read(staticSegmentResponse, "$.data.staticSegment");
|
|
|
|
|
mvc.perform(get(QUOTA_CONTROL_BASE_PATH + "/segments/static")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.dynamicSegment").value("DYN_7G8H9I0J_20260730153600"));
|
|
|
|
|
.andExpect(jsonPath("$.data.staticSegment").value(staticSegment))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1));
|
|
|
|
|
mvc.perform(get(QUOTA_CONTROL_BASE_PATH + "/segments/dynamic")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isNotFound())
|
|
|
|
|
.andExpect(jsonPath("$.message").value("当前尚未生成步骤八动态段"));
|
|
|
|
|
String firstDynamicSegmentResponse = mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/dynamic-segment")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.dynamicSegment").value(
|
|
|
|
|
org.hamcrest.Matchers.matchesPattern("DYN_[A-Z0-9]{8}_\\d{14}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1))
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andReturn().getResponse().getContentAsString();
|
|
|
|
|
String firstDynamicSegment = com.jayway.jsonpath.JsonPath.read(
|
|
|
|
|
firstDynamicSegmentResponse, "$.data.dynamicSegment");
|
|
|
|
|
mvc.perform(get(QUOTA_CONTROL_BASE_PATH + "/segments/dynamic")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.dynamicSegment").value(firstDynamicSegment))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1));
|
|
|
|
|
long stepEightRecordId = quotaControlBitMapper.selectList(null).get(0).getId();
|
|
|
|
|
String secondDynamicSegmentResponse = mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/dynamic-segment")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.dynamicSegment").value(
|
|
|
|
|
org.hamcrest.Matchers.matchesPattern("DYN_[A-Z0-9]{8}_\\d{14}")))
|
|
|
|
|
.andReturn().getResponse().getContentAsString();
|
|
|
|
|
String secondDynamicSegment = com.jayway.jsonpath.JsonPath.read(
|
|
|
|
|
secondDynamicSegmentResponse, "$.data.dynamicSegment");
|
|
|
|
|
assertThat(secondDynamicSegment).isNotEqualTo(firstDynamicSegment);
|
|
|
|
|
assertThat(quotaControlBitMapper.selectList(null)).hasSize(1);
|
|
|
|
|
assertThat(quotaControlBitMapper.selectList(null).get(0).getId()).isEqualTo(stepEightRecordId);
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/read-central-bank-signature")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.centralBankSignatureSegment").value(
|
|
|
|
|
org.hamcrest.Matchers.startsWith("CB_CTRL_")));
|
|
|
|
|
org.hamcrest.Matchers.startsWith("CB_CTRL_")))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1))
|
|
|
|
|
.andExpect(jsonPath("$.data.status").doesNotExist())
|
|
|
|
|
.andExpect(jsonPath("$.data.completeControlBit").doesNotExist());
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/assemble").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.completeControlBit").value(
|
|
|
|
|
org.hamcrest.Matchers.containsString("|DYN_7G8H9I0J_20260730153600|CB_CTRL_")));
|
|
|
|
|
.andExpect(jsonPath("$.data.completeControlBit").value(org.hamcrest.Matchers.allOf(
|
|
|
|
|
org.hamcrest.Matchers.containsString("|DYN_"),
|
|
|
|
|
org.hamcrest.Matchers.containsString("|CB_CTRL_"))));
|
|
|
|
|
String completeControlBit = quotaControlBitMapper.selectList(null).get(0).getCompleteControlBit();
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/sign")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"" + bankPrivateKey + "\",\"hashAlgorithm\":\"SM3\"}"))
|
|
|
|
|
.content("{\"privateKey\":\"" + bankPrivateKey + "\",\"completeControlBit\":\""
|
|
|
|
|
+ completeControlBit + "\",\"hashAlgorithm\":\"SM3\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("第5次错误")));
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("第4次错误")));
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/sign")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"WRONG_BANK_PRIVATE_KEY\",\"hashAlgorithm\":\"SM2\"}"))
|
|
|
|
|
.content("{\"privateKey\":\"" + bankPrivateKey + "\",\"completeControlBit\":\""
|
|
|
|
|
+ completeControlBit + "_TAMPERED\",\"hashAlgorithm\":\"SM2\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.allOf(
|
|
|
|
|
org.hamcrest.Matchers.containsString("完整额度控制位与步骤八拼接结果不一致"),
|
|
|
|
|
org.hamcrest.Matchers.containsString("第5次错误"))));
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/sign")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"WRONG_BANK_PRIVATE_KEY\",\"completeControlBit\":\""
|
|
|
|
|
+ completeControlBit + "\",\"hashAlgorithm\":\"SM2\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("第6次错误")));
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/sign")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"" + bankPrivateKey + "\",\"hashAlgorithm\":\"SM2\"}"))
|
|
|
|
|
.andExpect(status().isOk()).andExpect(jsonPath("$.data.status").value("SIGNED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.bankSignature").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]+")));
|
|
|
|
|
.content("{\"privateKey\":\"" + bankPrivateKey + "\",\"completeControlBit\":\""
|
|
|
|
|
+ completeControlBit + "\",\"hashAlgorithm\":\"SM2\"}"))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.signature").value(org.hamcrest.Matchers.matchesPattern("[0-9A-F]+")))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(1));
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/package").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk()).andExpect(jsonPath("$.data.status").value("PACKAGED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.requestMessage").value(org.hamcrest.Matchers.containsString("\"quotaId\"")));
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/static-segment")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.staticSegment").value(
|
|
|
|
|
org.hamcrest.Matchers.matchesPattern("STATIC_[0-9A-F]{64}")));
|
|
|
|
|
QuotaControlBitEntity resetByStatic = quotaControlBitMapper.selectList(null).get(0);
|
|
|
|
|
assertThat(resetByStatic.getId()).isEqualTo(stepEightRecordId);
|
|
|
|
|
assertThat(resetByStatic.getStatus()).isEqualTo("STATIC_READY");
|
|
|
|
|
assertThat(resetByStatic.getDynamicSegment()).isNull();
|
|
|
|
|
assertThat(resetByStatic.getCentralBankSignatureSegment()).isNull();
|
|
|
|
|
assertThat(resetByStatic.getCompleteControlBit()).isNull();
|
|
|
|
|
assertThat(resetByStatic.getBankSignature()).isNull();
|
|
|
|
|
assertThat(resetByStatic.getRequestMessage()).isNull();
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/dynamic-segment")
|
|
|
|
|
.header("Authorization", authorization)).andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/read-central-bank-signature")
|
|
|
|
|
.header("Authorization", authorization)).andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/assemble")
|
|
|
|
|
.header("Authorization", authorization)).andExpect(status().isOk());
|
|
|
|
|
String regeneratedCompleteControlBit = quotaControlBitMapper.selectList(null).get(0).getCompleteControlBit();
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/sign")
|
|
|
|
|
.header("Authorization", authorization).contentType("application/json")
|
|
|
|
|
.content("{\"privateKey\":\"" + bankPrivateKey + "\",\"completeControlBit\":\""
|
|
|
|
|
+ regeneratedCompleteControlBit + "\",\"hashAlgorithm\":\"SM2\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/package").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(QUOTA_CONTROL_BASE_PATH + "/steps/send").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk()).andExpect(jsonPath("$.data.status").value("SENT"))
|
|
|
|
|
.andExpect(jsonPath("$.data.receiveStatus").value(1));
|
|
|
|
|
mvc.perform(get(CENTRAL_QUOTA_CONTROL_BASE_PATH).header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk()).andExpect(jsonPath("$.data.receiveStatus").value(1));
|
|
|
|
|
mvc.perform(post(CENTRAL_QUOTA_CONTROL_BASE_PATH + "/steps/receive").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk()).andExpect(jsonPath("$.data.status").value("RECEIVED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.receiveStatus").value(2));
|
|
|
|
|
mvc.perform(get(CENTRAL_QUOTA_CONTROL_BASE_PATH).header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value(2))
|
|
|
|
|
.andExpect(jsonPath("$.data.quotaId").value(org.hamcrest.Matchers.startsWith("QC_")))
|
|
|
|
|
.andExpect(jsonPath("$.data.staticSegment").value(
|
|
|
|
|
org.hamcrest.Matchers.matchesPattern("STATIC_[0-9A-F]{64}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.dynamicSegment").value(
|
|
|
|
|
org.hamcrest.Matchers.matchesPattern("DYN_[A-Z0-9]{8}_\\d{14}")))
|
|
|
|
|
.andExpect(jsonPath("$.data.cbSignatureSegment").value(
|
|
|
|
|
org.hamcrest.Matchers.startsWith("CB_CTRL_")))
|
|
|
|
|
.andExpect(jsonPath("$.data.bankSignature").value(
|
|
|
|
|
org.hamcrest.Matchers.matchesPattern("[0-9A-F]+")))
|
|
|
|
|
.andExpect(jsonPath("$.data.length()").value(6));
|
|
|
|
|
mvc.perform(post(CENTRAL_QUOTA_CONTROL_BASE_PATH + "/steps/receive")
|
|
|
|
|
.header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isNotFound());
|
|
|
|
|
|
|
|
|
|
QuotaControlBitEntity stored = quotaControlBitMapper.selectList(null).get(0);
|
|
|
|
|
assertThat(stored.getStatus()).isEqualTo("RECEIVED");
|
|
|
|
|
@ -496,10 +729,18 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
assertThat(currencies.stream().map(StandardCurrencyEntity::getDenomination)
|
|
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add)).isEqualByComparingTo("1589.85");
|
|
|
|
|
assertThat(currencies.stream().map(StandardCurrencyEntity::getCurrencyId).distinct().count()).isEqualTo(27);
|
|
|
|
|
List<Long> currencyIds = currencies.stream().map(StandardCurrencyEntity::getId)
|
|
|
|
|
.collect(java.util.stream.Collectors.toList());
|
|
|
|
|
long batchId = standardCurrencyBatchMapper.selectList(null).get(0).getId();
|
|
|
|
|
mvc.perform(post(STANDARD_CURRENCY_BASE_PATH + "/steps/generate").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("当前状态:GENERATED")));
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
.andExpect(jsonPath("$.data.status").value("GENERATED"))
|
|
|
|
|
.andExpect(jsonPath("$.data.currencies.length()").value(27));
|
|
|
|
|
assertThat(standardCurrencyBatchMapper.selectList(null)).hasSize(1);
|
|
|
|
|
assertThat(standardCurrencyBatchMapper.selectList(null).get(0).getId()).isEqualTo(batchId);
|
|
|
|
|
assertThat(standardCurrencyMapper.selectList(null)).hasSize(27);
|
|
|
|
|
assertThat(standardCurrencyMapper.selectList(null).stream().map(StandardCurrencyEntity::getId)
|
|
|
|
|
.collect(java.util.stream.Collectors.toList())).containsExactlyElementsOf(currencyIds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@ -525,18 +766,36 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
assertThat(quotaControlBitMapper.selectList(null)).isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void rejectsIncorrectStepFiveOriginalTextAndRecordsError() throws Exception {
|
|
|
|
|
insertCompletedPrecedingData();
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"1589.85|ORG_3A4B5C6D7E8F|20260730153330\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/assemble").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"999.00|ORG_3A4B5C6D7E8F|TXN_"
|
|
|
|
|
+ "7A8B9C0D1E2F3A4B5C6D7E8F9A0B1C2D3E4F5A6B7C8D9E0F1A2B3C4D5E6F\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value("数据拼接错误"));
|
|
|
|
|
assertThat(transactionMapper.selectList(null).get(0).getStatus()).isEqualTo("ASSEMBLED");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void rejectsQuotaVerificationUntilStepFiveIsReceived() throws Exception {
|
|
|
|
|
insertCompletedPrecedingData();
|
|
|
|
|
String publicKey = keyService.commercialBankKey(
|
|
|
|
|
new InstitutionKeySubject(USER_ID, SCHOOL_ID, CLASS_ID), "module-four-tester").getPublicKey();
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/verify")
|
|
|
|
|
mvc.perform(post(VERIFICATION_BASE_PATH + "/steps/hash")
|
|
|
|
|
.header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"publicKey\":\"" + publicKey + "\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.content("{\"originalText\":\"1589.85|ORG_3A4B5C6D7E8F|TXN_"
|
|
|
|
|
+ "7A8B9C0D1E2F3A4B5C6D7E8F9A0B1C2D3E4F5A6B7C8D9E0F1A2B3C4D5E6F\"}"))
|
|
|
|
|
.andExpect(status().isNotFound())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString(
|
|
|
|
|
"步骤五额度请求尚未发送并由央行接收")));
|
|
|
|
|
"当前没有额度请求记录")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@ -545,24 +804,36 @@ class TransactionInformationIdentifierControllerTest {
|
|
|
|
|
mvc.perform(get(QUOTA_BASE_PATH + "/source-data").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString(
|
|
|
|
|
"步骤四尚未完成交易信息标识组装")));
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/prepare").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isBadRequest())
|
|
|
|
|
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString(
|
|
|
|
|
"步骤四尚未完成交易信息标识组装")));
|
|
|
|
|
"步骤四尚未完成交易信息标识")));
|
|
|
|
|
mvc.perform(post(QUOTA_BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"1589.85|ORG_3A4B5C6D7E8F|TXN_"
|
|
|
|
|
+ "7A8B9C0D1E2F3A4B5C6D7E8F9A0B1C2D3E4F5A6B7C8D9E0F1A2B3C4D5E6F\"}"))
|
|
|
|
|
.andExpect(status().isBadRequest());
|
|
|
|
|
assertThat(transactionMapper.selectList(null)).isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void duplicatePreparationReturnsLatestRecordWithoutAddingData() throws Exception {
|
|
|
|
|
void repeatedCorrectDigestUpdatesExistingRecordWithoutAddingData() throws Exception {
|
|
|
|
|
insertCompletedPrecedingData();
|
|
|
|
|
String first = mvc.perform(post(BASE_PATH + "/steps/prepare").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
|
|
|
|
|
String second = mvc.perform(post(BASE_PATH + "/steps/prepare").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk()).andReturn().getResponse().getContentAsString();
|
|
|
|
|
assertThat(com.jayway.jsonpath.JsonPath.<Number>read(second, "$.data.id").longValue())
|
|
|
|
|
.isEqualTo(com.jayway.jsonpath.JsonPath.<Number>read(first, "$.data.id").longValue());
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"1589.85|ORG_3A4B5C6D7E8F|20260730153330\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
long id = transactionMapper.selectList(null).get(0).getId();
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/assemble").header("Authorization", authorization))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
mvc.perform(post(BASE_PATH + "/steps/digest").header("Authorization", authorization)
|
|
|
|
|
.contentType("application/json")
|
|
|
|
|
.content("{\"originalText\":\"1589.85|ORG_3A4B5C6D7E8F|20260730154444\"}"))
|
|
|
|
|
.andExpect(status().isOk());
|
|
|
|
|
|
|
|
|
|
assertThat(transactionMapper.selectList(null)).hasSize(1);
|
|
|
|
|
TransactionInformationIdentifierEntity updated = transactionMapper.selectList(null).get(0);
|
|
|
|
|
assertThat(updated.getId()).isEqualTo(id);
|
|
|
|
|
assertThat(updated.getTransactionTimestamp()).isEqualTo("20260730154444");
|
|
|
|
|
assertThat(updated.getStatus()).isEqualTo("DIGESTED");
|
|
|
|
|
assertThat(updated.getTransactionIdentifier()).isNull();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private PrecedingData insertCompletedPrecedingData() {
|
|
|
|
|
|