|
|
@@ -1,21 +1,21 @@
|
|
|
package com.mangoo.rating.recommend.cart;
|
|
|
|
|
|
import com.mangoo.rating.recommend.AjaxResult;
|
|
|
+import com.mangoo.rating.recommend.client.feign.PreOrderFeignClient;
|
|
|
import com.mangoo.rating.recommend.config.RecommendProperties;
|
|
|
-import com.mangoo.rating.recommend.enums.MatchLevelEnum;
|
|
|
import com.mangoo.rating.recommend.manager.ActiveBatchManager;
|
|
|
-import com.mangoo.rating.recommend.manager.CardPopManager;
|
|
|
import com.mangoo.rating.recommend.manager.RatingRecommendRuleManager;
|
|
|
import com.mangoo.rating.recommend.po.RatingRecommendRulePO;
|
|
|
+import com.mangoo.rating.recommend.request.recommend.PreOrderCardDTO;
|
|
|
+import com.mangoo.rating.recommend.request.recommend.PreOrderSaveDTO;
|
|
|
import com.mangoo.rating.recommend.request.recommend.RecommendCardDTO;
|
|
|
import com.mangoo.rating.recommend.request.recommend.RecommendRequest;
|
|
|
-import com.mangoo.rating.recommend.response.recommend.OrderSuggestionVO;
|
|
|
-import com.mangoo.rating.recommend.response.recommend.RecommendResultVO;
|
|
|
import com.mangoo.rating.recommend.service.impl.RecommendServiceImpl;
|
|
|
import com.mangoo.rating.recommend.service.recommend.EfficiencyPriceProvider;
|
|
|
-import org.junit.jupiter.api.BeforeEach;
|
|
|
+import com.mangoo.rating.recommend.service.recommend.LoginUserProvider;
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
import org.junit.jupiter.api.extension.ExtendWith;
|
|
|
+import org.mockito.ArgumentCaptor;
|
|
|
import org.mockito.InjectMocks;
|
|
|
import org.mockito.Mock;
|
|
|
import org.mockito.junit.jupiter.MockitoExtension;
|
|
|
@@ -23,58 +23,57 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
-import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
import java.util.Map;
|
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
|
|
-import static org.junit.jupiter.api.Assertions.assertNull;
|
|
|
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
|
import static org.mockito.ArgumentMatchers.anyString;
|
|
|
-import static org.mockito.ArgumentMatchers.eq;
|
|
|
import static org.mockito.Mockito.lenient;
|
|
|
+import static org.mockito.Mockito.never;
|
|
|
+import static org.mockito.Mockito.verify;
|
|
|
import static org.mockito.Mockito.when;
|
|
|
|
|
|
/**
|
|
|
- * RecommendServiceImpl Mockito 单测(适配 batch_no 过滤 + POP/价值增强)
|
|
|
+ * RecommendServiceImpl 单测(预订单落库改造后:返回 preOrderNo + Feign 落库)
|
|
|
+ *
|
|
|
+ * 覆盖的目标场景:
|
|
|
+ * 1) 空入参 / null → 非 0 code
|
|
|
+ * 2) 超上限 → 非 0 code
|
|
|
+ * 3) 正常,Feign 返回 preOrderNo → code=0,data=preOrderNo
|
|
|
+ * 4) userId 为 null(未登录) → 非 0 code,且不调用 Feign
|
|
|
+ * 5) Feign 抛异常 → 非 0 code
|
|
|
+ * 6) Feign 返回 code!=0 → 非 0 code(下游 msg 不再透传,改为固定文案)
|
|
|
+ * 7) 落库包字段映射:10 个识别字段 + userId/totalCards/packageId 全透传
|
|
|
*
|
|
|
* @author gengjintao
|
|
|
- * @date 2026/06/25
|
|
|
*/
|
|
|
@ExtendWith(MockitoExtension.class)
|
|
|
class RecommendServiceImplTest {
|
|
|
|
|
|
@Mock
|
|
|
- private RatingRecommendRuleManager ruleManager;
|
|
|
+ private RatingRecommendRuleManager ratingRecommendRuleManager;
|
|
|
@Mock
|
|
|
- private EfficiencyPriceProvider priceProvider;
|
|
|
+ private EfficiencyPriceProvider efficiencyPriceProvider;
|
|
|
@Mock
|
|
|
private RecommendProperties recommendProperties;
|
|
|
@Mock
|
|
|
private ActiveBatchManager activeBatchManager;
|
|
|
@Mock
|
|
|
- private CardPopManager cardPopManager;
|
|
|
+ private PreOrderFeignClient preOrderFeignClient;
|
|
|
+ @Mock
|
|
|
+ private LoginUserProvider loginUserProvider;
|
|
|
@InjectMocks
|
|
|
private RecommendServiceImpl recommendService;
|
|
|
|
|
|
- @BeforeEach
|
|
|
- void setUp() {
|
|
|
- lenient().when(recommendProperties.getDefaultEfficiency()).thenReturn(1);
|
|
|
- lenient().when(recommendProperties.getBatchMax()).thenReturn(50);
|
|
|
- lenient().when(activeBatchManager.selectActiveBatchNo()).thenReturn("B1");
|
|
|
- lenient().when(cardPopManager.selectByCardId(anyString(), anyString())).thenReturn(Collections.emptyList());
|
|
|
- Map<Integer, BigDecimal> defaultPrices = new HashMap<>();
|
|
|
- defaultPrices.put(1, new BigDecimal("50.00"));
|
|
|
- defaultPrices.put(2, new BigDecimal("100.00"));
|
|
|
- defaultPrices.put(3, new BigDecimal("200.00"));
|
|
|
- lenient().when(priceProvider.loadEfficiencyPrices()).thenReturn(defaultPrices);
|
|
|
- }
|
|
|
+ /** 落库失败对外统一文案(生产代码不再透传下游 msg) */
|
|
|
+ private static final String FAIL_MSG = "预订单生成失败,请稍后重试";
|
|
|
|
|
|
- private RecommendCardDTO card(String id, String player, String year, String series, String cardSet) {
|
|
|
+ /** 造最简卡入参:仅带识别 4 字段 */
|
|
|
+ private RecommendCardDTO card(String player, String year, String series, String cardSet) {
|
|
|
RecommendCardDTO d = new RecommendCardDTO();
|
|
|
- d.setClientCardId(id);
|
|
|
d.setPlayer(player);
|
|
|
d.setYear(year);
|
|
|
d.setSeries(series);
|
|
|
@@ -82,198 +81,158 @@ class RecommendServiceImplTest {
|
|
|
return d;
|
|
|
}
|
|
|
|
|
|
+ /** 造一个 request(浅拷贝入参列表,避免测试之间共享同一 List) */
|
|
|
private RecommendRequest req(RecommendCardDTO... cards) {
|
|
|
RecommendRequest r = new RecommendRequest();
|
|
|
r.setCards(new ArrayList<>(Arrays.asList(cards)));
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
- private RatingRecommendRulePO rule(Integer eff) {
|
|
|
+ /**
|
|
|
+ * 构造一条"合法且能通过 isLegalRule 校验"的 EXACT 命中规则。
|
|
|
+ * 注意 evaluateEfficiencyName 在 PO 中是 Long(非 String),此处按真实签名给 3L。
|
|
|
+ */
|
|
|
+ private RatingRecommendRulePO exactRule() {
|
|
|
RatingRecommendRulePO po = new RatingRecommendRulePO();
|
|
|
- po.setRecommendEfficiency(eff);
|
|
|
+ po.setEvaluateEfficiencyId(3L);
|
|
|
+ po.setEvaluateEfficiencyName(3L);
|
|
|
+ po.setCardId("DW-CARD-1");
|
|
|
return po;
|
|
|
}
|
|
|
|
|
|
- private int code(AjaxResult r) {
|
|
|
- return ((Number) r.get("code")).intValue();
|
|
|
+ /** 构造 Feign 成功返回:data 里带 preOrderNo */
|
|
|
+ private AjaxResult okWith(String preOrderNo) {
|
|
|
+ Map<String, Object> data = new HashMap<>();
|
|
|
+ data.put("preOrderNo", preOrderNo);
|
|
|
+ return AjaxResult.success(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 默认让匹配命中、价格可取、用户已登录(各用例可覆盖) */
|
|
|
+ private void defaultHappyStubs() {
|
|
|
+ lenient().when(recommendProperties.getBatchMax()).thenReturn(50);
|
|
|
+ lenient().when(activeBatchManager.selectActiveBatchNo()).thenReturn("B1");
|
|
|
+ lenient().when(ratingRecommendRuleManager.selectByExact(any(), any(), any(), any(), any()))
|
|
|
+ .thenReturn(exactRule());
|
|
|
+ Map<Long, BigDecimal> prices = new HashMap<>();
|
|
|
+ prices.put(3L, new BigDecimal("200.00"));
|
|
|
+ lenient().when(efficiencyPriceProvider.loadEfficiencyPrices()).thenReturn(prices);
|
|
|
+ lenient().when(loginUserProvider.currentUserId()).thenReturn(1001L);
|
|
|
+ lenient().when(loginUserProvider.currentUserHeader()).thenReturn("base64header");
|
|
|
}
|
|
|
|
|
|
- private RecommendResultVO data(AjaxResult r) {
|
|
|
- return (RecommendResultVO) r.get("data");
|
|
|
+ private int code(AjaxResult r) {
|
|
|
+ return r.getCode();
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
void 空入参_返回error() {
|
|
|
+ // null / 空列表:直接拦截,不调用 Feign
|
|
|
assertNotEquals(0, code(recommendService.recommendEfficiency(null)));
|
|
|
assertNotEquals(0, code(recommendService.recommendEfficiency(new RecommendRequest())));
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
void 超限_返回error() {
|
|
|
+ // 上限=1,传 2 张 → 拦截
|
|
|
when(recommendProperties.getBatchMax()).thenReturn(1);
|
|
|
AjaxResult result = recommendService.recommendEfficiency(
|
|
|
- req(card("c1", "p", "y", "s", "cs"), card("c2", "p", "y", "s", "cs")));
|
|
|
+ req(card("p", "y", "s", "cs"), card("p", "y", "s", "cs")));
|
|
|
assertNotEquals(0, code(result));
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void L1全等命中_单卡_单订单_含价格() {
|
|
|
- when(ruleManager.selectByExact("Jordan", "1986", "Fleer", "Base", "B1")).thenReturn(rule(3));
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(card("c1", "Jordan", "1986", "Fleer", "Base")));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- assertEquals(1, d.getTotalCards());
|
|
|
- assertEquals(1, d.getOrderCount());
|
|
|
- OrderSuggestionVO order = d.getOrders().get(0);
|
|
|
- assertEquals(3, order.getEfficiency());
|
|
|
- assertEquals(MatchLevelEnum.EXACT.getCode(), order.getCards().get(0).getMatchLevel());
|
|
|
- assertEquals(new BigDecimal("200.00"), order.getUnitPrice());
|
|
|
- assertEquals(new BigDecimal("200.00"), order.getTotalAmount());
|
|
|
- assertEquals(new BigDecimal("200.00"), d.getGrandTotal());
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- void L1未命中_L2命中_matchLevel为L2() {
|
|
|
- when(ruleManager.selectByExact(anyString(), anyString(), anyString(), anyString(), anyString())).thenReturn(null);
|
|
|
- when(ruleManager.selectBySeriesSetYear("Fleer", "Base", "1986", "B1")).thenReturn(rule(2));
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(card("c1", "Jordan", "1986", "Fleer", "Base")));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- assertEquals(MatchLevelEnum.L2.getCode(), d.getOrders().get(0).getCards().get(0).getMatchLevel());
|
|
|
- assertEquals(2, d.getOrders().get(0).getEfficiency());
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- void L1L2未命中_L3命中_matchLevel为L3() {
|
|
|
- when(ruleManager.selectByExact(anyString(), anyString(), anyString(), anyString(), anyString())).thenReturn(null);
|
|
|
- when(ruleManager.selectBySeriesSetYear(anyString(), anyString(), anyString(), anyString())).thenReturn(null);
|
|
|
- when(ruleManager.selectBySeriesSet("Fleer", "Base", "B1")).thenReturn(rule(2));
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(card("c1", "Jordan", "1986", "Fleer", "Base")));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- assertEquals(MatchLevelEnum.L3.getCode(), d.getOrders().get(0).getCards().get(0).getMatchLevel());
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- void 三层均未命中_走兜底_matchLevel为DEFAULT() {
|
|
|
- when(ruleManager.selectByExact(any(), any(), any(), any(), any())).thenReturn(null);
|
|
|
- when(ruleManager.selectBySeriesSetYear(any(), any(), any(), any())).thenReturn(null);
|
|
|
- when(ruleManager.selectBySeriesSet(any(), any(), any())).thenReturn(null);
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(card("c1", "X", "Y", "Z", "W")));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- assertEquals(MatchLevelEnum.DEFAULT.getCode(), d.getOrders().get(0).getCards().get(0).getMatchLevel());
|
|
|
- assertEquals(1, d.getOrders().get(0).getEfficiency());
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- void 规则时效非法_跳过该层继续降级() {
|
|
|
- when(ruleManager.selectByExact(any(), any(), any(), any(), any())).thenReturn(rule(99));
|
|
|
- when(ruleManager.selectBySeriesSetYear(any(), any(), any(), any())).thenReturn(rule(2));
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(card("c1", "p", "y", "s", "cs")));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- assertEquals(MatchLevelEnum.L2.getCode(), d.getOrders().get(0).getCards().get(0).getMatchLevel());
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- void 价格Map为空_单价均为null_grandTotal为null() {
|
|
|
- when(ruleManager.selectByExact(any(), any(), any(), any(), any())).thenReturn(rule(3));
|
|
|
- when(priceProvider.loadEfficiencyPrices()).thenReturn(Collections.emptyMap());
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(card("c1", "p", "y", "s", "cs")));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- assertNull(d.getOrders().get(0).getUnitPrice());
|
|
|
- assertNull(d.getOrders().get(0).getTotalAmount());
|
|
|
- assertNull(d.getOrders().get(0).getCards().get(0).getUnitPrice());
|
|
|
- assertNull(d.getGrandTotal());
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- void 多卡多档_按档位升序分3单_总计正确() {
|
|
|
- when(ruleManager.selectByExact("p1", "y", "s", "cs", "B1")).thenReturn(rule(1));
|
|
|
- when(ruleManager.selectByExact("p2", "y", "s", "cs", "B1")).thenReturn(rule(2));
|
|
|
- when(ruleManager.selectByExact("p3", "y", "s", "cs", "B1")).thenReturn(rule(3));
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(
|
|
|
- card("c1", "p1", "y", "s", "cs"),
|
|
|
- card("c2", "p2", "y", "s", "cs"),
|
|
|
- card("c3", "p3", "y", "s", "cs")));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- assertEquals(3, d.getOrderCount());
|
|
|
- assertEquals(1, d.getOrders().get(0).getEfficiency());
|
|
|
- assertEquals(2, d.getOrders().get(1).getEfficiency());
|
|
|
- assertEquals(3, d.getOrders().get(2).getEfficiency());
|
|
|
- assertEquals(new BigDecimal("350.00"), d.getGrandTotal());
|
|
|
+ void 正常_落库成功_返回preOrderNo() {
|
|
|
+ defaultHappyStubs();
|
|
|
+ when(preOrderFeignClient.savePreOrder(anyString(), any(PreOrderSaveDTO.class)))
|
|
|
+ .thenReturn(okWith("PRE123456"));
|
|
|
+ AjaxResult result = recommendService.recommendEfficiency(req(card("Jordan", "1986", "Fleer", "Base")));
|
|
|
+ assertEquals(0, code(result));
|
|
|
+ // 生产代码:成功时 data 为 String preOrderNo
|
|
|
+ assertEquals("PRE123456", result.get("data"));
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void 同档多卡_合并为一单_无套餐价时总计等于时效单价() {
|
|
|
- // 新公式:totalAmount = packageTotal × 卡数 + 时效单价;无套餐价 → 0×3 + 100 = 100
|
|
|
- when(ruleManager.selectByExact(any(), any(), any(), any(), any())).thenReturn(rule(2));
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(
|
|
|
- card("c1", "p", "y", "s", "cs"),
|
|
|
- card("c2", "p", "y", "s", "cs"),
|
|
|
- card("c3", "p", "y", "s", "cs")));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- assertEquals(1, d.getOrderCount());
|
|
|
- OrderSuggestionVO order = d.getOrders().get(0);
|
|
|
- assertEquals(3, order.getCardCount());
|
|
|
- assertEquals(new BigDecimal("100.00"), order.getUnitPrice());
|
|
|
- assertEquals(new BigDecimal("100.00"), order.getTotalAmount());
|
|
|
+ void 用户未登录_不调用Feign_返回error() {
|
|
|
+ defaultHappyStubs();
|
|
|
+ // 覆盖 defaultHappyStubs 里的登录用户
|
|
|
+ when(loginUserProvider.currentUserId()).thenReturn(null);
|
|
|
+ AjaxResult result = recommendService.recommendEfficiency(req(card("p", "y", "s", "cs")));
|
|
|
+ assertNotEquals(0, code(result));
|
|
|
+ // 关键:未登录时不得触发远程调用
|
|
|
+ verify(preOrderFeignClient, never()).savePreOrder(any(), any());
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void 图片透传_clientCardId与图片原样返回() {
|
|
|
- when(ruleManager.selectByExact(any(), any(), any(), any(), any())).thenReturn(rule(1));
|
|
|
- RecommendCardDTO c = card("MY-CARD-1", "p", "y", "s", "cs");
|
|
|
- c.setFrontImageUrl("http://x/f.jpg");
|
|
|
- c.setBackImageUrl("http://x/b.jpg");
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(c));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- assertEquals("MY-CARD-1", d.getOrders().get(0).getCards().get(0).getClientCardId());
|
|
|
- assertEquals("http://x/f.jpg", d.getOrders().get(0).getCards().get(0).getFrontImageUrl());
|
|
|
- assertEquals("http://x/b.jpg", d.getOrders().get(0).getCards().get(0).getBackImageUrl());
|
|
|
+ void Feign抛异常_返回生成失败() {
|
|
|
+ defaultHappyStubs();
|
|
|
+ when(preOrderFeignClient.savePreOrder(anyString(), any(PreOrderSaveDTO.class)))
|
|
|
+ .thenThrow(new RuntimeException("timeout"));
|
|
|
+ AjaxResult result = recommendService.recommendEfficiency(req(card("p", "y", "s", "cs")));
|
|
|
+ assertNotEquals(0, code(result));
|
|
|
+ assertEquals(FAIL_MSG, result.getMsg());
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void 套餐价生效_订单总额包含套餐价合计_且卡级透传packageId与packagePrice() {
|
|
|
- // 同档 2 卡,时效价 100,每卡套餐价 30 / 50
|
|
|
- when(ruleManager.selectByExact(any(), any(), any(), any(), any())).thenReturn(rule(2));
|
|
|
- RecommendCardDTO c1 = card("c1", "p", "y", "s", "cs");
|
|
|
- c1.setId(101L);
|
|
|
- c1.setPrice(new BigDecimal("30"));
|
|
|
- RecommendCardDTO c2 = card("c2", "p", "y", "s", "cs");
|
|
|
- c2.setId(102L);
|
|
|
- c2.setPrice(new BigDecimal("50"));
|
|
|
-
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(c1, c2));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- OrderSuggestionVO order = d.getOrders().get(0);
|
|
|
-
|
|
|
- // 时效价单价 100
|
|
|
- assertEquals(new BigDecimal("100.00"), order.getUnitPrice());
|
|
|
- // 套餐价合计 = 30 + 50 = 80
|
|
|
- assertEquals(new BigDecimal("80"), order.getPackageTotal());
|
|
|
- // 订单总计 = 套餐合计 × 卡数 + 时效单价 = 80×2 + 100 = 260(scale=2 因为时效价 100.00 传染)
|
|
|
- assertEquals(new BigDecimal("260.00"), order.getTotalAmount());
|
|
|
- // grandTotal 与订单总计一致
|
|
|
- assertEquals(new BigDecimal("260.00"), d.getGrandTotal());
|
|
|
- // 卡级透传 packageId / packagePrice
|
|
|
- assertEquals(101L, order.getCards().get(0).getPackageId());
|
|
|
- assertEquals(new BigDecimal("30"), order.getCards().get(0).getPackagePrice());
|
|
|
- assertEquals(102L, order.getCards().get(1).getPackageId());
|
|
|
- assertEquals(new BigDecimal("50"), order.getCards().get(1).getPackagePrice());
|
|
|
+ void Feign返回非0_透传错误() {
|
|
|
+ defaultHappyStubs();
|
|
|
+ // 下游返回 error(含具体 msg "下游库满"),生产代码经质量审查后已不再透传下游 msg,
|
|
|
+ // 对外统一为固定文案 FAIL_MSG,避免下游信息泄露。故只断言 code 非 0 + 固定文案。
|
|
|
+ when(preOrderFeignClient.savePreOrder(anyString(), any(PreOrderSaveDTO.class)))
|
|
|
+ .thenReturn(AjaxResult.error("下游库满"));
|
|
|
+ AjaxResult result = recommendService.recommendEfficiency(req(card("p", "y", "s", "cs")));
|
|
|
+ assertNotEquals(0, code(result));
|
|
|
+ assertEquals(FAIL_MSG, result.getMsg());
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- void 套餐价部分为null_当0处理_不阻断() {
|
|
|
- // 同档 2 卡,时效价 100,一卡套餐价 40 另一卡 null
|
|
|
- when(ruleManager.selectByExact(any(), any(), any(), any(), any())).thenReturn(rule(2));
|
|
|
- RecommendCardDTO c1 = card("c1", "p", "y", "s", "cs");
|
|
|
- c1.setPrice(new BigDecimal("40"));
|
|
|
- RecommendCardDTO c2 = card("c2", "p", "y", "s", "cs");
|
|
|
- // c2.price 不设 → null 当 0
|
|
|
-
|
|
|
- AjaxResult result = recommendService.recommendEfficiency(req(c1, c2));
|
|
|
- RecommendResultVO d = data(result);
|
|
|
- OrderSuggestionVO order = d.getOrders().get(0);
|
|
|
-
|
|
|
- // 套餐合计 = 40 + 0 = 40;订单总计 = 40×2 + 100 = 180(新公式:合计×卡数+时效单价;scale=2)
|
|
|
- assertEquals(new BigDecimal("40"), order.getPackageTotal());
|
|
|
- assertEquals(new BigDecimal("180.00"), order.getTotalAmount());
|
|
|
+ void 落库包_识别字段与关键字段全部透传() {
|
|
|
+ defaultHappyStubs();
|
|
|
+ when(preOrderFeignClient.savePreOrder(anyString(), any(PreOrderSaveDTO.class)))
|
|
|
+ .thenReturn(okWith("PRE999"));
|
|
|
+
|
|
|
+ // 构造含 10 个补齐识别字段 + id/price 的入参卡
|
|
|
+ RecommendCardDTO c = card("Jordan", "1986", "Fleer", "Base");
|
|
|
+ c.setSportEvent("篮球");
|
|
|
+ c.setCardType(2);
|
|
|
+ c.setRole("SG");
|
|
|
+ c.setCardNo("NO-1");
|
|
|
+ c.setTeam("Bulls");
|
|
|
+ c.setLimitId("/99");
|
|
|
+ c.setIpName("NBA");
|
|
|
+ c.setRule("MVP");
|
|
|
+ c.setRarity("SSR");
|
|
|
+ c.setMaterial("金箔");
|
|
|
+ c.setId(88L);
|
|
|
+ c.setPrice(new BigDecimal("120"));
|
|
|
+
|
|
|
+ recommendService.recommendEfficiency(req(c));
|
|
|
+
|
|
|
+ // 抓取实际传给 Feign 的 PreOrderSaveDTO
|
|
|
+ ArgumentCaptor<PreOrderSaveDTO> captor = ArgumentCaptor.forClass(PreOrderSaveDTO.class);
|
|
|
+ verify(preOrderFeignClient).savePreOrder(anyString(), captor.capture());
|
|
|
+ PreOrderSaveDTO sent = captor.getValue();
|
|
|
+
|
|
|
+ // 主表汇总字段
|
|
|
+ assertEquals(1001L, sent.getUserId());
|
|
|
+ assertEquals(1, sent.getTotalCards());
|
|
|
+
|
|
|
+ // 卡片明细:10 识别字段全部透传(sportEvent/cardType/role/cardNo/team/limitId/ipName/rule/rarity/material)
|
|
|
+ PreOrderCardDTO card = sent.getGroups().get(0).getCards().get(0);
|
|
|
+ assertEquals("篮球", card.getSportEvent());
|
|
|
+ assertEquals(2, card.getCardType());
|
|
|
+ assertEquals("SG", card.getRole());
|
|
|
+ assertEquals("NO-1", card.getCardNo());
|
|
|
+ assertEquals("Bulls", card.getTeam());
|
|
|
+ assertEquals("/99", card.getLimitId());
|
|
|
+ assertEquals("NBA", card.getIpName());
|
|
|
+ // 入参 rule -> VO roleName -> PreOrderCardDTO.rule(往返映射)
|
|
|
+ assertEquals("MVP", card.getRule());
|
|
|
+ assertEquals("SSR", card.getRarity());
|
|
|
+ assertEquals("金箔", card.getMaterial());
|
|
|
+ // 套餐/命中:入参 id -> packageId;规则 cardId -> matchedCardId
|
|
|
+ assertEquals(88L, card.getPackageId());
|
|
|
+ assertEquals("DW-CARD-1", card.getMatchedCardId());
|
|
|
+ // 时效价可取到时应大于 0
|
|
|
+ assertTrue(card.getEfficiencyPrice().compareTo(BigDecimal.ZERO) > 0);
|
|
|
}
|
|
|
}
|