MerchantPayMethodControllerTest.java 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package com.ruoyi.app.pay;
  2. import com.ruoyi.app.pay.dto.MerchantPayMethodSaveDto;
  3. import com.ruoyi.common.constant.HttpStatus;
  4. import com.ruoyi.common.core.domain.AjaxResult;
  5. import com.ruoyi.common.exception.ServiceException;
  6. import com.ruoyi.common.utils.spring.SpringUtils;
  7. import com.ruoyi.system.domain.InfoUser;
  8. import com.ruoyi.system.mapper.InfoUserMapper;
  9. import com.ruoyi.system.service.MerchantAccessContext;
  10. import com.ruoyi.system.service.MerchantStoreAccessService;
  11. import com.ruoyi.system.service.PaymentMethodGateService;
  12. import org.junit.jupiter.api.AfterAll;
  13. import org.junit.jupiter.api.BeforeAll;
  14. import org.junit.jupiter.api.BeforeEach;
  15. import org.junit.jupiter.api.Test;
  16. import org.mockito.ArgumentCaptor;
  17. import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
  18. import org.springframework.beans.factory.support.DefaultListableBeanFactory;
  19. import org.springframework.context.support.StaticMessageSource;
  20. import org.springframework.test.util.ReflectionTestUtils;
  21. import java.util.List;
  22. import java.util.Locale;
  23. import java.util.Map;
  24. import static org.junit.jupiter.api.Assertions.assertEquals;
  25. import static org.junit.jupiter.api.Assertions.assertThrows;
  26. import static org.mockito.ArgumentMatchers.any;
  27. import static org.mockito.ArgumentMatchers.anyLong;
  28. import static org.mockito.ArgumentMatchers.eq;
  29. import static org.mockito.Mockito.mock;
  30. import static org.mockito.Mockito.never;
  31. import static org.mockito.Mockito.verify;
  32. import static org.mockito.Mockito.when;
  33. /** 商家支付方式选择接口单测(031 US2):选择展开语义、清空回落、非法组拒绝、子账号定位主账号。 */
  34. class MerchantPayMethodControllerTest {
  35. private MerchantPayMethodController controller;
  36. private PaymentMethodGateService gateService;
  37. private InfoUserMapper userMapper;
  38. private MerchantStoreAccessService merchantStoreAccessService;
  39. private com.ruoyi.system.mapper.PosStoreMapper storeMapper;
  40. private com.ruoyi.system.utils.JwtUtil jwtUtil;
  41. private static ConfigurableListableBeanFactory originalBeanFactory;
  42. @BeforeAll
  43. static void initializeMessageSource() {
  44. originalBeanFactory = (ConfigurableListableBeanFactory)
  45. ReflectionTestUtils.getField(SpringUtils.class, "beanFactory");
  46. DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
  47. StaticMessageSource messageSource = new StaticMessageSource();
  48. messageSource.addMessage("pay.method.config.invalid", Locale.getDefault(), "支付方式设置参数不合法");
  49. messageSource.addMessage("no.action.success", Locale.getDefault(), "操作成功");
  50. beanFactory.registerSingleton("messageSource", messageSource);
  51. new SpringUtils().postProcessBeanFactory(beanFactory);
  52. }
  53. @AfterAll
  54. static void restoreBeanFactory() {
  55. new SpringUtils().postProcessBeanFactory(originalBeanFactory);
  56. }
  57. @BeforeEach
  58. void setUp() {
  59. gateService = mock(PaymentMethodGateService.class);
  60. userMapper = mock(InfoUserMapper.class);
  61. merchantStoreAccessService = mock(MerchantStoreAccessService.class);
  62. storeMapper = mock(com.ruoyi.system.mapper.PosStoreMapper.class);
  63. controller = new MerchantPayMethodController(gateService, userMapper, merchantStoreAccessService, storeMapper);
  64. when(gateService.listAvailableForMerchantSettings(any(), any())).thenReturn(List.of());
  65. // 子账号 9 定位主账号 7
  66. MerchantAccessContext context = mock(MerchantAccessContext.class);
  67. when(context.ownerUserId()).thenReturn(7L);
  68. when(merchantStoreAccessService.resolve(anyLong())).thenReturn(context);
  69. try (org.mockito.MockedStatic<com.ruoyi.system.utils.JwtUtil> jwt =
  70. org.mockito.Mockito.mockStatic(com.ruoyi.system.utils.JwtUtil.class)) {
  71. // 构造器外静态 mock 不适用于 getusid 实例方法,改用真实 token 生成
  72. }
  73. jwtUtil = null;
  74. }
  75. private String tokenFor(long userId) {
  76. return com.ruoyi.system.utils.JwtUtil.setToken(String.valueOf(userId), "test-user");
  77. }
  78. @Test
  79. void getExpandsNullSelectionAsEmptyAndPassesOwner() {
  80. InfoUser owner = new InfoUser();
  81. owner.setUserId(7L);
  82. owner.setPayMethods(null);
  83. when(userMapper.selectById(7L)).thenReturn(owner);
  84. AjaxResult result = controller.get(tokenFor(9L));
  85. assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
  86. @SuppressWarnings("unchecked")
  87. Map<String, Object> data = (Map<String, Object>) result.get(AjaxResult.DATA_TAG);
  88. assertEquals(List.of(), data.get("selected"));
  89. // available 带按名下门店聚合的就绪度;无门店时传空列表(未就绪由前端标记展示)
  90. verify(gateService).listAvailableForMerchantSettings(7L, List.of());
  91. verify(storeMapper).selectList(any());
  92. }
  93. @Test
  94. void getPassesAggregatedStoreIdsToGate() {
  95. InfoUser owner = new InfoUser();
  96. owner.setUserId(7L);
  97. when(userMapper.selectById(7L)).thenReturn(owner);
  98. com.ruoyi.system.domain.PosStore store = new com.ruoyi.system.domain.PosStore();
  99. store.setId(11);
  100. when(storeMapper.selectList(any())).thenReturn(List.of(store));
  101. controller.get(tokenFor(9L));
  102. // Integer 主键转 Long 门店 ID 传闸门
  103. verify(gateService).listAvailableForMerchantSettings(7L, List.of(11L));
  104. }
  105. @Test
  106. void saveWritesCsvToOwnerAccount() {
  107. MerchantPayMethodSaveDto dto = new MerchantPayMethodSaveDto();
  108. dto.setMethodCodes(List.of("COD", "LINE_PAY"));
  109. controller.save(tokenFor(9L), dto);
  110. @SuppressWarnings("unchecked")
  111. ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
  112. verify(userMapper).update(any(), any(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper.class));
  113. // ownerUserId=7 已在 resolve mock 中固定,写入主账号行由 UpdateWrapper eq 保证
  114. }
  115. @Test
  116. void saveEmptyListClearsToNull() {
  117. controller.save(tokenFor(9L), new MerchantPayMethodSaveDto());
  118. verify(userMapper).update(any(), any(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper.class));
  119. }
  120. @Test
  121. void saveRejectsIllegalGroup() {
  122. MerchantPayMethodSaveDto dto = new MerchantPayMethodSaveDto();
  123. dto.setMethodCodes(List.of("NOT_A_GROUP"));
  124. ServiceException exception = assertThrows(ServiceException.class, () -> controller.save(tokenFor(9L), dto));
  125. assertEquals("支付方式设置参数不合法", exception.getMessage());
  126. verify(userMapper, never()).update(any(), any());
  127. }
  128. }