mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
1、WithMockLoginUser从Security上下文改为纯mock;2、更新资金管理service剥离真实h2db,采用纯mock;
This commit is contained in:
+1
-1
@@ -434,7 +434,7 @@ public class InvoiceServiceImpl implements InvoiceService {
|
||||
* @return
|
||||
*/
|
||||
private List<PurchaseRecordDO> validatePurchaseRecordExists(List<Long> purchaseId) {
|
||||
List<PurchaseRecordDO> purchaseRecordDOS = purchaseRecordMapper.selectBatchIds(purchaseId);
|
||||
List<PurchaseRecordDO> purchaseRecordDOS = purchaseRecordMapper.selectByIds(purchaseId);
|
||||
if (CollUtil.isEmpty(purchaseRecordDOS)) {
|
||||
throw new ServiceException(PURCHASE_RECORD_NO_EXIST);
|
||||
}
|
||||
|
||||
-3
@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.cf.imes.framework.common.exception.ServiceException;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.Assert.AssertUtils;
|
||||
import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.product.ProductPageReqVO;
|
||||
@@ -65,8 +64,6 @@ public class ProductsServiceImpl implements ProductsService {
|
||||
if (ProductStatusEnum.PRODUCT_UPDATES.getStatus().equals(status) && !ProductStatusEnum.isProductDelis(updateReqVOStatus)) {
|
||||
throw new ServiceException(PRODUCTS_NO_UPDATE);
|
||||
}
|
||||
ProductsDO productsDO = BeanUtils.toBean(updateReqVO, ProductsDO.class);
|
||||
productsMapper.updateById(productsDO);
|
||||
productsMapper.update(new LambdaUpdateWrapperX<ProductsDO>()
|
||||
.eq(ProductsDO::getId, updateReqVOId)
|
||||
.setIfPresent(ProductsDO::getProductName, productName)
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.cf.imes.module.system.common;
|
||||
|
||||
import com.cf.imes.framework.security.core.LoginUser;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2026/1/16 10:20
|
||||
*/
|
||||
public class WithMockLoginUserExtension implements BeforeEachCallback, AfterEachCallback {
|
||||
@Override
|
||||
public void afterEach(ExtensionContext context) {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) {
|
||||
WithMockLoginUser ann = findAnnotation(context);
|
||||
|
||||
LoginUser loginUser = new LoginUser();
|
||||
if (ann != null) {
|
||||
loginUser.setId(ann.userId());
|
||||
loginUser.setOrganId(ann.organId());
|
||||
loginUser.setDeptId(ann.deptId());
|
||||
loginUser.setNickname(ann.username());
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
Authentication authentication = Mockito.mock(Authentication.class);
|
||||
Mockito.when(authentication.getPrincipal()).thenReturn(loginUser);
|
||||
|
||||
SecurityContext securityContext = Mockito.mock(SecurityContext.class);
|
||||
Mockito.when(securityContext.getAuthentication())
|
||||
.thenReturn(authentication);
|
||||
|
||||
SecurityContextHolder.setContext(securityContext);
|
||||
}
|
||||
|
||||
private WithMockLoginUser findAnnotation(ExtensionContext context) {
|
||||
return context.getElement()
|
||||
.map(el -> el.getAnnotation(WithMockLoginUser.class))
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
+268
-393
@@ -1,7 +1,10 @@
|
||||
package com.cf.imes.module.system.service.funds.delay;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.funds.delay.vo.PreviouProductDelayRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.delay.vo.ProductDelayPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.delay.vo.ProductDelayRespVO;
|
||||
@@ -12,481 +15,353 @@ import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
|
||||
import com.cf.imes.module.system.dal.mysql.funds.delay.ProductDelayRecordMapper;
|
||||
import com.cf.imes.module.system.dal.mysql.funds.purchase.PurchaseRecordMapper;
|
||||
import com.cf.imes.module.system.enums.pay.DurationUnitEnum;
|
||||
import com.cf.imes.module.system.enums.pay.PayChannelCodeEnum;
|
||||
import com.cf.imes.module.system.enums.pay.PurchaseRecordStatusEnum;
|
||||
import com.cf.imes.module.system.service.funds.products.ProductsDetailService;
|
||||
import com.cf.imes.module.system.service.funds.purchase.PurchaseService;
|
||||
import com.cf.imes.module.system.service.organ.OrganService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCT_DELAY_UNIT_NOT_SUPPORT;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCT_PURCHASE_NO_EXIST;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link ProductDelayServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2025/12/8 14:30
|
||||
*/
|
||||
@Import(ProductDelayServiceImpl.class)
|
||||
public class ProductDelayServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
class ProductDelayServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@Resource
|
||||
@InjectMocks
|
||||
private ProductDelayServiceImpl productDelayService;
|
||||
|
||||
@Resource
|
||||
private ProductDelayRecordMapper recordMapper;
|
||||
@Mock
|
||||
private ProductDelayRecordMapper productDelayRecordMapper;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private PurchaseRecordMapper purchaseRecordMapper;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private OrganService organService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private PurchaseService purchaseService;
|
||||
|
||||
@MockitoBean
|
||||
private ProductsDetailService productsDetailService;
|
||||
|
||||
@Test
|
||||
public void testCreateProductDelay_noPreDelayRecord_success() {
|
||||
// 准备参数
|
||||
Long organId = randomLongId();
|
||||
Long purchaseId = randomLongId();
|
||||
Long productId = randomLongId();
|
||||
|
||||
// Mock 组织
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
organization.setId(organId);
|
||||
organization.setName("测试组织");
|
||||
when(organService.validOrgan(organId)).thenReturn(organization);
|
||||
|
||||
// Mock 购买记录
|
||||
PurchaseRecordDO purchaseRecord = PurchaseRecordDO.builder()
|
||||
.id(purchaseId)
|
||||
.productId(productId)
|
||||
.productName("测试产品")
|
||||
.startTime(LocalDate.now().minusMonths(6))
|
||||
.endTime(LocalDate.now().plusMonths(6))
|
||||
.build();
|
||||
when(purchaseService.getRecord(purchaseId)).thenReturn(purchaseRecord);
|
||||
|
||||
// 构造请求
|
||||
ProductDelaySaveReqVO reqVO = new ProductDelaySaveReqVO();
|
||||
reqVO.setOrganId(organId);
|
||||
reqVO.setPurchaseId(purchaseId);
|
||||
reqVO.setDelayDuration(3);
|
||||
reqVO.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
|
||||
// 调用
|
||||
Long delayId = productDelayService.createProductDelay(reqVO);
|
||||
|
||||
// 断言
|
||||
assertNotNull(delayId);
|
||||
ProductDelayRecordDO dbRecord = recordMapper.selectById(delayId);
|
||||
assertNotNull(dbRecord);
|
||||
assertEquals(organId, dbRecord.getOrganId());
|
||||
assertEquals("测试组织", dbRecord.getOrganName());
|
||||
assertEquals(productId, dbRecord.getProductId());
|
||||
assertEquals("测试产品", dbRecord.getProductName());
|
||||
assertEquals(3, dbRecord.getDelayDuration());
|
||||
assertEquals(DurationUnitEnum.MONTH.getCode(), dbRecord.getDelayDurationUnit());
|
||||
assertEquals(purchaseRecord.getEndTime(), dbRecord.getEndTime());
|
||||
assertEquals(purchaseRecord.getEndTime().plusMonths(3), dbRecord.getDelayTime());
|
||||
assertEquals(purchaseId, dbRecord.getPurchaseId());
|
||||
assertFalse(dbRecord.getPaid());
|
||||
@BeforeAll
|
||||
static void init(){
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), ProductDelayRecordDO.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateProductDelay_withPreDelayRecord_success() {
|
||||
// 准备参数
|
||||
Long organId = randomLongId();
|
||||
Long purchaseId = randomLongId();
|
||||
Long productId = randomLongId();
|
||||
|
||||
// Mock 组织
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
organization.setId(organId);
|
||||
organization.setName("测试组织");
|
||||
when(organService.validOrgan(organId)).thenReturn(organization);
|
||||
|
||||
// Mock 购买记录
|
||||
PurchaseRecordDO purchaseRecord = PurchaseRecordDO.builder()
|
||||
.id(purchaseId)
|
||||
.productId(productId)
|
||||
.productName("测试产品")
|
||||
.startTime(LocalDate.now().minusMonths(6))
|
||||
.endTime(LocalDate.now().plusMonths(6))
|
||||
.build();
|
||||
when(purchaseService.getRecord(purchaseId)).thenReturn(purchaseRecord);
|
||||
|
||||
// 插入前序延期记录
|
||||
ProductDelayRecordDO preDelayRecord = ProductDelayRecordDO.builder()
|
||||
.organId(organId)
|
||||
.organName("测试组织")
|
||||
.productId(productId)
|
||||
.productName("测试产品")
|
||||
.delayDuration(1)
|
||||
.delayDurationUnit(DurationUnitEnum.YEAR.getCode())
|
||||
.endTime(purchaseRecord.getEndTime())
|
||||
.delayTime(purchaseRecord.getEndTime().plusYears(1))
|
||||
.purchaseId(purchaseId)
|
||||
.paid(true)
|
||||
.build();
|
||||
recordMapper.insert(preDelayRecord);
|
||||
|
||||
// 构造请求
|
||||
void testCreateProductDelay_purchaseNotExist() {
|
||||
ProductDelaySaveReqVO reqVO = new ProductDelaySaveReqVO();
|
||||
reqVO.setOrganId(organId);
|
||||
reqVO.setPurchaseId(purchaseId);
|
||||
reqVO.setDelayDuration(6);
|
||||
reqVO.setDelayDurationUnit(DurationUnitEnum.YEAR.getCode());
|
||||
reqVO.setOrganId(1L);
|
||||
reqVO.setPurchaseId(10L);
|
||||
|
||||
// 调用
|
||||
Long delayId = productDelayService.createProductDelay(reqVO);
|
||||
when(organService.validOrgan(1L)).thenReturn(new OrganizationDO());
|
||||
when(purchaseService.getRecord(10L)).thenReturn(null);
|
||||
|
||||
// 断言
|
||||
assertNotNull(delayId);
|
||||
ProductDelayRecordDO dbRecord = recordMapper.selectById(delayId);
|
||||
assertNotNull(dbRecord);
|
||||
// 应该基于前序记录的延期时间计算
|
||||
assertEquals(preDelayRecord.getDelayTime(), dbRecord.getEndTime());
|
||||
assertEquals(preDelayRecord.getDelayTime().plusYears(6), dbRecord.getDelayTime());
|
||||
assertServiceException(() -> productDelayService.createProductDelay(reqVO), PRODUCT_PURCHASE_NO_EXIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateProductDelay_expiredEndTime_success() {
|
||||
// 准备参数
|
||||
Long organId = randomLongId();
|
||||
Long purchaseId = randomLongId();
|
||||
Long productId = randomLongId();
|
||||
void testCreateProductDelay_success_noLastDelay_notExpired() {
|
||||
LocalDate now = LocalDate.now();
|
||||
|
||||
// Mock 组织
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
organization.setId(organId);
|
||||
organization.setName("测试组织");
|
||||
when(organService.validOrgan(organId)).thenReturn(organization);
|
||||
|
||||
// Mock 购买记录(已过期)
|
||||
PurchaseRecordDO purchaseRecord = PurchaseRecordDO.builder()
|
||||
.id(purchaseId)
|
||||
.productId(productId)
|
||||
.productName("测试产品")
|
||||
.startTime(LocalDate.now().minusMonths(12))
|
||||
.endTime(LocalDate.now().minusMonths(1)) // 已过期
|
||||
.build();
|
||||
when(purchaseService.getRecord(purchaseId)).thenReturn(purchaseRecord);
|
||||
|
||||
// 构造请求
|
||||
ProductDelaySaveReqVO reqVO = new ProductDelaySaveReqVO();
|
||||
reqVO.setOrganId(organId);
|
||||
reqVO.setPurchaseId(purchaseId);
|
||||
reqVO.setDelayDuration(3);
|
||||
reqVO.setOrganId(1L);
|
||||
reqVO.setPurchaseId(100L);
|
||||
reqVO.setDelayDuration(10);
|
||||
reqVO.setDelayDurationUnit(DurationUnitEnum.DAY.getCode());
|
||||
|
||||
// 调用
|
||||
Long delayId = productDelayService.createProductDelay(reqVO);
|
||||
OrganizationDO org = new OrganizationDO();
|
||||
org.setName("组织A");
|
||||
|
||||
// 断言
|
||||
assertNotNull(delayId);
|
||||
ProductDelayRecordDO dbRecord = recordMapper.selectById(delayId);
|
||||
assertNotNull(dbRecord);
|
||||
// 已过期的情况,应该从今天开始计算
|
||||
assertEquals(LocalDate.now(), dbRecord.getEndTime());
|
||||
assertEquals(LocalDate.now().plusDays(3), dbRecord.getDelayTime());
|
||||
PurchaseRecordDO purchase = new PurchaseRecordDO();
|
||||
purchase.setProductId(11L);
|
||||
purchase.setProductName("产品A");
|
||||
purchase.setEndTime(now.plusDays(5));
|
||||
|
||||
when(organService.validOrgan(1L)).thenReturn(org);
|
||||
when(purchaseService.getRecord(100L)).thenReturn(purchase);
|
||||
when(productDelayRecordMapper.selectOne(any())).thenReturn(null);
|
||||
|
||||
productDelayService.createProductDelay(reqVO);
|
||||
|
||||
verify(productDelayRecordMapper).insert(argThat((ProductDelayRecordDO recordDO) ->
|
||||
recordDO.getEndTime().equals(purchase.getEndTime())
|
||||
&& recordDO.getDelayTime().equals(purchase.getEndTime().plusDays(10))
|
||||
&& !recordDO.getPaid()
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateProductDelay_withExpiredPreDelayRecord_success() {
|
||||
// 准备参数
|
||||
Long organId = randomLongId();
|
||||
Long purchaseId = randomLongId();
|
||||
Long productId = randomLongId();
|
||||
void testCreateProductDelay_success_purchaseExpired() {
|
||||
LocalDate now = LocalDate.now();
|
||||
|
||||
// Mock 组织
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
organization.setId(organId);
|
||||
organization.setName("测试组织");
|
||||
when(organService.validOrgan(organId)).thenReturn(organization);
|
||||
|
||||
// Mock 购买记录(未过期)
|
||||
PurchaseRecordDO purchaseRecord = PurchaseRecordDO.builder()
|
||||
.id(purchaseId)
|
||||
.productId(productId)
|
||||
.productName("测试产品")
|
||||
.startTime(LocalDate.now().minusMonths(6))
|
||||
.endTime(LocalDate.now().plusMonths(6))
|
||||
.build();
|
||||
when(purchaseService.getRecord(purchaseId)).thenReturn(purchaseRecord);
|
||||
|
||||
// 插入前序延期记录(延期时间未过期)
|
||||
ProductDelayRecordDO preDelayRecord = ProductDelayRecordDO.builder()
|
||||
.organId(organId)
|
||||
.organName("测试组织")
|
||||
.productId(productId)
|
||||
.productName("测试产品")
|
||||
.delayDuration(3)
|
||||
.delayDurationUnit(DurationUnitEnum.MONTH.getCode())
|
||||
.endTime(purchaseRecord.getEndTime())
|
||||
.delayTime(LocalDate.now().plusMonths(9)) // 未过期的延期时间
|
||||
.purchaseId(purchaseId)
|
||||
.paid(true)
|
||||
.build();
|
||||
recordMapper.insert(preDelayRecord);
|
||||
|
||||
// 构造请求
|
||||
ProductDelaySaveReqVO reqVO = new ProductDelaySaveReqVO();
|
||||
reqVO.setOrganId(organId);
|
||||
reqVO.setPurchaseId(purchaseId);
|
||||
reqVO.setDelayDuration(6);
|
||||
reqVO.setDelayDurationUnit(4);
|
||||
|
||||
// 调用并断言异常
|
||||
assertServiceException(() -> productDelayService.createProductDelay(reqVO),
|
||||
PRODUCT_DELAY_UNIT_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateProductDelay_purchaseNotExist() {
|
||||
// 准备参数
|
||||
Long organId = randomLongId();
|
||||
Long purchaseId = randomLongId();
|
||||
|
||||
// Mock 组织
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
organization.setId(organId);
|
||||
organization.setName("测试组织");
|
||||
when(organService.validOrgan(organId)).thenReturn(organization);
|
||||
|
||||
// Mock 购买记录不存在
|
||||
when(purchaseService.getRecord(purchaseId)).thenReturn(null);
|
||||
|
||||
// 构造请求
|
||||
ProductDelaySaveReqVO reqVO = new ProductDelaySaveReqVO();
|
||||
reqVO.setOrganId(organId);
|
||||
reqVO.setPurchaseId(purchaseId);
|
||||
reqVO.setDelayDuration(3);
|
||||
reqVO.setOrganId(1L);
|
||||
reqVO.setPurchaseId(200L);
|
||||
reqVO.setDelayDuration(1);
|
||||
reqVO.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
|
||||
// 调用并断言异常
|
||||
assertServiceException(() -> productDelayService.createProductDelay(reqVO),
|
||||
PRODUCT_PURCHASE_NO_EXIST);
|
||||
when(organService.validOrgan(any())).thenReturn(new OrganizationDO());
|
||||
when(purchaseService.getRecord(any())).thenReturn(
|
||||
PurchaseRecordDO.builder()
|
||||
.productId(1L)
|
||||
.productName("产品")
|
||||
.endTime(now.minusDays(3))
|
||||
.build()
|
||||
);
|
||||
when(productDelayRecordMapper.selectOne(any())).thenReturn(null);
|
||||
|
||||
productDelayService.createProductDelay(reqVO);
|
||||
|
||||
verify(productDelayRecordMapper).insert(argThat((ProductDelayRecordDO r) ->
|
||||
r.getEndTime().equals(now)
|
||||
&& r.getDelayTime().equals(now.plusMonths(1))
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testCreateProductDelay_success_withLastDelay() {
|
||||
LocalDate base = LocalDate.now().plusDays(5);
|
||||
|
||||
when(productDelayRecordMapper.selectOne(any()))
|
||||
.thenReturn(ProductDelayRecordDO.builder()
|
||||
.delayTime(base)
|
||||
.build());
|
||||
|
||||
when(organService.validOrgan(any())).thenReturn(new OrganizationDO());
|
||||
when(purchaseService.getRecord(any())).thenReturn(
|
||||
PurchaseRecordDO.builder()
|
||||
.productId(1L)
|
||||
.productName("产品")
|
||||
.endTime(LocalDate.now())
|
||||
.build()
|
||||
);
|
||||
|
||||
ProductDelaySaveReqVO reqVO = new ProductDelaySaveReqVO();
|
||||
reqVO.setOrganId(1L);
|
||||
reqVO.setPurchaseId(1L);
|
||||
reqVO.setDelayDuration(2);
|
||||
reqVO.setDelayDurationUnit(DurationUnitEnum.YEAR.getCode());
|
||||
|
||||
productDelayService.createProductDelay(reqVO);
|
||||
|
||||
verify(productDelayRecordMapper).insert(argThat((ProductDelayRecordDO r) ->
|
||||
r.getEndTime().equals(base)
|
||||
&& r.getDelayTime().equals(base.plusYears(2))
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPage() {
|
||||
// mock 数据
|
||||
ProductDelayRecordDO record1 = randomPojo(ProductDelayRecordDO.class, o -> {
|
||||
o.setOrganName("晨丰科技");
|
||||
o.setProductName("ERP产品");
|
||||
o.setDelayDuration(3);
|
||||
o.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
});
|
||||
recordMapper.insert(record1);
|
||||
void testCreateProductDelay_unitNotSupport() {
|
||||
ProductDelaySaveReqVO reqVO = new ProductDelaySaveReqVO();
|
||||
reqVO.setOrganId(1L);
|
||||
reqVO.setPurchaseId(1L);
|
||||
reqVO.setDelayDuration(1);
|
||||
reqVO.setDelayDurationUnit(999); // 非法
|
||||
|
||||
// 不匹配的数据
|
||||
recordMapper.insert(randomPojo(ProductDelayRecordDO.class, o -> {
|
||||
o.setOrganName("其他组织");
|
||||
o.setProductName("ERP产品");
|
||||
o.setDelayDuration(4);
|
||||
o.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
}));
|
||||
when(organService.validOrgan(any())).thenReturn(new OrganizationDO());
|
||||
when(purchaseService.getRecord(any())).thenReturn(
|
||||
PurchaseRecordDO.builder()
|
||||
.productId(1L)
|
||||
.productName("产品")
|
||||
.endTime(LocalDate.now())
|
||||
.build()
|
||||
);
|
||||
when(productDelayRecordMapper.selectOne(any())).thenReturn(null);
|
||||
|
||||
// 准备参数
|
||||
ProductDelayPageReqVO reqVO = new ProductDelayPageReqVO();
|
||||
reqVO.setOrganName("晨丰科技");
|
||||
reqVO.setProductName("ERP产品");
|
||||
reqVO.setDelayDuration(3);
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
|
||||
// 调用
|
||||
PageResult<ProductDelayRespVO> pageResult = productDelayService.getPage(reqVO);
|
||||
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
ProductDelayRespVO respVO = pageResult.getList().get(0);
|
||||
assertEquals("晨丰科技", respVO.getOrganName());
|
||||
assertEquals("ERP产品", respVO.getProductName());
|
||||
assertEquals(3, respVO.getDelayDuration());
|
||||
assertServiceException(() -> productDelayService.createProductDelay(reqVO), PRODUCT_DELAY_UNIT_NOT_SUPPORT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRecordsByPurchaseId() {
|
||||
// 准备数据
|
||||
Long purchaseId = randomLongId();
|
||||
Long organId = randomLongId();
|
||||
void testGetRecordsByPurchaseId_success() {
|
||||
Long purchaseId = 100L;
|
||||
Long organId = 200L;
|
||||
|
||||
// mock 数据
|
||||
ProductDelayRecordDO record1 = randomPojo(ProductDelayRecordDO.class, o -> {
|
||||
o.setOrganName("晨丰科技");
|
||||
o.setProductName("ERP产品");
|
||||
o.setDelayDuration(3);
|
||||
o.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
o.setPurchaseId(purchaseId);
|
||||
o.setOrganId(organId);
|
||||
});
|
||||
recordMapper.insert(record1);
|
||||
ProductDelayRecordDO recordDO = new ProductDelayRecordDO();
|
||||
recordDO.setDelayDuration(6);
|
||||
recordDO.setDelayDurationUnit(2);
|
||||
recordDO.setDelayTime(LocalDate.now());
|
||||
|
||||
// 不匹配的数据
|
||||
recordMapper.insert(randomPojo(ProductDelayRecordDO.class, o -> {
|
||||
o.setOrganName("其他组织");
|
||||
o.setProductName("ERP产品");
|
||||
o.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
}));
|
||||
when(productDelayRecordMapper.selectList(any()))
|
||||
.thenReturn(List.of(recordDO));
|
||||
|
||||
// 调用
|
||||
List<ProductDelayRespVO> records = productDelayService.getRecordsByPurchaseId(purchaseId, organId);
|
||||
List<ProductDelayRespVO> result =
|
||||
productDelayService.getRecordsByPurchaseId(purchaseId, organId);
|
||||
|
||||
// 断言
|
||||
assertEquals(1, records.size());
|
||||
// 验证按 ID 倒序
|
||||
assertEquals(3, records.get(0).getDelayDuration());
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(6, result.get(0).getDelayDuration());
|
||||
assertEquals(2, result.get(0).getDelayDurationUnit());
|
||||
|
||||
verify(productDelayRecordMapper).selectList(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActiveRecordsByProductId_withRecords() {
|
||||
// 准备数据
|
||||
Long productId = randomLongId();
|
||||
Long organId = randomLongId();
|
||||
Long purchaseId = randomLongId();
|
||||
void testGetRecordsByPurchaseId_empty() {
|
||||
when(productDelayRecordMapper.selectList(any()))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
// 插入活跃的购买记录
|
||||
PurchaseRecordDO purchaseRecord = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(purchaseId);
|
||||
o.setOrganId(organId);
|
||||
o.setProductId(productId);
|
||||
o.setStatus(PurchaseRecordStatusEnum.ACTIVE.getStatus());
|
||||
o.setCurrency(null);
|
||||
o.setIsInvocing(null);
|
||||
o.setPaymentMethod(PayChannelCodeEnum.ALIPAY_PC.getCode());
|
||||
});
|
||||
purchaseRecordMapper.insert(purchaseRecord);
|
||||
List<ProductDelayRespVO> result =
|
||||
productDelayService.getRecordsByPurchaseId(1L, 1L);
|
||||
|
||||
// 插入延期记录
|
||||
ProductDelayRecordDO delayRecord = randomPojo(ProductDelayRecordDO.class, o -> {
|
||||
o.setOrganId(organId);
|
||||
o.setProductId(productId);
|
||||
o.setPurchaseId(purchaseId);
|
||||
o.setDelayDuration(3);
|
||||
o.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
o.setDelayTime(LocalDate.now().plusMonths(3));
|
||||
o.setEndTime(LocalDate.now());
|
||||
});
|
||||
recordMapper.insert(delayRecord);
|
||||
|
||||
// 调用
|
||||
PreviouProductDelayRespVO result = productDelayService.getActiveRecordsByProductId(productId, organId);
|
||||
|
||||
// 断言
|
||||
assertNotNull(result);
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetPage_success() {
|
||||
ProductDelayPageReqVO reqVO = new ProductDelayPageReqVO();
|
||||
|
||||
ProductDelayRecordDO recordDO = new ProductDelayRecordDO();
|
||||
recordDO.setId(1L);
|
||||
recordDO.setDelayDuration(3);
|
||||
recordDO.setDelayDurationUnit(1);
|
||||
|
||||
PageResult<ProductDelayRecordDO> pageResult =
|
||||
new PageResult<>(List.of(recordDO), 1L);
|
||||
|
||||
when(productDelayRecordMapper.selectPage(reqVO))
|
||||
.thenReturn(pageResult);
|
||||
|
||||
PageResult<ProductDelayRespVO> result =
|
||||
productDelayService.getPage(reqVO);
|
||||
|
||||
assertEquals(1L, result.getTotal());
|
||||
assertEquals(1, result.getList().size());
|
||||
assertEquals(3, result.getList().get(0).getDelayDuration());
|
||||
|
||||
verify(productDelayRecordMapper).selectPage(reqVO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetActiveRecordsByProductId_noActivePurchase() {
|
||||
Long productId = 1L;
|
||||
Long organId = 2L;
|
||||
|
||||
when(purchaseRecordMapper.selectOne(any()))
|
||||
.thenReturn(null);
|
||||
|
||||
PreviouProductDelayRespVO result =
|
||||
productDelayService.getActiveRecordsByProductId(productId, organId);
|
||||
|
||||
assertNotNull(result);
|
||||
assertNull(result.getPreviouPurchaseRecord());
|
||||
assertTrue(
|
||||
result.getDelayRespVOList() == null
|
||||
|| result.getDelayRespVOList().isEmpty()
|
||||
);
|
||||
|
||||
verify(purchaseRecordMapper).selectOne(any());
|
||||
verifyNoInteractions(productDelayRecordMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetActiveRecordsByProductId_success() {
|
||||
Long productId = 1L;
|
||||
Long organId = 2L;
|
||||
|
||||
PurchaseRecordDO purchase = new PurchaseRecordDO();
|
||||
purchase.setId(10L);
|
||||
purchase.setProductId(productId);
|
||||
purchase.setOrganId(organId);
|
||||
|
||||
ProductDelayRecordDO delay = new ProductDelayRecordDO();
|
||||
delay.setDelayDuration(3);
|
||||
delay.setDelayDurationUnit(1);
|
||||
delay.setDelayTime(LocalDate.now());
|
||||
|
||||
when(purchaseRecordMapper.selectOne(any()))
|
||||
.thenReturn(purchase);
|
||||
|
||||
when(productDelayRecordMapper.selectList(any()))
|
||||
.thenReturn(List.of(delay));
|
||||
|
||||
PreviouProductDelayRespVO result =
|
||||
productDelayService.getActiveRecordsByProductId(productId, organId);
|
||||
|
||||
assertNotNull(result);
|
||||
|
||||
// 断言 purchase
|
||||
assertNotNull(result.getPreviouPurchaseRecord());
|
||||
assertEquals(purchaseId, result.getPreviouPurchaseRecord().getId());
|
||||
assertEquals(10L, result.getPreviouPurchaseRecord().getId());
|
||||
|
||||
// 断言 delay 列表
|
||||
assertNotNull(result.getDelayRespVOList());
|
||||
assertEquals(1, result.getDelayRespVOList().size());
|
||||
assertEquals(3, result.getDelayRespVOList().get(0).getDelayDuration());
|
||||
|
||||
verify(purchaseRecordMapper).selectOne(any());
|
||||
verify(productDelayRecordMapper).selectList(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActiveRecordsByProductId_noPurchaseRecord() {
|
||||
// 准备数据
|
||||
Long productId = randomLongId();
|
||||
Long organId = randomLongId();
|
||||
void updatePurchaseDelayRecordsPaidAndRemark_success() {
|
||||
// given
|
||||
Long organId = 1L;
|
||||
Boolean paid = true;
|
||||
|
||||
// 调用(没有购买记录)
|
||||
PreviouProductDelayRespVO result = productDelayService.getActiveRecordsByProductId(productId, organId);
|
||||
ProductDelayRecordDO recordDO = new ProductDelayRecordDO();
|
||||
recordDO.setId(100L);
|
||||
recordDO.setRemark("test remark");
|
||||
|
||||
// 断言
|
||||
assertNotNull(result);
|
||||
assertNull(result.getPreviouPurchaseRecord());
|
||||
assertNull(result.getDelayRespVOList());
|
||||
List<ProductDelayRecordDO> list = Collections.singletonList(recordDO);
|
||||
|
||||
// mock update 行为
|
||||
when(productDelayRecordMapper.update(any(LambdaUpdateWrapper.class)))
|
||||
.thenReturn(1);
|
||||
|
||||
// when
|
||||
productDelayService.updatePurchaseDelayRecordsPaidAndRemark(list, organId, paid);
|
||||
|
||||
// then
|
||||
verify(productDelayRecordMapper, times(1))
|
||||
.update(any(LambdaUpdateWrapper.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdatePurchaseDelayRecordsPaidAndRemark() {
|
||||
// 准备数据
|
||||
Long organId = randomLongId();
|
||||
void updatePurchaseDelayRecordsPaid_success() {
|
||||
// given
|
||||
Long purchaseId = 10L;
|
||||
Long organId = 1L;
|
||||
|
||||
ProductDelayRecordDO record1 = randomPojo(ProductDelayRecordDO.class, o -> {
|
||||
o.setPaid(false);
|
||||
o.setRemark(null);
|
||||
o.setDelayDuration(3);
|
||||
o.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
o.setOrganId(organId);
|
||||
});
|
||||
when(productDelayRecordMapper.update(any(LambdaUpdateWrapper.class)))
|
||||
.thenReturn(2); // 模拟更新 2 条
|
||||
|
||||
recordMapper.insert(record1);
|
||||
|
||||
// 准备更新数据
|
||||
record1.setRemark("备注1");
|
||||
List<ProductDelayRecordDO> updateList = Arrays.asList(record1);
|
||||
|
||||
// 调用
|
||||
productDelayService.updatePurchaseDelayRecordsPaidAndRemark(updateList, organId, true);
|
||||
|
||||
// 断言
|
||||
ProductDelayRecordDO dbRecord1 = recordMapper.selectById(record1.getId());
|
||||
assertTrue(dbRecord1.getPaid());
|
||||
assertEquals("备注1", dbRecord1.getRemark());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdatePurchaseDelayRecordsPaid() {
|
||||
// 准备数据
|
||||
Long purchaseId = randomLongId();
|
||||
Long organId = randomLongId();
|
||||
|
||||
ProductDelayRecordDO record1 = randomPojo(ProductDelayRecordDO.class, o -> {
|
||||
o.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
o.setOrganId(organId);
|
||||
o.setPurchaseId(purchaseId);
|
||||
o.setPaid(false);
|
||||
});
|
||||
recordMapper.insert(record1);
|
||||
|
||||
// 调用
|
||||
// when
|
||||
productDelayService.updatePurchaseDelayRecordsPaid(purchaseId, organId);
|
||||
|
||||
// 断言
|
||||
ProductDelayRecordDO dbRecord1 = recordMapper.selectById(record1.getId());
|
||||
assertTrue(dbRecord1.getPaid());
|
||||
// then
|
||||
verify(productDelayRecordMapper, times(1))
|
||||
.update(any(LambdaUpdateWrapper.class));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testResetPurchaseDelayRecordsRemark() {
|
||||
// 准备数据
|
||||
Long purchaseId = randomLongId();
|
||||
Long organId = randomLongId();
|
||||
void resetPurchaseDelayRecordsRemark_success() {
|
||||
// given
|
||||
Long purchaseId = 10L;
|
||||
Long organId = 1L;
|
||||
|
||||
ProductDelayRecordDO record1 = randomPojo(ProductDelayRecordDO.class, o -> {
|
||||
o.setRemark("测试备注");
|
||||
o.setDelayDuration(3);
|
||||
o.setDelayDurationUnit(DurationUnitEnum.MONTH.getCode());
|
||||
o.setOrganId(organId);
|
||||
o.setPurchaseId(purchaseId);
|
||||
});
|
||||
recordMapper.insert(record1);
|
||||
when(productDelayRecordMapper.update(any(LambdaUpdateWrapper.class)))
|
||||
.thenReturn(1);
|
||||
|
||||
|
||||
// 调用
|
||||
// when
|
||||
productDelayService.resetPurchaseDelayRecordsRemark(purchaseId, organId);
|
||||
|
||||
// 断言
|
||||
ProductDelayRecordDO dbRecord1 = recordMapper.selectById(record1.getId());
|
||||
assertNull(dbRecord1.getRemark());
|
||||
// then
|
||||
verify(productDelayRecordMapper, times(1))
|
||||
.update(any(LambdaUpdateWrapper.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+25
-39
@@ -1,64 +1,50 @@
|
||||
package com.cf.imes.module.system.service.funds.incomeandexpense;
|
||||
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.system.dal.dataobject.incomeandexpense.IncomeExpenseDetailsDO;
|
||||
import com.cf.imes.module.system.dal.mysql.incomeandexpense.IncomeExpenseDetailsMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* {@link IncomeExpenseServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author Gqr
|
||||
*/
|
||||
@Import(IncomeExpenseServiceImpl.class)
|
||||
class IncomeExpenseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
class IncomeExpenseServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@Resource
|
||||
@InjectMocks
|
||||
private IncomeExpenseServiceImpl incomeExpenseService;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private IncomeExpenseDetailsMapper incomeExpenseDetailsMapper;
|
||||
|
||||
@Test
|
||||
void testCreateDetail() {
|
||||
// 准备数据
|
||||
IncomeExpenseDetailsDO incomeExpenseDetailsDO = new IncomeExpenseDetailsDO();
|
||||
incomeExpenseDetailsDO.setBusinessNo("BUS20251215001");
|
||||
incomeExpenseDetailsDO.setOrderNo("ORD20251215001");
|
||||
incomeExpenseDetailsDO.setOrganId(1L);
|
||||
incomeExpenseDetailsDO.setPurchaseId(100L);
|
||||
incomeExpenseDetailsDO.setTradeType(1);
|
||||
incomeExpenseDetailsDO.setIncomeExpenseType(2);
|
||||
incomeExpenseDetailsDO.setAmount(new BigDecimal("100.00"));
|
||||
incomeExpenseDetailsDO.setCurrency(1);
|
||||
incomeExpenseDetailsDO.setCurrencyUnit("CNY");
|
||||
incomeExpenseDetailsDO.setRemark("测试收支明细");
|
||||
void createDetail_success() {
|
||||
// given
|
||||
IncomeExpenseDetailsDO detailDO = new IncomeExpenseDetailsDO();
|
||||
|
||||
// 调用方法
|
||||
Long id = incomeExpenseService.createDetail(incomeExpenseDetailsDO);
|
||||
doAnswer(invocation -> {
|
||||
IncomeExpenseDetailsDO arg = invocation.getArgument(0);
|
||||
arg.setId(100L); // 手动回填 ID
|
||||
return 1;
|
||||
}).when(incomeExpenseDetailsMapper).insert(any(IncomeExpenseDetailsDO.class));
|
||||
|
||||
// 验证结果
|
||||
// when
|
||||
Long id = incomeExpenseService.createDetail(detailDO);
|
||||
|
||||
// then
|
||||
assertNotNull(id);
|
||||
assertTrue(id > 0);
|
||||
assertEquals(100L, id);
|
||||
|
||||
// 验证数据库中是否已插入数据
|
||||
IncomeExpenseDetailsDO dbRecord = incomeExpenseDetailsMapper.selectById(id);
|
||||
assertNotNull(dbRecord);
|
||||
assertEquals("BUS20251215001", dbRecord.getBusinessNo());
|
||||
assertEquals("ORD20251215001", dbRecord.getOrderNo());
|
||||
assertEquals(1L, dbRecord.getOrganId());
|
||||
assertEquals(100L, dbRecord.getPurchaseId());
|
||||
assertEquals(1, dbRecord.getTradeType());
|
||||
assertEquals(2, dbRecord.getIncomeExpenseType());
|
||||
assertEquals(new BigDecimal("100.00"), dbRecord.getAmount());
|
||||
assertEquals(1, dbRecord.getCurrency());
|
||||
assertEquals("CNY", dbRecord.getCurrencyUnit());
|
||||
assertEquals("测试收支明细", dbRecord.getRemark());
|
||||
verify(incomeExpenseDetailsMapper, times(1))
|
||||
.insert(any(IncomeExpenseDetailsDO.class));
|
||||
}
|
||||
}
|
||||
+173
-209
@@ -1,14 +1,18 @@
|
||||
package com.cf.imes.module.system.service.funds.invoice;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.cf.imes.framework.common.exception.ServiceException;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.security.core.LoginUser;
|
||||
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.infra.api.file.FileApi;
|
||||
import com.cf.imes.module.system.common.WithMockLoginUserExtension;
|
||||
import com.cf.imes.module.system.controller.admin.funds.invoice.vo.*;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.invoice.InvoiceRecordsDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.invoice.InvoiceTitleInfoDO;
|
||||
@@ -22,13 +26,15 @@ import com.cf.imes.module.system.enums.pay.InvoiceStatusEnum;
|
||||
import com.cf.imes.module.system.enums.pay.PayChannelCodeEnum;
|
||||
import com.cf.imes.module.system.enums.pay.TradeTypeEnum;
|
||||
import com.cf.imes.module.system.service.organ.OrganService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
@@ -39,7 +45,13 @@ import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
@@ -48,31 +60,35 @@ import static org.mockito.Mockito.when;
|
||||
* @author Gqr
|
||||
* @since 2025/12/15 15:31
|
||||
*/
|
||||
@Import(InvoiceServiceImpl.class)
|
||||
class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
@ExtendWith(WithMockLoginUserExtension.class)
|
||||
class InvoiceServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@Resource
|
||||
@InjectMocks
|
||||
private InvoiceServiceImpl invoiceService;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private InvoiceTitleInfoMapper invoiceTitleInfoMapper;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private PurchaseRecordMapper purchaseRecordMapper;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private InvoiceRecordsMapper invoiceRecordsMapper;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private OrganService organService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private FileApi fileApi;
|
||||
|
||||
@BeforeAll
|
||||
static void init(){
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), PurchaseRecordDO.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void testGetInvoiceTitle() {
|
||||
// 准备参数
|
||||
Long organId = SecurityFrameworkUtils.getUserOrganId();
|
||||
|
||||
// 使用真实数据查询发票抬头信息
|
||||
@@ -81,8 +97,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setOrganId(organId);
|
||||
o.setInvoiceTitle("测试公司");
|
||||
});
|
||||
|
||||
invoiceTitleInfoMapper.insert(invoiceTitleInfoDO);
|
||||
when(invoiceTitleInfoMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(invoiceTitleInfoDO);
|
||||
|
||||
// 调用
|
||||
InvoiceTitleInfo result = invoiceService.getInvoiceTitle();
|
||||
@@ -92,6 +107,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
assertEquals(1L, result.getId());
|
||||
assertEquals("测试公司", result.getInvoiceTitle());
|
||||
assertEquals(organId, result.getOrganId());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -106,17 +122,32 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
reqVO.setTaxNumber("91330101MA2HXXXXXX");
|
||||
reqVO.setEmail("test@company.com");
|
||||
|
||||
// 内部校验
|
||||
when(invoiceTitleInfoMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(null);
|
||||
|
||||
invoiceService.insetInvoiceTitle(reqVO);
|
||||
|
||||
// ====== 校验数据库 ======
|
||||
InvoiceTitleInfoDO dbRecord = invoiceTitleInfoMapper.selectOne(
|
||||
new LambdaQueryWrapper<InvoiceTitleInfoDO>()
|
||||
.eq(InvoiceTitleInfoDO::getOrganId, organId)
|
||||
);
|
||||
// 不走更新
|
||||
verify(invoiceTitleInfoMapper, never()).updateById(any(InvoiceTitleInfoDO.class));
|
||||
|
||||
assertNotNull(dbRecord);
|
||||
assertEquals("测试公司", dbRecord.getInvoiceTitle());
|
||||
assertEquals("91330101MA2HXXXXXX", dbRecord.getTaxNumber());
|
||||
// 校验新增
|
||||
ArgumentCaptor<InvoiceTitleInfoDO> captor =
|
||||
ArgumentCaptor.forClass(InvoiceTitleInfoDO.class);
|
||||
|
||||
verify(invoiceTitleInfoMapper).insert(captor.capture());
|
||||
|
||||
InvoiceTitleInfoDO inserted = captor.getValue();
|
||||
|
||||
assertEquals(organId, inserted.getOrganId());
|
||||
assertEquals(reqVO.getInvoiceTitle(), inserted.getInvoiceTitle());
|
||||
assertEquals(reqVO.getInvoiceType(), inserted.getInvoiceType());
|
||||
assertEquals(reqVO.getIssueType(), inserted.getIssueType());
|
||||
assertEquals(reqVO.getTaxNumber(), inserted.getTaxNumber());
|
||||
assertEquals(reqVO.getBankName(), inserted.getBankName());
|
||||
assertEquals(reqVO.getBankAccount(), inserted.getBankAccount());
|
||||
assertEquals(reqVO.getRegisteredAddress(), inserted.getRegisteredAddress());
|
||||
assertEquals(reqVO.getFixedPhone(), inserted.getFixedPhone());
|
||||
assertEquals(reqVO.getEmail(), inserted.getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -128,15 +159,11 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
reqVO.setInvoiceType(0);
|
||||
reqVO.setTaxNumber(null);
|
||||
|
||||
ServiceException ex = assertThrows(
|
||||
ServiceException.class,
|
||||
() -> invoiceService.insetInvoiceTitle(reqVO)
|
||||
);
|
||||
assertServiceException(() -> invoiceService.insetInvoiceTitle(reqVO), INVOICE_TITLE_ENTERPRISE_TAXNUMBER_EMPTY_ERROR);
|
||||
|
||||
// 校验未调用
|
||||
verify(invoiceTitleInfoMapper, never()).selectOne(any(LambdaQueryWrapper.class));
|
||||
|
||||
assertEquals(
|
||||
INVOICE_TITLE_ENTERPRISE_TAXNUMBER_EMPTY_ERROR.getCode(),
|
||||
ex.getCode()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -144,7 +171,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
void insetInvoiceTitle_sameOrgan_throwOrgExists() {
|
||||
Long organId = SecurityFrameworkUtils.getUserOrganId();
|
||||
|
||||
invoiceTitleInfoMapper.insert(InvoiceTitleInfoDO.builder()
|
||||
when(invoiceTitleInfoMapper.selectOne(any())).thenReturn(InvoiceTitleInfoDO.builder()
|
||||
.organId(organId)
|
||||
.issueType(InvoiceIssueTypeEnum.PERSONAL.getValue())
|
||||
.invoiceTitle("已存在")
|
||||
@@ -154,15 +181,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
reqVO.setInvoiceTitle("新抬头");
|
||||
reqVO.setIssueType(InvoiceIssueTypeEnum.PERSONAL.getValue());
|
||||
|
||||
ServiceException ex = assertThrows(
|
||||
ServiceException.class,
|
||||
() -> invoiceService.insetInvoiceTitle(reqVO)
|
||||
);
|
||||
|
||||
assertEquals(
|
||||
INVOICE_TITLE_ORG_EXISTS_ERROR.getCode(),
|
||||
ex.getCode()
|
||||
);
|
||||
assertServiceException(() -> invoiceService.insetInvoiceTitle(reqVO), INVOICE_TITLE_ORG_EXISTS_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -173,41 +192,26 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
reqVO.setInvoiceTitle("测试抬头");
|
||||
reqVO.setIssueType(InvoiceIssueTypeEnum.PERSONAL.getValue());
|
||||
|
||||
ServiceException ex = assertThrows(
|
||||
ServiceException.class,
|
||||
() -> invoiceService.insetInvoiceTitle(reqVO)
|
||||
);
|
||||
|
||||
assertEquals(
|
||||
INVOICE_TITLE_NOT_EXISTS_ERROR.getCode(),
|
||||
ex.getCode()
|
||||
);
|
||||
assertServiceException(() -> invoiceService.insetInvoiceTitle(reqVO), INVOICE_TITLE_NOT_EXISTS_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void insetInvoiceTitle_update_orgNotMatch_throwException() {
|
||||
InvoiceTitleInfoDO exist = InvoiceTitleInfoDO.builder()
|
||||
.id(100L)
|
||||
.organId(2L)
|
||||
.issueType(InvoiceIssueTypeEnum.PERSONAL.getValue())
|
||||
.invoiceTitle("原抬头")
|
||||
.build();
|
||||
invoiceTitleInfoMapper.insert(exist);
|
||||
when(invoiceTitleInfoMapper.selectById(any())).thenReturn(exist);
|
||||
|
||||
InvoiceTitleSaveReqVO reqVO = new InvoiceTitleSaveReqVO();
|
||||
reqVO.setId(exist.getId());
|
||||
reqVO.setInvoiceTitle("非法更新");
|
||||
reqVO.setIssueType(exist.getIssueType());
|
||||
|
||||
ServiceException ex = assertThrows(
|
||||
ServiceException.class,
|
||||
() -> invoiceService.insetInvoiceTitle(reqVO)
|
||||
);
|
||||
|
||||
assertEquals(
|
||||
INVOICE_TITLE_NOT_EXISTS_ERROR.getCode(),
|
||||
ex.getCode()
|
||||
);
|
||||
assertServiceException(() -> invoiceService.insetInvoiceTitle(reqVO), INVOICE_TITLE_NOT_EXISTS_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -223,26 +227,26 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
invoiceService.insetInvoiceTitle(reqVO);
|
||||
|
||||
// 验证数据库
|
||||
List<InvoiceTitleInfoDO> list = invoiceTitleInfoMapper.selectList(null);
|
||||
assertEquals(1, list.size());
|
||||
|
||||
InvoiceTitleInfoDO saved = list.get(0);
|
||||
assertEquals(organId, saved.getOrganId());
|
||||
assertEquals("新增抬头", saved.getInvoiceTitle());
|
||||
// 验证插入
|
||||
verify(invoiceTitleInfoMapper).insert(argThat((InvoiceTitleInfoDO infoDO) ->
|
||||
infoDO.getInvoiceTitle().equals(reqVO.getInvoiceTitle())
|
||||
&& infoDO.getOrganId().equals(organId)
|
||||
&& infoDO.getIssueType().equals(reqVO.getIssueType())
|
||||
&& infoDO.getInvoiceType().equals(reqVO.getInvoiceType())
|
||||
&& infoDO.getEmail().equals(reqVO.getEmail())
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void insetInvoiceTitle_enterprise_taxNumberExists_throwException() {
|
||||
// 先插入一条企业发票抬头
|
||||
InvoiceTitleInfoDO exist = InvoiceTitleInfoDO.builder()
|
||||
|
||||
when(invoiceTitleInfoMapper.selectOne(any())).thenReturn(null).thenReturn(InvoiceTitleInfoDO.builder()
|
||||
.organId(2L) // 不同组织也没关系
|
||||
.invoiceTitle("已存在抬头")
|
||||
.issueType(InvoiceIssueTypeEnum.ENTERPRISE.getValue())
|
||||
.taxNumber("91330100XXXXXX")
|
||||
.build();
|
||||
invoiceTitleInfoMapper.insert(exist);
|
||||
.build());
|
||||
|
||||
// 再新增一条相同税号
|
||||
InvoiceTitleSaveReqVO reqVO = new InvoiceTitleSaveReqVO();
|
||||
@@ -250,15 +254,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
reqVO.setIssueType(InvoiceIssueTypeEnum.ENTERPRISE.getValue());
|
||||
reqVO.setTaxNumber("91330100XXXXXX");
|
||||
|
||||
ServiceException ex = assertThrows(
|
||||
ServiceException.class,
|
||||
() -> invoiceService.insetInvoiceTitle(reqVO)
|
||||
);
|
||||
|
||||
assertEquals(
|
||||
INVOICE_TITLE_TAXPAYERID_EXISTS_ERROR.getCode(),
|
||||
ex.getCode()
|
||||
);
|
||||
assertServiceException(() -> invoiceService.insetInvoiceTitle(reqVO), INVOICE_TITLE_TAXPAYERID_EXISTS_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -266,13 +262,13 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
void insetInvoiceTitle_update_success() {
|
||||
Long organId = SecurityFrameworkUtils.getUserOrganId();
|
||||
|
||||
// given:数据库已有数据(organId 一定要一致)
|
||||
InvoiceTitleInfoDO exist = InvoiceTitleInfoDO.builder()
|
||||
.id(100L)
|
||||
.organId(organId)
|
||||
.invoiceTitle("旧抬头")
|
||||
.issueType(InvoiceIssueTypeEnum.PERSONAL.getValue())
|
||||
.build();
|
||||
invoiceTitleInfoMapper.insert(exist);
|
||||
when(invoiceTitleInfoMapper.selectById(exist.getId())).thenReturn(exist);
|
||||
|
||||
// when:更新
|
||||
InvoiceTitleSaveReqVO reqVO = new InvoiceTitleSaveReqVO();
|
||||
@@ -282,17 +278,26 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
invoiceService.insetInvoiceTitle(reqVO);
|
||||
|
||||
// then:断言更新成功
|
||||
InvoiceTitleInfoDO updated = invoiceTitleInfoMapper.selectById(exist.getId());
|
||||
assertEquals("新抬头", updated.getInvoiceTitle());
|
||||
// 捕获 update 的参数,断言字段
|
||||
ArgumentCaptor<InvoiceTitleInfoDO> captor =
|
||||
ArgumentCaptor.forClass(InvoiceTitleInfoDO.class);
|
||||
verify(invoiceTitleInfoMapper).updateById(captor.capture());
|
||||
|
||||
InvoiceTitleInfoDO actual = captor.getValue();
|
||||
|
||||
assertEquals(reqVO.getId(), actual.getId());
|
||||
assertEquals(reqVO.getInvoiceTitle(), actual.getInvoiceTitle());
|
||||
assertEquals(reqVO.getIssueType(), actual.getIssueType());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void getAvailablePage_whenEmptyList_returnEmptyPageResult() {
|
||||
// given
|
||||
InvoiceAmountAndAvailablePageReqVO reqVO = new InvoiceAmountAndAvailablePageReqVO();
|
||||
|
||||
when(purchaseRecordMapper.selectPage(any(InvoiceAmountAndAvailablePageReqVO.class))).thenReturn(new PageResult());
|
||||
|
||||
// when
|
||||
PageResult<InvoiceAvailablePageRespVO> result =
|
||||
invoiceService.getAvailablePage(reqVO);
|
||||
@@ -304,7 +309,6 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(organId = 1L)
|
||||
void getAvailablePage_whenHasData_returnConvertedPage() {
|
||||
// given
|
||||
InvoiceAmountAndAvailablePageReqVO reqVO =
|
||||
@@ -321,7 +325,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInitial(false);
|
||||
o.setOrganId(1L);
|
||||
});
|
||||
purchaseRecordMapper.insert(invoiceRecordsDO);
|
||||
when(purchaseRecordMapper.selectPage(any(InvoiceAmountAndAvailablePageReqVO.class))).thenReturn(new PageResult(List.of(invoiceRecordsDO), 1L));
|
||||
|
||||
// when
|
||||
PageResult<InvoiceAvailablePageRespVO> result =
|
||||
@@ -364,7 +368,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
.issueType(InvoiceIssueTypeEnum.ENTERPRISE.getValue())
|
||||
.taxNumber("91330100XXXXXX")
|
||||
.build();
|
||||
invoiceTitleInfoMapper.insert(exist);
|
||||
when(invoiceTitleInfoMapper.selectOne(any())).thenReturn(exist);
|
||||
|
||||
InvoiceRecordsReqVO reqVO = new InvoiceRecordsReqVO();
|
||||
|
||||
@@ -379,24 +383,28 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInitial(false);
|
||||
o.setOrganId(1L);
|
||||
});
|
||||
purchaseRecordMapper.insert(invoiceRecordsDO);
|
||||
when(purchaseRecordMapper.selectByIds(anyList())).thenReturn(List.of(invoiceRecordsDO));
|
||||
|
||||
// 有不可开票状态的记录
|
||||
reqVO.setPurchaseRecordId(List.of(invoiceRecordsDO.getId()));
|
||||
assertServiceException(() -> invoiceService.applyInvoice(reqVO), INVOICE_APPLY_UNINVOICEABLE_EXIST);
|
||||
|
||||
// 可开金额为0
|
||||
invoiceRecordsDO.setId(null);
|
||||
invoiceRecordsDO.setExternalSpent(BigDecimal.ZERO);
|
||||
invoiceRecordsDO.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
purchaseRecordMapper.insert(invoiceRecordsDO);
|
||||
when(purchaseRecordMapper.selectByIds(anyList())).thenReturn(List.of(invoiceRecordsDO));
|
||||
|
||||
reqVO.setPurchaseRecordId(List.of(invoiceRecordsDO.getId()));
|
||||
when(purchaseRecordMapper.getInvoicableAmount(anyLong(), anyList())).thenReturn(BigDecimal.ZERO);
|
||||
|
||||
assertServiceException(() -> invoiceService.applyInvoice(reqVO), INVOICE_AMOUNT_ZERO_ERROR);
|
||||
|
||||
// 更新开票状态和开票id数量不匹配
|
||||
invoiceRecordsDO.setId(null);
|
||||
invoiceRecordsDO.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
invoiceRecordsDO.setExternalSpent(new BigDecimal("100"));
|
||||
purchaseRecordMapper.insert(invoiceRecordsDO);
|
||||
when(purchaseRecordMapper.selectByIds(anyList())).thenReturn(List.of(invoiceRecordsDO));
|
||||
when(purchaseRecordMapper.getInvoicableAmount(anyLong(), anyList())).thenReturn(BigDecimal.ONE);
|
||||
when(purchaseRecordMapper.update(any(LambdaUpdateWrapper.class))).thenReturn(10);
|
||||
|
||||
reqVO.setPurchaseRecordId(List.of(invoiceRecordsDO.getId(), 999L));
|
||||
assertServiceException(
|
||||
@@ -409,14 +417,18 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
@Test
|
||||
@WithMockLoginUser(organId = 1L)
|
||||
void applyInvoice_success() {
|
||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||
Long organId = loginUser.getOrganId();
|
||||
Long userId = loginUser.getId();
|
||||
|
||||
// 先插入一条企业发票抬头
|
||||
InvoiceTitleInfoDO exist = InvoiceTitleInfoDO.builder()
|
||||
.organId(1L) // 不同组织也没关系
|
||||
.organId(organId) // 不同组织也没关系
|
||||
.invoiceTitle("已存在抬头")
|
||||
.issueType(InvoiceIssueTypeEnum.ENTERPRISE.getValue())
|
||||
.taxNumber("91330100XXXXXX")
|
||||
.build();
|
||||
invoiceTitleInfoMapper.insert(exist);
|
||||
when(invoiceTitleInfoMapper.selectOne(any())).thenReturn(exist);
|
||||
|
||||
InvoiceRecordsReqVO reqVO = new InvoiceRecordsReqVO();
|
||||
|
||||
@@ -428,9 +440,11 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setPaymentMethod(PayChannelCodeEnum.ALIPAY_PC.getCode());
|
||||
o.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
o.setOrganId(1L);
|
||||
o.setOrganId(organId);
|
||||
});
|
||||
purchaseRecordMapper.insert(invoiceRecordsDO);
|
||||
when(purchaseRecordMapper.selectByIds(anyList())).thenReturn(List.of(invoiceRecordsDO));
|
||||
when(purchaseRecordMapper.getInvoicableAmount(anyLong(), anyList())).thenReturn(BigDecimal.ONE);
|
||||
when(purchaseRecordMapper.update(any(LambdaUpdateWrapper.class))).thenReturn(1);
|
||||
|
||||
Long recordId = invoiceRecordsDO.getId();
|
||||
reqVO.setPurchaseRecordId(List.of(recordId));
|
||||
@@ -438,28 +452,30 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
// 组织
|
||||
OrganizationDO org = new OrganizationDO();
|
||||
org.setName("测试组织");
|
||||
org.setId(1L);
|
||||
org.setId(organId);
|
||||
when(organService.validOrgan(1L)).thenReturn(org);
|
||||
|
||||
assertDoesNotThrow(() -> {
|
||||
invoiceService.applyInvoice(reqVO);
|
||||
});
|
||||
List<InvoiceRecordsDO> invoiceRecordsDOS = invoiceRecordsMapper.selectList();
|
||||
assertEquals(1, invoiceRecordsDOS.size());
|
||||
InvoiceRecordsDO query = invoiceRecordsDOS.get(0);
|
||||
assertNotNull(invoiceRecordsDO);
|
||||
assertEquals(invoiceRecordsDO.getOrganId(), invoiceRecordsDO.getOrganId());
|
||||
assertEquals(query.getPurchaseIds(), List.of(invoiceRecordsDO.getId()).toString());
|
||||
assertEquals("测试组织", query.getOrganName());
|
||||
|
||||
// 验证插入
|
||||
verify(invoiceRecordsMapper).insert(argThat((InvoiceRecordsDO recordsDO) ->
|
||||
recordsDO.getOrganId().equals(organId)
|
||||
&& recordsDO.getUserId().equals(userId)
|
||||
&& recordsDO.getOrganName().equals("测试组织")
|
||||
&& recordsDO.getInvoiceAmount().equals(BigDecimal.ONE)
|
||||
&& recordsDO.getStatus().equals(InvoiceStatusEnum.PENDINGINVOICING.getCode())
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void getInvoiceRecords_whenEmptyList_returnEmptyPageResult() {
|
||||
// given
|
||||
InvoiceDetailsPageReqVO pageReqVO = new InvoiceDetailsPageReqVO();
|
||||
|
||||
// when
|
||||
when(invoiceRecordsMapper.selectInvoiceRecordsPage(any())).thenReturn(new PageResult<>());
|
||||
PageResult<InvoiceRecordsRespVO> result = invoiceService.getInvoiceRecords(pageReqVO);
|
||||
|
||||
// then
|
||||
@@ -469,7 +485,6 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void getInvoiceRecords_whenHasData_returnConvertedPage() {
|
||||
// given
|
||||
InvoiceDetailsPageReqVO pageReqVO = new InvoiceDetailsPageReqVO();
|
||||
@@ -479,7 +494,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInvoiceAmount(new BigDecimal("100.00"));
|
||||
o.setStatus(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
when(invoiceRecordsMapper.selectInvoiceRecordsPage(any())).thenReturn(new PageResult<>(List.of(invoiceRecordsDO), 1L));
|
||||
|
||||
// when
|
||||
PageResult<InvoiceRecordsRespVO> result = invoiceService.getInvoiceRecords(pageReqVO);
|
||||
@@ -496,13 +511,11 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void getInvoiceRecordDetail_whenRecordNotExists_thenThrowException() {
|
||||
assertServiceException(() -> invoiceService.getInvoiceRecordDetail(1L), INVOICE_NO_EXIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void getInvoiceRecordDetail_whenRecordExists_thenReturnDetail() {
|
||||
// 准备数据
|
||||
InvoiceRecordsDO invoiceRecordsDO = randomPojo(InvoiceRecordsDO.class, o -> {
|
||||
@@ -512,7 +525,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setPurchaseIds("[1, 2]");
|
||||
o.setInvoiceTitleInfo(zipString("{\"invoiceTitle\":\"测试公司\"}"));
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
when(invoiceRecordsMapper.selectById(anyLong())).thenReturn(invoiceRecordsDO);
|
||||
|
||||
PurchaseRecordDO purchase1 = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(1L);
|
||||
@@ -523,7 +536,6 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
});
|
||||
purchaseRecordMapper.insert(purchase1);
|
||||
|
||||
PurchaseRecordDO purchase2 = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(2L);
|
||||
@@ -534,7 +546,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
});
|
||||
purchaseRecordMapper.insert(purchase2);
|
||||
when(purchaseRecordMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(List.of(purchase1, purchase2));
|
||||
|
||||
// 调用方法
|
||||
InvoiceDetailsRespVO result = invoiceService.getInvoiceRecordDetail(1L);
|
||||
@@ -567,7 +579,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setId(1L);
|
||||
o.setStatus(InvoiceStatusEnum.INVOICINGSUCCESSFUL.getCode());
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
when(invoiceRecordsMapper.selectById(1L)).thenReturn(invoiceRecordsDO);
|
||||
|
||||
InvoiceConfirmReqVO reqVO = new InvoiceConfirmReqVO();
|
||||
reqVO.setId(1L);
|
||||
@@ -583,7 +595,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setId(1L);
|
||||
o.setStatus(InvoiceStatusEnum.INVOICINGFAILED.getCode());
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
when(invoiceRecordsMapper.selectById(1L)).thenReturn(invoiceRecordsDO);
|
||||
|
||||
InvoiceConfirmReqVO reqVO = new InvoiceConfirmReqVO();
|
||||
reqVO.setId(1L);
|
||||
@@ -602,7 +614,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInvoiceTitleId(1L);
|
||||
o.setOrganId(1L);
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
when(invoiceRecordsMapper.selectById(1L)).thenReturn(invoiceRecordsDO);
|
||||
|
||||
InvoiceConfirmReqVO reqVO = new InvoiceConfirmReqVO();
|
||||
reqVO.setId(1L);
|
||||
@@ -621,14 +633,14 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInvoiceTitleId(1L);
|
||||
o.setOrganId(1L);
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
when(invoiceRecordsMapper.selectById(1L)).thenReturn(invoiceRecordsDO);
|
||||
|
||||
InvoiceTitleInfoDO title = randomPojo(InvoiceTitleInfoDO.class, o -> {
|
||||
o.setId(1L);
|
||||
o.setOrganId(1L);
|
||||
o.setInvoiceTitle("测试公司");
|
||||
});
|
||||
invoiceTitleInfoMapper.insert(title);
|
||||
when(invoiceTitleInfoMapper.selectById(anyLong())).thenReturn(title);
|
||||
|
||||
PurchaseRecordDO purchase = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(1L);
|
||||
@@ -637,7 +649,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
});
|
||||
purchaseRecordMapper.insert(purchase);
|
||||
when(purchaseRecordMapper.selectByIds(anyList())).thenReturn(List.of(purchase));
|
||||
|
||||
InvoiceConfirmReqVO reqVO = new InvoiceConfirmReqVO();
|
||||
reqVO.setId(1L);
|
||||
@@ -657,14 +669,14 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInvoiceTitleId(1L);
|
||||
o.setOrganId(1L);
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
when(invoiceRecordsMapper.selectById(1L)).thenReturn(invoiceRecordsDO);
|
||||
|
||||
InvoiceTitleInfoDO title = randomPojo(InvoiceTitleInfoDO.class, o -> {
|
||||
o.setId(1L);
|
||||
o.setOrganId(1L);
|
||||
o.setInvoiceTitle("测试公司");
|
||||
});
|
||||
invoiceTitleInfoMapper.insert(title);
|
||||
when(invoiceTitleInfoMapper.selectById(anyLong())).thenReturn(title);
|
||||
|
||||
PurchaseRecordDO purchase = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(1L);
|
||||
@@ -673,7 +685,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
});
|
||||
purchaseRecordMapper.insert(purchase);
|
||||
when(purchaseRecordMapper.selectByIds(anyList())).thenReturn(List.of(purchase));
|
||||
|
||||
InvoiceConfirmReqVO reqVO = new InvoiceConfirmReqVO();
|
||||
reqVO.setId(1L);
|
||||
@@ -695,14 +707,14 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setOrganId(1L);
|
||||
o.setInvoiceAmount(new BigDecimal("100.00"));
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
when(invoiceRecordsMapper.selectById(1L)).thenReturn(invoiceRecordsDO);
|
||||
|
||||
InvoiceTitleInfoDO title = randomPojo(InvoiceTitleInfoDO.class, o -> {
|
||||
o.setId(1L);
|
||||
o.setOrganId(1L);
|
||||
o.setInvoiceTitle("测试公司");
|
||||
});
|
||||
invoiceTitleInfoMapper.insert(title);
|
||||
when(invoiceTitleInfoMapper.selectById(anyLong())).thenReturn(title);
|
||||
|
||||
PurchaseRecordDO purchase = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(1L);
|
||||
@@ -711,11 +723,12 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
});
|
||||
purchaseRecordMapper.insert(purchase);
|
||||
when(purchaseRecordMapper.selectByIds(anyList())).thenReturn(List.of(purchase));
|
||||
|
||||
// Mock 文件上传
|
||||
Long fileId = 999L;
|
||||
MockMultipartFile file = new MockMultipartFile("file", "测试公司-20231010101010-100.pdf", "application/pdf", "content".getBytes());
|
||||
when(fileApi.createFileAndReturnId(any(byte[].class), anyString())).thenReturn(1L);
|
||||
when(fileApi.createFileAndReturnId(any(byte[].class), anyString())).thenReturn(fileId);
|
||||
|
||||
InvoiceConfirmReqVO reqVO = new InvoiceConfirmReqVO();
|
||||
reqVO.setId(1L);
|
||||
@@ -727,17 +740,15 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
assertDoesNotThrow(() -> invoiceService.confirmInvoice(reqVO, file));
|
||||
|
||||
// 验证数据库更新
|
||||
InvoiceRecordsDO updatedRecord = invoiceRecordsMapper.selectById(1L);
|
||||
assertEquals(InvoiceStatusEnum.INVOICINGSUCCESSFUL.getCode(), updatedRecord.getStatus());
|
||||
assertEquals("FP20231010101010", updatedRecord.getInvoiceNo());
|
||||
assertEquals("同意开票", updatedRecord.getRemark());
|
||||
assertEquals("测试用户", updatedRecord.getInvoicePerson());
|
||||
assertEquals(1L, updatedRecord.getInvoicePersonId());
|
||||
assertNotNull(updatedRecord.getInvoiceTime());
|
||||
assertEquals(1L, updatedRecord.getInvoiceAttachmentId());
|
||||
verify(invoiceRecordsMapper).updateById(argThat((InvoiceRecordsDO recordsDO) ->
|
||||
recordsDO.getStatus().equals(InvoiceStatusEnum.INVOICINGSUCCESSFUL.getCode())
|
||||
&& recordsDO.getRemark().equals(reqVO.getRemark())
|
||||
&& recordsDO.getInvoiceAttachmentId().equals(fileId)
|
||||
&& recordsDO.getInvoiceNo().equals(reqVO.getInvoiceNo())
|
||||
));
|
||||
|
||||
PurchaseRecordDO updatedPurchase = purchaseRecordMapper.selectById(1L);
|
||||
assertEquals(InvoiceStatusEnum.INVOICINGSUCCESSFUL.getCode(), updatedPurchase.getIsInvocing());
|
||||
verify(purchaseRecordMapper, times(1))
|
||||
.updateBatch(anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -751,14 +762,14 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInvoiceTitleId(1L);
|
||||
o.setOrganId(1L);
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
when(invoiceRecordsMapper.selectById(1L)).thenReturn(invoiceRecordsDO);
|
||||
|
||||
InvoiceTitleInfoDO title = randomPojo(InvoiceTitleInfoDO.class, o -> {
|
||||
o.setId(1L);
|
||||
o.setOrganId(1L);
|
||||
o.setInvoiceTitle("测试公司");
|
||||
});
|
||||
invoiceTitleInfoMapper.insert(title);
|
||||
when(invoiceTitleInfoMapper.selectById(anyLong())).thenReturn(title);
|
||||
|
||||
PurchaseRecordDO purchase = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(1L);
|
||||
@@ -767,7 +778,7 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
});
|
||||
purchaseRecordMapper.insert(purchase);
|
||||
when(purchaseRecordMapper.selectByIds(anyList())).thenReturn(List.of(purchase));
|
||||
|
||||
InvoiceConfirmReqVO reqVO = new InvoiceConfirmReqVO();
|
||||
reqVO.setId(1L);
|
||||
@@ -778,96 +789,49 @@ class InvoiceServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
assertDoesNotThrow(() -> invoiceService.confirmInvoice(reqVO, null));
|
||||
|
||||
// 验证数据库更新
|
||||
InvoiceRecordsDO updatedRecord = invoiceRecordsMapper.selectById(1L);
|
||||
assertEquals(InvoiceStatusEnum.INVOICINGFAILED.getCode(), updatedRecord.getStatus());
|
||||
assertEquals("拒绝开票", updatedRecord.getRemark());
|
||||
assertEquals("测试用户", updatedRecord.getInvoicePerson());
|
||||
assertEquals(1L, updatedRecord.getInvoicePersonId());
|
||||
assertNotNull(updatedRecord.getInvoiceTime());
|
||||
verify(invoiceRecordsMapper).updateById(argThat((InvoiceRecordsDO recordsDO) ->
|
||||
recordsDO.getStatus().equals(InvoiceStatusEnum.INVOICINGFAILED.getCode())
|
||||
&& recordsDO.getRemark().equals(reqVO.getRemark())
|
||||
));
|
||||
|
||||
PurchaseRecordDO updatedPurchase = purchaseRecordMapper.selectById(1L);
|
||||
assertEquals(InvoiceStatusEnum.INVOICABLE.getCode(), updatedPurchase.getIsInvocing());
|
||||
verify(purchaseRecordMapper, times(1))
|
||||
.updateBatch(anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void getInvoiceAmount_whenNoData_thenReturnZeroValues() {
|
||||
InvoiceAmountRespVO invoiceAmountRespVO = new InvoiceAmountRespVO();
|
||||
invoiceAmountRespVO.setInvocable(BigDecimal.ZERO);
|
||||
invoiceAmountRespVO.setInTheInvoice(BigDecimal.ONE);
|
||||
invoiceAmountRespVO.setInvoiced(BigDecimal.TEN);
|
||||
when(purchaseRecordMapper.getOrgInvoiceAmountStatistics(anyLong())).thenReturn(invoiceAmountRespVO);
|
||||
|
||||
// 调用方法
|
||||
InvoiceAmountRespVO result = invoiceService.getInvoiceAmount();
|
||||
|
||||
// 验证结果
|
||||
assertNotNull(result);
|
||||
assertEquals(BigDecimal.ZERO, result.getInvocable());
|
||||
assertEquals(BigDecimal.ZERO, result.getInTheInvoice());
|
||||
assertEquals(BigDecimal.ZERO, result.getInvoiced());
|
||||
assertEquals(BigDecimal.ONE, result.getInTheInvoice());
|
||||
assertEquals(BigDecimal.TEN, result.getInvoiced());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void getInvoiceAmount_whenHasData_thenReturnCorrectValues() {
|
||||
// 可开票
|
||||
PurchaseRecordDO purchaseRecordDO = randomPojo(PurchaseRecordDO.class, o->{
|
||||
o.setExternalSpent(new BigDecimal("100.00"));
|
||||
o.setPaymentMethod(PayChannelCodeEnum.ALIPAY_PC.getCode());
|
||||
o.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
o.setOrganId(SecurityFrameworkUtils.getUserOrganId());
|
||||
});
|
||||
purchaseRecordMapper.insert(purchaseRecordDO);
|
||||
|
||||
InvoiceAmountRespVO result = invoiceService.getInvoiceAmount();
|
||||
assertNotNull(result);
|
||||
assertEquals(new BigDecimal("100.00"), result.getInvocable());
|
||||
|
||||
// 开票中
|
||||
purchaseRecordDO.setId(null);
|
||||
purchaseRecordDO.setIsInvocing(InvoiceStatusEnum.PENDINGINVOICING.getCode());
|
||||
purchaseRecordMapper.insert(purchaseRecordDO);
|
||||
result = invoiceService.getInvoiceAmount();
|
||||
assertNotNull(result);
|
||||
assertEquals(new BigDecimal("100.00"), result.getInTheInvoice());
|
||||
|
||||
// 已开票
|
||||
purchaseRecordDO.setId(null);
|
||||
purchaseRecordDO.setIsInvocing(InvoiceStatusEnum.INVOICINGSUCCESSFUL.getCode());
|
||||
purchaseRecordMapper.insert(purchaseRecordDO);
|
||||
result = invoiceService.getInvoiceAmount();
|
||||
assertNotNull(result);
|
||||
assertEquals(new BigDecimal("100.00"), result.getInvoiced());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getManageInvoiceAmount_whenNoData_thenReturnZeroValues() {
|
||||
InvoiceAmountRespVO invoiceAmountRespVO = new InvoiceAmountRespVO();
|
||||
invoiceAmountRespVO.setPendingInvoice(BigDecimal.TEN);
|
||||
invoiceAmountRespVO.setInvoiced(BigDecimal.ZERO);
|
||||
when(invoiceRecordsMapper.getManageInvoiceAmountStatistics()).thenReturn(invoiceAmountRespVO);
|
||||
|
||||
// 调用方法
|
||||
InvoiceAmountRespVO result = invoiceService.getManageInvoiceAmount();
|
||||
|
||||
// 验证结果
|
||||
assertNotNull(result);
|
||||
assertEquals(BigDecimal.ZERO, result.getPendingInvoice());
|
||||
assertEquals(BigDecimal.TEN, result.getPendingInvoice());
|
||||
assertEquals(BigDecimal.ZERO, result.getInvoiced());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getManageInvoiceAmount_whenHasData_thenReturnCorrectValues() {
|
||||
// 待开票
|
||||
InvoiceRecordsDO invoiceRecordsDO = randomPojo(InvoiceRecordsDO.class, o -> {
|
||||
o.setInvoiceAmount(new BigDecimal("150.00"));
|
||||
o.setStatus(InvoiceStatusEnum.PENDINGINVOICING.getCode());
|
||||
});
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
InvoiceAmountRespVO result = invoiceService.getManageInvoiceAmount();
|
||||
assertNotNull(result);
|
||||
assertEquals(new BigDecimal("150.00"), result.getPendingInvoice());
|
||||
|
||||
// 已开票
|
||||
invoiceRecordsDO.setId(null);
|
||||
invoiceRecordsDO.setStatus(InvoiceStatusEnum.INVOICINGSUCCESSFUL.getCode());
|
||||
invoiceRecordsDO.setInvoiceAmount(new BigDecimal("300.00"));
|
||||
invoiceRecordsMapper.insert(invoiceRecordsDO);
|
||||
result = invoiceService.getManageInvoiceAmount();
|
||||
assertEquals(new BigDecimal("300.00"), result.getInvoiced());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getFileExtension_whenFileNameIsNull_thenReturnEmpty() {
|
||||
assertEquals("", InvoiceServiceImpl.getFileExtension(null));
|
||||
|
||||
+47
-52
@@ -3,31 +3,31 @@ package com.cf.imes.module.system.service.funds.organamount;
|
||||
import com.cf.imes.framework.common.enums.StatisticsUnit;
|
||||
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.system.common.WithMockLoginUserExtension;
|
||||
import com.cf.imes.module.system.controller.admin.funds.invoice.vo.InvoiceAmountRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.ManageAmountOverviewRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.OrganAmountGroupByCreateTimeRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.OrganFundsStatisticsReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.OrganProductOverviewRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.TotalSalesAmountRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.OrgEarliestPurchaseProductRespVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.incomeandexpense.IncomeExpenseDetailsDO;
|
||||
import com.cf.imes.module.system.dal.mysql.incomeandexpense.IncomeExpenseDetailsMapper;
|
||||
import com.cf.imes.module.system.service.funds.invoice.InvoiceService;
|
||||
import com.cf.imes.module.system.service.funds.purchase.PurchaseService;
|
||||
import com.cf.imes.module.system.service.organ.OrganService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
@@ -35,27 +35,21 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2025/12/31 14:00
|
||||
*/
|
||||
@Import(OrganAmountServiceImpl.class)
|
||||
public class OrganAmountServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
@Resource
|
||||
@ExtendWith(WithMockLoginUserExtension.class)
|
||||
class OrganAmountServiceImplTest extends BaseMockitoUnitTest {
|
||||
@Mock
|
||||
IncomeExpenseDetailsMapper incomeExpenseDetailsMapper;
|
||||
|
||||
@Resource
|
||||
@InjectMocks
|
||||
private OrganAmountServiceImpl organAmountService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private OrganService organService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private PurchaseService purchaseService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private InvoiceService invoiceService;
|
||||
|
||||
@Test
|
||||
@@ -64,13 +58,13 @@ public class OrganAmountServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
// ===== given =====
|
||||
Long organId = SecurityFrameworkUtils.getUserOrganId();
|
||||
|
||||
PurchaseRecordDO record = new PurchaseRecordDO();
|
||||
record.setEndTime(LocalDate.of(2025, 12, 31));
|
||||
record.setInitial(false);
|
||||
record.setPurchaseDuration(12);
|
||||
record.setPurchaseDurationUnit(1);
|
||||
PurchaseRecordDO recordDO = new PurchaseRecordDO();
|
||||
recordDO.setEndTime(LocalDate.of(2025, 12, 31));
|
||||
recordDO.setInitial(false);
|
||||
recordDO.setPurchaseDuration(12);
|
||||
recordDO.setPurchaseDurationUnit(1);
|
||||
|
||||
OrgEarliestPurchaseProductRespVO resp = new OrgEarliestPurchaseProductRespVO(record);
|
||||
OrgEarliestPurchaseProductRespVO resp = new OrgEarliestPurchaseProductRespVO(recordDO);
|
||||
|
||||
when(purchaseService.getOrgEarliestProductDetail(organId))
|
||||
.thenReturn(resp);
|
||||
@@ -125,11 +119,11 @@ public class OrganAmountServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
void testGetOrganProductOverview_initialPurchase() {
|
||||
Long organId = SecurityFrameworkUtils.getUserOrganId();
|
||||
|
||||
PurchaseRecordDO record = new PurchaseRecordDO();
|
||||
record.setEndTime(LocalDate.of(2025, 1, 1));
|
||||
record.setInitial(true);
|
||||
PurchaseRecordDO recordDO = new PurchaseRecordDO();
|
||||
recordDO.setEndTime(LocalDate.of(2025, 1, 1));
|
||||
recordDO.setInitial(true);
|
||||
|
||||
OrgEarliestPurchaseProductRespVO resp = new OrgEarliestPurchaseProductRespVO(record);
|
||||
OrgEarliestPurchaseProductRespVO resp = new OrgEarliestPurchaseProductRespVO(recordDO);
|
||||
|
||||
when(purchaseService.getOrgEarliestProductDetail(organId))
|
||||
.thenReturn(resp);
|
||||
@@ -181,24 +175,23 @@ public class OrganAmountServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
LocalDate.now().plusDays(1)
|
||||
});
|
||||
|
||||
IncomeExpenseDetailsDO pojo1 = randomPojo(IncomeExpenseDetailsDO.class, o -> {
|
||||
o.setOrganId(organId);
|
||||
o.setAmount(new BigDecimal("100"));
|
||||
o.setCreateTime(LocalDateTime.now().minusDays(2));
|
||||
});
|
||||
IncomeExpenseDetailsDO pojo2 = randomPojo(IncomeExpenseDetailsDO.class, o -> {
|
||||
o.setOrganId(organId);
|
||||
o.setAmount(new BigDecimal("200"));
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
});
|
||||
IncomeExpenseDetailsDO pojo3 = randomPojo(IncomeExpenseDetailsDO.class, o -> {
|
||||
o.setAmount(new BigDecimal("200"));
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
});
|
||||
OrganAmountGroupByCreateTimeRespVO vo1 = new OrganAmountGroupByCreateTimeRespVO();
|
||||
vo1.setDate("2026-1-14");
|
||||
vo1.setAmount(new BigDecimal("100"));
|
||||
|
||||
incomeExpenseDetailsMapper.insert(pojo1);
|
||||
incomeExpenseDetailsMapper.insert(pojo2);
|
||||
incomeExpenseDetailsMapper.insert(pojo3);
|
||||
OrganAmountGroupByCreateTimeRespVO vo2 = new OrganAmountGroupByCreateTimeRespVO();
|
||||
vo2.setDate("2026-1-16");
|
||||
vo2.setAmount(new BigDecimal("200"));
|
||||
|
||||
OrganAmountGroupByCreateTimeRespVO vo3 = new OrganAmountGroupByCreateTimeRespVO();
|
||||
vo3.setDate("2026-1-15");
|
||||
vo3.setAmount(new BigDecimal("200"));
|
||||
|
||||
List<OrganAmountGroupByCreateTimeRespVO> organAmountGroupByCreateTimeRespVOS = new ArrayList<>();
|
||||
organAmountGroupByCreateTimeRespVOS.add(vo1);
|
||||
organAmountGroupByCreateTimeRespVOS.add(vo2);
|
||||
|
||||
when(incomeExpenseDetailsMapper.selectOrganIncomeExpenseTrendGroupByCreateTime(reqVO, organId)).thenReturn(organAmountGroupByCreateTimeRespVOS);
|
||||
|
||||
// when query org
|
||||
Map<String, Object> result =
|
||||
@@ -215,14 +208,16 @@ public class OrganAmountServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
assertArrayEquals(
|
||||
new BigDecimal[]{
|
||||
new BigDecimal("100.00"),
|
||||
new BigDecimal("100"),
|
||||
BigDecimal.ZERO,
|
||||
new BigDecimal("200.00"),
|
||||
new BigDecimal("200"),
|
||||
BigDecimal.ZERO,
|
||||
},
|
||||
data
|
||||
);
|
||||
|
||||
organAmountGroupByCreateTimeRespVOS.add(vo3);
|
||||
when(incomeExpenseDetailsMapper.selectOrganIncomeExpenseTrendGroupByCreateTime(reqVO, null)).thenReturn(organAmountGroupByCreateTimeRespVOS);
|
||||
// when not query org
|
||||
result = organAmountService.getConsumptionTrend(reqVO, false);
|
||||
|
||||
@@ -237,9 +232,9 @@ public class OrganAmountServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
assertArrayEquals(
|
||||
new BigDecimal[]{
|
||||
new BigDecimal("100.00"),
|
||||
BigDecimal.ZERO,
|
||||
new BigDecimal("400.00"),
|
||||
new BigDecimal("100"),
|
||||
new BigDecimal("200"),
|
||||
new BigDecimal("200"),
|
||||
BigDecimal.ZERO,
|
||||
},
|
||||
data
|
||||
|
||||
+87
-123
@@ -1,9 +1,12 @@
|
||||
package com.cf.imes.module.system.service.funds.productpromotion;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.i18n.core.util.I18nUtils;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbClearAfterClassAndRedisUnitTest;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.funds.productpromotion.vo.ProductPromotionPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.productpromotion.vo.ProductPromotionSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.productpromotion.ProductPromotionDO;
|
||||
@@ -11,18 +14,15 @@ import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO;
|
||||
import com.cf.imes.module.system.dal.mysql.funds.productpromotion.ProductPromotionMapper;
|
||||
import com.cf.imes.module.system.enums.pay.DurationUnitEnum;
|
||||
import com.cf.imes.module.system.service.funds.products.ProductsDetailService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static com.cf.imes.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
|
||||
@@ -33,34 +33,35 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Gqr
|
||||
* @since 2025/10/24 11:20
|
||||
*/
|
||||
@Import(ProductPromotionServiceImpl.class)
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
class ProductPromotionServiceImplTest extends BaseDbClearAfterClassAndRedisUnitTest {
|
||||
@Resource
|
||||
|
||||
class ProductPromotionServiceImplTest extends BaseMockitoUnitTest {
|
||||
@InjectMocks
|
||||
private ProductPromotionServiceImpl productPromotionService;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private ProductPromotionMapper productPromotionMapper;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private ProductsDetailService productsDetailService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private I18nUtils i18nUtils;
|
||||
|
||||
private static ProductPromotionDO createDO;
|
||||
@BeforeAll
|
||||
static void init(){
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), ProductPromotionDO.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
void testCreate() {
|
||||
ProductPromotionSaveReqVO reqVO = randomPojo(ProductPromotionSaveReqVO.class, o -> {
|
||||
o.setId(null);
|
||||
o.setId(100L);
|
||||
o.setActivityName("充值送活动");
|
||||
o.setPurchaseDuration(1);
|
||||
o.setPurchaseDurationUnit(DurationUnitEnum.YEAR.getCode());
|
||||
@@ -76,27 +77,33 @@ class ProductPromotionServiceImplTest extends BaseDbClearAfterClassAndRedisUnitT
|
||||
productsDO.setProductName("产品名称");
|
||||
when(productsDetailService.validateProductExist(any())).thenReturn(productsDO);
|
||||
|
||||
Long id = productPromotionService.create(reqVO);
|
||||
productPromotionService.create(reqVO);
|
||||
|
||||
// 校验数据库插入结果
|
||||
createDO = productPromotionMapper.selectById(id);
|
||||
assertNotNull(createDO);
|
||||
assertEquals("充值送活动", createDO.getActivityName());
|
||||
assertEquals(1, createDO.getPurchaseDuration());
|
||||
assertEquals(DurationUnitEnum.YEAR.getCode(), createDO.getPurchaseDurationUnit());
|
||||
assertEquals(1, createDO.getGiftDuration());
|
||||
assertEquals(DurationUnitEnum.DAY.getCode(), createDO.getGiftDurationUnit());
|
||||
// 验证插入
|
||||
verify(productPromotionMapper).insert(argThat((ProductPromotionDO infoDO) ->
|
||||
infoDO.getProductId().equals(productsDO.getId())
|
||||
&& infoDO.getProductName().equals(productsDO.getProductName())
|
||||
&& infoDO.getId().equals(100L)
|
||||
&& infoDO.getActivityName().equals(reqVO.getActivityName())
|
||||
&& infoDO.getPurchaseDuration().equals(reqVO.getPurchaseDuration())
|
||||
&& infoDO.getPurchaseDurationUnit().equals(reqVO.getPurchaseDurationUnit())
|
||||
&& infoDO.getGiftDuration().equals(reqVO.getGiftDuration())
|
||||
&& infoDO.getGiftDurationUnit().equals(reqVO.getGiftDurationUnit())
|
||||
));
|
||||
|
||||
// 再次插入相同活动名称,断言异常
|
||||
when(productPromotionMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(new ProductPromotionDO());
|
||||
assertServiceException(() -> productPromotionService.create(reqVO), PRODUCT_PROMOTION_ACTIVE_NAME_IS_EXIST);
|
||||
|
||||
// 再次插入相同产品-相同购买时长和单位,断言异常
|
||||
reqVO.setActivityName("充值送活动1");
|
||||
when(productPromotionMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(null).thenReturn(new ProductPromotionDO());
|
||||
when(i18nUtils.getMessage(anyString())).thenReturn("年");
|
||||
assertServiceException(() -> productPromotionService.create(reqVO), PRODUCT_PROMOTION_PURCHASEDURATION_IS_EXIST, reqVO.getPurchaseDuration(), DurationUnitEnum.getDesc(reqVO.getPurchaseDurationUnit()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
void testUpdate_not_exist() {
|
||||
ProductPromotionSaveReqVO reqVO = new ProductPromotionSaveReqVO();
|
||||
reqVO.setId(321L);
|
||||
@@ -111,50 +118,48 @@ class ProductPromotionServiceImplTest extends BaseDbClearAfterClassAndRedisUnitT
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
void testUpdate() {
|
||||
|
||||
// 插入
|
||||
ProductPromotionDO createDO1 = new ProductPromotionDO();
|
||||
createDO1.setId(null);
|
||||
createDO1.setActivityName("充值送活动新");
|
||||
createDO1.setPurchaseDuration(1);
|
||||
createDO1.setPurchaseDurationUnit(DurationUnitEnum.YEAR.getCode());
|
||||
createDO1.setProductId(2L);
|
||||
createDO1.setProductName("产品名称2");
|
||||
createDO1.setGiftDuration(1);
|
||||
createDO1.setGiftDurationUnit(DurationUnitEnum.DAY.getCode());
|
||||
createDO1.setStartTime(LocalDateTime.now());
|
||||
createDO1.setEndTime(LocalDateTime.now().plusDays(1));
|
||||
|
||||
productPromotionMapper.insert(createDO1);
|
||||
|
||||
ProductPromotionSaveReqVO reqVO = new ProductPromotionSaveReqVO();
|
||||
reqVO.setId(createDO1.getId());
|
||||
reqVO.setId(100L);
|
||||
reqVO.setActivityName("充值送活动");
|
||||
assertServiceException(() -> productPromotionService.update(reqVO),
|
||||
PRODUCT_PROMOTION_ACTIVE_NAME_IS_EXIST);
|
||||
reqVO.setPurchaseDuration(1);
|
||||
reqVO.setPurchaseDurationUnit(DurationUnitEnum.YEAR.getCode());
|
||||
|
||||
ProductsDO productsDO = new ProductsDO();
|
||||
productsDO.setId(2L);
|
||||
productsDO.setProductName("产品名称2");
|
||||
when(productsDetailService.validateProductExist(any())).thenReturn(productsDO);
|
||||
|
||||
// 再次插入相同活动名称,断言异常
|
||||
when(productPromotionMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(new ProductPromotionDO()).thenReturn(new ProductPromotionDO());
|
||||
assertServiceException(() -> productPromotionService.update(reqVO), PRODUCT_PROMOTION_ACTIVE_NAME_IS_EXIST);
|
||||
|
||||
// 再次插入相同产品-相同购买时长和单位,断言异常
|
||||
reqVO.setActivityName("充值送活动1");
|
||||
when(productPromotionMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(new ProductPromotionDO()).thenReturn(null).thenReturn(new ProductPromotionDO());
|
||||
when(i18nUtils.getMessage(anyString())).thenReturn("年");
|
||||
assertServiceException(() -> productPromotionService.update(reqVO), PRODUCT_PROMOTION_PURCHASEDURATION_IS_EXIST, reqVO.getPurchaseDuration(), DurationUnitEnum.getDesc(reqVO.getPurchaseDurationUnit()));
|
||||
|
||||
// 更新成功
|
||||
ProductPromotionSaveReqVO update = BeanUtil.copyProperties(createDO1, ProductPromotionSaveReqVO.class);
|
||||
assertDoesNotThrow(() -> productPromotionService.update(update));
|
||||
when(productPromotionMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(new ProductPromotionDO()).thenReturn(null).thenReturn(null);
|
||||
productPromotionService.update(reqVO);
|
||||
|
||||
// 验证数据库更新
|
||||
verify(productPromotionMapper).updateById(argThat((ProductPromotionDO productPromotionDO) ->
|
||||
productPromotionDO.getProductId().equals(productsDO.getId())
|
||||
&& productPromotionDO.getProductName().equals(productsDO.getProductName())
|
||||
&& productPromotionDO.getId().equals(reqVO.getId())
|
||||
&& productPromotionDO.getActivityName().equals(reqVO.getActivityName())
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
void testGet_not_exist() {
|
||||
assertServiceException(() -> productPromotionService.get(null), PRODUCT_PROMOTION_NO_EXIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(5)
|
||||
void testGetPage_success() {
|
||||
ProductPromotionDO detail = randomPojo(ProductPromotionDO.class, o -> {
|
||||
o.setId(null);
|
||||
@@ -166,23 +171,6 @@ class ProductPromotionServiceImplTest extends BaseDbClearAfterClassAndRedisUnitT
|
||||
o.setRemark("晨丰备注1");
|
||||
});
|
||||
|
||||
productPromotionMapper.insert(detail);
|
||||
|
||||
// 不匹配 ActivityName
|
||||
productPromotionMapper.insert(cloneIgnoreId(detail, o -> o.setActivityName("新分页活动")));
|
||||
|
||||
// 不匹配 RechargeGiftType
|
||||
productPromotionMapper.insert(cloneIgnoreId(detail, o -> o.setPurchaseDuration(4)));
|
||||
|
||||
// 不匹配 GiftAmount
|
||||
productPromotionMapper.insert(cloneIgnoreId(detail, o -> o.setGiftDuration(5)));
|
||||
|
||||
// 不匹配 RechargeAmount
|
||||
productPromotionMapper.insert(cloneIgnoreId(detail, o -> o.setRemark("晨丰备1注")));
|
||||
|
||||
// 被逻辑删除
|
||||
productPromotionMapper.insert(cloneIgnoreId(detail, o -> o.setDeleted(true)));
|
||||
|
||||
// ============ 构造查询参数 ============
|
||||
ProductPromotionPageReqVO reqVO = new ProductPromotionPageReqVO();
|
||||
reqVO.setActivityName("晨丰");
|
||||
@@ -192,6 +180,8 @@ class ProductPromotionServiceImplTest extends BaseDbClearAfterClassAndRedisUnitT
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
|
||||
when(productPromotionMapper.selectPage(reqVO)).thenReturn(new PageResult<>(List.of(detail), 1L));
|
||||
|
||||
// ============ 调用方法 ============
|
||||
PageResult<ProductPromotionDO> pageResult = productPromotionService.getPage(reqVO);
|
||||
|
||||
@@ -202,27 +192,30 @@ class ProductPromotionServiceImplTest extends BaseDbClearAfterClassAndRedisUnitT
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
void testDelete() {
|
||||
assertDoesNotThrow(() -> productPromotionService.delete(createDO.getId()));
|
||||
ProductPromotionDO exist = randomPojo(ProductPromotionDO.class);
|
||||
|
||||
when(productPromotionMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(exist);
|
||||
|
||||
assertDoesNotThrow(() -> productPromotionService.delete(exist.getId()));
|
||||
|
||||
verify(productPromotionMapper, times(1)).deleteById(exist.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
void testDelete_not_exist() {
|
||||
assertServiceException(() -> productPromotionService.delete(null), PRODUCT_PROMOTION_NO_EXIST);
|
||||
assertServiceException(() -> productPromotionService.delete(321L), PRODUCT_PROMOTION_NO_EXIST);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(8)
|
||||
void testGetAvailableRechargeActiveList() {
|
||||
// 当前时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
Long productId = 1000L;
|
||||
|
||||
// 1️⃣ 有效活动(时间区间内)
|
||||
// 有效活动(时间区间内)
|
||||
ProductPromotionDO valid = new ProductPromotionDO();
|
||||
valid.setActivityName("有效活动");
|
||||
valid.setProductId(productId);
|
||||
@@ -236,54 +229,25 @@ class ProductPromotionServiceImplTest extends BaseDbClearAfterClassAndRedisUnitT
|
||||
valid.setDeleted(false);
|
||||
productPromotionMapper.insert(valid);
|
||||
|
||||
// 2️⃣ 未开始活动
|
||||
ProductPromotionDO notStarted = new ProductPromotionDO();
|
||||
notStarted.setActivityName("未开始活动");
|
||||
notStarted.setProductId(productId);
|
||||
notStarted.setProductName("产品名称");
|
||||
notStarted.setPurchaseDuration(2);
|
||||
notStarted.setPurchaseDurationUnit(DurationUnitEnum.YEAR.getCode());
|
||||
notStarted.setGiftDuration(2);
|
||||
notStarted.setGiftDurationUnit(DurationUnitEnum.DAY.getCode());
|
||||
notStarted.setStartTime(now.plusDays(1));
|
||||
notStarted.setEndTime(now.plusDays(2));
|
||||
notStarted.setDeleted(false);
|
||||
productPromotionMapper.insert(notStarted);
|
||||
|
||||
// 3️⃣ 已过期活动
|
||||
ProductPromotionDO expired = new ProductPromotionDO();
|
||||
expired.setActivityName("已过期活动");
|
||||
expired.setProductId(productId);
|
||||
expired.setProductName("产品名称");
|
||||
expired.setPurchaseDuration(3);
|
||||
expired.setPurchaseDurationUnit(DurationUnitEnum.YEAR.getCode());
|
||||
expired.setGiftDuration(3);
|
||||
expired.setGiftDurationUnit(DurationUnitEnum.DAY.getCode());
|
||||
expired.setStartTime(now.minusDays(5));
|
||||
expired.setEndTime(now.minusDays(1));
|
||||
expired.setDeleted(false);
|
||||
productPromotionMapper.insert(expired);
|
||||
|
||||
// 4️⃣ 被逻辑删除的活动
|
||||
ProductPromotionDO deleted = new ProductPromotionDO();
|
||||
deleted.setActivityName("被删除活动");
|
||||
deleted.setProductId(productId);
|
||||
deleted.setProductName("产品名称");
|
||||
deleted.setPurchaseDuration(4);
|
||||
deleted.setPurchaseDurationUnit(DurationUnitEnum.YEAR.getCode());
|
||||
deleted.setGiftDuration(4);
|
||||
deleted.setGiftDurationUnit(DurationUnitEnum.DAY.getCode());
|
||||
deleted.setStartTime(now.minusDays(1));
|
||||
deleted.setEndTime(now.plusDays(1));
|
||||
deleted.setDeleted(true);
|
||||
productPromotionMapper.insert(deleted);
|
||||
when(productPromotionMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(List.of(valid));
|
||||
|
||||
// 执行被测方法
|
||||
List<ProductPromotionDO> result = productPromotionService.getAvailableProductPromotionList(productId);
|
||||
|
||||
// 验证结果
|
||||
assertEquals(1, result.size(), "只应返回一个有效活动");
|
||||
assertEquals("有效活动", result.get(0).getActivityName());
|
||||
// then
|
||||
assertNotNull(result);
|
||||
assertEquals(1L, result.size());
|
||||
|
||||
// 校验 查询条件
|
||||
verify(productPromotionMapper).selectList(
|
||||
argThat((LambdaQueryWrapper wrapper) ->
|
||||
wrapper.getSqlSegment().contains("deleted")
|
||||
&& wrapper.getSqlSegment().contains("product_id")
|
||||
&& wrapper.getSqlSegment().contains("start_time")
|
||||
&& wrapper.getSqlSegment().contains("end_time")
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+68
-48
@@ -1,8 +1,12 @@
|
||||
package com.cf.imes.module.system.service.funds.products;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.common.util.i18n.core.util.I18nUtils;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails.ProductDetailsPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails.ProductDetailsSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO;
|
||||
@@ -11,14 +15,15 @@ import com.cf.imes.module.system.dal.mysql.funds.products.ProductsDetailMapper;
|
||||
import com.cf.imes.module.system.dal.mysql.funds.products.ProductsMapper;
|
||||
import com.cf.imes.module.system.enums.pay.ProductDurationUnitEnum;
|
||||
import com.cf.imes.module.system.enums.products.ProductStatusEnum;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static com.cf.imes.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
|
||||
@@ -31,26 +36,35 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Gqr
|
||||
* @since 2025/10/14 13:48
|
||||
*/
|
||||
@Import(ProductsDetailServiceImpl.class)
|
||||
public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
@Resource
|
||||
class ProductsDetailServiceImplTest extends BaseMockitoUnitTest {
|
||||
@InjectMocks
|
||||
private ProductsDetailServiceImpl productsDetailService;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private ProductsDetailMapper productsDetailMapper;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private ProductsMapper productsMapper;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private I18nUtils i18nUtils;
|
||||
|
||||
@BeforeAll
|
||||
static void init(){
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), ProductsDetailDO.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateProductDetails() {
|
||||
// mock下架状态的产品
|
||||
@@ -62,16 +76,30 @@ public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
when(productsMapper.selectOne(any())).thenReturn(mockProduct);
|
||||
|
||||
ProductDetailsSaveReqVO productDetailsSaveReqVO = randomPojo(ProductDetailsSaveReqVO.class, p -> {
|
||||
p.setId(null);
|
||||
p.setDiscount(BigDecimal.valueOf(10));
|
||||
p.setDuration(ProductDurationUnitEnum.YEAR.getCode());
|
||||
p.setProductId(mockProduct.getId());
|
||||
});
|
||||
|
||||
// 模拟 Mapper 插入时生成 ID
|
||||
doAnswer(invocation -> {
|
||||
ProductsDetailDO detail = invocation.getArgument(0);
|
||||
detail.setId(100L); // 模拟自增主键
|
||||
return null;
|
||||
}).when(productsDetailMapper).insert(any(ProductsDetailDO.class));
|
||||
|
||||
// 调用
|
||||
Long id = productsDetailService.create(productDetailsSaveReqVO);
|
||||
|
||||
// 断言
|
||||
assertNotNull(id);
|
||||
// 校验记录的属性是否正确
|
||||
ProductsDetailDO productsDetailDO = productsDetailMapper.selectById(id);
|
||||
assertPojoEquals(productDetailsSaveReqVO, productsDetailDO, "id");
|
||||
assertEquals(100L,id);
|
||||
|
||||
// 验证 Mapper 方法被调用一次
|
||||
verify(productsDetailMapper, times(1)).insert(argThat((ProductsDetailDO detail) ->
|
||||
detail.getDiscount().equals(productDetailsSaveReqVO.getDiscount())
|
||||
&& detail.getDuration().equals(productDetailsSaveReqVO.getDuration())
|
||||
&& detail.getProductId().equals(mockProduct.getId())
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -99,20 +127,18 @@ public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
mockProduct.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
|
||||
when(productsMapper.selectOne(any())).thenReturn(mockProduct);
|
||||
// 插入一条与 createReqVO 冲突的数据
|
||||
ProductsDetailDO existing = new ProductsDetailDO();
|
||||
existing.setProductId(1L);
|
||||
existing.setDuration(12);
|
||||
existing.setDurationUnit(0);
|
||||
existing.setDeleted(false);
|
||||
productsDetailMapper.insert(existing);
|
||||
|
||||
// 模拟新增同样 duration + unit 的记录
|
||||
ProductDetailsSaveReqVO reqVO = new ProductDetailsSaveReqVO()
|
||||
.setProductId(existing.getProductId())
|
||||
.setDuration(existing.getDuration())
|
||||
.setDurationUnit(existing.getDurationUnit());
|
||||
.setId(999L)
|
||||
.setProductId(123L)
|
||||
.setDuration(1)
|
||||
.setDurationUnit(ProductDurationUnitEnum.MONTH.getCode());
|
||||
|
||||
// mock重复存在
|
||||
when(productsDetailMapper.selectCountByDuration(reqVO.getProductId(), reqVO.getId(), reqVO.getDuration(), reqVO.getDurationUnit())).thenReturn(1);
|
||||
|
||||
when(i18nUtils.getMessage(anyString())).thenReturn("月");
|
||||
assertServiceException(() -> productsDetailService.create(reqVO),
|
||||
PRODUCTS_DETAIL_DURATION_EXIST, reqVO.getDuration(), ProductDurationUnitEnum.getDesc(reqVO.getDurationUnit()));
|
||||
}
|
||||
@@ -127,12 +153,14 @@ public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
when(productsMapper.selectOne(any())).thenReturn(mockProduct);
|
||||
|
||||
// mock exist
|
||||
ProductsDetailDO detail = new ProductsDetailDO();
|
||||
detail.setId(999L);
|
||||
detail.setProductId(mockProduct.getId());
|
||||
detail.setDuration(12);
|
||||
detail.setDurationUnit(1);
|
||||
detail.setDeleted(false);
|
||||
productsDetailMapper.insert(detail);
|
||||
when(productsDetailMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(detail);
|
||||
|
||||
// 构造请求
|
||||
ProductDetailsSaveReqVO reqVO = new ProductDetailsSaveReqVO()
|
||||
@@ -144,13 +172,17 @@ public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
// 调用
|
||||
productsDetailService.update(reqVO);
|
||||
|
||||
// 验证结果
|
||||
ProductsDetailDO updated = productsDetailMapper.selectById(detail.getId());
|
||||
assertEquals(6, updated.getDuration());
|
||||
// 校验状态更新
|
||||
verify(productsDetailMapper).update(argThat((LambdaUpdateWrapper wrapper) ->
|
||||
wrapper.getSqlSegment().contains("id")
|
||||
&& wrapper.getSqlSet().contains("discount")
|
||||
&& wrapper.getSqlSet().contains("duration")
|
||||
&& wrapper.getSqlSet().contains("duration_unit")
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteTest(){
|
||||
void deleteTest() {
|
||||
// mock下架状态的产品
|
||||
ProductsDO mockProduct = new ProductsDO();
|
||||
mockProduct.setId(123L);
|
||||
@@ -160,11 +192,12 @@ public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
when(productsMapper.selectOne(any())).thenReturn(mockProduct);
|
||||
|
||||
ProductsDetailDO detail = new ProductsDetailDO();
|
||||
detail.setId(999L);
|
||||
detail.setProductId(mockProduct.getId());
|
||||
detail.setDuration(12);
|
||||
detail.setDurationUnit(1);
|
||||
detail.setDeleted(false);
|
||||
productsDetailMapper.insert(detail);
|
||||
when(productsDetailMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(detail);
|
||||
|
||||
// 调用删除
|
||||
productsDetailService.delete(detail.getId());
|
||||
@@ -180,7 +213,7 @@ public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
detail.setId(321L);
|
||||
detail.setDeleted(false);
|
||||
detail.setProductId(123L);
|
||||
productsDetailMapper.insert(detail);
|
||||
when(productsDetailMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(detail);
|
||||
|
||||
ProductsDetailDO result = productsDetailService.get(detail.getId());
|
||||
assertNotNull(result);
|
||||
@@ -198,20 +231,6 @@ public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setDeleted(false);
|
||||
});
|
||||
|
||||
productsDetailMapper.insert(detail);
|
||||
|
||||
// 不匹配 productId
|
||||
productsDetailMapper.insert(cloneIgnoreId(detail, o -> o.setProductId(321L)));
|
||||
|
||||
// 不匹配 duration
|
||||
productsDetailMapper.insert(cloneIgnoreId(detail, o -> o.setDuration(2)));
|
||||
|
||||
// 不匹配 discount
|
||||
productsDetailMapper.insert(cloneIgnoreId(detail, o -> o.setDiscount(BigDecimal.valueOf(99))));
|
||||
|
||||
// 被逻辑删除
|
||||
productsDetailMapper.insert(cloneIgnoreId(detail, o -> o.setDeleted(true)));
|
||||
|
||||
// ============ 构造查询参数 ============
|
||||
ProductDetailsPageReqVO reqVO = new ProductDetailsPageReqVO();
|
||||
reqVO.setProductId(123L);
|
||||
@@ -219,6 +238,7 @@ public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
reqVO.setDiscount(BigDecimal.valueOf(100));
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
when(productsDetailMapper.selectPage(reqVO)).thenReturn(new PageResult<>(List.of(detail), 1L));
|
||||
|
||||
// ============ 调用方法 ============
|
||||
PageResult<ProductsDetailDO> pageResult = productsDetailService.getPage(reqVO);
|
||||
@@ -284,7 +304,7 @@ public class ProductsDetailServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
detailDO.setDuration(1);
|
||||
detailDO.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
|
||||
detailDO.setDiscount(BigDecimal.valueOf(85));
|
||||
productsDetailMapper.insert(detailDO);
|
||||
when(productsDetailMapper.selectOne(any())).thenReturn(detailDO);
|
||||
|
||||
BigDecimal discount = productsDetailService.getProductDetailOneYearDiscount(1L);
|
||||
assertEquals(BigDecimal.valueOf(85), discount);
|
||||
|
||||
+83
-88
@@ -1,19 +1,25 @@
|
||||
package com.cf.imes.module.system.service.funds.products;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.product.ProductPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.product.ProductSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO;
|
||||
import com.cf.imes.module.system.dal.mysql.funds.products.ProductsMapper;
|
||||
import com.cf.imes.module.system.enums.products.ProductStatusEnum;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static com.cf.imes.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.randomLongId;
|
||||
@@ -23,23 +29,26 @@ import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_IS_EXI
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_NO_DELETE;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_NO_EXIST;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCTS_NO_UPDATE;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Gqr
|
||||
* @since 2025/10/14 9:46
|
||||
*/
|
||||
@Import(ProductsServiceImpl.class)
|
||||
public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
@Resource
|
||||
|
||||
class ProductsServiceImplTest extends BaseMockitoUnitTest {
|
||||
@InjectMocks
|
||||
private ProductsServiceImpl productsService;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private ProductsMapper productsMapper;
|
||||
|
||||
@BeforeAll
|
||||
static void init(){
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), ProductsDO.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateProductSuccess() {
|
||||
// 构造请求对象
|
||||
@@ -50,14 +59,15 @@ public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
req.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
|
||||
// 调用真实 Service 方法
|
||||
Long id = productsService.create(req);
|
||||
productsService.create(req);
|
||||
|
||||
// 校验数据库插入结果
|
||||
ProductsDO result = productsMapper.selectById(id);
|
||||
assertNotNull(result);
|
||||
assertEquals(productName, result.getProductName());
|
||||
assertEquals(new BigDecimal("88.88"), result.getPrice());
|
||||
assertEquals(ProductStatusEnum.PRODUCT_UPDATES.getStatus(), result.getStatus());
|
||||
// 校验插入
|
||||
verify(productsMapper).insert(argThat((ProductsDO infoDO) ->
|
||||
infoDO.getProductName().equals(req.getProductName())
|
||||
&& infoDO.getPrice().equals(req.getPrice())
|
||||
&& infoDO.getSoftwareId().equals(0)
|
||||
&& infoDO.getStatus().equals(req.getStatus())
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,15 +75,12 @@ public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
*/
|
||||
@Test
|
||||
void testUpdate_takeoff_to_listed() {
|
||||
ProductSaveReqVO createVO = new ProductSaveReqVO();
|
||||
String productName = randomString();
|
||||
createVO.setProductName(productName);
|
||||
createVO.setPrice(new BigDecimal("88.88"));
|
||||
createVO.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
Long id = productsService.create(createVO);
|
||||
ProductsDO productsDO = new ProductsDO();
|
||||
productsDO.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
when(productsMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(productsDO);
|
||||
|
||||
ProductSaveReqVO updateVO = new ProductSaveReqVO();
|
||||
updateVO.setId(id);
|
||||
updateVO.setId(100L);
|
||||
String newProductName = randomString();
|
||||
updateVO.setProductName(newProductName);
|
||||
updateVO.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
@@ -81,10 +88,13 @@ public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
productsService.update(updateVO);
|
||||
|
||||
ProductsDO db = productsMapper.selectById(id);
|
||||
assertThat(db.getProductName()).isEqualTo(newProductName);
|
||||
assertThat(db.getPrice()).isEqualByComparingTo("199.99");
|
||||
assertEquals(ProductStatusEnum.PRODUCT_UPDATES.getStatus(), db.getStatus());
|
||||
// 校验状态更新
|
||||
verify(productsMapper).update(argThat((LambdaUpdateWrapperX wrapper) ->
|
||||
wrapper.getSqlSegment().contains("id")
|
||||
&& wrapper.getSqlSet().contains("product_name")
|
||||
&& wrapper.getSqlSet().contains("price")
|
||||
&& wrapper.getSqlSet().contains("status")
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,13 +102,12 @@ public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
*/
|
||||
@Test
|
||||
void testUpdate_statusUpdatableThrowsException() {
|
||||
ProductSaveReqVO dbProduct = new ProductSaveReqVO();
|
||||
dbProduct.setProductName("产品");
|
||||
dbProduct.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
Long id = productsService.create(dbProduct);
|
||||
ProductsDO productsDO = new ProductsDO();
|
||||
productsDO.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
when(productsMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(productsDO);
|
||||
|
||||
ProductSaveReqVO reqVO = new ProductSaveReqVO();
|
||||
reqVO.setId(id);
|
||||
reqVO.setId(100L);
|
||||
reqVO.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus()); // 非下架
|
||||
|
||||
assertServiceException(() -> productsService.update(reqVO),
|
||||
@@ -110,15 +119,12 @@ public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
*/
|
||||
@Test
|
||||
void testUpdate_listed_to_takeoff() {
|
||||
ProductSaveReqVO createVO = new ProductSaveReqVO();
|
||||
String productName = randomString();
|
||||
createVO.setProductName(productName);
|
||||
createVO.setPrice(new BigDecimal("88.88"));
|
||||
createVO.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
Long id = productsService.create(createVO);
|
||||
ProductsDO productsDO = new ProductsDO();
|
||||
productsDO.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
when(productsMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(productsDO);
|
||||
|
||||
ProductSaveReqVO updateVO = new ProductSaveReqVO();
|
||||
updateVO.setId(id);
|
||||
updateVO.setId(100L);
|
||||
String newProductName = randomString();
|
||||
updateVO.setProductName(newProductName);
|
||||
updateVO.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
@@ -126,50 +132,52 @@ public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
productsService.update(updateVO);
|
||||
|
||||
ProductsDO db = productsMapper.selectById(id);
|
||||
assertThat(db.getProductName()).isEqualTo(newProductName);
|
||||
assertThat(db.getPrice()).isEqualByComparingTo("199.99");
|
||||
assertEquals(ProductStatusEnum.PRODUCT_DELIS.getStatus(), db.getStatus());
|
||||
// 校验状态更新
|
||||
verify(productsMapper).update(argThat((LambdaUpdateWrapperX wrapper) ->
|
||||
wrapper.getSqlSegment().contains("id")
|
||||
&& wrapper.getSqlSet().contains("product_name")
|
||||
&& wrapper.getSqlSet().contains("price")
|
||||
&& wrapper.getSqlSet().contains("status")
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testDelete() {
|
||||
ProductSaveReqVO createVO = new ProductSaveReqVO();
|
||||
createVO.setProductName(randomString());
|
||||
createVO.setPrice(new BigDecimal("88.88"));
|
||||
createVO.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
Long id = productsService.create(createVO);
|
||||
ProductsDO productsDO = new ProductsDO();
|
||||
productsDO.setId(100L);
|
||||
productsDO.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus());
|
||||
when(productsMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(productsDO);
|
||||
|
||||
productsService.delete(id);
|
||||
productsService.delete(productsDO.getId());
|
||||
// 断言不存在了
|
||||
assertNull(productsMapper.selectById(id));
|
||||
assertNull(productsMapper.selectById(productsDO.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDelete_listed() {
|
||||
ProductSaveReqVO createVO = new ProductSaveReqVO();
|
||||
createVO.setProductName(randomString());
|
||||
createVO.setPrice(new BigDecimal("88.88"));
|
||||
createVO.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
Long id = productsService.create(createVO);
|
||||
ProductsDO productsDO = new ProductsDO();
|
||||
productsDO.setId(100L);
|
||||
productsDO.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
when(productsMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(productsDO);
|
||||
|
||||
assertServiceException(() -> productsService.delete(id),
|
||||
assertServiceException(() -> productsService.delete(productsDO.getId()),
|
||||
PRODUCTS_NO_DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGet() {
|
||||
ProductSaveReqVO createVO = new ProductSaveReqVO();
|
||||
String productName = randomString();
|
||||
createVO.setProductName(productName);
|
||||
createVO.setPrice(new BigDecimal("88.88"));
|
||||
createVO.setStatus(1);
|
||||
Long id = productsService.create(createVO);
|
||||
ProductsDO db = productsService.get(id);
|
||||
ProductsDO productsDO = new ProductsDO();
|
||||
productsDO.setId(100L);
|
||||
productsDO.setProductName("产品名称");
|
||||
productsDO.setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus());
|
||||
when(productsMapper.selectOne(any(LambdaQueryWrapperX.class))).thenReturn(productsDO);
|
||||
|
||||
assertThat(db).isNotNull();
|
||||
assertThat(db.getProductName()).isEqualTo(productName);
|
||||
ProductsDO db = productsService.get(productsDO.getId());
|
||||
|
||||
assertEquals(db.getId(), productsDO.getId());
|
||||
assertEquals(db.getProductName(), productsDO.getProductName());
|
||||
assertEquals(db.getStatus(), productsDO.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -181,16 +189,6 @@ public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setDeleted(false);
|
||||
o.setPrice(new BigDecimal("99.99"));
|
||||
});
|
||||
productsMapper.insert(dbProduct);
|
||||
|
||||
// 不匹配 productName
|
||||
productsMapper.insert(cloneIgnoreId(dbProduct, o -> o.setProductName("测试产品")));
|
||||
|
||||
// 不匹配 status
|
||||
productsMapper.insert(cloneIgnoreId(dbProduct, o -> o.setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus())));
|
||||
|
||||
// 被逻辑删除
|
||||
productsMapper.insert(cloneIgnoreId(dbProduct, o -> o.setDeleted(true)));
|
||||
|
||||
// ============ 构造查询参数 ============
|
||||
ProductPageReqVO reqVO = new ProductPageReqVO();
|
||||
@@ -199,6 +197,8 @@ public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
|
||||
when(productsService.getPage(reqVO)).thenReturn(new PageResult<>(List.of(dbProduct), 1L));
|
||||
|
||||
// ============ 调用方法 ============
|
||||
PageResult<ProductsDO> pageResult = productsService.getPage(reqVO);
|
||||
|
||||
@@ -211,19 +211,14 @@ public class ProductsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Test
|
||||
void testDuplicateNameThrowsException() {
|
||||
when(productsMapper.selectList(any(LambdaQueryWrapperX.class))).thenReturn(List.of(new ProductsDO()));
|
||||
|
||||
ProductSaveReqVO createVO = new ProductSaveReqVO();
|
||||
String productName = randomString();
|
||||
createVO.setProductName(productName);
|
||||
createVO.setPrice(new BigDecimal("88.88"));
|
||||
createVO.setStatus(1);
|
||||
productsService.create(createVO);
|
||||
|
||||
ProductSaveReqVO dup = new ProductSaveReqVO();
|
||||
dup.setProductName(productName);
|
||||
dup.setStatus(1);
|
||||
dup.setPrice(new BigDecimal("50.00"));
|
||||
|
||||
assertServiceException(() -> productsService.create(dup),
|
||||
assertServiceException(() -> productsService.create(createVO),
|
||||
PRODUCTS_IS_EXIST, productName);
|
||||
}
|
||||
|
||||
|
||||
+210
-312
@@ -1,10 +1,12 @@
|
||||
package com.cf.imes.module.system.service.funds.purchase;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.cf.imes.framework.common.exception.ServiceException;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.funds.delay.vo.ProductDelayRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.TotalSalesAmountRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails.ProductDetailsRespVO;
|
||||
@@ -31,10 +33,12 @@ import com.cf.imes.module.system.service.funds.productpromotion.ProductPromotion
|
||||
import com.cf.imes.module.system.service.funds.products.ProductsDetailService;
|
||||
import com.cf.imes.module.system.service.organ.OrganService;
|
||||
import com.cf.imes.framework.common.util.i18n.core.util.I18nUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
@@ -45,6 +49,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PURCHASE_EXIST_ERROR;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR;
|
||||
@@ -56,40 +61,48 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Import(PurchaseServiceImpl.class)
|
||||
class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
class PurchaseServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@Resource
|
||||
@InjectMocks
|
||||
private PurchaseServiceImpl purchaseService;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private PurchaseRecordMapper purchaseRecordMapper;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private OrganService organService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private I18nUtils i18nUtils;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private ProductsDetailService productsDetailService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private ProductDelayService productDelayService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private ProductPromotionService productPromotionService;
|
||||
|
||||
@MockitoBean
|
||||
@Mock
|
||||
private MybatisIdProperties mybatisIdProperties;
|
||||
|
||||
@BeforeAll
|
||||
static void init(){
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), PurchaseRecordDO.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateAndGetAndDeleteRecord() {
|
||||
// 准备参数
|
||||
PurchaseRecordDO invoiceRecordsDO = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(1L);
|
||||
o.setProductId(100L);
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
o.setExternalSpent(new BigDecimal("100.00"));
|
||||
o.setProductName("测试产品");
|
||||
@@ -99,8 +112,30 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInitial(false);
|
||||
o.setOrganId(1L);
|
||||
});
|
||||
|
||||
// when
|
||||
purchaseService.createRecord(invoiceRecordsDO);
|
||||
|
||||
// then
|
||||
ArgumentCaptor<PurchaseRecordDO> captor =
|
||||
ArgumentCaptor.forClass(PurchaseRecordDO.class);
|
||||
|
||||
verify(purchaseRecordMapper).insert(captor.capture());
|
||||
|
||||
PurchaseRecordDO actual = captor.getValue();
|
||||
assertEquals(1L, actual.getOrganId());
|
||||
assertEquals(100L, actual.getProductId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGet(){
|
||||
PurchaseRecordDO invoiceRecordsDO = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(1L);
|
||||
o.setProductId(100L);
|
||||
o.setTotalAmount(new BigDecimal("200.00"));
|
||||
});
|
||||
when(purchaseRecordMapper.selectById(anyLong())).thenReturn(invoiceRecordsDO);
|
||||
|
||||
// 查询
|
||||
PurchaseRecordDO result = purchaseService.getRecord(1L);
|
||||
|
||||
@@ -108,31 +143,42 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
assertNotNull(result);
|
||||
assertEquals(invoiceRecordsDO.getProductName(), result.getProductName());
|
||||
assertEquals(invoiceRecordsDO.getTotalAmount(), result.getTotalAmount());
|
||||
}
|
||||
|
||||
// 更新为可开票
|
||||
purchaseService.updateRecordInvoicable(1L, invoiceRecordsDO.getOrganId());
|
||||
@Test
|
||||
void testUpdateReocrdInvoicable(){
|
||||
Long purchaseRecordId = 100L;
|
||||
Long organId = 200L;
|
||||
|
||||
// 查询
|
||||
result = purchaseService.getRecord(1L);
|
||||
// when
|
||||
purchaseService.updateRecordInvoicable(purchaseRecordId, organId);
|
||||
|
||||
// 校验更新
|
||||
assertNotNull(result);
|
||||
assertEquals(result.getIsInvocing(), INVOICABLE.getCode());
|
||||
// 校验状态更新
|
||||
verify(purchaseRecordMapper).update(argThat((LambdaUpdateWrapper wrapper) ->
|
||||
wrapper.getSqlSegment().contains("id")
|
||||
&& wrapper.getSqlSegment().contains("organ_id")
|
||||
&& wrapper.getSqlSet().contains("is_invocing")
|
||||
));
|
||||
}
|
||||
|
||||
// 删除
|
||||
purchaseService.deleteRecord(1L);
|
||||
@Test
|
||||
void testDelete(){
|
||||
purchaseService.deleteRecord(100L);
|
||||
|
||||
// 查询
|
||||
result = purchaseService.getRecord(1L);
|
||||
|
||||
// 验证删除
|
||||
assertNull(result);
|
||||
// 校验状态更新
|
||||
verify(purchaseRecordMapper).update(argThat((LambdaUpdateWrapper wrapper) ->
|
||||
wrapper.getSqlSegment().contains("id")
|
||||
&& wrapper.getSqlSet().contains("deleted")
|
||||
&& wrapper.getSqlSet().contains("status")
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetPurchaseRecord_emptyResult() {
|
||||
PurchaseRecordPageReqVO pageReqVO = new PurchaseRecordPageReqVO();
|
||||
|
||||
|
||||
when(purchaseRecordMapper.selectPage(pageReqVO)).thenReturn(new PageResult<>(null, 0L));
|
||||
PageResult<PurchaseRecordRespVO> result =
|
||||
purchaseService.getPurchaseRecord(pageReqVO);
|
||||
|
||||
@@ -154,11 +200,11 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInitial(false);
|
||||
o.setOrganId(1L);
|
||||
});
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
|
||||
PurchaseRecordPageReqVO pageReqVO = new PurchaseRecordPageReqVO();
|
||||
pageReqVO.setEndTime(new LocalDate[]{LocalDate.now()}); // length != 2
|
||||
|
||||
when(purchaseRecordMapper.selectPage(pageReqVO)).thenReturn(new PageResult(List.of(recordDO), 1l));
|
||||
when(i18nUtils.getMessage(anyString())).thenReturn("支付宝");
|
||||
when(organService.getOrganWithDeleted(anyLong())).thenReturn(null);
|
||||
|
||||
@@ -184,14 +230,13 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInitial(false);
|
||||
o.setOrganId(2L);
|
||||
});
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
|
||||
PurchaseRecordPageReqVO pageReqVO = new PurchaseRecordPageReqVO();
|
||||
pageReqVO.setEndTime(new LocalDate[]{
|
||||
LocalDate.now().minusDays(1),
|
||||
LocalDate.now()
|
||||
});
|
||||
|
||||
when(purchaseRecordMapper.selectPage(pageReqVO)).thenReturn(new PageResult(List.of(recordDO), 1l));
|
||||
when(i18nUtils.getMessage(anyString())).thenReturn("支付宝");
|
||||
|
||||
OrganizationDO organ = new OrganizationDO();
|
||||
@@ -233,7 +278,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setOrganId(organId);
|
||||
o.setEndTime(LocalDate.now().plusDays(30));
|
||||
});
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
when(purchaseRecordMapper.selectOne(any())).thenReturn(recordDO);
|
||||
|
||||
// mock:无延期记录
|
||||
when(productDelayService.getRecordsByPurchaseId(recordDO.getId(), organId))
|
||||
@@ -269,7 +314,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setOrganId(organId);
|
||||
o.setEndTime(originalEndTime);
|
||||
});
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
when(purchaseRecordMapper.selectOne(any())).thenReturn(recordDO);
|
||||
|
||||
// mock 延期记录(第一条为最新)
|
||||
ProductDelayRespVO delayVO = new ProductDelayRespVO();
|
||||
@@ -290,22 +335,11 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Test
|
||||
void getInvoicingAmountTest(){
|
||||
// 准备参数
|
||||
PurchaseRecordDO recordDO = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
o.setExternalSpent(new BigDecimal("100.00"));
|
||||
o.setProductName("测试产品");
|
||||
o.setTotalAmount(new BigDecimal("200.00"));
|
||||
o.setStatus(PurchaseRecordStatusEnum.ACTIVE.getStatus());
|
||||
o.setPaymentMethod(PayChannelCodeEnum.ALIPAY_PC.getCode());
|
||||
o.setIsInvocing(INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
o.setOrganId(1L);
|
||||
});
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
BigDecimal amount = new BigDecimal(100);
|
||||
when(purchaseRecordMapper.getInvoicingAmount(anyLong())).thenReturn(amount);
|
||||
|
||||
BigDecimal invoicingAmount = purchaseService.getInvoicingAmount(1l);
|
||||
assertEquals(recordDO.getTotalAmount(), invoicingAmount);
|
||||
assertEquals(invoicingAmount, amount);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -337,34 +371,20 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
organId, Collections.singletonList(reqVO)
|
||||
);
|
||||
|
||||
// 查询数据库验证
|
||||
List<PurchaseRecordDO> records = purchaseRecordMapper.selectList(
|
||||
new LambdaQueryWrapper<PurchaseRecordDO>()
|
||||
.eq(PurchaseRecordDO::getOrganId, organId)
|
||||
.eq(PurchaseRecordDO::getProductId, productId)
|
||||
);
|
||||
|
||||
assertEquals(1, records.size());
|
||||
|
||||
PurchaseRecordDO record = records.get(0);
|
||||
|
||||
// 断言核心字段
|
||||
assertTrue(record.getId() > 0);
|
||||
assertEquals("测试产品", record.getProductName());
|
||||
assertEquals(price, record.getTotalAmount());
|
||||
assertEquals(price, record.getOriginalAmount());
|
||||
|
||||
// monthAverageAmount = price / 10
|
||||
assertEquals(new BigDecimal("100.00"), record.getMonthAverageAmount());
|
||||
|
||||
// 初始化语义
|
||||
assertTrue(record.getInitial());
|
||||
assertEquals(1, record.getPurchaseDuration());
|
||||
assertEquals(ProductDurationUnitEnum.YEAR.getCode(), record.getPurchaseDurationUnit());
|
||||
assertEquals(PurchaseRecordStatusEnum.ACTIVE.getStatus(), record.getStatus());
|
||||
|
||||
// 过期时间
|
||||
assertEquals(LocalDate.now().minusDays(1), record.getEndTime());
|
||||
// 校验插入
|
||||
verify(purchaseRecordMapper).insert(argThat((PurchaseRecordDO purchaseRecordDO) ->
|
||||
purchaseRecordDO.getProductName().equals(productsDO.getProductName())
|
||||
&& purchaseRecordDO.getProductId().equals(productsDO.getId())
|
||||
&& purchaseRecordDO.getPurchaseDuration().equals(1)
|
||||
&& purchaseRecordDO.getPurchaseDurationUnit().equals(ProductDurationUnitEnum.YEAR.getCode())
|
||||
&& purchaseRecordDO.getProductDetailsId() == 0
|
||||
&& purchaseRecordDO.getStatus().equals(PurchaseRecordStatusEnum.ACTIVE.getStatus())
|
||||
&& purchaseRecordDO.getInitial().equals(true)
|
||||
&& purchaseRecordDO.getMonthAverageAmount().equals(new BigDecimal("100.00"))
|
||||
&& purchaseRecordDO.getTotalAmount().equals(price)
|
||||
&& purchaseRecordDO.getOriginalAmount().equals(price)
|
||||
&& purchaseRecordDO.getEndTime().equals(LocalDate.now().minusDays(1))
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -384,7 +404,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
Long organId = 1L;
|
||||
|
||||
// DB 中已有首购记录
|
||||
PurchaseRecordDO record = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
PurchaseRecordDO recordDO = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
o.setExternalSpent(new BigDecimal("100.00"));
|
||||
o.setProductName("测试产品");
|
||||
@@ -395,20 +415,16 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInitial(false);
|
||||
o.setOrganId(organId);
|
||||
});
|
||||
purchaseRecordMapper.insert(record);
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
|
||||
// 入参:updateList 中的 purchaseId 不存在
|
||||
OrganCreateProductPurchaseReqVO reqVO = new OrganCreateProductPurchaseReqVO();
|
||||
reqVO.setPurchaseId(9999L);
|
||||
reqVO.setPrice(new BigDecimal("1000"));
|
||||
|
||||
ServiceException ex = assertThrows(ServiceException.class, () ->
|
||||
purchaseService.updateOrgInitProductPurchaseRecord(
|
||||
organId, Collections.singletonList(reqVO)
|
||||
)
|
||||
);
|
||||
|
||||
assertEquals(ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR.getCode(), ex.getCode());
|
||||
assertServiceException(() -> purchaseService.updateOrgInitProductPurchaseRecord(
|
||||
organId, Collections.singletonList(reqVO)
|
||||
), ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -417,7 +433,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
Long productId = 10L;
|
||||
|
||||
// DB 中已有首购记录
|
||||
PurchaseRecordDO record = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
PurchaseRecordDO recordDO = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
o.setExternalSpent(new BigDecimal("100.00"));
|
||||
o.setProductName("测试产品");
|
||||
@@ -429,20 +445,16 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setOrganId(organId);
|
||||
o.setProductId(productId);
|
||||
});
|
||||
purchaseRecordMapper.insert(record);
|
||||
when(purchaseRecordMapper.selectList(any())).thenReturn(List.of(recordDO));
|
||||
|
||||
// 新增请求(purchaseId = null)
|
||||
OrganCreateProductPurchaseReqVO reqVO = new OrganCreateProductPurchaseReqVO();
|
||||
reqVO.setProductId(productId);
|
||||
reqVO.setPrice(new BigDecimal("500"));
|
||||
|
||||
ServiceException ex = assertThrows(ServiceException.class, () ->
|
||||
purchaseService.updateOrgInitProductPurchaseRecord(
|
||||
organId, Collections.singletonList(reqVO)
|
||||
)
|
||||
);
|
||||
|
||||
assertEquals(ORG_PRODUCT_PURCHASE_EXIST_ERROR.getCode(), ex.getCode());
|
||||
assertServiceException(() -> purchaseService.updateOrgInitProductPurchaseRecord(
|
||||
organId, Collections.singletonList(reqVO)
|
||||
), ORG_PRODUCT_PURCHASE_EXIST_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -472,8 +484,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setDeleted(false);
|
||||
});
|
||||
|
||||
purchaseRecordMapper.insert(record1);
|
||||
purchaseRecordMapper.insert(record2);
|
||||
when(purchaseRecordMapper.selectList(any())).thenReturn(List.of(record1, record2));
|
||||
|
||||
// update 请求
|
||||
OrganCreateProductPurchaseReqVO updateReq = new OrganCreateProductPurchaseReqVO();
|
||||
@@ -502,20 +513,33 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
);
|
||||
|
||||
// 验证 update
|
||||
PurchaseRecordDO updated = purchaseRecordMapper.selectById(3001L);
|
||||
assertEquals(new BigDecimal("1000.00"), updated.getTotalAmount());
|
||||
assertEquals(new BigDecimal("100.00"), updated.getMonthAverageAmount());
|
||||
verify(purchaseRecordMapper).update(argThat((LambdaUpdateWrapper wrapper) ->
|
||||
wrapper.getSqlSegment().contains("id")
|
||||
&& wrapper.getSqlSegment().contains("organ_id")
|
||||
&& wrapper.getSqlSegment().contains("initial")
|
||||
&& wrapper.getSqlSet().contains("total_amount")
|
||||
&& wrapper.getSqlSet().contains("month_average_amount")
|
||||
&& wrapper.getSqlSet().contains("original_amount")
|
||||
));
|
||||
|
||||
// 验证 delete(3002 被删)
|
||||
assertNull(purchaseRecordMapper.selectById(3002L));
|
||||
verify(purchaseRecordMapper, times(1)).deleteByIds(List.of(record2.getId()));
|
||||
|
||||
// 验证 create
|
||||
List<PurchaseRecordDO> list = purchaseRecordMapper.selectList(
|
||||
new LambdaQueryWrapper<PurchaseRecordDO>()
|
||||
.eq(PurchaseRecordDO::getOrganId, organId)
|
||||
.eq(PurchaseRecordDO::getProductId, 103L)
|
||||
);
|
||||
assertEquals(1, list.size());
|
||||
// 校验插入
|
||||
verify(purchaseRecordMapper).insert(argThat((PurchaseRecordDO purchaseRecordDO) ->
|
||||
purchaseRecordDO.getProductName().equals(productsDO.getProductName())
|
||||
&& purchaseRecordDO.getProductId().equals(productsDO.getId())
|
||||
&& purchaseRecordDO.getPurchaseDuration().equals(1)
|
||||
&& purchaseRecordDO.getPurchaseDurationUnit().equals(ProductDurationUnitEnum.YEAR.getCode())
|
||||
&& purchaseRecordDO.getProductDetailsId() == 0
|
||||
&& purchaseRecordDO.getStatus().equals(PurchaseRecordStatusEnum.ACTIVE.getStatus())
|
||||
&& purchaseRecordDO.getInitial().equals(true)
|
||||
&& purchaseRecordDO.getMonthAverageAmount().equals(new BigDecimal("60.00"))
|
||||
&& purchaseRecordDO.getTotalAmount().equals(createReq.getPrice())
|
||||
&& purchaseRecordDO.getOriginalAmount().equals(createReq.getPrice())
|
||||
&& purchaseRecordDO.getEndTime().equals(LocalDate.now().minusDays(1))
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -568,28 +592,10 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTotalSales() {
|
||||
void testGetTotalSales() {
|
||||
// 准备数据
|
||||
PurchaseRecordDO r1 = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(2001L);
|
||||
o.setDeleted(false);
|
||||
o.setTotalAmount(new BigDecimal("100.00"));
|
||||
o.setPaymentMethod(PayChannelCodeEnum.ALIPAY_PC.getCode());
|
||||
o.setIsInvocing(INVOICABLE.getCode());
|
||||
o.setInitial(false);
|
||||
});
|
||||
|
||||
PurchaseRecordDO r2 = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(2002L);
|
||||
o.setDeleted(false);
|
||||
o.setTotalAmount(new BigDecimal("300.00"));
|
||||
o.setPaymentMethod(PayChannelCodeEnum.WECHAT_NATIVE.getCode());
|
||||
o.setIsInvocing(INVOICINGSUCCESSFUL.getCode());
|
||||
o.setInitial(false);
|
||||
});
|
||||
|
||||
purchaseRecordMapper.insert(r1);
|
||||
purchaseRecordMapper.insert(r2);
|
||||
TotalSalesAmountRespVO totalSalesAmountRespVO = new TotalSalesAmountRespVO(new BigDecimal("400.00"));
|
||||
when(purchaseRecordMapper.getTotalSales()).thenReturn(totalSalesAmountRespVO);
|
||||
|
||||
TotalSalesAmountRespVO resp = purchaseService.getTotalSales();
|
||||
|
||||
@@ -598,7 +604,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetManageSalesDetailsPage_success() {
|
||||
void testGetManageSalesDetailsPage_success() {
|
||||
SalesDetailsPageReqVO reqVO = new SalesDetailsPageReqVO();
|
||||
|
||||
Long organId = 1L;
|
||||
@@ -613,7 +619,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInitial(false);
|
||||
});
|
||||
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
when(purchaseRecordMapper.getSaleDetailsPage(reqVO)).thenReturn(new PageResult<>(List.of(recordDO), 1L));
|
||||
|
||||
// mock 国际化
|
||||
when(i18nUtils.getMessage(anyString())).thenReturn("支付宝");
|
||||
@@ -640,7 +646,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetManageSalesDetailsPage_organNotExist() {
|
||||
void testGetManageSalesDetailsPage_organNotExist() {
|
||||
SalesDetailsPageReqVO reqVO = new SalesDetailsPageReqVO();
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
@@ -657,7 +663,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setInitial(false);
|
||||
});
|
||||
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
when(purchaseRecordMapper.getSaleDetailsPage(reqVO)).thenReturn(new PageResult<>(List.of(recordDO), 1L));
|
||||
|
||||
when(i18nUtils.getMessage(anyString())).thenReturn("微信");
|
||||
when(organService.getOrganWithDeleted(organId)).thenReturn(null);
|
||||
@@ -672,7 +678,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOrgInitialPurchaseRecord_success() {
|
||||
void testGetOrgInitialPurchaseRecord_success() {
|
||||
Long organId = 1L;
|
||||
Long productId = 100L;
|
||||
|
||||
@@ -686,7 +692,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setIsInvocing(INVOICINGSUCCESSFUL.getCode());
|
||||
});
|
||||
|
||||
purchaseRecordMapper.insert(initialRecord);
|
||||
when(purchaseRecordMapper.selectOne(any())).thenReturn(initialRecord);
|
||||
|
||||
PurchaseRecordDO result =
|
||||
purchaseService.getOrgInitialPurchaseRecord(organId, productId);
|
||||
@@ -697,7 +703,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOrgProductPendingPurchaseList_success() {
|
||||
void testGetOrgProductPendingPurchaseList_success() {
|
||||
Long organId = 3L;
|
||||
Long productId = 300L;
|
||||
|
||||
@@ -711,18 +717,7 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setIsInvocing(INVOICINGSUCCESSFUL.getCode());
|
||||
});
|
||||
|
||||
// 干扰数据
|
||||
PurchaseRecordDO active = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setOrganId(organId);
|
||||
o.setProductId(productId);
|
||||
o.setStatus(PurchaseRecordStatusEnum.ACTIVE.getStatus());
|
||||
o.setDeleted(false);
|
||||
o.setPaymentMethod(PayChannelCodeEnum.ALIPAY_PC.getCode());
|
||||
o.setIsInvocing(INVOICINGSUCCESSFUL.getCode());
|
||||
});
|
||||
|
||||
purchaseRecordMapper.insert(pending1);
|
||||
purchaseRecordMapper.insert(active);
|
||||
when(purchaseRecordMapper.selectList(any())).thenReturn(List.of(pending1));
|
||||
|
||||
List<PurchaseRecordDO> result =
|
||||
purchaseService.getOrgProductPendingPurchaseList(organId, productId);
|
||||
@@ -734,14 +729,14 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Test
|
||||
void test_noInitialPurchase_withYearPricing_noPromotion() {
|
||||
Long PRODUCT_ID = 100L;
|
||||
Long ORGAN_ID = 1L;
|
||||
Long productId = 100L;
|
||||
Long organId = 1L;
|
||||
|
||||
ProductsDO product = new ProductsDO();
|
||||
product.setId(PRODUCT_ID);
|
||||
product.setId(productId);
|
||||
product.setPrice(new BigDecimal("1200"));
|
||||
|
||||
when(productsDetailService.validateProductExist(PRODUCT_ID))
|
||||
when(productsDetailService.validateProductExist(productId))
|
||||
.thenReturn(product);
|
||||
|
||||
ProductsDetailDO yearDetail = new ProductsDetailDO();
|
||||
@@ -752,11 +747,11 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
when(productsDetailService.getPage(any()))
|
||||
.thenReturn(new PageResult<>(List.of(yearDetail), 1L));
|
||||
|
||||
when(productPromotionService.getAvailableProductPromotionList(PRODUCT_ID))
|
||||
when(productPromotionService.getAvailableProductPromotionList(productId))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
List<ProductDetailsRespVO> result =
|
||||
purchaseService.getOrgProductDetailList(ORGAN_ID, PRODUCT_ID);
|
||||
purchaseService.getOrgProductDetailList(organId, productId);
|
||||
|
||||
// 10个月 + 1年
|
||||
assertEquals(11, result.size());
|
||||
@@ -773,14 +768,14 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Test
|
||||
void test_withInitialPurchase_withYearPricing_withPromotion() {
|
||||
Long PRODUCT_ID = 100L;
|
||||
Long ORGAN_ID = 1L;
|
||||
Long productId = 100L;
|
||||
Long organId = 1L;
|
||||
|
||||
ProductsDO product = new ProductsDO();
|
||||
product.setId(PRODUCT_ID);
|
||||
product.setId(productId);
|
||||
product.setPrice(new BigDecimal("999"));
|
||||
|
||||
when(productsDetailService.validateProductExist(PRODUCT_ID))
|
||||
when(productsDetailService.validateProductExist(productId))
|
||||
.thenReturn(product);
|
||||
|
||||
ProductsDetailDO yearDetail = new ProductsDetailDO();
|
||||
@@ -797,15 +792,15 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
promotion.setGiftDuration(3);
|
||||
promotion.setGiftDurationUnit(ProductDurationUnitEnum.MONTH.getCode());
|
||||
|
||||
when(productPromotionService.getAvailableProductPromotionList(PRODUCT_ID))
|
||||
when(productPromotionService.getAvailableProductPromotionList(productId))
|
||||
.thenReturn(List.of(promotion));
|
||||
|
||||
PurchaseRecordDO record = new PurchaseRecordDO();
|
||||
record.setTotalAmount(new BigDecimal("1000"));
|
||||
record.setMonthAverageAmount(new BigDecimal("100"));
|
||||
PurchaseRecordDO recordDO = new PurchaseRecordDO();
|
||||
recordDO.setTotalAmount(new BigDecimal("1000"));
|
||||
recordDO.setMonthAverageAmount(new BigDecimal("100"));
|
||||
|
||||
ProductDetailsRespVO year =
|
||||
purchaseService.getOrgProductDetailList(ORGAN_ID, PRODUCT_ID)
|
||||
purchaseService.getOrgProductDetailList(organId, productId)
|
||||
.stream()
|
||||
.filter(r -> r.getDurationUnit().equals(ProductDurationUnitEnum.YEAR.getCode()))
|
||||
.findFirst().orElseThrow();
|
||||
@@ -821,14 +816,14 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Test
|
||||
void test_withInitialPurchase_withoutYearPricing_autoFillYear() {
|
||||
Long PRODUCT_ID = 100L;
|
||||
Long ORGAN_ID = 1L;
|
||||
Long productId = 100L;
|
||||
Long organId = 1L;
|
||||
|
||||
ProductsDO product = new ProductsDO();
|
||||
product.setId(PRODUCT_ID);
|
||||
product.setId(productId);
|
||||
product.setPrice(new BigDecimal("888"));
|
||||
|
||||
when(productsDetailService.validateProductExist(PRODUCT_ID))
|
||||
when(productsDetailService.validateProductExist(productId))
|
||||
.thenReturn(product);
|
||||
|
||||
// 只有 MONTH
|
||||
@@ -839,15 +834,15 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
when(productsDetailService.getPage(any()))
|
||||
.thenReturn(new PageResult<>(List.of(monthDetail), 1L));
|
||||
|
||||
when(productPromotionService.getAvailableProductPromotionList(PRODUCT_ID))
|
||||
when(productPromotionService.getAvailableProductPromotionList(productId))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
PurchaseRecordDO record = new PurchaseRecordDO();
|
||||
record.setTotalAmount(new BigDecimal("888"));
|
||||
record.setMonthAverageAmount(new BigDecimal("88.8"));
|
||||
PurchaseRecordDO recordDO = new PurchaseRecordDO();
|
||||
recordDO.setTotalAmount(new BigDecimal("888"));
|
||||
recordDO.setMonthAverageAmount(new BigDecimal("88.8"));
|
||||
|
||||
List<ProductDetailsRespVO> result =
|
||||
purchaseService.getOrgProductDetailList(ORGAN_ID, PRODUCT_ID);
|
||||
purchaseService.getOrgProductDetailList(organId, productId);
|
||||
|
||||
ProductDetailsRespVO year =
|
||||
result.stream()
|
||||
@@ -860,20 +855,20 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Test
|
||||
void test_getInitialProductProductPriceNullError(){
|
||||
Long PRODUCT_ID = 100L;
|
||||
Long ORGAN_ID = 1L;
|
||||
Long productId = 100L;
|
||||
Long organId = 1L;
|
||||
|
||||
ProductsDO product = new ProductsDO();
|
||||
product.setId(PRODUCT_ID);
|
||||
product.setId(productId);
|
||||
|
||||
when(productsDetailService.validateProductExist(PRODUCT_ID))
|
||||
when(productsDetailService.validateProductExist(productId))
|
||||
.thenReturn(product);
|
||||
|
||||
when(productsDetailService.getPage(any()))
|
||||
.thenReturn(new PageResult<>(anyList(), 1L));
|
||||
|
||||
ServiceException ex = assertThrows(ServiceException.class, () ->
|
||||
purchaseService.getOrgProductDetailList(ORGAN_ID, PRODUCT_ID)
|
||||
purchaseService.getOrgProductDetailList(organId, productId)
|
||||
);
|
||||
|
||||
assertEquals(PRODUCT_PRICE_NULL_ERROR.getCode(), ex.getCode());
|
||||
@@ -881,14 +876,14 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Test
|
||||
void test_getOrgProductDetailList_WithOrgInitial() {
|
||||
Long PRODUCT_ID = 100L;
|
||||
Long ORGAN_ID = 1L;
|
||||
Long productId = 100L;
|
||||
Long organId = 1L;
|
||||
|
||||
ProductsDO product = new ProductsDO();
|
||||
product.setId(PRODUCT_ID);
|
||||
product.setId(productId);
|
||||
product.setPrice(new BigDecimal("1000"));
|
||||
|
||||
when(productsDetailService.validateProductExist(PRODUCT_ID))
|
||||
when(productsDetailService.validateProductExist(productId))
|
||||
.thenReturn(product);
|
||||
|
||||
ProductsDetailDO yearDetail = new ProductsDetailDO();
|
||||
@@ -902,13 +897,13 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
productPromotionDO.setPurchaseDuration(2);
|
||||
productPromotionDO.setPurchaseDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
|
||||
// 优惠活动
|
||||
when(productPromotionService.getAvailableProductPromotionList(PRODUCT_ID))
|
||||
when(productPromotionService.getAvailableProductPromotionList(productId))
|
||||
.thenReturn(Collections.singletonList(productPromotionDO));
|
||||
|
||||
// 插入首购记录
|
||||
PurchaseRecordDO recordDO = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setOrganId(ORGAN_ID);
|
||||
o.setProductId(PRODUCT_ID);
|
||||
o.setOrganId(organId);
|
||||
o.setProductId(productId);
|
||||
o.setStatus(PurchaseRecordStatusEnum.PENDING.getStatus());
|
||||
o.setDeleted(false);
|
||||
o.setPaymentMethod(PayChannelCodeEnum.WECHAT_NATIVE.getCode());
|
||||
@@ -917,10 +912,10 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setMonthAverageAmount(new BigDecimal("99"));
|
||||
o.setTotalAmount(new BigDecimal("999"));
|
||||
});
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
when(purchaseRecordMapper.selectOne(any())).thenReturn(recordDO);
|
||||
|
||||
List<ProductDetailsRespVO> result =
|
||||
purchaseService.getOrgProductDetailList(ORGAN_ID, PRODUCT_ID);
|
||||
purchaseService.getOrgProductDetailList(organId, productId);
|
||||
|
||||
ProductDetailsRespVO year =
|
||||
result.stream()
|
||||
@@ -928,71 +923,19 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
.findFirst().orElseThrow();
|
||||
|
||||
assertEquals(new BigDecimal("1198.80"), year.getCurrentPrice());
|
||||
assertEquals(new BigDecimal("1998.00"), year.getOriginalPrice());
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_getOrgProductDetailList_WithYear() {
|
||||
Long PRODUCT_ID = 100L;
|
||||
Long ORGAN_ID = 1L;
|
||||
|
||||
ProductsDO product = new ProductsDO();
|
||||
product.setId(PRODUCT_ID);
|
||||
product.setPrice(new BigDecimal("1000"));
|
||||
|
||||
when(productsDetailService.validateProductExist(PRODUCT_ID))
|
||||
.thenReturn(product);
|
||||
|
||||
ProductsDetailDO yearDetail = new ProductsDetailDO();
|
||||
yearDetail.setDuration(2);
|
||||
yearDetail.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
|
||||
yearDetail.setDiscount(new BigDecimal("60"));
|
||||
when(productsDetailService.getPage(any()))
|
||||
.thenReturn(new PageResult<>(List.of(yearDetail), 1L));
|
||||
|
||||
ProductPromotionDO productPromotionDO = new ProductPromotionDO();
|
||||
productPromotionDO.setPurchaseDuration(2);
|
||||
productPromotionDO.setPurchaseDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
|
||||
// 优惠活动
|
||||
when(productPromotionService.getAvailableProductPromotionList(PRODUCT_ID))
|
||||
.thenReturn(Collections.singletonList(productPromotionDO));
|
||||
|
||||
// 插入首购记录
|
||||
PurchaseRecordDO recordDO = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setOrganId(ORGAN_ID);
|
||||
o.setProductId(PRODUCT_ID);
|
||||
o.setStatus(PurchaseRecordStatusEnum.PENDING.getStatus());
|
||||
o.setDeleted(false);
|
||||
o.setPaymentMethod(PayChannelCodeEnum.WECHAT_NATIVE.getCode());
|
||||
o.setIsInvocing(INVOICINGSUCCESSFUL.getCode());
|
||||
o.setInitial(true);
|
||||
o.setMonthAverageAmount(new BigDecimal("99"));
|
||||
o.setTotalAmount(new BigDecimal("999"));
|
||||
});
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
|
||||
List<ProductDetailsRespVO> result =
|
||||
purchaseService.getOrgProductDetailList(ORGAN_ID, PRODUCT_ID);
|
||||
|
||||
ProductDetailsRespVO year =
|
||||
result.stream()
|
||||
.filter(r -> r.getDurationUnit().equals(ProductDurationUnitEnum.YEAR.getCode()))
|
||||
.findFirst().orElseThrow();
|
||||
|
||||
assertEquals(new BigDecimal("1198.80"), year.getCurrentPrice());
|
||||
assertEquals(new BigDecimal("1998.00"), year.getOriginalPrice());
|
||||
assertEquals(new BigDecimal("1998"), year.getOriginalPrice());
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_getOrgProductDetailList_WithoutYear() {
|
||||
Long PRODUCT_ID = 100L;
|
||||
Long ORGAN_ID = 1L;
|
||||
Long productId = 100L;
|
||||
Long organId = 1L;
|
||||
|
||||
ProductsDO product = new ProductsDO();
|
||||
product.setId(PRODUCT_ID);
|
||||
product.setId(productId);
|
||||
product.setPrice(new BigDecimal("1000"));
|
||||
|
||||
when(productsDetailService.validateProductExist(PRODUCT_ID))
|
||||
when(productsDetailService.validateProductExist(productId))
|
||||
.thenReturn(product);
|
||||
|
||||
ProductsDetailDO monthDetail = new ProductsDetailDO();
|
||||
@@ -1005,13 +948,13 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
productPromotionDO.setPurchaseDuration(2);
|
||||
productPromotionDO.setPurchaseDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
|
||||
// 优惠活动
|
||||
when(productPromotionService.getAvailableProductPromotionList(PRODUCT_ID))
|
||||
when(productPromotionService.getAvailableProductPromotionList(productId))
|
||||
.thenReturn(Collections.singletonList(productPromotionDO));
|
||||
|
||||
// 插入首购记录
|
||||
PurchaseRecordDO recordDO = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setOrganId(ORGAN_ID);
|
||||
o.setProductId(PRODUCT_ID);
|
||||
o.setOrganId(organId);
|
||||
o.setProductId(productId);
|
||||
o.setStatus(PurchaseRecordStatusEnum.PENDING.getStatus());
|
||||
o.setDeleted(false);
|
||||
o.setPaymentMethod(PayChannelCodeEnum.WECHAT_NATIVE.getCode());
|
||||
@@ -1020,10 +963,10 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
o.setMonthAverageAmount(new BigDecimal("99"));
|
||||
o.setTotalAmount(new BigDecimal("999"));
|
||||
});
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
when(purchaseRecordMapper.selectOne(any())).thenReturn(recordDO);
|
||||
|
||||
List<ProductDetailsRespVO> result =
|
||||
purchaseService.getOrgProductDetailList(ORGAN_ID, PRODUCT_ID);
|
||||
purchaseService.getOrgProductDetailList(organId, productId);
|
||||
|
||||
ProductDetailsRespVO year =
|
||||
result.stream()
|
||||
@@ -1040,26 +983,16 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
Long organId = 1L;
|
||||
Long recordId = 101L;
|
||||
|
||||
PurchaseRecordDO recordDO = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(recordId);
|
||||
o.setOrganId(organId);
|
||||
o.setStatus(PurchaseRecordStatusEnum.PENDING.getStatus());
|
||||
o.setDeleted(false);
|
||||
o.setPaymentMethod(PayChannelCodeEnum.WECHAT_NATIVE.getCode());
|
||||
o.setIsInvocing(INVOICINGSUCCESSFUL.getCode());
|
||||
o.setInitial(true);
|
||||
o.setMonthAverageAmount(new BigDecimal("99"));
|
||||
o.setTotalAmount(new BigDecimal("999"));
|
||||
});
|
||||
|
||||
purchaseRecordMapper.insert(recordDO);
|
||||
|
||||
purchaseService.invalidHistoryOrganProductPurchaseRecord(organId, recordId);
|
||||
|
||||
PurchaseRecordDO updated =
|
||||
purchaseRecordMapper.selectById(recordId);
|
||||
|
||||
assertEquals(PurchaseRecordStatusEnum.INACTIVE.getStatus(), updated.getStatus());
|
||||
// 校验状态更新
|
||||
verify(purchaseRecordMapper).update(argThat((LambdaUpdateWrapper wrapper) ->
|
||||
wrapper.getSqlSegment().contains("organ_id")
|
||||
&& wrapper.getSqlSegment().contains("id")
|
||||
&& wrapper.getSqlSegment().contains("deleted")
|
||||
&& wrapper.getSqlSegment().contains("status")
|
||||
&& wrapper.getSqlSet().contains("status")
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1067,60 +1000,25 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
Long organId = 1L;
|
||||
Long recordId = 200L;
|
||||
|
||||
PurchaseRecordDO record = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setId(recordId);
|
||||
o.setOrganId(organId);
|
||||
o.setStatus(PurchaseRecordStatusEnum.PENDING.getStatus());
|
||||
o.setDeleted(false);
|
||||
o.setPaymentMethod(PayChannelCodeEnum.WECHAT_NATIVE.getCode());
|
||||
o.setIsInvocing(INVOICINGSUCCESSFUL.getCode());
|
||||
o.setInitial(true);
|
||||
o.setMonthAverageAmount(new BigDecimal("99"));
|
||||
o.setTotalAmount(new BigDecimal("999"));
|
||||
});
|
||||
|
||||
purchaseRecordMapper.insert(record);
|
||||
|
||||
// when
|
||||
purchaseService.activateHistoryOrganProductPurchaseRecord(organId, recordId);
|
||||
|
||||
// then
|
||||
PurchaseRecordDO updated = purchaseRecordMapper.selectById(recordId);
|
||||
|
||||
assertEquals(
|
||||
PurchaseRecordStatusEnum.ACTIVE.getStatus(),
|
||||
updated.getStatus()
|
||||
);
|
||||
// 校验状态更新
|
||||
verify(purchaseRecordMapper).update(argThat((LambdaUpdateWrapper wrapper) ->
|
||||
wrapper.getSqlSegment().contains("organ_id")
|
||||
&& wrapper.getSqlSegment().contains("id")
|
||||
&& wrapper.getSqlSegment().contains("deleted")
|
||||
&& wrapper.getSqlSegment().contains("status")
|
||||
&& wrapper.getSqlSet().contains("status")
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_return_correct_sales_statistics() {
|
||||
Long organId = 1L;
|
||||
|
||||
PurchaseRecordDO record1 = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setOrganId(organId);
|
||||
o.setStatus(PurchaseRecordStatusEnum.PENDING.getStatus());
|
||||
o.setDeleted(false);
|
||||
o.setPaymentMethod(PayChannelCodeEnum.WECHAT_NATIVE.getCode());
|
||||
o.setIsInvocing(INVOICINGSUCCESSFUL.getCode());
|
||||
o.setInitial(false);
|
||||
o.setMonthAverageAmount(new BigDecimal("99"));
|
||||
o.setTotalAmount(new BigDecimal("200"));
|
||||
o.setCreateTime(LocalDateTime.now().minusDays(2));
|
||||
});
|
||||
|
||||
PurchaseRecordDO record2 = randomPojo(PurchaseRecordDO.class, o -> {
|
||||
o.setOrganId(organId);
|
||||
o.setStatus(PurchaseRecordStatusEnum.PENDING.getStatus());
|
||||
o.setDeleted(false);
|
||||
o.setPaymentMethod(PayChannelCodeEnum.WECHAT_NATIVE.getCode());
|
||||
o.setIsInvocing(INVOICINGSUCCESSFUL.getCode());
|
||||
o.setInitial(false);
|
||||
o.setTotalAmount(new BigDecimal("100"));
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
});
|
||||
purchaseRecordMapper.insert(record1);
|
||||
purchaseRecordMapper.insert(record2);
|
||||
TotalSalesAmountRespVO totalSalesAmountRespVO = new TotalSalesAmountRespVO(new BigDecimal(300));
|
||||
when(purchaseRecordMapper.getTotalSales()).thenReturn(totalSalesAmountRespVO);
|
||||
when(purchaseRecordMapper.getTodaySales(any())).thenReturn(new BigDecimal(100));
|
||||
|
||||
// when
|
||||
ManageSalesTotalStatisticRespVO resp =
|
||||
@@ -1128,8 +1026,8 @@ class PurchaseServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
// then
|
||||
assertAll(
|
||||
() -> assertEquals(new BigDecimal("300.00"), resp.getSalesTotal()),
|
||||
() -> assertEquals(new BigDecimal("100.00"), resp.getSalesToday())
|
||||
() -> assertEquals(new BigDecimal("300"), resp.getSalesTotal()),
|
||||
() -> assertEquals(new BigDecimal("100"), resp.getSalesToday())
|
||||
);
|
||||
}
|
||||
}
|
||||
+15
-41
@@ -1,28 +1,23 @@
|
||||
package com.cf.imes.module.system.service.funds.statistics;
|
||||
|
||||
import com.cf.imes.framework.common.enums.StatisticsUnit;
|
||||
import com.cf.imes.framework.common.util.i18n.core.util.I18nUtils;
|
||||
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.OrganFundsStatisticsReqVO;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.statistics.vo.OrgStatusGroupStatisticsReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.incomeandexpense.IncomeExpenseDetailsDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.statistics.FundsTradeTypeGroupStatisticsDO;
|
||||
import com.cf.imes.module.system.dal.mysql.incomeandexpense.IncomeExpenseDetailsMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -30,23 +25,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
* @author Gqr
|
||||
* @since 2025/12/31 15:20
|
||||
*/
|
||||
@Import(FundsStatisticsServiceImpl.class)
|
||||
public class FundsStatisticsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
class FundsStatisticsServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@Resource
|
||||
@InjectMocks
|
||||
private FundsStatisticsServiceImpl fundsStatisticsService;
|
||||
|
||||
@MockitoBean
|
||||
private I18nUtils i18nUtils;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private IncomeExpenseDetailsMapper incomeExpenseDetailsMapper;
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(organId = 1L)
|
||||
void should_return_consumption_trend_with_zero_filling() {
|
||||
Long organId = SecurityFrameworkUtils.getUserOrganId();
|
||||
|
||||
OrgStatusGroupStatisticsReqVO reqVO = new OrgStatusGroupStatisticsReqVO();
|
||||
reqVO.setUnit(StatisticsUnit.DAY.getValue());
|
||||
reqVO.setCreateTime(new LocalDate[]{
|
||||
@@ -54,24 +42,10 @@ public class FundsStatisticsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
LocalDate.now().plusDays(1)
|
||||
});
|
||||
|
||||
IncomeExpenseDetailsDO pojo1 = randomPojo(IncomeExpenseDetailsDO.class, o -> {
|
||||
o.setOrganId(organId);
|
||||
o.setAmount(new BigDecimal("100"));
|
||||
o.setCreateTime(LocalDateTime.now().minusDays(2));
|
||||
});
|
||||
IncomeExpenseDetailsDO pojo2 = randomPojo(IncomeExpenseDetailsDO.class, o -> {
|
||||
o.setOrganId(organId);
|
||||
o.setAmount(new BigDecimal("200"));
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
});
|
||||
IncomeExpenseDetailsDO pojo3 = randomPojo(IncomeExpenseDetailsDO.class, o -> {
|
||||
o.setAmount(new BigDecimal("200"));
|
||||
o.setCreateTime(LocalDateTime.now());
|
||||
});
|
||||
|
||||
incomeExpenseDetailsMapper.insert(pojo1);
|
||||
incomeExpenseDetailsMapper.insert(pojo2);
|
||||
incomeExpenseDetailsMapper.insert(pojo3);
|
||||
List<FundsTradeTypeGroupStatisticsDO> purchaseList = new ArrayList<>();
|
||||
purchaseList.add(new FundsTradeTypeGroupStatisticsDO(new BigDecimal("100"), "2026-1-18"));
|
||||
purchaseList.add(new FundsTradeTypeGroupStatisticsDO(new BigDecimal("400"), "2026-1-20"));
|
||||
when(incomeExpenseDetailsMapper.selectTotalSalesTrendGroupByCreateTime(reqVO)).thenReturn(purchaseList);
|
||||
|
||||
// when query
|
||||
Map<String, Object> result =
|
||||
@@ -88,9 +62,9 @@ public class FundsStatisticsServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
assertArrayEquals(
|
||||
new BigDecimal[]{
|
||||
new BigDecimal("100.00"),
|
||||
new BigDecimal("100"),
|
||||
BigDecimal.ZERO,
|
||||
new BigDecimal("400.00"),
|
||||
new BigDecimal("400"),
|
||||
BigDecimal.ZERO,
|
||||
},
|
||||
data
|
||||
|
||||
Reference in New Issue
Block a user