Some checks failed
Build and Push Backend / docker (push) Has been cancelled
- Add llm/wechat-subsystem-test-matrix.md and tests covering Wx controllers/services\n- Make ApiTestDataSeeder personnel group seeding idempotent for full-suite stability
161 lines
8.4 KiB
Java
161 lines
8.4 KiB
Java
package com.starry.admin.api;
|
|
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.starry.admin.common.apitest.ApiTestDataSeeder;
|
|
import com.starry.admin.modules.custom.module.entity.PlayCustomGiftInfoEntity;
|
|
import com.starry.admin.modules.custom.service.IPlayCustomGiftInfoService;
|
|
import com.starry.admin.modules.order.module.constant.OrderConstant;
|
|
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
|
|
import com.starry.admin.modules.shop.module.entity.PlayClerkGiftInfoEntity;
|
|
import com.starry.admin.modules.shop.module.entity.PlayGiftInfoEntity;
|
|
import com.starry.admin.modules.shop.service.IPlayClerkGiftInfoService;
|
|
import com.starry.admin.modules.shop.service.IPlayGiftInfoService;
|
|
import com.starry.admin.modules.withdraw.entity.EarningsLineEntity;
|
|
import com.starry.admin.utils.SecurityUtils;
|
|
import com.starry.common.constant.Constants;
|
|
import com.starry.common.context.CustomSecurityContextHolder;
|
|
import com.starry.common.utils.IdUtils;
|
|
import java.math.BigDecimal;
|
|
import org.assertj.core.api.Assertions;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.http.MediaType;
|
|
|
|
class WxCustomGiftOrderApiTest extends WxCustomOrderApiTestSupport {
|
|
|
|
@Autowired
|
|
private IPlayGiftInfoService playGiftInfoService;
|
|
|
|
@Autowired
|
|
private IPlayCustomGiftInfoService playCustomGiftInfoService;
|
|
|
|
@Autowired
|
|
private IPlayClerkGiftInfoService playClerkGiftInfoService;
|
|
|
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
@Test
|
|
void giftOrderFailsWhenBalanceInsufficient() throws Exception {
|
|
SecurityUtils.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID);
|
|
String remark = "API gift insufficient " + IdUtils.getUuid();
|
|
try {
|
|
setCustomerBalance(BigDecimal.ZERO);
|
|
String customerToken = wxTokenService.createWxUserToken(ApiTestDataSeeder.DEFAULT_CUSTOMER_ID);
|
|
customUserInfoService.updateTokenById(ApiTestDataSeeder.DEFAULT_CUSTOMER_ID, customerToken);
|
|
|
|
String payload = "{" +
|
|
"\"clerkId\":\"" + ApiTestDataSeeder.DEFAULT_CLERK_ID + "\"," +
|
|
"\"giftId\":\"" + ApiTestDataSeeder.DEFAULT_GIFT_ID + "\"," +
|
|
"\"giftQuantity\":1," +
|
|
"\"weiChatCode\":\"apitest-customer-wx\"," +
|
|
"\"remark\":\"" + remark + "\"" +
|
|
"}";
|
|
|
|
mockMvc.perform(post("/wx/custom/order/gift")
|
|
.header(USER_HEADER, DEFAULT_USER)
|
|
.header(TENANT_HEADER, DEFAULT_TENANT)
|
|
.header(Constants.CUSTOM_USER_LOGIN_TOKEN, Constants.TOKEN_PREFIX + customerToken)
|
|
.contentType(MediaType.APPLICATION_JSON)
|
|
.content(payload))
|
|
.andExpect(status().isOk())
|
|
.andExpect(jsonPath("$.code").value(998));
|
|
|
|
ensureTenantContext();
|
|
long count = playOrderInfoService.lambdaQuery()
|
|
.eq(PlayOrderInfoEntity::getPurchaserBy, ApiTestDataSeeder.DEFAULT_CUSTOMER_ID)
|
|
.eq(PlayOrderInfoEntity::getRemark, remark)
|
|
.count();
|
|
Assertions.assertThat(count).isZero();
|
|
} finally {
|
|
CustomSecurityContextHolder.remove();
|
|
}
|
|
}
|
|
|
|
@Test
|
|
// 测试用例:用户余额充足且携带有效登录态时,请求 /wx/custom/order/gift 下单指定礼物,
|
|
// 期望生成已完成的礼物奖励订单、产生对应收益记录,同时校验用户/陪玩师礼物计数与账户余额随订单金额同步更新。
|
|
void giftOrderCreatesCompletedRewardAndUpdatesGiftCounters__covers_CUS_005() throws Exception {
|
|
SecurityUtils.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID);
|
|
try {
|
|
resetCustomerBalance();
|
|
String customerToken = wxTokenService.createWxUserToken(ApiTestDataSeeder.DEFAULT_CUSTOMER_ID);
|
|
customUserInfoService.updateTokenById(ApiTestDataSeeder.DEFAULT_CUSTOMER_ID, customerToken);
|
|
|
|
PlayGiftInfoEntity gift = playGiftInfoService.selectPlayGiftInfoById(ApiTestDataSeeder.DEFAULT_GIFT_ID);
|
|
Assertions.assertThat(gift).as("seeded gift should exist").isNotNull();
|
|
|
|
int giftQuantity = 2;
|
|
String remark = "API gift order " + IdUtils.getUuid();
|
|
BigDecimal totalAmount = gift.getPrice().multiply(BigDecimal.valueOf(giftQuantity));
|
|
BigDecimal initialBalance = customUserInfoService.getById(ApiTestDataSeeder.DEFAULT_CUSTOMER_ID).getAccountBalance();
|
|
|
|
String payload = "{" +
|
|
"\"clerkId\":\"" + ApiTestDataSeeder.DEFAULT_CLERK_ID + "\"," +
|
|
"\"giftId\":\"" + ApiTestDataSeeder.DEFAULT_GIFT_ID + "\"," +
|
|
"\"giftQuantity\":" + giftQuantity + "," +
|
|
"\"weiChatCode\":\"apitest-customer-wx\"," +
|
|
"\"remark\":\"" + remark + "\"" +
|
|
"}";
|
|
|
|
String response = mockMvc.perform(post("/wx/custom/order/gift")
|
|
.header(USER_HEADER, DEFAULT_USER)
|
|
.header(TENANT_HEADER, DEFAULT_TENANT)
|
|
.header(Constants.CUSTOM_USER_LOGIN_TOKEN, Constants.TOKEN_PREFIX + customerToken)
|
|
.contentType(MediaType.APPLICATION_JSON)
|
|
.content(payload))
|
|
.andExpect(status().isOk())
|
|
.andExpect(jsonPath("$.code").value(200))
|
|
.andExpect(jsonPath("$.data").isNotEmpty())
|
|
.andReturn()
|
|
.getResponse()
|
|
.getContentAsString();
|
|
|
|
JsonNode root = objectMapper.readTree(response);
|
|
String orderId = root.path("data").asText();
|
|
|
|
ensureTenantContext();
|
|
PlayOrderInfoEntity order = playOrderInfoService.selectOrderInfoById(orderId);
|
|
Assertions.assertThat(order).isNotNull();
|
|
Assertions.assertThat(order.getRemark()).isEqualTo(remark);
|
|
Assertions.assertThat(order.getOrderStatus()).isEqualTo(OrderConstant.OrderStatus.COMPLETED.getCode());
|
|
Assertions.assertThat(order.getPlaceType()).isEqualTo(OrderConstant.PlaceType.REWARD.getCode());
|
|
Assertions.assertThat(order.getRewardType()).isEqualTo(OrderConstant.RewardType.GIFT.getCode());
|
|
Assertions.assertThat(order.getFinalAmount()).isEqualByComparingTo(totalAmount);
|
|
|
|
ensureTenantContext();
|
|
long earningsCount = earningsService.lambdaQuery()
|
|
.eq(EarningsLineEntity::getOrderId, orderId)
|
|
.count();
|
|
Assertions.assertThat(earningsCount).isEqualTo(1);
|
|
|
|
ensureTenantContext();
|
|
PlayCustomGiftInfoEntity customerGift = playCustomGiftInfoService.lambdaQuery()
|
|
.eq(PlayCustomGiftInfoEntity::getCustomId, ApiTestDataSeeder.DEFAULT_CUSTOMER_ID)
|
|
.eq(PlayCustomGiftInfoEntity::getGiffId, ApiTestDataSeeder.DEFAULT_GIFT_ID)
|
|
.one();
|
|
Assertions.assertThat(customerGift).isNotNull();
|
|
Assertions.assertThat(customerGift.getGiffNumber()).isEqualTo((long) giftQuantity);
|
|
|
|
ensureTenantContext();
|
|
PlayClerkGiftInfoEntity clerkGift = playClerkGiftInfoService.lambdaQuery()
|
|
.eq(PlayClerkGiftInfoEntity::getClerkId, ApiTestDataSeeder.DEFAULT_CLERK_ID)
|
|
.eq(PlayClerkGiftInfoEntity::getGiffId, ApiTestDataSeeder.DEFAULT_GIFT_ID)
|
|
.one();
|
|
Assertions.assertThat(clerkGift).isNotNull();
|
|
Assertions.assertThat(clerkGift.getGiffNumber()).isEqualTo((long) giftQuantity);
|
|
|
|
ensureTenantContext();
|
|
BigDecimal finalBalance = customUserInfoService.getById(ApiTestDataSeeder.DEFAULT_CUSTOMER_ID)
|
|
.getAccountBalance();
|
|
Assertions.assertThat(finalBalance).isEqualByComparingTo(initialBalance.subtract(totalAmount));
|
|
} finally {
|
|
CustomSecurityContextHolder.remove();
|
|
}
|
|
}
|
|
}
|