package com.talentcard.server.service; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.List; import com.baomidou.mybatisplus.core.MybatisConfiguration; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.talentcard.server.entity.DependentCardApply; import com.talentcard.server.entity.DependentCardApplyStatusLog; import com.talentcard.server.mapper.DependentCardApplyMapper; import com.talentcard.server.mapper.DependentCardApplyStatusLogMapper; import com.talentcard.server.request.DependentCardApplyRequest; import com.talentcard.server.response.DependentCardApplyItemResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.apache.ibatis.builder.MapperBuilderAssistant; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) class DependentCardApplyServiceTests { @Mock private DependentCardApplyMapper mapper; @Mock private DependentCardApplyStatusLogMapper statusLogMapper; private DependentCardApplyService service; @BeforeEach void setUp() { TableInfoHelper.initTableInfo( new MapperBuilderAssistant(new MybatisConfiguration(), "dependent-card-test"), DependentCardApply.class ); service = new DependentCardApplyService(mapper, statusLogMapper); } @Test void listExcludesCancelledFamilyCards() { when(mapper.selectList(any(Wrapper.class))).thenReturn(List.of()); service.list(34L); ArgumentCaptor> queryCaptor = ArgumentCaptor.forClass(LambdaQueryWrapper.class); verify(mapper).selectList(queryCaptor.capture()); LambdaQueryWrapper query = queryCaptor.getValue(); assertThat(query.getSqlSegment()).contains("talent_card_id", "status <>"); assertThat(query.getParamNameValuePairs()).containsValue(34L).containsValue(DependentCardApply.STATUS_CANCELLED); } @Test void resubmitCreatesANewApplicationAndKeepsRejectedApplicationUnchanged() { DependentCardApply rejected = new DependentCardApply( "DCA-OLD", 12L, 34L, "持卡人", "13900000000", "TC-001", "卓越人才卡", "旧家属", "13800000000", "510105199001011234", "配偶" ); setStatus(rejected, DependentCardApply.STATUS_REJECTED); when(mapper.selectByIdForUpdate(99L)).thenReturn(rejected); when(mapper.insert(any(DependentCardApply.class))).thenAnswer(invocation -> { setId(invocation.getArgument(0), 100L); return 1; }); when(statusLogMapper.insert(any(DependentCardApplyStatusLog.class))).thenReturn(1); DependentCardApplyItemResponse result = service.resubmit( 99L, new DependentCardApplyRequest( 34L, " 新家属 ", "51010519900101123X", "13700000000", " 子女 " ) ); ArgumentCaptor applicationCaptor = ArgumentCaptor.forClass(DependentCardApply.class); verify(mapper).insert(applicationCaptor.capture()); DependentCardApply created = applicationCaptor.getValue(); assertThat(created.getId()).isEqualTo(100L); assertThat(created.getApplyNo()).startsWith("DCA").isNotEqualTo(rejected.getApplyNo()); assertThat(created.getTalentId()).isEqualTo(rejected.getTalentId()); assertThat(created.getTalentCardId()).isEqualTo(rejected.getTalentCardId()); assertThat(created.getDependentName()).isEqualTo("新家属"); assertThat(created.getDependentIdCardNo()).isEqualTo("51010519900101123X"); assertThat(created.getDependentMobile()).isEqualTo("13700000000"); assertThat(created.getRelation()).isEqualTo("子女"); assertThat(created.getStatus()).isEqualTo(DependentCardApply.STATUS_PENDING_REVIEW); assertThat(result.id()).isEqualTo(100L); assertThat(result.status()).isEqualTo(DependentCardApply.STATUS_PENDING_REVIEW); assertThat(rejected.getStatus()).isEqualTo(DependentCardApply.STATUS_REJECTED); verify(mapper, never()).update(any(), any(Wrapper.class)); ArgumentCaptor logCaptor = ArgumentCaptor.forClass(DependentCardApplyStatusLog.class); verify(statusLogMapper).insert(logCaptor.capture()); assertThat(logCaptor.getValue().getApplyId()).isEqualTo(100L); assertThat(logCaptor.getValue().getApplyNo()).isEqualTo(created.getApplyNo()); assertThat(logCaptor.getValue().getFromStatus()).isNull(); assertThat(logCaptor.getValue().getToStatus()).isEqualTo(DependentCardApply.STATUS_PENDING_REVIEW); } private void setId(DependentCardApply apply, Long id) { setField(apply, "id", id); } private void setStatus(DependentCardApply apply, Integer status) { setField(apply, "status", status); } private void setField(DependentCardApply apply, String name, Object value) { try { var field = DependentCardApply.class.getDeclaredField(name); field.setAccessible(true); field.set(apply, value); } catch (ReflectiveOperationException exception) { throw new AssertionError(exception); } } }