|
@@ -0,0 +1,130 @@
|
|
|
|
|
+package com.ruoyi.app.pay;
|
|
|
|
|
+
|
|
|
|
|
+import com.ruoyi.app.pay.dto.MerchantPayMethodSaveDto;
|
|
|
|
|
+import com.ruoyi.common.constant.HttpStatus;
|
|
|
|
|
+import com.ruoyi.common.core.domain.AjaxResult;
|
|
|
|
|
+import com.ruoyi.common.exception.ServiceException;
|
|
|
|
|
+import com.ruoyi.common.utils.spring.SpringUtils;
|
|
|
|
|
+import com.ruoyi.system.domain.InfoUser;
|
|
|
|
|
+import com.ruoyi.system.mapper.InfoUserMapper;
|
|
|
|
|
+import com.ruoyi.system.service.MerchantAccessContext;
|
|
|
|
|
+import com.ruoyi.system.service.MerchantStoreAccessService;
|
|
|
|
|
+import com.ruoyi.system.service.PaymentMethodGateService;
|
|
|
|
|
+import org.junit.jupiter.api.AfterAll;
|
|
|
|
|
+import org.junit.jupiter.api.BeforeAll;
|
|
|
|
|
+import org.junit.jupiter.api.BeforeEach;
|
|
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
|
|
+import org.mockito.ArgumentCaptor;
|
|
|
|
|
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|
|
|
|
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
|
|
|
|
+import org.springframework.context.support.StaticMessageSource;
|
|
|
|
|
+import org.springframework.test.util.ReflectionTestUtils;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Locale;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+
|
|
|
|
|
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
|
+import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
|
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
|
|
|
+import static org.mockito.ArgumentMatchers.anyLong;
|
|
|
|
|
+import static org.mockito.ArgumentMatchers.eq;
|
|
|
|
|
+import static org.mockito.Mockito.mock;
|
|
|
|
|
+import static org.mockito.Mockito.never;
|
|
|
|
|
+import static org.mockito.Mockito.verify;
|
|
|
|
|
+import static org.mockito.Mockito.when;
|
|
|
|
|
+
|
|
|
|
|
+/** 商家支付方式选择接口单测(031 US2):选择展开语义、清空回落、非法组拒绝、子账号定位主账号。 */
|
|
|
|
|
+class MerchantPayMethodControllerTest {
|
|
|
|
|
+
|
|
|
|
|
+ private MerchantPayMethodController controller;
|
|
|
|
|
+ private PaymentMethodGateService gateService;
|
|
|
|
|
+ private InfoUserMapper userMapper;
|
|
|
|
|
+ private MerchantStoreAccessService merchantStoreAccessService;
|
|
|
|
|
+ private com.ruoyi.system.utils.JwtUtil jwtUtil;
|
|
|
|
|
+ private static ConfigurableListableBeanFactory originalBeanFactory;
|
|
|
|
|
+
|
|
|
|
|
+ @BeforeAll
|
|
|
|
|
+ static void initializeMessageSource() {
|
|
|
|
|
+ originalBeanFactory = (ConfigurableListableBeanFactory)
|
|
|
|
|
+ ReflectionTestUtils.getField(SpringUtils.class, "beanFactory");
|
|
|
|
|
+ DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
|
|
|
|
+ StaticMessageSource messageSource = new StaticMessageSource();
|
|
|
|
|
+ messageSource.addMessage("pay.method.config.invalid", Locale.getDefault(), "支付方式设置参数不合法");
|
|
|
|
|
+ messageSource.addMessage("no.action.success", Locale.getDefault(), "操作成功");
|
|
|
|
|
+ beanFactory.registerSingleton("messageSource", messageSource);
|
|
|
|
|
+ new SpringUtils().postProcessBeanFactory(beanFactory);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @AfterAll
|
|
|
|
|
+ static void restoreBeanFactory() {
|
|
|
|
|
+ new SpringUtils().postProcessBeanFactory(originalBeanFactory);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @BeforeEach
|
|
|
|
|
+ void setUp() {
|
|
|
|
|
+ gateService = mock(PaymentMethodGateService.class);
|
|
|
|
|
+ userMapper = mock(InfoUserMapper.class);
|
|
|
|
|
+ merchantStoreAccessService = mock(MerchantStoreAccessService.class);
|
|
|
|
|
+ controller = new MerchantPayMethodController(gateService, userMapper, merchantStoreAccessService);
|
|
|
|
|
+ when(gateService.listAvailable(any(), any(), any())).thenReturn(List.of());
|
|
|
|
|
+ // 子账号 9 定位主账号 7
|
|
|
|
|
+ MerchantAccessContext context = mock(MerchantAccessContext.class);
|
|
|
|
|
+ when(context.ownerUserId()).thenReturn(7L);
|
|
|
|
|
+ when(merchantStoreAccessService.resolve(anyLong())).thenReturn(context);
|
|
|
|
|
+ try (org.mockito.MockedStatic<com.ruoyi.system.utils.JwtUtil> jwt =
|
|
|
|
|
+ org.mockito.Mockito.mockStatic(com.ruoyi.system.utils.JwtUtil.class)) {
|
|
|
|
|
+ // 构造器外静态 mock 不适用于 getusid 实例方法,改用真实 token 生成
|
|
|
|
|
+ }
|
|
|
|
|
+ jwtUtil = null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String tokenFor(long userId) {
|
|
|
|
|
+ return com.ruoyi.system.utils.JwtUtil.setToken(String.valueOf(userId), "test-user");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void getExpandsNullSelectionAsEmptyAndPassesOwner() {
|
|
|
|
|
+ InfoUser owner = new InfoUser();
|
|
|
|
|
+ owner.setUserId(7L);
|
|
|
|
|
+ owner.setPayMethods(null);
|
|
|
|
|
+ when(userMapper.selectById(7L)).thenReturn(owner);
|
|
|
|
|
+
|
|
|
|
|
+ AjaxResult result = controller.get(tokenFor(9L));
|
|
|
|
|
+
|
|
|
|
|
+ assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ Map<String, Object> data = (Map<String, Object>) result.get(AjaxResult.DATA_TAG);
|
|
|
|
|
+ assertEquals(List.of(), data.get("selected"));
|
|
|
|
|
+ // available 用平台层(不带门店/收款方),设置页只关心平台开关
|
|
|
|
|
+ verify(gateService).listAvailable(PaymentMethodGateService.GateScope.MERCHANT, null, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void saveWritesCsvToOwnerAccount() {
|
|
|
|
|
+ MerchantPayMethodSaveDto dto = new MerchantPayMethodSaveDto();
|
|
|
|
|
+ dto.setMethodCodes(List.of("COD", "LINE_PAY"));
|
|
|
|
|
+
|
|
|
|
|
+ controller.save(tokenFor(9L), dto);
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
|
|
|
|
|
+ verify(userMapper).update(any(), any(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper.class));
|
|
|
|
|
+ // ownerUserId=7 已在 resolve mock 中固定,写入主账号行由 UpdateWrapper eq 保证
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void saveEmptyListClearsToNull() {
|
|
|
|
|
+ controller.save(tokenFor(9L), new MerchantPayMethodSaveDto());
|
|
|
|
|
+ verify(userMapper).update(any(), any(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper.class));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void saveRejectsIllegalGroup() {
|
|
|
|
|
+ MerchantPayMethodSaveDto dto = new MerchantPayMethodSaveDto();
|
|
|
|
|
+ dto.setMethodCodes(List.of("NOT_A_GROUP"));
|
|
|
|
|
+ ServiceException exception = assertThrows(ServiceException.class, () -> controller.save(tokenFor(9L), dto));
|
|
|
|
|
+ assertEquals("支付方式设置参数不合法", exception.getMessage());
|
|
|
|
|
+ verify(userMapper, never()).update(any(), any());
|
|
|
|
|
+ }
|
|
|
|
|
+}
|