diff --git a/nflg-qms-admin/src/test/java/com/nflg/qms/admin/QmsIncomingInspectionTaskApiTest.java b/nflg-qms-admin/src/test/java/com/nflg/qms/admin/QmsIncomingInspectionTaskApiTest.java new file mode 100644 index 00000000..242115f9 --- /dev/null +++ b/nflg-qms-admin/src/test/java/com/nflg/qms/admin/QmsIncomingInspectionTaskApiTest.java @@ -0,0 +1,393 @@ +package com.nflg.qms.admin; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.lang.TypeReference; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.json.JSONUtil; +import com.nflg.wms.common.pojo.ApiResult; +import com.nflg.wms.common.pojo.qo.QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO; +import com.nflg.wms.common.pojo.qo.QmsIncomingInspectionTaskTodoCheckSubmitItemQO; +import com.nflg.wms.common.pojo.qo.QmsIncomingInspectionTaskTodoCheckSubmitQO; +import com.nflg.wms.common.pojo.vo.FileUploadVO; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * 提交检测项(addCheckItem)接口测试 + *

+ * 测试前提: + * 1. qms-admin 服务已启动(默认 http://localhost:8105) + * 2. 测试账号已登录,将有效的 token 填入 TOKEN 常量 + * 3. 数据库中存在有效的任务ID(VALID_TASK_ID)和对应的物料唯一编号(VALID_MATERIAL_UNIQUE_NO) + * 4. VALID_STANDARD_ITEM_CONTENT_ID 对应数据库中已存在的检验标准项内容ID + *

+ */ +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class QmsIncomingInspectionTaskApiTest { + + // ===================== 配置区 ===================== + /** 服务地址 */ + private static final String BASE_URL = "http://localhost:8105"; + /** 当前登录用户的 token */ + private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiU0VxNWhlcXdHOERvVTBkeWFLZnZDbW1FTGFuek5jQlMiLCJuYW1lIjoi6LaF57qn566h55CG5ZGYIiwiY29kZSI6ImFkbWluIiwicm9sZXMiOlsiU3VwZXJBZG1pbiJdLCJ0eXBlIjoxfQ.wuEnMU5vJSqh2vr69MKooFUHD04-_-86eeJee_2zir4"; + /** 有效的任务ID */ + private static final Long VALID_TASK_ID = 2046829044461977601L; + /** 有效的物料唯一编号 */ + private static final String VALID_MATERIAL_UNIQUE_NO = "MAT_UNIQUE_001"; + /** 有效的检验标准项内容ID */ + private static final Long VALID_STANDARD_ITEM_CONTENT_ID = 2047511371773046785L; + // ===================== 配置区结束 ===================== + + // ==================== HTTP 工具方法 ==================== + + private static ApiResult post(String path, Object body, TypeReference> typeRef) { + String url = BASE_URL + path; + String reqBody = body == null ? "" : JSONUtil.toJsonStr(body); + HttpResponse resp = HttpRequest.post(url) + .header("authorization", TOKEN) + .header("Content-Type", "application/json") + .body(reqBody) + .execute(); + String raw = resp.body(); + System.out.println("[POST] " + path); + System.out.println(" 请求: " + reqBody); + System.out.println(" 响应: " + raw); + return JSONUtil.toBean(raw, typeRef, false); + } + + private static void assertSuccess(ApiResult result, String msg) { + Assert.isTrue(result != null && result.getCode() == 200, + () -> new RuntimeException(msg + " => " + JSONUtil.toJsonStr(result))); + } + + private static void assertFailed(ApiResult result, String msg) { + Assert.isTrue(result != null && result.getCode() != 200, + () -> new RuntimeException(msg + " => 预期失败但实际成功")); + } + + // ==================== 提交检测项接口测试 ==================== + + /** + * 【提交检测项】正常提交(所有样本合格) + * 验证点: + * 1. 接口返回成功 + * 2. inspectionQty == qualifiedQty,记录应标记为合格 + */ + @Test + @Order(1) + public void test01_addCheckItem_Success_AllQualified() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setQualifiedQty(5); + request.setUnqualifiedQty(0); + request.setInspectionQty(5); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertSuccess(result, "提交检测项(全部合格)失败"); + System.out.println(" ✅ 提交检测项(全部合格)成功"); + } + + /** + * 【提交检测项】正常提交(存在不合格样本) + * 验证点: + * 1. 接口返回成功 + * 2. qualifiedQty < inspectionQty,记录应标记为不合格 + */ + @Test + @Order(2) + public void test02_addCheckItem_Success_PartialUnqualified() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setQualifiedQty(3); + request.setUnqualifiedQty(2); + request.setInspectionQty(5); + + // 不合格样本设置 qualified=false + QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO unqualifiedData = + buildItemData(false, new BigDecimal("9.5"), Collections.emptyList()); + request.getItems().get(0).getDatas().add(unqualifiedData); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertSuccess(result, "提交检测项(含不合格样本)失败"); + System.out.println(" ✅ 提交检测项(含不合格样本)成功"); + } + + /** + * 【提交检测项】带图片的样本提交 + * 验证点:图片ID能正常保存到检验数据记录 + */ + @Test + @Order(3) + public void test03_addCheckItem_Success_WithImages() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + + FileUploadVO image = new FileUploadVO(100L, "test_image.jpg", "http://example.com/test_image.jpg"); + request.getItems().get(0).getDatas().get(0).setImages(List.of(image)); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertSuccess(result, "带图片提交检测项失败"); + System.out.println(" ✅ 带图片提交检测项成功"); + } + + /** + * 【提交检测项】带备注的检验项提交 + * 验证点:备注字段能正常保存 + */ + @Test + @Order(4) + public void test04_addCheckItem_Success_WithRemark() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.getItems().get(0).setRemark("外观轻微划痕,不影响功能"); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertSuccess(result, "带备注提交检测项失败"); + System.out.println(" ✅ 带备注提交检测项成功"); + } + + /** + * 【提交检测项】更新已有检验记录(传入已有ID) + * 验证点:当 id 不为 null 时,接口执行 saveOrUpdate 逻辑,更新已有记录 + */ + @Test + @Order(5) + public void test05_addCheckItem_Success_UpdateExisting() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setId(1L); // 已存在的记录ID,根据实际环境替换 + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertSuccess(result, "更新已有检验记录失败"); + System.out.println(" ✅ 更新已有检验记录成功"); + } + + /** + * 【提交检测项】任务ID为空 + * 验证点:接口返回参数校验错误(@NotNull 校验) + */ + @Test + @Order(6) + public void test06_addCheckItem_Fail_TaskIdNull() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setTaskId(null); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "任务ID为空应返回失败"); + System.out.println(" ✅ 任务ID为空校验通过"); + } + + /** + * 【提交检测项】物料唯一编号为空 + * 验证点:接口返回参数校验错误(@NotNull 校验) + */ + @Test + @Order(7) + public void test07_addCheckItem_Fail_MaterialUniqueNoNull() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setMaterialUniqueNo(null); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "物料唯一编号为空应返回失败"); + System.out.println(" ✅ 物料唯一编号为空校验通过"); + } + + /** + * 【提交检测项】样本数量为空 + * 验证点:接口返回参数校验错误(@NotNull 校验) + */ + @Test + @Order(8) + public void test08_addCheckItem_Fail_InspectionQtyNull() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setInspectionQty(null); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "样本数量为空应返回失败"); + System.out.println(" ✅ 样本数量为空校验通过"); + } + + /** + * 【提交检测项】合格数量为空 + * 验证点:接口返回参数校验错误(@NotNull 校验) + */ + @Test + @Order(9) + public void test09_addCheckItem_Fail_QualifiedQtyNull() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setQualifiedQty(null); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "合格数量为空应返回失败"); + System.out.println(" ✅ 合格数量为空校验通过"); + } + + /** + * 【提交检测项】不合格数量为空 + * 验证点:接口返回参数校验错误(@NotNull 校验) + */ + @Test + @Order(10) + public void test10_addCheckItem_Fail_UnqualifiedQtyNull() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setUnqualifiedQty(null); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "不合格数量为空应返回失败"); + System.out.println(" ✅ 不合格数量为空校验通过"); + } + + /** + * 【提交检测项】检验项列表为空 + * 验证点:接口返回参数校验错误(@NotEmpty 校验) + */ + @Test + @Order(11) + public void test11_addCheckItem_Fail_ItemsEmpty() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setItems(Collections.emptyList()); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "检验项列表为空应返回失败"); + System.out.println(" ✅ 检验项列表为空校验通过"); + } + + /** + * 【提交检测项】检验项列表为null + * 验证点:接口返回参数校验错误(@NotEmpty 校验) + */ + @Test + @Order(12) + public void test12_addCheckItem_Fail_ItemsNull() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.setItems(null); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "检验项列表为null应返回失败"); + System.out.println(" ✅ 检验项列表为null校验通过"); + } + + /** + * 【提交检测项】检验项中检验标准项内容ID为空 + * 验证点:接口返回参数校验错误(@NotNull 级联校验) + */ + @Test + @Order(13) + public void test13_addCheckItem_Fail_ItemContentIdNull() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.getItems().get(0).setInspectionStandardItemContentId(null); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "检验标准项内容ID为空应返回失败"); + System.out.println(" ✅ 检验标准项内容ID为空校验通过"); + } + + /** + * 【提交检测项】检验项的样本列表为空 + * 验证点:接口返回参数校验错误(@NotEmpty 级联校验) + */ + @Test + @Order(14) + public void test14_addCheckItem_Fail_ItemDatasEmpty() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.getItems().get(0).setDatas(Collections.emptyList()); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "样本列表为空应返回失败"); + System.out.println(" ✅ 样本列表为空校验通过"); + } + + /** + * 【提交检测项】样本中是否合格字段为空 + * 验证点:接口返回参数校验错误(@NotNull 级联校验) + */ + @Test + @Order(15) + public void test15_addCheckItem_Fail_DataQualifiedNull() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + request.getItems().get(0).getDatas().get(0).setQualified(null); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertFailed(result, "是否合格字段为空应返回失败"); + System.out.println(" ✅ 是否合格字段为空校验通过"); + } + + /** + * 【提交检测项】多个检验项提交 + * 验证点:可以一次提交多个检验项,每项下有多个样本数据 + */ + @Test + @Order(16) + public void test16_addCheckItem_Success_MultipleItems() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest(); + + QmsIncomingInspectionTaskTodoCheckSubmitItemQO item2 = buildItem(VALID_STANDARD_ITEM_CONTENT_ID + 1, null); + request.setItems(new ArrayList<>(List.of(request.getItems().get(0), item2))); + + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {}); + assertSuccess(result, "多个检验项提交失败"); + System.out.println(" ✅ 多个检验项提交成功"); + } + + /** + * 【提交检测项】请求体为空(无请求体) + * 验证点:接口返回参数解析或校验错误 + */ + @Test + @Order(17) + public void test17_addCheckItem_Fail_EmptyBody() { + ApiResult result = post("/incoming-inspection-task/pad/add-check-item", null, new TypeReference<>() {}); + assertFailed(result, "空请求体应返回失败"); + System.out.println(" ✅ 空请求体校验通过"); + } + + // ==================== 辅助方法 ==================== + + /** + * 构建一个有效的提交检测项请求 + */ + private QmsIncomingInspectionTaskTodoCheckSubmitQO buildValidRequest() { + QmsIncomingInspectionTaskTodoCheckSubmitQO request = new QmsIncomingInspectionTaskTodoCheckSubmitQO(); + request.setTaskId(VALID_TASK_ID); + request.setMaterialUniqueNo(VALID_MATERIAL_UNIQUE_NO); + request.setInspectionQty(5); + request.setQualifiedQty(5); + request.setUnqualifiedQty(0); + request.setItems(new ArrayList<>(List.of(buildItem(VALID_STANDARD_ITEM_CONTENT_ID, null)))); + return request; + } + + /** + * 构建一个检验项 + * + * @param contentId 检验标准项内容ID + * @param remark 备注(可为null) + */ + private QmsIncomingInspectionTaskTodoCheckSubmitItemQO buildItem(Long contentId, String remark) { + QmsIncomingInspectionTaskTodoCheckSubmitItemQO item = new QmsIncomingInspectionTaskTodoCheckSubmitItemQO(); + item.setInspectionStandardItemContentId(contentId); + item.setRemark(remark); + item.setDatas(new ArrayList<>(List.of(buildItemData(true, new BigDecimal("10.5"), Collections.emptyList())))); + return item; + } + + /** + * 构建一个样本数据 + * + * @param qualified 是否合格 + * @param measuredValue 测量值(可为null) + * @param images 图片列表 + */ + private QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO buildItemData( + Boolean qualified, BigDecimal measuredValue, List images) { + QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO data = + new QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO(); + data.setQualified(qualified); + data.setMeasuredValue(measuredValue); + data.setImages(images); + return data; + } +}