package cn.iocoder.yudao.module.mes.service.qc.seedquality; import cn.iocoder.yudao.module.mes.controller.admin.qc.seedquality.vo.MesQcSeedQualityPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.qc.seedquality.vo.MesQcSeedQualitySubmitReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.seedquality.MesQcSeedQualityDO; import cn.iocoder.yudao.module.mes.dal.mysql.pro.bagcode.MesProBagCodeMapper; import cn.iocoder.yudao.module.mes.dal.mysql.qc.seedquality.MesQcSeedQualityMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.test.util.ReflectionTestUtils; import java.util.Collections; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; class SeedQualityScanTest { private final MesQcSeedQualityServiceImpl service = new MesQcSeedQualityServiceImpl(); private final MesProBagCodeMapper bags = mock(MesProBagCodeMapper.class); private final MesQcSeedQualityMapper qualities = mock(MesQcSeedQualityMapper.class); @BeforeEach void setup() { ReflectionTestUtils.setField(service,"bagCodeMapper",bags); ReflectionTestUtils.setField(service,"qualityMapper",qualities); } private MesProBagCodeDO bag() { return new MesProBagCodeDO().setId(1L).setCode("TRACE").setBusinessCode("BUSINESS").setStatus(20).setInboundEventId(9L).setBatchCode("BATCH"); } @Test void businessScanReturnsCanonicalCodeAndPreviousResultWithoutWrites() { when(bags.selectByScanCode("BUSINESS")).thenReturn(bag()); when(qualities.selectByCode("TRACE")).thenReturn(MesQcSeedQualityDO.builder().id(2L).result(1).build()); var result = service.resolveScan("BUSINESS"); assertEquals("TRACE",result.get("code"));assertEquals(2L,result.get("qualityId"));assertEquals(true,result.get("inbound")); verify(qualities,never()).insert(any(MesQcSeedQualityDO.class)); } @Test void businessCodeRecordQueryUsesCanonicalCode() { when(bags.selectByScanCode("BUSINESS")).thenReturn(bag()); var req = new MesQcSeedQualityPageReqVO();req.setCode("BUSINESS");service.getQualityPage(req); assertEquals("TRACE",req.getCode());verify(qualities).selectPage(req); } @Test void duplicateQualityIsRejectedAfterLockingSameBagForBothCodes() { when(bags.selectByScanCodeForUpdate("BUSINESS")).thenReturn(bag()); var req = new MesQcSeedQualitySubmitReqVO();req.setCode("BUSINESS"); when(qualities.selectByCodeForUpdate("TRACE")).thenReturn(MesQcSeedQualityDO.builder().id(2L).result(1).build()); req.setIndicators(Collections.nCopies(4,new MesQcSeedQualitySubmitReqVO.Indicator())); assertThrows(IllegalArgumentException.class,()->service.submit(req)); verify(qualities).selectByCodeForUpdate("TRACE");verify(qualities,never()).insert(any(MesQcSeedQualityDO.class)); } @Test void unenteredAndCanceledBagsCannotSubmit() { var req = new MesQcSeedQualitySubmitReqVO();req.setCode("BUSINESS");req.setIndicators(Collections.nCopies(4,new MesQcSeedQualitySubmitReqVO.Indicator())); when(bags.selectByScanCodeForUpdate("BUSINESS")).thenReturn(bag().setInboundEventId(null)); assertThrows(IllegalArgumentException.class,()->service.submit(req)); when(bags.selectByScanCodeForUpdate("BUSINESS")).thenReturn(bag().setStatus(30)); assertThrows(IllegalArgumentException.class,()->service.submit(req));verifyNoInteractions(qualities); } }