1、组织资金、销售明细、购买记录controller单元测试完善;2、token管理service、controller单元测试完善;3、新增/贴皮管理http method错误修正;

This commit is contained in:
gaoqr
2026-01-07 14:40:15 +08:00
parent 953ad8909f
commit 58c06ba5d4
12 changed files with 1172 additions and 36 deletions
@@ -95,13 +95,13 @@ public class VeneerController {
return success(veneerService.get(id));
}
@PutMapping("")
@PostMapping("")
@Operation(summary = "创建贴皮")
public CommonResult<Long> createVeneer(@Valid @RequestBody VeneerSaveReqVO reqVO) {
return success(veneerService.create(reqVO));
}
@PostMapping("")
@PutMapping("")
@Operation(summary = "编辑贴皮")
public CommonResult<Boolean> updateVeneer(@Valid @RequestBody VeneerSaveReqVO reqVO) {
return success(veneerService.update(reqVO) == 1);
@@ -123,7 +123,8 @@ public class TokenConfigController {
public void exportTokenConfigExcel(@Valid TokenConfigPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<TokenConfigRespVO> list = tokenConfigService.exportTokenConfigExcel(pageReqVO).getList();
pageReqVO.setTimeType(null);
List<TokenConfigRespVO> list = tokenConfigService.getTokenConfigPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "token配置信息表.xls", "数据", TokenConfigRespVO.class,
BeanUtils.toBean(list, TokenConfigRespVO.class));
@@ -62,7 +62,7 @@ public class TokenConfigDO extends BaseDO {
/**
* 组织id
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
@TableField(fill = FieldFill.INSERT)
private Long organId;
}
@@ -12,24 +12,56 @@ import com.cf.imes.module.system.dal.dataobject.tokenconfig.TokenConfigDO;
*/
public interface TokenConfigService {
/**
* 获取token分页
*
* @param pageReqVO
* @return
*/
PageResult<TokenConfigRespVO> getTokenConfigPage(TokenConfigPageReqVO pageReqVO);
/**
* 根据id查询token
*
* @param id
* @return
*/
TokenConfigDO getTokenConConfig(Long id);
/**
* 新增token
*
* @param reqVO
*/
void insertTokenConfig(TokenConfigSaveReqVO reqVO);
/**
* 更新token
*
* @param reqVO
*/
void updateTokenConfig(TokenConfigSaveReqVO reqVO);
/**
* 删除token
*
* @param id
*/
void deleteTokenConfig(Long id);
/**
* 校验token
*
* @param token
* @return
*/
Long checkTokenConfig(String token);
/**
* 复制token
*
* @param id
* @return
*/
String tokenConfigCopy(Long id);
PageResult<TokenConfigRespVO> exportTokenConfigExcel(TokenConfigPageReqVO pageReqVO);
}
@@ -247,29 +247,6 @@ public class TokenConfigServiceImpl implements TokenConfigService{
}
@Override
public PageResult<TokenConfigRespVO> exportTokenConfigExcel(TokenConfigPageReqVO pageReqVO) {
PageResult<TokenConfigDO> pageResult = tokenConfigMapper.selectConfigPage(pageReqVO,null);
if(CollUtil.isEmpty(pageResult.getList())) {
return new PageResult<>();
}
OrganizationDO organizationDO = organService.validOrgan(getUserOrganId());
PageResult<TokenConfigRespVO> result = BeanUtils.toBean(pageResult, TokenConfigRespVO.class);
result.getList().forEach(f->{
f.setOrganName(organizationDO.getName());
f.setAppToken(FIELD_IMES+f.getAppToken());
});
return result;
}
private TokenConfigDO validateTokenConfigExists(Long id) {
TokenConfigDO tokenConfigDO = tokenConfigMapper.selectById(id);
@@ -0,0 +1,122 @@
package com.cf.imes.module.system.controller.admin.funds.organamount;
import com.cf.imes.framework.common.enums.StatisticsUnit;
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.ManageAmountOverviewRespVO;
import com.cf.imes.module.system.service.funds.organamount.OrganAmountService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* 组织资金 controller 单元测试
*
* @author Gqr
* @since 2026/1/7 10:26
*/
@WebMvcTest(
controllers = OrganAmountController.class,
excludeAutoConfiguration = SecurityAutoConfiguration.class
)
class OrganAmountControllerTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean
private OrganAmountService organAmountService;
@Autowired
private ObjectMapper objectMapper;
/**
* 获取管理端资金总览
*/
@Test
void testGetManageTotalAmount() throws Exception {
// mock 返回
ManageAmountOverviewRespVO respVO = new ManageAmountOverviewRespVO();
respVO.setToExamineAmount(new BigDecimal("10000.00"));
respVO.setTotalSalesAmount(new BigDecimal("8000.00"));
when(organAmountService.getOrganAmountAll())
.thenReturn(respVO);
mockMvc.perform(get("/system/amount/manage/total")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.toExamineAmount").value(10000.00))
.andExpect(jsonPath("$.data.totalSalesAmount").value(8000.00));
verify(organAmountService, times(1))
.getOrganAmountAll();
}
/**
* 获取组织消费趋势(非管理端)
*/
@Test
void testGetOrganConsumptionTrend() throws Exception {
// 构造返回数据
Map<String, Object> result = new HashMap<>();
result.put("dateList", List.of("2025-01", "2025-02"));
result.put("series", List.of(100, 200));
when(organAmountService.getConsumptionTrend(any(), eq(true)))
.thenReturn(result);
mockMvc.perform(get("/system/amount/statistics/consumptionTrend")
.contentType(MediaType.APPLICATION_JSON)
.param("createTime", "2025-01-01")
.param("createTime", "2025-02-28")
.param("unit", StatisticsUnit.MONTH.getValue().toString()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.dateList[0]").value("2025-01"))
.andExpect(jsonPath("$.data.series[1]").value(200));
verify(organAmountService, times(1))
.getConsumptionTrend(any(), eq(true));
}
/**
* 获取管理端消费趋势
*/
@Test
void testGetManageConsumptionTrend() throws Exception {
Map<String, Object> result = new HashMap<>();
result.put("dateList", List.of("2025-01"));
result.put("series", List.of(999));
when(organAmountService.getConsumptionTrend(any(), eq(false)))
.thenReturn(result);
mockMvc.perform(get("/system/amount/manage/statistics/consumptionTrend")
.contentType(MediaType.APPLICATION_JSON)
.param("createTime", "2025-01-01")
.param("createTime", "2025-02-28")
.param("unit", StatisticsUnit.MONTH.getValue().toString()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.dateList[0]").value("2025-01"))
.andExpect(jsonPath("$.data.series[0]").value(999));
verify(organAmountService, times(1))
.getConsumptionTrend(any(), eq(false));
}
}
@@ -0,0 +1,173 @@
package com.cf.imes.module.system.controller.admin.funds.purchase;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordRespVO;
import com.cf.imes.module.system.service.funds.purchase.PurchaseService;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* 购买记录 controller 单元测试
*
* @author Gqr
* @since 2026/1/7 10:16
*/
@WebMvcTest(
controllers = PurchaseController.class,
excludeAutoConfiguration = SecurityAutoConfiguration.class
)
class PurchaseControllerTest extends BaseWebUnitTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean
private PurchaseService purchaseService;
/**
* 非管理端:获取购买记录分页
*/
@Test
void testGetPurchaseRecord_nonManage() throws Exception {
try (MockedStatic<SecurityFrameworkUtils> mocked = Mockito.mockStatic(SecurityFrameworkUtils.class)) {
// mock 当前为非管理端
mocked.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(false);
mocked.when(SecurityFrameworkUtils::getUserOrganId).thenReturn(1L);
// mock service 返回
PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
respVO.setId(1L);
respVO.setOrganId(1L);
PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
pageResult.setTotal(1L);
pageResult.setList(List.of(respVO));
when(purchaseService.getPurchaseRecord(any()))
.thenReturn(pageResult);
// 发起请求
mockMvc.perform(get("/system/purchase")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.total").value(1))
.andExpect(jsonPath("$.data.list[0].id").value(1L));
// 校验 organId 被强制设置
ArgumentCaptor<PurchaseRecordPageReqVO> captor =
ArgumentCaptor.forClass(PurchaseRecordPageReqVO.class);
verify(purchaseService, times(1))
.getPurchaseRecord(captor.capture());
assertEquals(1L, captor.getValue().getOrganId());
}
}
/**
* 管理端:获取购买记录分页
*/
@Test
void testGetPurchaseRecord_manage() throws Exception {
try (MockedStatic<SecurityFrameworkUtils> mocked = Mockito.mockStatic(SecurityFrameworkUtils.class)) {
mocked.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(true);
PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
pageResult.setTotal(0L);
pageResult.setList(Collections.emptyList());
when(purchaseService.getPurchaseRecord(any()))
.thenReturn(pageResult);
mockMvc.perform(get("/system/purchase")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.total").value(0));
verify(purchaseService, times(1))
.getPurchaseRecord(any());
}
}
/**
* 非管理端:导出购买记录
*/
@Test
void testExportPurchaseRecord_nonManage() throws Exception {
try (MockedStatic<SecurityFrameworkUtils> mocked = Mockito.mockStatic(SecurityFrameworkUtils.class)) {
mocked.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(false);
mocked.when(SecurityFrameworkUtils::getUserOrganId).thenReturn(1L);
PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
respVO.setId(1L);
respVO.setOrganId(1L);
PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
pageResult.setTotal(1L);
pageResult.setList(List.of(respVO));
when(purchaseService.getPurchaseRecord(any()))
.thenReturn(pageResult);
mockMvc.perform(get("/system/purchase/export")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
verify(purchaseService, times(1))
.getPurchaseRecord(any());
}
}
//
/**
* 管理端:导出购买记录
*/
@Test
void testExportPurchaseRecord_manage() throws Exception {
try (MockedStatic<SecurityFrameworkUtils> mocked = Mockito.mockStatic(SecurityFrameworkUtils.class)) {
mocked.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(true);
PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
respVO.setId(1L);
PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
pageResult.setTotal(1L);
pageResult.setList(List.of(respVO));
when(purchaseService.getPurchaseRecord(any()))
.thenReturn(pageResult);
mockMvc.perform(get("/system/purchase/export")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
verify(purchaseService, times(1))
.getPurchaseRecord(any());
}
}
}
@@ -0,0 +1,138 @@
package com.cf.imes.module.system.controller.admin.funds.purchase;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.TotalSalesAmountRespVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.SalesDetailRespVO;
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.SalesDetailsPageReqVO;
import com.cf.imes.module.system.service.funds.purchase.PurchaseService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import java.math.BigDecimal;
import java.util.List;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* 销售明细管理controller单元测试
*
* @author Gqr
* @since 2026/1/7 9:53
*/
@WebMvcTest(controllers = SalesDetailsController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
class SalesDetailsControllerTest extends BaseWebUnitTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean
private PurchaseService purchaseService;
@Autowired
private ObjectMapper objectMapper;
/**
* 获取销售明细分页
*/
@Test
void testGetManageSalesDetailsPage() throws Exception {
// 构造请求参数
SalesDetailsPageReqVO reqVO = new SalesDetailsPageReqVO();
reqVO.setId(123L);
reqVO.setProductPrice(new BigDecimal(100));
// mock 返回数据
SalesDetailRespVO respVO = new SalesDetailRespVO();
respVO.setId(1L);
respVO.setOrganName("测试组织");
respVO.setPaymentMethod("支付宝");
PageResult<SalesDetailRespVO> mockPage = new PageResult<>();
mockPage.setTotal(1L);
mockPage.setList(List.of(respVO));
when(purchaseService.getManageSalesDetailsPage(any()))
.thenReturn(mockPage);
// 发起请求 & 断言
mockMvc.perform(get("/system/sales/page")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqVO)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.total").value(1))
.andExpect(jsonPath("$.data.list[0].id").value(1L))
.andExpect(jsonPath("$.data.list[0].paymentMethod").value("支付宝"));
// 验证 service 调用
verify(purchaseService, times(1))
.getManageSalesDetailsPage(any());
}
/**
* 导出销售明细
*/
@Test
void testExportSalesDetailsPage() throws Exception {
// 构造请求参数
SalesDetailsPageReqVO reqVO = new SalesDetailsPageReqVO();
reqVO.setId(123L);
reqVO.setProductPrice(new BigDecimal(100));
// mock 返回数据
SalesDetailRespVO respVO = new SalesDetailRespVO();
respVO.setId(1L);
respVO.setOrganName("测试组织");
respVO.setPaymentMethod("支付宝");
PageResult<SalesDetailRespVO> mockPage = new PageResult<>();
mockPage.setTotal(1L);
mockPage.setList(List.of(respVO));
when(purchaseService.getManageSalesDetailsPage(any()))
.thenReturn(mockPage);
// 发起请求
mockMvc.perform(get("/system/sales/export")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqVO)))
.andExpect(status().isOk());
// 验证 service 调用
verify(purchaseService, times(1))
.getManageSalesDetailsPage(any());
}
/**
* 获取管理端销售总额信息
*/
@Test
void testGetManageTotalSalesInfo() throws Exception {
// mock 返回
TotalSalesAmountRespVO respVO = new TotalSalesAmountRespVO(new BigDecimal("1000.00"));
when(purchaseService.getTotalSales())
.thenReturn(respVO);
// 发起请求 & 断言
mockMvc.perform(get("/system/sales/total")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.amount").value(1000.00));
// 验证 service 调用
verify(purchaseService, times(1))
.getTotalSales();
}
}
@@ -0,0 +1,157 @@
package com.cf.imes.module.system.controller.admin.tokenconfig;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
import com.cf.imes.module.system.controller.admin.tokenconfig.vo.TokenConfigRespVO;
import com.cf.imes.module.system.controller.admin.tokenconfig.vo.TokenConfigSaveReqVO;
import com.cf.imes.module.system.dal.dataobject.tokenconfig.TokenConfigDO;
import com.cf.imes.module.system.service.tokenconfig.TokenConfigService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Collections;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
*
*
* @author Gqr
* @since 2026/1/7 14:30
*/
@WebMvcTest(
controllers = TokenConfigController.class,
excludeAutoConfiguration = SecurityAutoConfiguration.class
)
class TokenConfigControllerTest extends BaseWebUnitTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean
private TokenConfigService tokenConfigService;
@Autowired
private ObjectMapper objectMapper;
@Test
void getTokenConfigPage_success() throws Exception {
TokenConfigRespVO respVO = new TokenConfigRespVO();
respVO.setId(1L);
PageResult<TokenConfigRespVO> pageResult =
new PageResult<>(Collections.singletonList(respVO), 1L);
when(tokenConfigService.getTokenConfigPage(any()))
.thenReturn(pageResult);
mockMvc.perform(get("/system/token")
.param("pageNo", "1")
.param("pageSize", "10"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.data.total").value(1))
.andExpect(jsonPath("$.data.list[0].id").value(1L));
verify(tokenConfigService).getTokenConfigPage(any());
}
@Test
void getTokenConfigById_success() throws Exception {
TokenConfigDO tokenConfigDO = new TokenConfigDO();
tokenConfigDO.setId(100L);
when(tokenConfigService.getTokenConConfig(100L))
.thenReturn(tokenConfigDO);
mockMvc.perform(get("/system/token/{id}", 100L))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(0))
.andExpect(jsonPath("$.data.id").value(100L));
verify(tokenConfigService).getTokenConConfig(100L);
}
@Test
void insertTokenConfig_success() throws Exception {
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
mockMvc.perform(post("/system/token")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqVO)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(true));
verify(tokenConfigService).insertTokenConfig(any());
}
@Test
void testUpdateTokenConfig_success() throws Exception {
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setId(1L);
mockMvc.perform(put("/system/token")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqVO)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(true));
verify(tokenConfigService).updateTokenConfig(any());
}
@Test
void testDeleteTokenConfig_success() throws Exception {
mockMvc.perform(delete("/system/token/{id}", 5L))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(true));
verify(tokenConfigService).deleteTokenConfig(5L);
}
@Test
void testCheckTokenConfig_success() throws Exception {
when(tokenConfigService.checkTokenConfig("abc"))
.thenReturn(100L);
mockMvc.perform(get("/system/token/check")
.param("token", "abc"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(100L));
}
@Test
void testTokenConfigCopy_success() throws Exception {
when(tokenConfigService.tokenConfigCopy(1L))
.thenReturn("PREFIX_xxx");
mockMvc.perform(get("/system/token/copy")
.param("id", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value("PREFIX_xxx"));
}
@Test
void testExportTokenConfigExcel_success() throws Exception {
PageResult<TokenConfigRespVO> pageResult =
new PageResult<>(Collections.emptyList(), 0L);
when(tokenConfigService.getTokenConfigPage(any()))
.thenReturn(pageResult);
mockMvc.perform(get("/system/token/export"))
.andExpect(status().isOk());
}
}
@@ -0,0 +1,517 @@
package com.cf.imes.module.system.service.tokenconfig;
import cn.hutool.core.collection.CollUtil;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
import com.cf.imes.framework.common.pojo.PageResult;
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.tokenconfig.vo.JwtConfig;
import com.cf.imes.module.system.controller.admin.tokenconfig.vo.TokenConfigPageReqVO;
import com.cf.imes.module.system.controller.admin.tokenconfig.vo.TokenConfigRespVO;
import com.cf.imes.module.system.controller.admin.tokenconfig.vo.TokenConfigSaveReqVO;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.dataobject.tokenconfig.TokenConfigDO;
import com.cf.imes.module.system.dal.mysql.organ.OrganMapper;
import com.cf.imes.module.system.dal.mysql.tokenconfig.TokenConfigMapper;
import com.cf.imes.module.system.enums.token.TokenConfigAppTypeEnum;
import com.cf.imes.module.system.enums.token.TokenExpiresTimeTypeEnum;
import com.cf.imes.module.system.service.organ.OrganService;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import java.time.LocalDate;
import java.time.LocalDateTime;
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.randomPojo;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAN_DISABLE;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAN_EXPIRE;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAN_NOT_EXISTS;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.TOKEN_APP_TYPE_EXIST;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.TOKEN_APP_TYPE_NO_UPDATE;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.TOKEN_CONFIG_NOT_EXISTS;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.TOKEN_DATA_IS_NULL;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.TOKEN_EXPIRES_TIME_DATA_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.TOKEN_EXPIRES_TIME_IS_NULL;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.TOKEN_TIME_IS_EXPIRES;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
@Import(TokenConfigServiceImpl.class)
class TokenConfigServiceImplTest extends BaseDbAndRedisUnitTest {
@Resource
private TokenConfigServiceImpl tokenConfigService;
@Resource
private TokenConfigMapper tokenConfigMapper;
@MockitoBean
private OrganMapper organMapper;
@MockitoBean
private OrganService organService;
@MockitoBean
private JwtConfig jwtConfig;
@BeforeEach
void setUp() {
OrganizationDO organ = new OrganizationDO();
organ.setId(1L);
organ.setContactMobile("13800000000");
organ.setName("测试组织");
when(organService.validOrgan(1L)).thenReturn(organ);
when(jwtConfig.getSecret()).thenReturn("BjEM0tnL3W5zYLQ6pllol49uYVXe+f66pHyOM/tkGWg=");
}
@Test
@WithMockLoginUser(organId = 1L)
void testGetTokenConfigPage_timeTypeNull_andEmptyResult() {
TokenConfigPageReqVO reqVO = TokenConfigPageReqVO
.builder()
.timeType(null)
.build();
// mapper 真实返回空(或你准备的测试数据为空)
PageResult<TokenConfigRespVO> result =
tokenConfigService.getTokenConfigPage(reqVO);
assertNotNull(result);
assertTrue(CollUtil.isEmpty(result.getList()));
// organService 不应该被调用
verify(organService, never()).validOrgan(anyLong());
}
@Test
@WithMockLoginUser(organId = 1L)
void testGetTokenConfigPage_timeTypeNotNull_andEmptyResult() {
TokenConfigPageReqVO reqVO = TokenConfigPageReqVO
.builder()
.timeType(new LocalDate[]{
LocalDate.of(2025, 1, 1),
LocalDate.of(2025, 1, 31)
})
.build();
PageResult<TokenConfigRespVO> result =
tokenConfigService.getTokenConfigPage(reqVO);
assertNotNull(result);
assertTrue(CollUtil.isEmpty(result.getList()));
verify(organService, never()).validOrgan(anyLong());
}
@Test
@WithMockLoginUser(organId = 1L)
void testGetTokenConfigPage_timeTypeNotNull_andHasData() {
TokenConfigPageReqVO reqVO = TokenConfigPageReqVO
.builder()
.timeType(new LocalDate[]{
LocalDate.of(2026, 1, 1),
LocalDate.of(2026, 1, 31)
})
.build();
// 准备数据
TokenConfigDO config = randomPojo(TokenConfigDO.class, o->{
o.setOrganId(1L);
o.setAppToken("imes-abcdefg123456");
o.setExpiresTime(LocalDateTime.now());
});
tokenConfigMapper.insert(config);
PageResult<TokenConfigRespVO> result =
tokenConfigService.getTokenConfigPage(reqVO);
assertNotNull(result);
assertFalse(CollUtil.isEmpty(result.getList()));
TokenConfigRespVO resp = result.getList().get(0);
// 组织名已填充
assertEquals("测试组织", resp.getOrganName());
// token 已脱敏
assertNotNull(resp.getAppToken());
assertTrue(resp.getAppToken().contains("*"));
verify(organService, times(1))
.validOrgan(anyLong());
}
@Test
void testGetTokenConfig_notExists() {
Long notExistsId = -1L; // 确保数据库不存在
assertServiceException(() -> tokenConfigService.getTokenConConfig(notExistsId),
TOKEN_CONFIG_NOT_EXISTS);
}
@Test
void testGetTokenConfig_success_andMaskToken() {
// 1.准备数据
TokenConfigDO config = randomPojo(TokenConfigDO.class, o->{
o.setOrganId(1L);
o.setAppToken("imes-abcdefg123456");
o.setExpiresTime(LocalDateTime.now());
});
tokenConfigMapper.insert(config);
Long id = config.getId();
// 2. 调用
TokenConfigDO result =
tokenConfigService.getTokenConConfig(id);
// 3. 断言
assertNotNull(result);
assertEquals(id, result.getId());
// token 已脱敏
assertNotEquals("imes-abcdefg123456", result.getAppToken());
assertTrue(result.getAppToken().contains("*"));
}
@Test
@WithMockLoginUser(organId = 1L)
void testInsertTokenConfig_appTypeExists() {
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
tokenConfigMapper.insert(randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
o.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
})
);
assertServiceException(() -> tokenConfigService.insertTokenConfig(reqVO),
TOKEN_APP_TYPE_EXIST);
}
@Test
@WithMockLoginUser(organId = 1L)
void testInsertTokenConfig_customizeTime() {
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
reqVO.setCustomizeTime("2025-01-01");
tokenConfigService.insertTokenConfig(reqVO);
List<Integer> db =
tokenConfigMapper.selectAppTypeByOrganId(1L);
assertEquals(1, db.size());
assertEquals(db.get(0), TokenConfigAppTypeEnum.WEBCAD.getType());
}
@Test
@WithMockLoginUser(organId = 1L)
void testInsertTokenConfig_timeTypeNull() {
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setAppType(3);
assertServiceException(() -> tokenConfigService.insertTokenConfig(reqVO),
TOKEN_EXPIRES_TIME_IS_NULL);
}
@Test
@WithMockLoginUser(organId = 1L)
void testInsertTokenConfig_timeTypeEnum() {
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
reqVO.setTimeType(TokenExpiresTimeTypeEnum.ONEHOURS.getType());
tokenConfigService.insertTokenConfig(reqVO);
List<TokenConfigDO> db =
tokenConfigMapper.selectList();
assertEquals(1, db.size());
assertTrue(db.get(0).getExpiresTime().isAfter(LocalDateTime.now()));
}
@Test
void testUpdateTokenConfig_notExists() {
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setId(999L);
assertServiceException(() -> tokenConfigService.updateTokenConfig(reqVO),
TOKEN_CONFIG_NOT_EXISTS);
}
@Test
void testUpdateTokenConfig_appTypeChanged() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
o.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
});
tokenConfigMapper.insert(tokenConfigDO);
Long id = tokenConfigDO.getId();
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setId(id);
reqVO.setAppType(2); // 改了
assertServiceException(() -> tokenConfigService.updateTokenConfig(reqVO),
TOKEN_APP_TYPE_NO_UPDATE);
}
@Test
void testUpdateTokenConfig_customizeTime() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
o.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
});
tokenConfigMapper.insert(tokenConfigDO);
Long id = tokenConfigDO.getId();
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setId(id);
reqVO.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
reqVO.setCustomizeTime("2026-01-08");
tokenConfigService.updateTokenConfig(reqVO);
TokenConfigDO db = tokenConfigMapper.selectById(id);
assertEquals(
LocalDateTime.of(2026,1,8,23,59,59),
db.getExpiresTime()
);
}
@Test
void testUpdateTokenConfig_timeType() {
LocalDateTime createTime = LocalDateTime.now().minusDays(1);
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
o.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
});
tokenConfigMapper.insert(tokenConfigDO);
Long id = tokenConfigDO.getId();
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setId(id);
reqVO.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
reqVO.setTimeType(TokenExpiresTimeTypeEnum.ONEMONTHS.getType());
tokenConfigService.updateTokenConfig(reqVO);
TokenConfigDO db = tokenConfigMapper.selectById(id);
assertTrue(db.getExpiresTime().isAfter(createTime));
}
@Test
void testUpdateTokenConfig_expiredTime() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
o.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
});
tokenConfigMapper.insert(tokenConfigDO);
Long id = tokenConfigDO.getId();
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setId(id);
reqVO.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
reqVO.setCustomizeTime("2020-01-01");
assertServiceException(() -> tokenConfigService.updateTokenConfig(reqVO),
TOKEN_EXPIRES_TIME_DATA_ERROR);
}
@Test
void testUpdateTokenConfig_noTimeChange() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
o.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
});
tokenConfigMapper.insert(tokenConfigDO);
Long id = tokenConfigDO.getId();
TokenConfigDO before = tokenConfigMapper.selectById(id);
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setId(id);
reqVO.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
tokenConfigService.updateTokenConfig(reqVO);
TokenConfigDO after = tokenConfigMapper.selectById(id);
assertEquals(before.getExpiresTime(), after.getExpiresTime());
}
@Test
void testUpdateTokenConfig_remarkNull() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
o.setRemark("old");
o.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
});
tokenConfigMapper.insert(tokenConfigDO);
Long id = tokenConfigDO.getId();
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setId(id);
reqVO.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
tokenConfigService.updateTokenConfig(reqVO);
assertEquals("old",
tokenConfigMapper.selectById(id).getRemark());
}
@Test
void testUpdateTokenConfig_remarkUpdate() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
o.setRemark("old");
o.setAppType(TokenConfigAppTypeEnum.WEBCAD.getType());
});
tokenConfigMapper.insert(tokenConfigDO);
Long id = tokenConfigDO.getId();
TokenConfigSaveReqVO reqVO = new TokenConfigSaveReqVO();
reqVO.setId(id);
reqVO.setAppType(1);
reqVO.setRemark("new");
tokenConfigService.updateTokenConfig(reqVO);
assertEquals("new",
tokenConfigMapper.selectById(id).getRemark());
}
@Test
void testDeleteTokenConfig_notExists() {
assertServiceException(() -> tokenConfigService.deleteTokenConfig(999L),
TOKEN_DATA_IS_NULL);
}
@Test
void testDeleteTokenConfig_success() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
});
tokenConfigMapper.insert(tokenConfigDO);
Long id = tokenConfigDO.getId();
// 先确认存在
assertNotNull(tokenConfigMapper.selectById(id));
// 删除
tokenConfigService.deleteTokenConfig(id);
// 再确认不存在
assertNull(tokenConfigMapper.selectById(id));
}
@Test
void testCheckTokenConfig_tokenNotExists() {
assertServiceException(() -> tokenConfigService.checkTokenConfig("imes-not-exists"),
TOKEN_CONFIG_NOT_EXISTS);
}
@Test
void testCheckTokenConfig_tokenExpired() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setExpiresTime(LocalDateTime.now().minusDays(1));
o.setAppToken("expired-token");
});
tokenConfigMapper.insert(tokenConfigDO);
assertServiceException(() -> tokenConfigService.checkTokenConfig("imes-expired-token"),
TOKEN_TIME_IS_EXPIRES);
}
@Test
void testCheckTokenConfig_organNotExists() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setExpiresTime(LocalDateTime.now().plusDays(1));
o.setAppToken("valid-token");
});
tokenConfigMapper.insert(tokenConfigDO);
when(organMapper.selectById(any())).thenReturn(null);
assertServiceException(() -> tokenConfigService.checkTokenConfig("imes-valid-token"),
ORGAN_NOT_EXISTS);
}
@Test
void testCheckTokenConfig_organDisabled() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setExpiresTime(LocalDateTime.now().plusDays(1));
o.setAppToken("valid-token");
});
tokenConfigMapper.insert(tokenConfigDO);
OrganizationDO disabledOrgan = new OrganizationDO();
disabledOrgan.setStatus(CommonStatusEnum.DISABLE.getStatus());
when(organMapper.selectById(any())).thenReturn(disabledOrgan);
assertServiceException(() -> tokenConfigService.checkTokenConfig("imes-valid-token"),
ORGAN_DISABLE);
}
@Test
void testCheckTokenConfig_organExpired() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setExpiresTime(LocalDateTime.now().plusDays(1));
o.setAppToken("valid-token");
});
tokenConfigMapper.insert(tokenConfigDO);
OrganizationDO disabledOrgan = new OrganizationDO();
disabledOrgan.setStatus(CommonStatusEnum.ENABLE.getStatus());
disabledOrgan.setExpireTime(LocalDate.now().minusDays(1));
when(organMapper.selectById(any())).thenReturn(disabledOrgan);
assertServiceException(() -> tokenConfigService.checkTokenConfig("imes-valid-token"),
ORGAN_EXPIRE);
}
@Test
void testCheckTokenConfig_success() {
TokenConfigDO tokenConfigDO = randomPojo(TokenConfigDO.class, o -> {
o.setOrganId(1L);
o.setAppToken("valid-token");
});
tokenConfigMapper.insert(tokenConfigDO);
OrganizationDO disabledOrgan = new OrganizationDO();
disabledOrgan.setStatus(CommonStatusEnum.ENABLE.getStatus());
disabledOrgan.setExpireTime(LocalDate.now().plusDays(1));
when(organMapper.selectById(any())).thenReturn(disabledOrgan);
Long result = tokenConfigService.checkTokenConfig("imes-valid-token");
assertEquals(1L, result);
}
@Test
void testTokenConfigCopy_notExists() {
assertServiceException(() -> tokenConfigService.tokenConfigCopy(999L),
TOKEN_CONFIG_NOT_EXISTS);
}
@Test
void testTokenConfigCopy_success() {
TokenConfigDO token = randomPojo(TokenConfigDO.class, o -> {
o.setAppToken("abc123");
});
tokenConfigMapper.insert(token);
String result = tokenConfigService.tokenConfigCopy(token.getId());
assertEquals("imes-abc123", result);
}
}
@@ -43,4 +43,5 @@ DELETE FROM "product_delay_record";
DELETE FROM "purchase_record";
DELETE FROM "income_expense_details";
DELETE FROM "invoice_title_info";
DELETE FROM "invoice_records";
DELETE FROM "invoice_records";
DELETE FROM "system_config_token";
@@ -881,4 +881,22 @@ CREATE TABLE IF NOT EXISTS "invoice_records"
"update_time" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
"deleted" BIT NOT NULL DEFAULT FALSE COMMENT '是否删除 0否1是',
PRIMARY KEY ("id")
) COMMENT '开票记录表';
) COMMENT '开票记录表';
CREATE TABLE IF NOT EXISTS "system_config_token"
(
"id" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号',
"organ_id" BIGINT NOT NULL DEFAULT 1 COMMENT '组织 ID',
"app_type" TINYINT NOT NULL COMMENT '应用类型,1 WebCAD',
"app_name" VARCHAR(64) NOT NULL COMMENT '用户名称',
"app_token" VARCHAR(255) NOT NULL COMMENT '应用token',
"expires_time" TIMESTAMP NOT NULL COMMENT '过期时间',
"time_type" VARCHAR(16) NOT NULL DEFAULT '' COMMENT '时间类型',
"remark" VARCHAR(255) NOT NULL DEFAULT '' COMMENT '备注',
"creator" VARCHAR(64) DEFAULT NULL COMMENT '创建者',
"create_time" TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
"updater" VARCHAR(64) DEFAULT NULL COMMENT '更新者',
"update_time" TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
"deleted" BIT DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY ("id")
) COMMENT 'Token配置表';