|
@@ -124,8 +124,6 @@ class ExamSprintReportApplicationServiceTest {
|
|
|
.contains("20260318测试")
|
|
.contains("20260318测试")
|
|
|
.contains("TestPaperWordIdArraySize")
|
|
.contains("TestPaperWordIdArraySize")
|
|
|
.contains("StudentWordsLatestSize")
|
|
.contains("StudentWordsLatestSize")
|
|
|
- .contains("TestPaperUnMasterWordsSize")
|
|
|
|
|
- .contains("TestPaperMastedWordsSize")
|
|
|
|
|
.doesNotContain("TestPaperWordIdArray\":")
|
|
.doesNotContain("TestPaperWordIdArray\":")
|
|
|
.doesNotContain("WordSpell\":\"w1")
|
|
.doesNotContain("WordSpell\":\"w1")
|
|
|
.doesNotContain("lot")
|
|
.doesNotContain("lot")
|
|
@@ -255,6 +253,38 @@ class ExamSprintReportApplicationServiceTest {
|
|
|
.isEqualTo(ErrorCode.VALIDATION_ERROR);
|
|
.isEqualTo(ErrorCode.VALIDATION_ERROR);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /** 覆盖展望报告新词汇契约校验场景,当 TestPaperUnMasterWordCount 缺失时,应返回字段级中文校验消息。 */
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void createOutlookReportRejectsMissingTestPaperUnMasterWordCountWithChineseFieldMessage() throws Exception {
|
|
|
|
|
+ ObjectNode invalidPayload = callerVocabularyPayload().deepCopy();
|
|
|
|
|
+ invalidPayload.remove("TestPaperUnMasterWordCount");
|
|
|
|
|
+
|
|
|
|
|
+ assertThatThrownBy(() -> service(new TestRepository(), reportId -> { }, new TestStorage())
|
|
|
|
|
+ .createOutlookReport(invalidPayload))
|
|
|
|
|
+ .isInstanceOf(BusinessException.class)
|
|
|
|
|
+ .hasMessageContaining("展望报告参数校验失败")
|
|
|
|
|
+ .hasMessageContaining("TestPaperUnMasterWordCount")
|
|
|
|
|
+ .hasMessageContaining("必须为数字")
|
|
|
|
|
+ .extracting(exception -> ((BusinessException) exception).getErrorCode())
|
|
|
|
|
+ .isEqualTo(ErrorCode.VALIDATION_ERROR);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /** 覆盖展望报告新词汇契约类型校验场景,当 TestPaperUnMasterWordCount 非数字时,应返回字段级中文校验消息。 */
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void createOutlookReportRejectsTestPaperUnMasterWordCountTypeMismatchWithChineseFieldMessage() throws Exception {
|
|
|
|
|
+ ObjectNode invalidPayload = callerVocabularyPayload().deepCopy();
|
|
|
|
|
+ invalidPayload.put("TestPaperUnMasterWordCount", "3");
|
|
|
|
|
+
|
|
|
|
|
+ assertThatThrownBy(() -> service(new TestRepository(), reportId -> { }, new TestStorage())
|
|
|
|
|
+ .createOutlookReport(invalidPayload))
|
|
|
|
|
+ .isInstanceOf(BusinessException.class)
|
|
|
|
|
+ .hasMessageContaining("展望报告参数校验失败")
|
|
|
|
|
+ .hasMessageContaining("TestPaperUnMasterWordCount")
|
|
|
|
|
+ .hasMessageContaining("必须为数字")
|
|
|
|
|
+ .extracting(exception -> ((BusinessException) exception).getErrorCode())
|
|
|
|
|
+ .isEqualTo(ErrorCode.VALIDATION_ERROR);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/** 覆盖展望报告嵌套列表 Bean Validation 路径映射场景,应暴露请求 JSON 字段名并保留索引。 */
|
|
/** 覆盖展望报告嵌套列表 Bean Validation 路径映射场景,应暴露请求 JSON 字段名并保留索引。 */
|
|
|
@Test
|
|
@Test
|
|
|
void createOutlookReportRejectsNestedStudentWordsLatestViolationWithApiFieldPath() throws Exception {
|
|
void createOutlookReportRejectsNestedStudentWordsLatestViolationWithApiFieldPath() throws Exception {
|
|
@@ -289,16 +319,15 @@ class ExamSprintReportApplicationServiceTest {
|
|
|
.isEqualTo(ErrorCode.VALIDATION_ERROR);
|
|
.isEqualTo(ErrorCode.VALIDATION_ERROR);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /** 覆盖上游词汇报文允许无已掌握真题词的场景,当 TestPaperMastedWords 为空且计数为 0 时,应正常创建并分发。 */
|
|
|
|
|
|
|
+ /** 覆盖展望报告新词汇契约场景,当调用方不再传真题词数组但传 TestPaperUnMasterWordCount 时,应正常创建并分发。 */
|
|
|
@Test
|
|
@Test
|
|
|
- void createOutlookReportAcceptsCallerVocabularyPayloadWithNoMasteredPaperWords() throws Exception {
|
|
|
|
|
|
|
+ void createOutlookReportAcceptsCallerVocabularyPayloadWithoutPaperWordArrays() throws Exception {
|
|
|
TestRepository repository = new TestRepository();
|
|
TestRepository repository = new TestRepository();
|
|
|
TestStorage storage = new TestStorage();
|
|
TestStorage storage = new TestStorage();
|
|
|
List<String> dispatchedReportIds = new ArrayList<>();
|
|
List<String> dispatchedReportIds = new ArrayList<>();
|
|
|
DefaultExamSprintReportApplicationService service = service(repository, dispatchedReportIds::add, storage);
|
|
DefaultExamSprintReportApplicationService service = service(repository, dispatchedReportIds::add, storage);
|
|
|
ObjectNode payload = callerVocabularyPayload().deepCopy();
|
|
ObjectNode payload = callerVocabularyPayload().deepCopy();
|
|
|
- payload.putArray("TestPaperMastedWords");
|
|
|
|
|
- payload.put("TestPaperMastedWordCount", 0);
|
|
|
|
|
|
|
+ payload.put("TestPaperUnMasterWordCount", 3);
|
|
|
|
|
|
|
|
var response = service.createOutlookReport(payload);
|
|
var response = service.createOutlookReport(payload);
|
|
|
|
|
|
|
@@ -307,6 +336,10 @@ class ExamSprintReportApplicationServiceTest {
|
|
|
assertThat(saved.reportType()).isEqualTo(ReportType.OUTLOOK);
|
|
assertThat(saved.reportType()).isEqualTo(ReportType.OUTLOOK);
|
|
|
assertThat(saved.generationStatus()).isEqualTo(ReportGenerationStatus.PENDING);
|
|
assertThat(saved.generationStatus()).isEqualTo(ReportGenerationStatus.PENDING);
|
|
|
assertThat(dispatchedReportIds).containsExactly(response.reportId());
|
|
assertThat(dispatchedReportIds).containsExactly(response.reportId());
|
|
|
|
|
+ JsonNode savedPayload = (JsonNode) ((UnmodeledReportContent) saved.content()).source();
|
|
|
|
|
+ assertThat(savedPayload.fieldNames()).toIterable()
|
|
|
|
|
+ .doesNotContain("TestPaper" + "UnMasterWords", "TestPaper" + "MastedWords");
|
|
|
|
|
+ assertThat(savedPayload.path("TestPaperUnMasterWordCount").asInt()).isEqualTo(3);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 覆盖上游词汇报文缺少词汇明细的场景,当 StudentWordsLatest 缺失时,应在保存前校验失败。 */
|
|
/** 覆盖上游词汇报文缺少词汇明细的场景,当 StudentWordsLatest 缺失时,应在保存前校验失败。 */
|
|
@@ -1139,8 +1172,7 @@ class ExamSprintReportApplicationServiceTest {
|
|
|
"ExamineStrangeWordCount": 3,
|
|
"ExamineStrangeWordCount": 3,
|
|
|
"TestPaperWordIdArray": [1, 2, 3, 4, 5],
|
|
"TestPaperWordIdArray": [1, 2, 3, 4, 5],
|
|
|
"TestPaperTitle": "文章2.jpg",
|
|
"TestPaperTitle": "文章2.jpg",
|
|
|
- "TestPaperUnMasterWords": ["lot", "father", "catch"],
|
|
|
|
|
- "TestPaperMastedWords": ["a", "the"],
|
|
|
|
|
|
|
+ "TestPaperUnMasterWordCount": 3,
|
|
|
"TestPaperMastedWordCount": 2,
|
|
"TestPaperMastedWordCount": 2,
|
|
|
"TestPaperWordCount": 5,
|
|
"TestPaperWordCount": 5,
|
|
|
"Complex": false
|
|
"Complex": false
|