Commit 1452f6b231bff6fd1977085de6762c59ef01d52d
1 parent
636b14cc
mall + trade:增肌爱 TradeCouponPriceCalculator 的单元测试
Showing
9 changed files
with
314 additions
and
140 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java
| @@ -52,10 +52,6 @@ public class ProductSkuRespDTO { | @@ -52,10 +52,6 @@ public class ProductSkuRespDTO { | ||
| 52 | */ | 52 | */ |
| 53 | private Integer stock; | 53 | private Integer stock; |
| 54 | /** | 54 | /** |
| 55 | - * 预警预存 | ||
| 56 | - */ | ||
| 57 | - private Integer warnStock; | ||
| 58 | - /** | ||
| 59 | * 商品重量,单位:kg 千克 | 55 | * 商品重量,单位:kg 千克 |
| 60 | */ | 56 | */ |
| 61 | private Double weight; | 57 | private Double weight; |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java
| @@ -57,54 +57,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { | @@ -57,54 +57,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { | ||
| 57 | private ProductSkuApi productSkuApi; | 57 | private ProductSkuApi productSkuApi; |
| 58 | 58 | ||
| 59 | @Test | 59 | @Test |
| 60 | - public void testCalculatePrice_memberDiscount() { | ||
| 61 | - // 准备参数 | ||
| 62 | - // TODO 芋艿:userId = 1,实现 9 折;后续改成 mock | ||
| 63 | - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1L) | ||
| 64 | - .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); | ||
| 65 | - // mock 方法(商品 SKU 信息) | ||
| 66 | - ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); | ||
| 67 | - when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); | ||
| 68 | - | ||
| 69 | - // 调用 | ||
| 70 | - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); | ||
| 71 | - // 断言 Order 部分 | ||
| 72 | - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); | ||
| 73 | - assertEquals(order.getTotalPrice(), 200); | ||
| 74 | - assertEquals(order.getDiscountPrice(), 0); | ||
| 75 | - assertEquals(order.getPointPrice(), 0); | ||
| 76 | - assertEquals(order.getDeliveryPrice(), 0); | ||
| 77 | - assertEquals(order.getPayPrice(), 180); | ||
| 78 | - assertNull(order.getCouponId()); | ||
| 79 | - // 断言 OrderItem 部分 | ||
| 80 | - assertEquals(order.getItems().size(), 1); | ||
| 81 | - PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0); | ||
| 82 | - assertEquals(orderItem.getSkuId(), 10L); | ||
| 83 | - assertEquals(orderItem.getCount(), 2); | ||
| 84 | - assertEquals(orderItem.getOriginalPrice(), 200); | ||
| 85 | - assertEquals(orderItem.getOriginalUnitPrice(), 100); | ||
| 86 | - assertEquals(orderItem.getDiscountPrice(), 20); | ||
| 87 | - assertEquals(orderItem.getPayPrice(), 180); | ||
| 88 | - assertEquals(orderItem.getOrderPartPrice(), 0); | ||
| 89 | - assertEquals(orderItem.getOrderDividePrice(), 180); | ||
| 90 | - // 断言 Promotion 部分 | ||
| 91 | - assertEquals(priceCalculate.getPromotions().size(), 1); | ||
| 92 | - PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0); | ||
| 93 | - assertNull(promotion.getId()); | ||
| 94 | - assertEquals(promotion.getName(), "会员折扣"); | ||
| 95 | - assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); | ||
| 96 | - assertEquals(promotion.getTotalPrice(), 200); | ||
| 97 | - assertEquals(promotion.getDiscountPrice(), 20); | ||
| 98 | - assertTrue(promotion.getMatch()); | ||
| 99 | - assertEquals(promotion.getDescription(), "会员折扣:省 0.20 元"); | ||
| 100 | - PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0); | ||
| 101 | - assertEquals(promotion.getItems().size(), 1); | ||
| 102 | - assertEquals(promotionItem.getSkuId(), 10L); | ||
| 103 | - assertEquals(promotionItem.getOriginalPrice(), 200); | ||
| 104 | - assertEquals(promotionItem.getDiscountPrice(), 20); | ||
| 105 | - } | ||
| 106 | - | ||
| 107 | - @Test | ||
| 108 | public void testCalculatePrice_discountActivity() { | 60 | public void testCalculatePrice_discountActivity() { |
| 109 | // 准备参数 | 61 | // 准备参数 |
| 110 | PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) | 62 | PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) |
| @@ -365,87 +317,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { | @@ -365,87 +317,6 @@ public class PriceServiceTest extends BaseMockitoUnitTest { | ||
| 365 | } | 317 | } |
| 366 | 318 | ||
| 367 | @Test | 319 | @Test |
| 368 | - public void testCalculatePrice_coupon() { | ||
| 369 | - // 准备参数 | ||
| 370 | - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) | ||
| 371 | - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), | ||
| 372 | - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), | ||
| 373 | - new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))) | ||
| 374 | - .setCouponId(1024L); | ||
| 375 | - // mock 方法(商品 SKU 信息) | ||
| 376 | - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); | ||
| 377 | - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); | ||
| 378 | - ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); | ||
| 379 | - when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); | ||
| 380 | - // mock 方法(优惠劵 Coupon 信息) | ||
| 381 | - CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setName("程序员节") | ||
| 382 | - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) | ||
| 383 | - .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) | ||
| 384 | - .setDiscountPercent(50).setDiscountLimitPrice(70)); | ||
| 385 | - when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon); | ||
| 386 | - | ||
| 387 | - // 调用 | ||
| 388 | - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); | ||
| 389 | - // 断言 Order 部分 | ||
| 390 | - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); | ||
| 391 | - assertEquals(order.getTotalPrice(), 470); | ||
| 392 | - assertEquals(order.getDiscountPrice(), 0); | ||
| 393 | - assertEquals(order.getPointPrice(), 0); | ||
| 394 | - assertEquals(order.getDeliveryPrice(), 0); | ||
| 395 | - assertEquals(order.getPayPrice(), 400); | ||
| 396 | - assertEquals(order.getCouponId(), 1024L); | ||
| 397 | - assertEquals(order.getCouponPrice(), 70); | ||
| 398 | - // 断言 OrderItem 部分 | ||
| 399 | - assertEquals(order.getItems().size(), 3); | ||
| 400 | - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); | ||
| 401 | - assertEquals(orderItem01.getSkuId(), 10L); | ||
| 402 | - assertEquals(orderItem01.getCount(), 2); | ||
| 403 | - assertEquals(orderItem01.getOriginalPrice(), 200); | ||
| 404 | - assertEquals(orderItem01.getOriginalUnitPrice(), 100); | ||
| 405 | - assertEquals(orderItem01.getDiscountPrice(), 0); | ||
| 406 | - assertEquals(orderItem01.getPayPrice(), 200); | ||
| 407 | - assertEquals(orderItem01.getOrderPartPrice(), 40); | ||
| 408 | - assertEquals(orderItem01.getOrderDividePrice(), 160); | ||
| 409 | - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); | ||
| 410 | - assertEquals(orderItem02.getSkuId(), 20L); | ||
| 411 | - assertEquals(orderItem02.getCount(), 3); | ||
| 412 | - assertEquals(orderItem02.getOriginalPrice(), 150); | ||
| 413 | - assertEquals(orderItem02.getOriginalUnitPrice(), 50); | ||
| 414 | - assertEquals(orderItem02.getDiscountPrice(), 0); | ||
| 415 | - assertEquals(orderItem02.getPayPrice(), 150); | ||
| 416 | - assertEquals(orderItem02.getOrderPartPrice(), 30); | ||
| 417 | - assertEquals(orderItem02.getOrderDividePrice(), 120); | ||
| 418 | - PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); | ||
| 419 | - assertEquals(orderItem03.getSkuId(), 30L); | ||
| 420 | - assertEquals(orderItem03.getCount(), 4); | ||
| 421 | - assertEquals(orderItem03.getOriginalPrice(), 120); | ||
| 422 | - assertEquals(orderItem03.getOriginalUnitPrice(), 30); | ||
| 423 | - assertEquals(orderItem03.getDiscountPrice(), 0); | ||
| 424 | - assertEquals(orderItem03.getPayPrice(), 120); | ||
| 425 | - assertEquals(orderItem03.getOrderPartPrice(), 0); | ||
| 426 | - assertEquals(orderItem03.getOrderDividePrice(), 120); | ||
| 427 | - // 断言 Promotion 部分 | ||
| 428 | - assertEquals(priceCalculate.getPromotions().size(), 1); | ||
| 429 | - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); | ||
| 430 | - assertEquals(promotion01.getId(), 1024L); | ||
| 431 | - assertEquals(promotion01.getName(), "程序员节"); | ||
| 432 | - assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); | ||
| 433 | - assertEquals(promotion01.getTotalPrice(), 350); | ||
| 434 | - assertEquals(promotion01.getDiscountPrice(), 70); | ||
| 435 | - assertTrue(promotion01.getMatch()); | ||
| 436 | - assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元"); | ||
| 437 | - assertEquals(promotion01.getItems().size(), 2); | ||
| 438 | - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); | ||
| 439 | - assertEquals(promotionItem011.getSkuId(), 10L); | ||
| 440 | - assertEquals(promotionItem011.getOriginalPrice(), 200); | ||
| 441 | - assertEquals(promotionItem011.getDiscountPrice(), 40); | ||
| 442 | - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); | ||
| 443 | - assertEquals(promotionItem012.getSkuId(), 20L); | ||
| 444 | - assertEquals(promotionItem012.getOriginalPrice(), 150); | ||
| 445 | - assertEquals(promotionItem012.getDiscountPrice(), 30); | ||
| 446 | - } | ||
| 447 | - | ||
| 448 | - @Test | ||
| 449 | public void testGetMeetCouponList() { | 320 | public void testGetMeetCouponList() { |
| 450 | // 准备参数 | 321 | // 准备参数 |
| 451 | PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1024L) | 322 | PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1024L) |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java
| @@ -101,7 +101,8 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator { | @@ -101,7 +101,8 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator { | ||
| 101 | CouponRespDTO coupon) { | 101 | CouponRespDTO coupon) { |
| 102 | Predicate<TradePriceCalculateRespBO.OrderItem> matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected; | 102 | Predicate<TradePriceCalculateRespBO.OrderItem> matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected; |
| 103 | if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) { | 103 | if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) { |
| 104 | - matchPredicate = orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId()); | 104 | + matchPredicate = matchPredicate // 额外加如下条件 |
| 105 | + .and(orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId())); | ||
| 105 | } | 106 | } |
| 106 | return filterList(result.getItems(), matchPredicate); | 107 | return filterList(result.getItems(), matchPredicate); |
| 107 | } | 108 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java
| @@ -15,8 +15,6 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | @@ -15,8 +15,6 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | ||
| 15 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; | 15 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; |
| 16 | import static java.util.Collections.singletonList; | 16 | import static java.util.Collections.singletonList; |
| 17 | 17 | ||
| 18 | -// TODO 芋艿:改成父类 | ||
| 19 | - | ||
| 20 | /** | 18 | /** |
| 21 | * {@link TradePriceCalculator} 的工具类 | 19 | * {@link TradePriceCalculator} 的工具类 |
| 22 | * | 20 | * |
| @@ -107,6 +105,31 @@ public class TradePriceCalculatorHelper { | @@ -107,6 +105,31 @@ public class TradePriceCalculatorHelper { | ||
| 107 | } | 105 | } |
| 108 | 106 | ||
| 109 | /** | 107 | /** |
| 108 | + * 重新计算每个订单项的支付金额 | ||
| 109 | + * | ||
| 110 | + * 【目前主要是单测使用】 | ||
| 111 | + * | ||
| 112 | + * @param orderItems 订单项数组 | ||
| 113 | + */ | ||
| 114 | + public static void recountPayPrice(List<TradePriceCalculateRespBO.OrderItem> orderItems) { | ||
| 115 | + orderItems.forEach(orderItem -> { | ||
| 116 | + if (orderItem.getDiscountPrice() == null) { | ||
| 117 | + orderItem.setDiscountPrice(0); | ||
| 118 | + } | ||
| 119 | + if (orderItem.getDeliveryPrice() == null) { | ||
| 120 | + orderItem.setDeliveryPrice(0); | ||
| 121 | + } | ||
| 122 | + if (orderItem.getCouponPrice() == null) { | ||
| 123 | + orderItem.setCouponPrice(0); | ||
| 124 | + } | ||
| 125 | + if (orderItem.getPointPrice() == null) { | ||
| 126 | + orderItem.setPointPrice(0); | ||
| 127 | + } | ||
| 128 | + recountPayPrice(orderItem); | ||
| 129 | + }); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + /** | ||
| 110 | * 计算已选中的订单项,总支付金额 | 133 | * 计算已选中的订单项,总支付金额 |
| 111 | * | 134 | * |
| 112 | * @param orderItems 订单项数组 | 135 | * @param orderItems 订单项数组 |
| @@ -114,7 +137,7 @@ public class TradePriceCalculatorHelper { | @@ -114,7 +137,7 @@ public class TradePriceCalculatorHelper { | ||
| 114 | */ | 137 | */ |
| 115 | public static Integer calculateTotalPayPrice(List<TradePriceCalculateRespBO.OrderItem> orderItems) { | 138 | public static Integer calculateTotalPayPrice(List<TradePriceCalculateRespBO.OrderItem> orderItems) { |
| 116 | return getSumValue(orderItems, | 139 | return getSumValue(orderItems, |
| 117 | - orderItem -> orderItem.getSelected() ? orderItem.getPayPrice() : 0, // 未选中的情况下,不计算支付金额 | 140 | + orderItem -> orderItem.getSelected() ? orderItem.getPayPrice() : 0, // 未选中的情况下,不计算支付金额 |
| 118 | Integer::sum); | 141 | Integer::sum); |
| 119 | } | 142 | } |
| 120 | 143 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java
| @@ -53,6 +53,9 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator | @@ -53,6 +53,9 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator | ||
| 53 | // 1.2 获得最大匹配的满减送活动的规则 | 53 | // 1.2 获得最大匹配的满减送活动的规则 |
| 54 | RewardActivityMatchRespDTO.Rule rule = getMaxMatchRewardActivityRule(rewardActivity, orderItems); | 54 | RewardActivityMatchRespDTO.Rule rule = getMaxMatchRewardActivityRule(rewardActivity, orderItems); |
| 55 | if (rule == null) { | 55 | if (rule == null) { |
| 56 | + TradePriceCalculatorHelper.addNotMatchPromotion(result, orderItems, | ||
| 57 | + rewardActivity.getId(), rewardActivity.getName(), PromotionTypeEnum.REWARD_ACTIVITY.getType(), | ||
| 58 | + getRewardActivityNotMeetTip(rewardActivity)); | ||
| 56 | return; | 59 | return; |
| 57 | } | 60 | } |
| 58 | 61 |
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java
| @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | ||
| 8 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; | 8 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; |
| 9 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; | 9 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; |
| 10 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | 10 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; |
| 11 | +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | ||
| 11 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | 12 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| 12 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | 13 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 13 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | 14 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; |
| @@ -101,10 +102,10 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { | @@ -101,10 +102,10 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { | ||
| 101 | // mock 方法(商品 SKU 检查) | 102 | // mock 方法(商品 SKU 检查) |
| 102 | ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) | 103 | ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) |
| 103 | .setPrice(50).setStock(100) | 104 | .setPrice(50).setStock(100) |
| 104 | - .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(111L).setValueId(222L)))); | 105 | + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(111L).setValueId(222L)))); |
| 105 | ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L) | 106 | ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L) |
| 106 | .setPrice(20).setStock(50)) | 107 | .setPrice(20).setStock(50)) |
| 107 | - .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(333L).setValueId(444L))); | 108 | + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(333L).setValueId(444L))); |
| 108 | when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02)); | 109 | when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02)); |
| 109 | // mock 方法(商品 SPU 检查) | 110 | // mock 方法(商品 SPU 检查) |
| 110 | ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L) | 111 | ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L) |
| @@ -114,7 +115,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { | @@ -114,7 +115,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { | ||
| 114 | when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02)); | 115 | when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02)); |
| 115 | // mock 方法(用户收件地址的校验) | 116 | // mock 方法(用户收件地址的校验) |
| 116 | AddressRespDTO addressRespDTO = new AddressRespDTO().setId(10L).setUserId(userId).setName("芋艿") | 117 | AddressRespDTO addressRespDTO = new AddressRespDTO().setId(10L).setUserId(userId).setName("芋艿") |
| 117 | - .setMobile("15601691300").setAreaId(3306L).setPostCode("85757").setDetailAddress("土豆村"); | 118 | + .setMobile("15601691300").setAreaId(3306).setPostCode("85757").setDetailAddress("土豆村"); |
| 118 | when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO); | 119 | when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO); |
| 119 | // mock 方法(价格计算) | 120 | // mock 方法(价格计算) |
| 120 | PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem() | 121 | PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem() |
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.price; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | ||
| 4 | +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | ||
| 5 | +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | ||
| 6 | +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | ||
| 7 | +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | ||
| 8 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | ||
| 9 | +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; | ||
| 10 | +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | ||
| 11 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | ||
| 12 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | ||
| 13 | +import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator; | ||
| 14 | +import org.junit.jupiter.api.Test; | ||
| 15 | +import org.mockito.InjectMocks; | ||
| 16 | +import org.mockito.Mock; | ||
| 17 | +import org.mockito.Mockito; | ||
| 18 | + | ||
| 19 | +import java.util.Arrays; | ||
| 20 | +import java.util.List; | ||
| 21 | + | ||
| 22 | +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | ||
| 23 | +import static java.util.Collections.singletonList; | ||
| 24 | +import static org.junit.jupiter.api.Assertions.*; | ||
| 25 | +import static org.mockito.Mockito.when; | ||
| 26 | + | ||
| 27 | +/** | ||
| 28 | + * {@link TradePriceServiceImpl} 的单元测试 | ||
| 29 | + * | ||
| 30 | + * @author 芋道源码 | ||
| 31 | + */ | ||
| 32 | +public class TradePriceServiceImplTest extends BaseMockitoUnitTest { | ||
| 33 | + | ||
| 34 | + @InjectMocks | ||
| 35 | + private TradePriceServiceImpl tradePriceService; | ||
| 36 | + | ||
| 37 | + @Mock | ||
| 38 | + private ProductSkuApi productSkuApi; | ||
| 39 | + @Mock | ||
| 40 | + private ProductSpuApi productSpuApi; | ||
| 41 | + @Mock | ||
| 42 | + private List<TradePriceCalculator> priceCalculators; | ||
| 43 | + | ||
| 44 | + @Test | ||
| 45 | + public void testCalculatePrice() { | ||
| 46 | + // 准备参数 | ||
| 47 | + TradePriceCalculateReqBO calculateReqBO = new TradePriceCalculateReqBO() | ||
| 48 | + .setType(TradeOrderTypeEnum.NORMAL.getType()).setUserId(10L) | ||
| 49 | + .setCouponId(20L).setAddressId(30L) | ||
| 50 | + .setItems(Arrays.asList( | ||
| 51 | + new TradePriceCalculateReqBO.Item().setSkuId(100L).setCount(1).setSelected(true), | ||
| 52 | + new TradePriceCalculateReqBO.Item().setSkuId(200L).setCount(3).setSelected(true), | ||
| 53 | + new TradePriceCalculateReqBO.Item().setSkuId(300L).setCount(6).setCartId(233L).setSelected(false) | ||
| 54 | + )); | ||
| 55 | + // mock 方法 | ||
| 56 | + List<ProductSkuRespDTO> skuList = Arrays.asList( | ||
| 57 | + new ProductSkuRespDTO().setId(100L).setStock(500).setPrice(1000).setPicUrl("https://t.cn/1.png").setSpuId(1001L) | ||
| 58 | + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色") | ||
| 59 | + .setValueId(2L).setValueName("红色"))), | ||
| 60 | + new ProductSkuRespDTO().setId(200L).setStock(400).setPrice(2000).setPicUrl("https://t.cn/2.png").setSpuId(1001L) | ||
| 61 | + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色") | ||
| 62 | + .setValueId(3L).setValueName("黄色"))), | ||
| 63 | + new ProductSkuRespDTO().setId(300L).setStock(600).setPrice(3000).setPicUrl("https://t.cn/3.png").setSpuId(1001L) | ||
| 64 | + .setProperties(singletonList(new ProductPropertyValueDetailRespDTO().setPropertyId(1L).setPropertyName("颜色") | ||
| 65 | + .setValueId(4L).setValueName("黑色"))) | ||
| 66 | + ); | ||
| 67 | + when(productSkuApi.getSkuList(Mockito.eq(asSet(100L, 200L, 300L)))).thenReturn(skuList); | ||
| 68 | + when(productSpuApi.getSpuList(Mockito.eq(asSet(1001L)))) | ||
| 69 | + .thenReturn(singletonList(new ProductSpuRespDTO().setId(1001L).setName("小菜").setCategoryId(666L) | ||
| 70 | + .setStatus(ProductSpuStatusEnum.ENABLE.getStatus()))); | ||
| 71 | + | ||
| 72 | + // 调用 | ||
| 73 | + TradePriceCalculateRespBO calculateRespBO = tradePriceService.calculatePrice(calculateReqBO); | ||
| 74 | + // 断言 | ||
| 75 | + assertEquals(TradeOrderTypeEnum.NORMAL.getType(), calculateRespBO.getType()); | ||
| 76 | + assertEquals(0, calculateRespBO.getPromotions().size()); | ||
| 77 | + assertNull(calculateRespBO.getCouponId()); | ||
| 78 | + // 断言:订单价格 | ||
| 79 | + assertEquals(7000, calculateRespBO.getPrice().getTotalPrice()); | ||
| 80 | + assertEquals(0, calculateRespBO.getPrice().getDiscountPrice()); | ||
| 81 | + assertEquals(0, calculateRespBO.getPrice().getDeliveryPrice()); | ||
| 82 | + assertEquals(0, calculateRespBO.getPrice().getCouponPrice()); | ||
| 83 | + assertEquals(0, calculateRespBO.getPrice().getPointPrice()); | ||
| 84 | + assertEquals(7000, calculateRespBO.getPrice().getPayPrice()); | ||
| 85 | + // 断言:SKU 1 | ||
| 86 | + assertEquals(1001L, calculateRespBO.getItems().get(0).getSpuId()); | ||
| 87 | + assertEquals(100L, calculateRespBO.getItems().get(0).getSkuId()); | ||
| 88 | + assertEquals(1, calculateRespBO.getItems().get(0).getCount()); | ||
| 89 | + assertNull(calculateRespBO.getItems().get(0).getCartId()); | ||
| 90 | + assertTrue(calculateRespBO.getItems().get(0).getSelected()); | ||
| 91 | + assertEquals(1000, calculateRespBO.getItems().get(0).getPrice()); | ||
| 92 | + assertEquals(0, calculateRespBO.getItems().get(0).getDiscountPrice()); | ||
| 93 | + assertEquals(0, calculateRespBO.getItems().get(0).getDeliveryPrice()); | ||
| 94 | + assertEquals(0, calculateRespBO.getItems().get(0).getCouponPrice()); | ||
| 95 | + assertEquals(0, calculateRespBO.getItems().get(0).getPointPrice()); | ||
| 96 | + assertEquals(1000, calculateRespBO.getItems().get(0).getPayPrice()); | ||
| 97 | + assertEquals("小菜", calculateRespBO.getItems().get(0).getSpuName()); | ||
| 98 | + assertEquals("https://t.cn/1.png", calculateRespBO.getItems().get(0).getPicUrl()); | ||
| 99 | + assertEquals(666L, calculateRespBO.getItems().get(0).getCategoryId()); | ||
| 100 | + assertEquals(skuList.get(0).getProperties(), calculateRespBO.getItems().get(0).getProperties()); | ||
| 101 | + // 断言:SKU 2 | ||
| 102 | + assertEquals(1001L, calculateRespBO.getItems().get(1).getSpuId()); | ||
| 103 | + assertEquals(200L, calculateRespBO.getItems().get(1).getSkuId()); | ||
| 104 | + assertEquals(3, calculateRespBO.getItems().get(1).getCount()); | ||
| 105 | + assertNull(calculateRespBO.getItems().get(1).getCartId()); | ||
| 106 | + assertTrue(calculateRespBO.getItems().get(1).getSelected()); | ||
| 107 | + assertEquals(2000, calculateRespBO.getItems().get(1).getPrice()); | ||
| 108 | + assertEquals(0, calculateRespBO.getItems().get(1).getDiscountPrice()); | ||
| 109 | + assertEquals(0, calculateRespBO.getItems().get(1).getDeliveryPrice()); | ||
| 110 | + assertEquals(0, calculateRespBO.getItems().get(1).getCouponPrice()); | ||
| 111 | + assertEquals(0, calculateRespBO.getItems().get(1).getPointPrice()); | ||
| 112 | + assertEquals(6000, calculateRespBO.getItems().get(1).getPayPrice()); | ||
| 113 | + assertEquals("小菜", calculateRespBO.getItems().get(1).getSpuName()); | ||
| 114 | + assertEquals("https://t.cn/2.png", calculateRespBO.getItems().get(1).getPicUrl()); | ||
| 115 | + assertEquals(666L, calculateRespBO.getItems().get(1).getCategoryId()); | ||
| 116 | + assertEquals(skuList.get(1).getProperties(), calculateRespBO.getItems().get(1).getProperties()); | ||
| 117 | + // 断言:SKU 3 | ||
| 118 | + assertEquals(1001L, calculateRespBO.getItems().get(2).getSpuId()); | ||
| 119 | + assertEquals(300L, calculateRespBO.getItems().get(2).getSkuId()); | ||
| 120 | + assertEquals(6, calculateRespBO.getItems().get(2).getCount()); | ||
| 121 | + assertEquals(233L, calculateRespBO.getItems().get(2).getCartId()); | ||
| 122 | + assertFalse(calculateRespBO.getItems().get(2).getSelected()); | ||
| 123 | + assertEquals(3000, calculateRespBO.getItems().get(2).getPrice()); | ||
| 124 | + assertEquals(0, calculateRespBO.getItems().get(2).getDiscountPrice()); | ||
| 125 | + assertEquals(0, calculateRespBO.getItems().get(2).getDeliveryPrice()); | ||
| 126 | + assertEquals(0, calculateRespBO.getItems().get(2).getCouponPrice()); | ||
| 127 | + assertEquals(0, calculateRespBO.getItems().get(2).getPointPrice()); | ||
| 128 | + assertEquals(18000, calculateRespBO.getItems().get(2).getPayPrice()); | ||
| 129 | + assertEquals("小菜", calculateRespBO.getItems().get(2).getSpuName()); | ||
| 130 | + assertEquals("https://t.cn/3.png", calculateRespBO.getItems().get(2).getPicUrl()); | ||
| 131 | + assertEquals(666L, calculateRespBO.getItems().get(2).getCategoryId()); | ||
| 132 | + assertEquals(skuList.get(2).getProperties(), calculateRespBO.getItems().get(2).getProperties()); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | +} |
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.price.calculator; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | ||
| 4 | +import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; | ||
| 5 | +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO; | ||
| 6 | +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO; | ||
| 7 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; | ||
| 8 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; | ||
| 9 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; | ||
| 10 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | ||
| 11 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | ||
| 12 | +import org.junit.jupiter.api.Test; | ||
| 13 | +import org.mockito.InjectMocks; | ||
| 14 | +import org.mockito.Mock; | ||
| 15 | + | ||
| 16 | +import java.util.ArrayList; | ||
| 17 | + | ||
| 18 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | ||
| 19 | +import static java.util.Arrays.asList; | ||
| 20 | +import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| 21 | +import static org.junit.jupiter.api.Assertions.assertTrue; | ||
| 22 | +import static org.mockito.ArgumentMatchers.eq; | ||
| 23 | +import static org.mockito.Mockito.when; | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * {@link TradeCouponPriceCalculator} 的单元测试类 | ||
| 27 | + * | ||
| 28 | + * @author 芋道源码 | ||
| 29 | + */ | ||
| 30 | +class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest { | ||
| 31 | + | ||
| 32 | + @InjectMocks | ||
| 33 | + private TradeCouponPriceCalculator tradeCouponPriceCalculator; | ||
| 34 | + | ||
| 35 | + @Mock | ||
| 36 | + private CouponApi couponApi; | ||
| 37 | + | ||
| 38 | + @Test | ||
| 39 | + void calculate() { | ||
| 40 | + // 准备参数 | ||
| 41 | + TradePriceCalculateReqBO param = new TradePriceCalculateReqBO() | ||
| 42 | + .setUserId(233L).setCouponId(1024L) | ||
| 43 | + .setItems(asList( | ||
| 44 | + new TradePriceCalculateReqBO.Item().setSkuId(10L).setCount(2).setSelected(true), // 匹配优惠劵 | ||
| 45 | + new TradePriceCalculateReqBO.Item().setSkuId(20L).setCount(3).setSelected(true), // 匹配优惠劵 | ||
| 46 | + new TradePriceCalculateReqBO.Item().setSkuId(30L).setCount(4).setSelected(true), // 不匹配优惠劵 | ||
| 47 | + new TradePriceCalculateReqBO.Item().setSkuId(40L).setCount(5).setSelected(false) // 匹配优惠劵,但是未选中 | ||
| 48 | + )); | ||
| 49 | + TradePriceCalculateRespBO result = new TradePriceCalculateRespBO() | ||
| 50 | + .setPrice(new TradePriceCalculateRespBO.Price()) | ||
| 51 | + .setPromotions(new ArrayList<>()) | ||
| 52 | + .setItems(asList( | ||
| 53 | + new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true) | ||
| 54 | + .setPrice(100).setSpuId(1L), | ||
| 55 | + new TradePriceCalculateRespBO.OrderItem().setSkuId(20L).setCount(3).setSelected(true) | ||
| 56 | + .setPrice(50).setSpuId(2L), | ||
| 57 | + new TradePriceCalculateRespBO.OrderItem().setSkuId(30L).setCount(4).setSelected(true) | ||
| 58 | + .setPrice(30).setSpuId(3L), | ||
| 59 | + new TradePriceCalculateRespBO.OrderItem().setSkuId(40L).setCount(5).setSelected(false) | ||
| 60 | + .setPrice(60).setSpuId(1L) | ||
| 61 | + )); | ||
| 62 | + // 保证价格被初始化上 | ||
| 63 | + TradePriceCalculatorHelper.recountPayPrice(result.getItems()); | ||
| 64 | + TradePriceCalculatorHelper.recountAllPrice(result); | ||
| 65 | + | ||
| 66 | + // mock 方法(优惠劵 Coupon 信息) | ||
| 67 | + CouponRespDTO coupon = randomPojo(CouponRespDTO.class, o -> o.setId(1024L).setName("程序员节") | ||
| 68 | + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) | ||
| 69 | + .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) | ||
| 70 | + .setDiscountPercent(50).setDiscountLimitPrice(70)); | ||
| 71 | + when(couponApi.validateCoupon(eq(new CouponValidReqDTO().setId(1024L).setUserId(233L)))).thenReturn(coupon); | ||
| 72 | + | ||
| 73 | + // 调用 | ||
| 74 | + tradeCouponPriceCalculator.calculate(param, result); | ||
| 75 | + // 断言 | ||
| 76 | + assertEquals(result.getCouponId(), 1024L); | ||
| 77 | + // 断言:Price 部分 | ||
| 78 | + TradePriceCalculateRespBO.Price price = result.getPrice(); | ||
| 79 | + assertEquals(price.getTotalPrice(), 470); | ||
| 80 | + assertEquals(price.getDiscountPrice(), 0); | ||
| 81 | + assertEquals(price.getPointPrice(), 0); | ||
| 82 | + assertEquals(price.getDeliveryPrice(), 0); | ||
| 83 | + assertEquals(price.getCouponPrice(), 70); | ||
| 84 | + assertEquals(price.getPayPrice(), 400); | ||
| 85 | + // 断言:SKU 1 | ||
| 86 | + TradePriceCalculateRespBO.OrderItem orderItem01 = result.getItems().get(0); | ||
| 87 | + assertEquals(orderItem01.getSkuId(), 10L); | ||
| 88 | + assertEquals(orderItem01.getCount(), 2); | ||
| 89 | + assertEquals(orderItem01.getPrice(), 100); | ||
| 90 | + assertEquals(orderItem01.getDiscountPrice(), 0); | ||
| 91 | + assertEquals(orderItem01.getDeliveryPrice(), 0); | ||
| 92 | + assertEquals(orderItem01.getCouponPrice(), 40); | ||
| 93 | + assertEquals(orderItem01.getPointPrice(), 0); | ||
| 94 | + assertEquals(orderItem01.getPayPrice(), 160); | ||
| 95 | + // 断言:SKU 2 | ||
| 96 | + TradePriceCalculateRespBO.OrderItem orderItem02 = result.getItems().get(1); | ||
| 97 | + assertEquals(orderItem02.getSkuId(), 20L); | ||
| 98 | + assertEquals(orderItem02.getCount(), 3); | ||
| 99 | + assertEquals(orderItem02.getPrice(), 50); | ||
| 100 | + assertEquals(orderItem02.getDiscountPrice(), 0); | ||
| 101 | + assertEquals(orderItem02.getDeliveryPrice(), 0); | ||
| 102 | + assertEquals(orderItem02.getCouponPrice(), 30); | ||
| 103 | + assertEquals(orderItem02.getPointPrice(), 0); | ||
| 104 | + assertEquals(orderItem02.getPayPrice(), 120); | ||
| 105 | + // 断言:SKU 3 | ||
| 106 | + TradePriceCalculateRespBO.OrderItem orderItem03 = result.getItems().get(2); | ||
| 107 | + assertEquals(orderItem03.getSkuId(), 30L); | ||
| 108 | + assertEquals(orderItem03.getCount(), 4); | ||
| 109 | + assertEquals(orderItem03.getPrice(), 30); | ||
| 110 | + assertEquals(orderItem03.getDiscountPrice(), 0); | ||
| 111 | + assertEquals(orderItem03.getCouponPrice(), 0); | ||
| 112 | + assertEquals(orderItem03.getPointPrice(), 0); | ||
| 113 | + assertEquals(orderItem03.getPayPrice(), 120); | ||
| 114 | + // 断言:SKU 4 | ||
| 115 | + TradePriceCalculateRespBO.OrderItem orderItem04 = result.getItems().get(3); | ||
| 116 | + assertEquals(orderItem04.getSkuId(), 40L); | ||
| 117 | + assertEquals(orderItem04.getCount(), 5); | ||
| 118 | + assertEquals(orderItem04.getPrice(), 60); | ||
| 119 | + assertEquals(orderItem04.getDiscountPrice(), 0); | ||
| 120 | + assertEquals(orderItem04.getCouponPrice(), 0); | ||
| 121 | + assertEquals(orderItem04.getPointPrice(), 0); | ||
| 122 | + assertEquals(orderItem04.getPayPrice(), 300); | ||
| 123 | + // 断言 Promotion 部分 | ||
| 124 | + assertEquals(result.getPromotions().size(), 1); | ||
| 125 | + TradePriceCalculateRespBO.Promotion promotion01 = result.getPromotions().get(0); | ||
| 126 | + assertEquals(promotion01.getId(), 1024L); | ||
| 127 | + assertEquals(promotion01.getName(), "程序员节"); | ||
| 128 | + assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); | ||
| 129 | + assertEquals(promotion01.getTotalPrice(), 350); | ||
| 130 | + assertEquals(promotion01.getDiscountPrice(), 70); | ||
| 131 | + assertTrue(promotion01.getMatch()); | ||
| 132 | + assertEquals(promotion01.getDescription(), "优惠劵:省 0.70 元"); | ||
| 133 | + assertEquals(promotion01.getItems().size(), 2); | ||
| 134 | + TradePriceCalculateRespBO.PromotionItem promotionItem011 = promotion01.getItems().get(0); | ||
| 135 | + assertEquals(promotionItem011.getSkuId(), 10L); | ||
| 136 | + assertEquals(promotionItem011.getTotalPrice(), 200); | ||
| 137 | + assertEquals(promotionItem011.getDiscountPrice(), 40); | ||
| 138 | + TradePriceCalculateRespBO.PromotionItem promotionItem012 = promotion01.getItems().get(1); | ||
| 139 | + assertEquals(promotionItem012.getSkuId(), 20L); | ||
| 140 | + assertEquals(promotionItem012.getTotalPrice(), 150); | ||
| 141 | + assertEquals(promotionItem012.getDiscountPrice(), 30); | ||
| 142 | + } | ||
| 143 | +} |