shinnosuke
2026-08-06 e5c6b415449d0b7a5e9027dba009e46543004dc0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package com.talentcard.server.business.portal;
 
import static org.assertj.core.api.Assertions.assertThat;
 
import java.util.Map;
 
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
 
@SpringBootTest
@ActiveProfiles("test")
class AppOrderPortalServiceTests {
    @Autowired
    private JdbcTemplate jdbc;
 
    @Autowired
    private AppOrderPortalService appOrderPortalService;
 
    private Long talentId;
    private Long merchantId;
    private Long productId;
    private Long couponId;
 
    @BeforeEach
    void prepareData() {
        String suffix = String.valueOf(System.nanoTime());
        jdbc.update("insert into talent_user(openid, name, mobile, status, deleted) values (?, ?, ?, 1, 0)", "app-order-" + suffix, "App order user", "13900000000");
        talentId = jdbc.queryForObject("select max(id) from talent_user", Long.class);
        jdbc.update("insert into talent_card(talent_id, card_no, card_type, card_level, status, deleted) values (?, ?, 'PERSONAL', ?, 1, 0)", talentId, "TC-APP-" + suffix, "卓越人才卡");
        jdbc.update("insert into merchant(merchant_name, contact_mobile, address, status, deleted) values (?, ?, ?, 1, 0)", "App order merchant " + suffix, "08120000000", "Test address");
        merchantId = jdbc.queryForObject("select max(id) from merchant", Long.class);
        jdbc.update("""
                insert into merchant_product(product_no, merchant_id, product_type, product_name, original_price, sale_price,
                                             subsidy_amount, stock, audit_status, status, deleted)
                values (?, ?, 'food', 'Test package', 100.00, 60.00, 0.00, 10, 2, 1, 0)
                """, "APP-ORDER-PRODUCT-" + suffix, merchantId);
        productId = jdbc.queryForObject("select max(id) from merchant_product", Long.class);
        jdbc.update("""
                insert into merchant_coupon(merchant_id, coupon_name, condition_type, coupon_amount, product_scope, status, deleted)
                values (?, 'Test coupon', 'NONE', 10.00, 'ALL', 1, 0)
                """, merchantId);
        couponId = jdbc.queryForObject("select max(id) from merchant_coupon", Long.class);
    }
 
    @Test
    void createsPendingOrderFromServerSideProductAndCouponSnapshot() {
        Map<String, Object> created = appOrderPortalService.create(talentId, new AppOrderCreateRequest(merchantId, productId, couponId), "app-order-test-" + System.nanoTime());
 
        assertThat(created.get("orderNo")).asString().startsWith("P");
        assertThat(created).containsEntry("talentId", talentId).containsEntry("merchantId", merchantId).containsEntry("productId", productId);
        Map<String, Object> row = jdbc.queryForMap("""
                select order_amount as orderAmount, base_pay_amount as basePayAmount, coupon_amount as couponAmount,
                       pay_amount as payAmount, order_status as orderStatus, order_type as orderType,
                       product_name_snapshot as productNameSnapshot
                from benefit_order
                where order_no = ?
                """, created.get("orderNo"));
        assertThat(row).containsEntry("ORDERAMOUNT", 10000L)
                .containsEntry("BASEPAYAMOUNT", 6000L)
                .containsEntry("COUPONAMOUNT", 1000L)
                .containsEntry("PAYAMOUNT", 5000L)
                .containsEntry("ORDERSTATUS", 0)
                .containsEntry("ORDERTYPE", "GROUP_BUY");
        assertThat(row.get("PRODUCTNAMESNAPSHOT")).isEqualTo("Test package");
    }
 
    @Test
    void reusesOrderForSameIdempotencyKey() {
        String idempotencyKey = "app-order-repeat-" + System.nanoTime();
        Map<String, Object> first = appOrderPortalService.create(talentId, new AppOrderCreateRequest(merchantId, productId, null), idempotencyKey);
        Map<String, Object> second = appOrderPortalService.create(talentId, new AppOrderCreateRequest(merchantId, productId, null), idempotencyKey);
 
        assertThat(second.get("orderNo")).isEqualTo(first.get("orderNo"));
    }
 
    @Test
    void usesAvailableFreeCountBeforeChargingTheProductPrice() {
        jdbc.update("""
                update merchant_product
                set rights_config = ?
                where id = ?
                """, "[{\"level\":\"卓越人才卡\",\"enabled\":true,\"free\":true,\"limitCount\":1,\"exceedDiscount\":6,\"resetCycle\":\"每月\"}]", productId);
 
        Map<String, Object> freeOrder = appOrderPortalService.create(talentId, new AppOrderCreateRequest(merchantId, productId, null), "app-order-free-" + System.nanoTime());
        Long freePayAmount = jdbc.queryForObject("select pay_amount from benefit_order where order_no = ?", Long.class, freeOrder.get("orderNo"));
        assertThat(freePayAmount).isZero();
 
        Map<String, Object> paidOrder = appOrderPortalService.create(talentId, new AppOrderCreateRequest(merchantId, productId, null), "app-order-after-free-" + System.nanoTime());
        Long paidAmount = jdbc.queryForObject("select pay_amount from benefit_order where order_no = ?", Long.class, paidOrder.get("orderNo"));
        assertThat(paidAmount).isEqualTo(6000L);
    }
}