test: add wechat integration test suite
Some checks failed
Build and Push Backend / docker (push) Has been cancelled
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
This commit is contained in:
@@ -102,7 +102,7 @@ class WxCouponControllerApiTest extends AbstractApiTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void obtainCouponRejectsNonWhitelistCustomer() throws Exception {
|
||||
void obtainCouponReturnsNonEligibilityReasonWhenNonWhitelisted__covers_CP_002() throws Exception {
|
||||
ensureTenantContext();
|
||||
String couponId = newCouponId("whitelist");
|
||||
PlayCouponInfoEntity coupon = createBaseCoupon(couponId);
|
||||
@@ -123,7 +123,7 @@ class WxCouponControllerApiTest extends AbstractApiTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void queryAllSkipsOfflineCouponsAndMarksObtainedOnes() throws Exception {
|
||||
void queryAllSkipsOfflineCouponsAndMarksObtainedOnes__covers_CP_004() throws Exception {
|
||||
ensureTenantContext();
|
||||
PlayCouponInfoEntity onlineCoupon = createBaseCoupon(newCouponId("online"));
|
||||
onlineCoupon.setCustomWhitelist(List.of(ApiTestDataSeeder.DEFAULT_CUSTOMER_ID));
|
||||
@@ -164,7 +164,7 @@ class WxCouponControllerApiTest extends AbstractApiTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void queryByOrderFlagsOnlyEligibleCouponsAsAvailable() throws Exception {
|
||||
void queryByOrderFlagsOnlyEligibleCouponsAsAvailable__covers_CP_006() throws Exception {
|
||||
ensureTenantContext();
|
||||
PlayCouponInfoEntity eligible = createBaseCoupon(newCouponId("eligible"));
|
||||
eligible.setUseMinAmount(MINIMUM_USAGE_AMOUNT);
|
||||
@@ -200,23 +200,30 @@ class WxCouponControllerApiTest extends AbstractApiTest {
|
||||
.andExpect(jsonPath("$.code").value(200))
|
||||
.andReturn();
|
||||
|
||||
ArrayNode data = (ArrayNode) mapper.readTree(result.getResponse().getContentAsString()).path("data");
|
||||
ArrayNode data = (ArrayNode) mapper.readTree(result.getResponse().getContentAsString(java.nio.charset.StandardCharsets.UTF_8))
|
||||
.path("data");
|
||||
assertThat(data).isNotNull();
|
||||
assertThat(data.size()).isGreaterThanOrEqualTo(2);
|
||||
boolean foundEligibleDetail = false;
|
||||
boolean foundIneligibleDetail = false;
|
||||
for (JsonNode node : data) {
|
||||
if (eligible.getId().equals(node.path("couponId").asText())) {
|
||||
if (eligibleDetail.getId().equals(node.path("id").asText())) {
|
||||
foundEligibleDetail = true;
|
||||
assertThat(node.path("available").asText()).isEqualTo("1");
|
||||
assertThat(node.path("reasonForUnavailableUse").asText("")).isEmpty();
|
||||
}
|
||||
if (ineligible.getId().equals(node.path("couponId").asText())) {
|
||||
if (ineligibleDetail.getId().equals(node.path("id").asText())) {
|
||||
foundIneligibleDetail = true;
|
||||
assertThat(node.path("available").asText()).isEqualTo("0");
|
||||
assertThat(node.path("reasonForUnavailableUse").asText()).isEqualTo("订单类型不符合");
|
||||
}
|
||||
}
|
||||
assertThat(foundEligibleDetail).isTrue();
|
||||
assertThat(foundIneligibleDetail).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void obtainCouponSucceedsWhenEligible() throws Exception {
|
||||
void obtainCouponSucceedsWhenEligible__covers_CP_003() throws Exception {
|
||||
ensureTenantContext();
|
||||
PlayCouponInfoEntity coupon = createBaseCoupon(newCouponId("success"));
|
||||
couponInfoService.save(coupon);
|
||||
@@ -244,7 +251,7 @@ class WxCouponControllerApiTest extends AbstractApiTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void obtainCouponHonorsPerUserLimit() throws Exception {
|
||||
void obtainCouponHonorsPerUserLimit__covers_CP_002() throws Exception {
|
||||
ensureTenantContext();
|
||||
PlayCouponInfoEntity coupon = createBaseCoupon(newCouponId("limit"));
|
||||
coupon.setClerkObtainedMaxQuantity(1);
|
||||
@@ -279,6 +286,121 @@ class WxCouponControllerApiTest extends AbstractApiTest {
|
||||
.andExpect(jsonPath("$.data.msg").value("优惠券已达到领取上限"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void obtainCouponRejectsEmptyId__covers_CP_001() throws Exception {
|
||||
ensureTenantContext();
|
||||
|
||||
mockMvc.perform(get("/wx/coupon/custom/obtainCoupon")
|
||||
.param("id", "")
|
||||
.header(USER_HEADER, DEFAULT_USER)
|
||||
.header(TENANT_HEADER, DEFAULT_TENANT)
|
||||
.header(Constants.CUSTOM_USER_LOGIN_TOKEN, Constants.TOKEN_PREFIX + customerToken))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(500))
|
||||
.andExpect(jsonPath("$.message").value("请求参数异常,优惠券ID不能为"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void queryAllHidesWhitelistCouponFromNonWhitelistCustomer__covers_CP_004() throws Exception {
|
||||
ensureTenantContext();
|
||||
|
||||
String couponId = newCouponId("qall-wl");
|
||||
PlayCouponInfoEntity coupon = createBaseCoupon(couponId);
|
||||
coupon.setClaimConditionType(CouponClaimConditionType.WHITELIST.code());
|
||||
coupon.setCustomWhitelist(List.of("other-customer"));
|
||||
couponInfoService.save(coupon);
|
||||
couponIds.add(coupon.getId());
|
||||
|
||||
MvcResult result = mockMvc.perform(post("/wx/coupon/custom/queryAll")
|
||||
.header(USER_HEADER, DEFAULT_USER)
|
||||
.header(TENANT_HEADER, DEFAULT_TENANT)
|
||||
.header(Constants.CUSTOM_USER_LOGIN_TOKEN, Constants.TOKEN_PREFIX + customerToken)
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(200))
|
||||
.andReturn();
|
||||
|
||||
JsonNode data = mapper.readTree(result.getResponse().getContentAsString(java.nio.charset.StandardCharsets.UTF_8))
|
||||
.path("data");
|
||||
assertThat(data).isNotNull();
|
||||
assertThat(data.isArray()).isTrue();
|
||||
for (JsonNode node : data) {
|
||||
assertThat(node.path("id").asText()).isNotEqualTo(coupon.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void queryByOrderRejectsWhenClerkIdAndLevelIdBothEmpty__covers_CP_005() throws Exception {
|
||||
ensureTenantContext();
|
||||
|
||||
ObjectNode payload = mapper.createObjectNode();
|
||||
payload.put("commodityId", ApiTestDataSeeder.DEFAULT_COMMODITY_ID);
|
||||
payload.put("levelId", "");
|
||||
payload.put("clerkId", "");
|
||||
payload.put("placeType", OrderConstant.PlaceType.RANDOM.getCode());
|
||||
payload.put("commodityQuantity", 1);
|
||||
|
||||
mockMvc.perform(post("/wx/coupon/custom/queryByOrder")
|
||||
.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.toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(500))
|
||||
.andExpect(jsonPath("$.message").value("请求参数异常,店员ID不能为空,等级ID不能为空"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void queryByOrderSwallowsBrokenCouponAndReturnsRemaining__covers_CP_007() throws Exception {
|
||||
ensureTenantContext();
|
||||
PlayCouponInfoEntity eligible = createBaseCoupon(newCouponId("swv"));
|
||||
eligible.setUseMinAmount(BigDecimal.ZERO);
|
||||
couponInfoService.save(eligible);
|
||||
couponIds.add(eligible.getId());
|
||||
|
||||
PlayCouponDetailsEntity eligibleDetail = createCouponDetail(eligible.getId(), CouponUseState.UNUSED);
|
||||
couponDetailsService.save(eligibleDetail);
|
||||
couponDetailIds.add(eligibleDetail.getId());
|
||||
|
||||
PlayCouponDetailsEntity brokenDetail = createCouponDetail(newCouponId("missing"), CouponUseState.UNUSED);
|
||||
couponDetailsService.save(brokenDetail);
|
||||
couponDetailIds.add(brokenDetail.getId());
|
||||
|
||||
ObjectNode payload = mapper.createObjectNode();
|
||||
payload.put("commodityId", ApiTestDataSeeder.DEFAULT_COMMODITY_ID);
|
||||
payload.put("levelId", ApiTestDataSeeder.DEFAULT_CLERK_LEVEL_ID);
|
||||
payload.put("clerkId", "");
|
||||
payload.put("placeType", OrderConstant.PlaceType.RANDOM.getCode());
|
||||
payload.put("commodityQuantity", 1);
|
||||
|
||||
MvcResult result = mockMvc.perform(post("/wx/coupon/custom/queryByOrder")
|
||||
.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.toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(200))
|
||||
.andReturn();
|
||||
|
||||
JsonNode data = mapper.readTree(result.getResponse().getContentAsString()).path("data");
|
||||
assertThat(data.isArray()).isTrue();
|
||||
boolean foundEligibleDetail = false;
|
||||
boolean foundBrokenDetail = false;
|
||||
for (JsonNode node : data) {
|
||||
String returnedId = node.path("id").asText();
|
||||
if (eligibleDetail.getId().equals(returnedId)) {
|
||||
foundEligibleDetail = true;
|
||||
}
|
||||
if (brokenDetail.getId().equals(returnedId)) {
|
||||
foundBrokenDetail = true;
|
||||
}
|
||||
}
|
||||
assertThat(foundEligibleDetail).isTrue();
|
||||
assertThat(foundBrokenDetail).isFalse();
|
||||
}
|
||||
|
||||
private PlayCouponInfoEntity createBaseCoupon(String id) {
|
||||
PlayCouponInfoEntity coupon = new PlayCouponInfoEntity();
|
||||
coupon.setId(id);
|
||||
|
||||
Reference in New Issue
Block a user