|
|
@@ -1,264 +0,0 @@
|
|
|
-package com.xuekairui.gateway;
|
|
|
-
|
|
|
-import com.fasterxml.jackson.databind.JsonNode;
|
|
|
-import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
-import org.junit.jupiter.api.*;
|
|
|
-import org.springframework.http.MediaType;
|
|
|
-import org.springframework.test.web.servlet.MvcResult;
|
|
|
-
|
|
|
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
|
|
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
|
|
-
|
|
|
-/**
|
|
|
- * 体验配额配置接口测试
|
|
|
- * 覆盖:用户端获取活跃配置、运营端CRUD管理、权限校验
|
|
|
- */
|
|
|
-@DisplayName("体验配额配置接口测试")
|
|
|
-@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
|
|
-class TrialQuotaConfigTest extends GatewayBaseTest {
|
|
|
-
|
|
|
- private static final ObjectMapper mapper = new ObjectMapper();
|
|
|
- /** 动态捕获的配置 ID,避免依赖 auto_increment 顺序 */
|
|
|
- private static Long createdConfigId;
|
|
|
- private static Long activityConfigId;
|
|
|
- private static Long deleteConfigId;
|
|
|
-
|
|
|
- private String adminToken() {
|
|
|
- return generateAccessToken(100L, "13900000000", "ADMIN");
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 用户端:获取活跃配置 ====================
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(1)
|
|
|
- @DisplayName("GET /api/trial-quota/active - 获取活跃体验配额配置(公开接口)")
|
|
|
- void getActiveConfig_shouldReturnConfig() throws Exception {
|
|
|
- mockMvc.perform(get("/api/trial-quota/active"))
|
|
|
- .andExpect(status().isOk())
|
|
|
- .andExpect(jsonPath("$.code").isNumber());
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 运营端:查询配置列表 ====================
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(10)
|
|
|
- @DisplayName("GET /api/admin/trial-quota/configs - 查询配置列表")
|
|
|
- void listConfigs_shouldReturnList() throws Exception {
|
|
|
- mockMvc.perform(get("/api/admin/trial-quota/configs")
|
|
|
- .header("Authorization", "Bearer " + adminToken()))
|
|
|
- .andExpect(status().isOk())
|
|
|
- .andExpect(jsonPath("$.code").value(200))
|
|
|
- .andExpect(jsonPath("$.data").isArray());
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(11)
|
|
|
- @DisplayName("GET /api/admin/trial-quota/configs - 无Token应返回401")
|
|
|
- void listConfigs_withoutToken_shouldReturn401() throws Exception {
|
|
|
- mockMvc.perform(get("/api/admin/trial-quota/configs"))
|
|
|
- .andExpect(status().isUnauthorized());
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 运营端:创建配置 ====================
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(20)
|
|
|
- @DisplayName("POST /api/admin/trial-quota/config - 创建体验配额配置")
|
|
|
- void createConfig_shouldSucceed() throws Exception {
|
|
|
- String body = """
|
|
|
- {
|
|
|
- "configName": "测试体验配置",
|
|
|
- "trialDays": 15,
|
|
|
- "dailyQueryLimit": 30,
|
|
|
- "monthlyWatchlistLimit": 200,
|
|
|
- "enabled": true,
|
|
|
- "configType": "DEFAULT",
|
|
|
- "applicableUserType": "NEW_USER",
|
|
|
- "priority": 1,
|
|
|
- "description": "自动化测试创建的配置"
|
|
|
- }
|
|
|
- """;
|
|
|
- MvcResult result = mockMvc.perform(post("/api/admin/trial-quota/config")
|
|
|
- .header("Authorization", "Bearer " + adminToken())
|
|
|
- .contentType(MediaType.APPLICATION_JSON)
|
|
|
- .content(body))
|
|
|
- .andExpect(status().isOk())
|
|
|
- .andExpect(jsonPath("$.code").value(200))
|
|
|
- .andExpect(jsonPath("$.data.id").isNumber())
|
|
|
- .andExpect(jsonPath("$.data.configName").value("测试体验配置"))
|
|
|
- .andExpect(jsonPath("$.data.trialDays").value(15))
|
|
|
- .andExpect(jsonPath("$.data.dailyQueryLimit").value(30))
|
|
|
- .andReturn();
|
|
|
- createdConfigId = mapper.readTree(result.getResponse().getContentAsString())
|
|
|
- .get("data").get("id").asLong();
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(21)
|
|
|
- @DisplayName("POST /api/admin/trial-quota/config - 创建活动类型配置")
|
|
|
- void createConfig_activityType_shouldSucceed() throws Exception {
|
|
|
- String body = """
|
|
|
- {
|
|
|
- "configName": "618活动体验配置",
|
|
|
- "trialDays": 30,
|
|
|
- "dailyQueryLimit": 50,
|
|
|
- "monthlyWatchlistLimit": 500,
|
|
|
- "enabled": true,
|
|
|
- "configType": "ACTIVITY",
|
|
|
- "applicableUserType": "ALL",
|
|
|
- "priority": 10,
|
|
|
- "maxUsers": 1000,
|
|
|
- "description": "618活动专属体验配置"
|
|
|
- }
|
|
|
- """;
|
|
|
- MvcResult result = mockMvc.perform(post("/api/admin/trial-quota/config")
|
|
|
- .header("Authorization", "Bearer " + adminToken())
|
|
|
- .contentType(MediaType.APPLICATION_JSON)
|
|
|
- .content(body))
|
|
|
- .andExpect(status().isOk())
|
|
|
- .andExpect(jsonPath("$.code").value(200))
|
|
|
- .andExpect(jsonPath("$.data.configName").value("618活动体验配置"))
|
|
|
- .andExpect(jsonPath("$.data.configType").value("ACTIVITY"))
|
|
|
- .andExpect(jsonPath("$.data.maxUsers").value(1000))
|
|
|
- .andReturn();
|
|
|
- activityConfigId = mapper.readTree(result.getResponse().getContentAsString())
|
|
|
- .get("data").get("id").asLong();
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(22)
|
|
|
- @DisplayName("POST /api/admin/trial-quota/config - 无Token应返回401")
|
|
|
- void createConfig_withoutToken_shouldReturn401() throws Exception {
|
|
|
- mockMvc.perform(post("/api/admin/trial-quota/config")
|
|
|
- .contentType(MediaType.APPLICATION_JSON)
|
|
|
- .content("{}"))
|
|
|
- .andExpect(status().isUnauthorized());
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 运营端:更新配置 ====================
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(30)
|
|
|
- @DisplayName("PUT /api/admin/trial-quota/config/{id} - 更新配置")
|
|
|
- void updateConfig_shouldSucceed() throws Exception {
|
|
|
- String body = """
|
|
|
- {
|
|
|
- "configName": "测试体验配置(已更新)",
|
|
|
- "trialDays": 20,
|
|
|
- "dailyQueryLimit": 40,
|
|
|
- "monthlyWatchlistLimit": 300,
|
|
|
- "enabled": true,
|
|
|
- "configType": "DEFAULT",
|
|
|
- "applicableUserType": "NEW_USER",
|
|
|
- "priority": 2,
|
|
|
- "description": "更新后的配置"
|
|
|
- }
|
|
|
- """;
|
|
|
- mockMvc.perform(put("/api/admin/trial-quota/config/" + createdConfigId)
|
|
|
- .header("Authorization", "Bearer " + adminToken())
|
|
|
- .contentType(MediaType.APPLICATION_JSON)
|
|
|
- .content(body))
|
|
|
- .andExpect(status().isOk())
|
|
|
- .andExpect(jsonPath("$.code").value(200))
|
|
|
- .andExpect(jsonPath("$.data.configName").value("测试体验配置(已更新)"))
|
|
|
- .andExpect(jsonPath("$.data.trialDays").value(20));
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(31)
|
|
|
- @DisplayName("PUT /api/admin/trial-quota/config/{id} - 更新不存在的配置应返回404")
|
|
|
- void updateConfig_nonExistent_shouldReturn404() throws Exception {
|
|
|
- String body = """
|
|
|
- {
|
|
|
- "configName": "不存在的配置",
|
|
|
- "trialDays": 15,
|
|
|
- "dailyQueryLimit": 20,
|
|
|
- "monthlyWatchlistLimit": 100,
|
|
|
- "enabled": true,
|
|
|
- "configType": "DEFAULT",
|
|
|
- "applicableUserType": "NEW_USER"
|
|
|
- }
|
|
|
- """;
|
|
|
- mockMvc.perform(put("/api/admin/trial-quota/config/9999")
|
|
|
- .header("Authorization", "Bearer " + adminToken())
|
|
|
- .contentType(MediaType.APPLICATION_JSON)
|
|
|
- .content(body))
|
|
|
- .andExpect(status().isOk())
|
|
|
- .andExpect(jsonPath("$.code").value(404));
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(32)
|
|
|
- @DisplayName("PUT /api/admin/trial-quota/config/{id} - 无Token应返回401")
|
|
|
- void updateConfig_withoutToken_shouldReturn401() throws Exception {
|
|
|
- mockMvc.perform(put("/api/admin/trial-quota/config/" + createdConfigId)
|
|
|
- .contentType(MediaType.APPLICATION_JSON)
|
|
|
- .content("{}"))
|
|
|
- .andExpect(status().isUnauthorized());
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 运营端:删除配置 ====================
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(40)
|
|
|
- @DisplayName("DELETE /api/admin/trial-quota/config/{id} - 删除配置")
|
|
|
- void deleteConfig_shouldSucceed() throws Exception {
|
|
|
- // 先创建一个新配置用来删除
|
|
|
- String createBody = """
|
|
|
- {
|
|
|
- "configName": "待删除配置",
|
|
|
- "trialDays": 7,
|
|
|
- "dailyQueryLimit": 10,
|
|
|
- "monthlyWatchlistLimit": 50,
|
|
|
- "enabled": true,
|
|
|
- "configType": "COUPON",
|
|
|
- "applicableUserType": "NEW_USER",
|
|
|
- "priority": 99,
|
|
|
- "description": "此配置将被删除"
|
|
|
- }
|
|
|
- """;
|
|
|
- MvcResult createResult = mockMvc.perform(post("/api/admin/trial-quota/config")
|
|
|
- .header("Authorization", "Bearer " + adminToken())
|
|
|
- .contentType(MediaType.APPLICATION_JSON)
|
|
|
- .content(createBody))
|
|
|
- .andExpect(status().isOk())
|
|
|
- .andExpect(jsonPath("$.data.id").isNumber())
|
|
|
- .andReturn();
|
|
|
- deleteConfigId = mapper.readTree(createResult.getResponse().getContentAsString())
|
|
|
- .get("data").get("id").asLong();
|
|
|
-
|
|
|
- // 删除该配置
|
|
|
- mockMvc.perform(delete("/api/admin/trial-quota/config/" + deleteConfigId)
|
|
|
- .header("Authorization", "Bearer " + adminToken()))
|
|
|
- .andExpect(status().isOk())
|
|
|
- .andExpect(jsonPath("$.code").value(200));
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(41)
|
|
|
- @DisplayName("DELETE /api/admin/trial-quota/config/{id} - 删除不存在的配置应返回404")
|
|
|
- void deleteConfig_nonExistent_shouldReturn404() throws Exception {
|
|
|
- mockMvc.perform(delete("/api/admin/trial-quota/config/9999")
|
|
|
- .header("Authorization", "Bearer " + adminToken()))
|
|
|
- .andExpect(status().isOk())
|
|
|
- .andExpect(jsonPath("$.code").value(404));
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(42)
|
|
|
- @DisplayName("DELETE /api/admin/trial-quota/config/{id} - 无Token应返回401")
|
|
|
- void deleteConfig_withoutToken_shouldReturn401() throws Exception {
|
|
|
- mockMvc.perform(delete("/api/admin/trial-quota/config/" + createdConfigId))
|
|
|
- .andExpect(status().isUnauthorized());
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 边界场景 ====================
|
|
|
-
|
|
|
- @Test
|
|
|
- @Order(50)
|
|
|
- @DisplayName("GET /api/trial-quota/active - 无Token也可访问(公开接口)")
|
|
|
- void getActiveConfig_noAuth_shouldBeAccessible() throws Exception {
|
|
|
- mockMvc.perform(get("/api/trial-quota/active"))
|
|
|
- .andExpect(status().isOk());
|
|
|
- }
|
|
|
-}
|