| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mdm.service.agent; |
| | | |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.agent.vo.MdmAgentImportPreflightReqVO; |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.agent.vo.MdmAgentImportPreflightRespVO; |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemImportExcelVO; |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemSaveReqVO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemDO; |
| | | import cn.iocoder.yudao.module.mdm.service.item.MdmItemImportContext; |
| | | import cn.iocoder.yudao.module.mdm.service.item.MdmItemRowResolution; |
| | | import cn.iocoder.yudao.module.mdm.service.item.MdmItemService; |
| | | import cn.iocoder.yudao.module.system.framework.agent.AgentPrincipal; |
| | | import cn.iocoder.yudao.module.system.service.storage.SystemAgentAttachmentRef; |
| | | import cn.iocoder.yudao.module.system.service.storage.SystemAgentImportBridgeService; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.junit.jupiter.api.extension.ExtendWith; |
| | | import org.mockito.InjectMocks; |
| | | import org.mockito.Mock; |
| | | import org.mockito.junit.jupiter.MockitoExtension; |
| | | import org.mockito.junit.jupiter.MockitoSettings; |
| | | import org.mockito.quality.Strictness; |
| | | |
| | | import java.nio.file.Path; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static org.junit.jupiter.api.Assertions.*; |
| | | import static org.mockito.ArgumentMatchers.any; |
| | | import static org.mockito.ArgumentMatchers.anyString; |
| | | import static org.mockito.Mockito.when; |
| | | |
| | | @ExtendWith(MockitoExtension.class) |
| | | @MockitoSettings(strictness = Strictness.LENIENT) |
| | | class MdmAgentImportPreflightServiceTest { |
| | | |
| | | private static final String SHA = "a".repeat(64); |
| | | |
| | | @Mock private SystemAgentImportBridgeService bridgeService; |
| | | @Mock private MdmItemService itemService; |
| | | @Mock private MdmAgentImportPolicy policy; |
| | | @InjectMocks private MdmAgentImportPreflightService service; |
| | | |
| | | private final AgentPrincipal principal = new AgentPrincipal(7L, "live"); |
| | | |
| | | @Test |
| | | void classifiesCreateSkipAndBlockedRows() { |
| | | stubAttachmentAndPolicy(); |
| | | MdmItemDO existing = new MdmItemDO(); |
| | | existing.setId(99L); |
| | | when(itemService.getItemListByCode("A")).thenReturn(List.of()); |
| | | when(itemService.getItemListByCode("B")).thenReturn(List.of(existing)); |
| | | |
| | | MdmAgentImportPreflightRespVO result = service.preflight( |
| | | request("A", "B", "C"), principal); |
| | | |
| | | assertEquals(3, result.getSummary().getTotal()); |
| | | assertEquals(1, result.getSummary().getCreate()); |
| | | assertEquals(1, result.getSummary().getSkip()); |
| | | assertEquals(1, result.getSummary().getBlocked()); |
| | | assertEquals("CREATE", result.getRows().get(0).getAction()); |
| | | assertEquals("SKIP", result.getRows().get(1).getAction()); |
| | | assertEquals(99L, result.getRows().get(1).getTargetItemId()); |
| | | assertFalse(result.getRows().get(1).getWarnings().isEmpty()); |
| | | assertEquals("BLOCKED", result.getRows().get(2).getAction()); |
| | | assertEquals("CATEGORY_NOT_FOUND", result.getRows().get(2).getBlockers().get(0).getCode()); |
| | | assertFalse(result.getCanCommit()); |
| | | } |
| | | |
| | | @Test |
| | | void duplicateCodeInFileIsBlocked() { |
| | | stubAttachmentAndPolicy(); |
| | | when(itemService.getItemListByCode(anyString())).thenReturn(List.of()); |
| | | |
| | | MdmAgentImportPreflightRespVO result = service.preflight( |
| | | request("A", "A"), principal); |
| | | |
| | | assertEquals(2, result.getSummary().getBlocked()); |
| | | assertEquals("DUPLICATE_CODE_IN_FILE", result.getRows().get(1).getBlockers().get(0).getCode()); |
| | | } |
| | | |
| | | @Test |
| | | void hashIsStableAcrossIdenticalRuns() { |
| | | stubAttachmentAndPolicy(); |
| | | when(itemService.getItemListByCode("A")).thenReturn(List.of()); |
| | | |
| | | MdmAgentImportPreflightRespVO first = service.preflight(request("A"), principal); |
| | | MdmAgentImportPreflightRespVO second = service.preflight(request("A"), principal); |
| | | |
| | | assertTrue(first.getCanCommit()); |
| | | assertEquals(first.getPreflightHash(), second.getPreflightHash()); |
| | | } |
| | | |
| | | private void stubAttachmentAndPolicy() { |
| | | when(bridgeService.requireOwnedAttachmentRef(5L)) |
| | | .thenReturn(new SystemAgentAttachmentRef(5L, 21L, "materials.csv", 100L, Path.of("x"))); |
| | | when(bridgeService.sha256OfAttachment(5L)).thenReturn(SHA); |
| | | when(policy.getMaxRows()).thenReturn(5000); |
| | | when(policy.isAllowMesSync()).thenReturn(false); |
| | | MdmItemImportContext context = new MdmItemImportContext( |
| | | Map.of("RAW", 11L), Map.of("RAW", "åæ"), |
| | | Map.of("PCS", 22L), Map.of("PCS", "个")); |
| | | when(itemService.buildImportContext(any())).thenReturn(context); |
| | | when(itemService.resolveImportRow(any(MdmItemImportExcelVO.class), any())) |
| | | .thenAnswer(invocation -> MdmItemRowResolution.success(new MdmItemSaveReqVO())); |
| | | } |
| | | |
| | | private static MdmAgentImportPreflightReqVO request(String... codes) { |
| | | MdmAgentImportPreflightReqVO reqVO = new MdmAgentImportPreflightReqVO(); |
| | | reqVO.setAttachmentId(5L); |
| | | reqVO.setSessionId(21L); |
| | | reqVO.setSourceSha256(SHA); |
| | | reqVO.setProposalRevision("rev-1"); |
| | | reqVO.setRows(java.util.stream.IntStream.range(0, codes.length).mapToObj(index -> { |
| | | String code = codes[index]; |
| | | MdmAgentImportPreflightReqVO.Row row = new MdmAgentImportPreflightReqVO.Row(); |
| | | row.setCandidateId("c-" + index); |
| | | row.setRowNo(index + 1); |
| | | row.setCode(code); |
| | | row.setName("ç©æ" + code); |
| | | row.setCategoryCode("C".equals(code) ? "NOPE" : "RAW"); |
| | | row.setUnitMeasureCode("PCS"); |
| | | return row; |
| | | }).toList()); |
| | | return reqVO; |
| | | } |
| | | } |