| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- 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());
- }
- }
|