Files
junhong_cmp_fiber/tests/hurl/flows/package-resource-full-flow.hurl
huang 2ef8b8a705
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
fix: 修复分页字段/角色DTO/套餐详情/批量分配Bug,新增C端测试登录接口和Hurl价格验证测试
- 修复B-2:27个分页DTO字段名统一(list→items, page_size→size,删除total_pages)
- 修复B-1:角色接口统一返回DTO(id小写,消除GORM大写字段名)
- 修复C-1:套餐详情接口(GET /packages/:id)补充代理佣金字段
- 修复C-2:批量分配已存在记录由500改为静默跳过
- 修复C-3:创建系列授权响应在事务提交后构建,packages数组不再为空
- 新增C端开发测试登录接口(POST /api/c/v1/auth/dev-login,仅logging.development=true时生效)
- 新增Hurl测试:card-price-verification-flow.hurl(导入卡→分配→C端价格验证)
- 新增测试Excel数据文件和dev.env测试变量
2026-03-31 09:54:08 +08:00

734 lines
28 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================
# 测试:套餐资源完整流程(创建→分配→佣金→调价→强充)
# 生成时间2026-03-30
# 涉及模块auth, role, package_series, package, shop,
# shop_series_grant, batch_allocation, batch_pricing
# 涉及接口25+ 个
# 前置条件:服务运行 + 数据库已迁移 + Redis 可用
# ============================================================
# 流程:
# 1. 平台管理员登录
# 2. 创建客户角色(创建店铺的前置依赖)
# 3. 创建套餐系列(含固定一次性佣金 + 强充配置)
# 4. 创建套餐 → 启用 → 上架
# 5. 创建一级代理店铺(自动创建初始账号)
# 6. 平台→一级代理:创建系列授权 + 管理授权套餐
# 7. 创建二级代理店铺(挂在一级代理下)
# 8. 一级代理登录 → 给二级代理分配系列授权
# 9. 各级代理修改零售价 → 验证价格隔离
# 10. 平台:批量分配 + 批量调价
# 11. 代理佣金概览验证
# 12. 强充配置验证
# 13. 异常测试(未认证、参数校验、越权)
# ============================================================
# ══════════════════════════════════════════════════════════════
# 第 1 步:平台管理员登录
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/auth/login
Content-Type: application/json
{
"username": "{{admin_username}}",
"password": "{{admin_password}}",
"device": "web"
}
HTTP 200
[Captures]
admin_token: jsonpath "$.data.access_token"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.msg" == "success"
jsonpath "$.timestamp" isString
jsonpath "$.data.access_token" isString
jsonpath "$.data.refresh_token" isString
jsonpath "$.data.expires_in" isInteger
jsonpath "$.data.user.id" isInteger
jsonpath "$.data.user.username" isString
jsonpath "$.data.user.user_type" == 1
# ══════════════════════════════════════════════════════════════
# 第 2 步:创建客户角色(创建店铺需要 default_role_id
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/admin/roles
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"role_name": "hurl测试角色-{{newUuid}}",
"role_desc": "hurl 自动化测试用客户角色",
"role_type": 2
}
HTTP 200
[Captures]
test_role_id: jsonpath "$.data.id"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.id" isInteger
jsonpath "$.data.role_type" == 2
jsonpath "$.data.status" == 1
# ══════════════════════════════════════════════════════════════
# 第 3 步:创建套餐系列(固定一次性佣金 + 强充配置)
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/admin/package-series
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"series_code": "HURL-SERIES-{{newUuid}}",
"series_name": "Hurl测试系列",
"description": "自动化测试用套餐系列",
"enable_one_time_commission": true,
"one_time_commission_config": {
"enable": true,
"trigger_type": "first_recharge",
"threshold": 0,
"commission_type": "fixed",
"commission_amount": 5000,
"tiers": [],
"validity_type": "permanent",
"validity_value": "",
"enable_force_recharge": true,
"force_calc_type": "fixed",
"force_amount": 5000
}
}
HTTP 200
[Captures]
series_id: jsonpath "$.data.id"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.id" isInteger
jsonpath "$.data.series_code" isString
jsonpath "$.data.series_name" == "Hurl测试系列"
jsonpath "$.data.description" == "自动化测试用套餐系列"
jsonpath "$.data.enable_one_time_commission" == true
jsonpath "$.data.one_time_commission_config" isObject
jsonpath "$.data.one_time_commission_config.enable" == true
jsonpath "$.data.one_time_commission_config.commission_type" == "fixed"
jsonpath "$.data.one_time_commission_config.commission_amount" == 5000
jsonpath "$.data.one_time_commission_config.enable_force_recharge" == true
jsonpath "$.data.one_time_commission_config.force_calc_type" == "fixed"
jsonpath "$.data.one_time_commission_config.force_amount" == 5000
jsonpath "$.data.status" == 1
jsonpath "$.data.created_at" isString
jsonpath "$.data.updated_at" isString
# ══════════════════════════════════════════════════════════════
# 第 4a 步:创建套餐(关联到系列)
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/admin/packages
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"package_code": "HURL-PKG-{{newUuid}}",
"package_name": "Hurl测试套餐-月包30G",
"series_id": {{series_id}},
"package_type": "formal",
"duration_months": 12,
"real_data_mb": 30720,
"virtual_data_mb": 0,
"enable_virtual_data": false,
"suggested_retail_price": 15000,
"cost_price": 8000,
"calendar_type": "natural_month",
"data_reset_cycle": "monthly",
"expiry_base": "from_activation"
}
HTTP 200
[Captures]
package_id: jsonpath "$.data.id"
package_code: jsonpath "$.data.package_code"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.id" isInteger
jsonpath "$.data.package_code" isString
jsonpath "$.data.package_name" == "Hurl测试套餐-月包30G"
jsonpath "$.data.series_id" == {{series_id}}
jsonpath "$.data.package_type" == "formal"
jsonpath "$.data.duration_months" == 12
jsonpath "$.data.real_data_mb" == 30720
jsonpath "$.data.virtual_data_mb" == 0
jsonpath "$.data.enable_virtual_data" == false
jsonpath "$.data.suggested_retail_price" == 15000
jsonpath "$.data.cost_price" == 8000
jsonpath "$.data.calendar_type" == "natural_month"
jsonpath "$.data.data_reset_cycle" == "monthly"
jsonpath "$.data.expiry_base" == "from_activation"
jsonpath "$.data.status" isInteger
jsonpath "$.data.shelf_status" isInteger
jsonpath "$.data.created_at" isString
jsonpath "$.data.updated_at" isString
# ── 第 4b 步:启用套餐 ──
PATCH {{base_url}}/api/admin/packages/{{package_id}}/status
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"status": 1
}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
# ── 第 4c 步:上架套餐 ──
PATCH {{base_url}}/api/admin/packages/{{package_id}}/shelf
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"shelf_status": 1
}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
# ── 第 4d 步:验证套餐详情(启用+上架后) ──
GET {{base_url}}/api/admin/packages/{{package_id}}
Authorization: Bearer {{admin_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.id" == {{package_id}}
jsonpath "$.data.status" == 1
jsonpath "$.data.shelf_status" == 1
# ══════════════════════════════════════════════════════════════
# 第 5 步:创建一级代理店铺(自动创建初始账号)
# 幂等处理:如果已存在则跳过创建,通过账号查询获取 shop_id
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/admin/shops
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"shop_name": "Hurl一级代理店铺",
"shop_code": "HURL-SHOP1-{{newUuid}}",
"contact_name": "测试联系人1",
"contact_phone": "13800000001",
"province": "湖南省",
"city": "长沙市",
"district": "岳麓区",
"address": "测试地址一级",
"default_role_id": {{test_role_id}},
"init_password": "{{agent1_password}}",
"init_username": "{{agent1_username}}",
"init_phone": "{{agent1_phone}}"
}
HTTP *
# 通过账号查询获取 shop_id无论创建成功或已存在
GET {{base_url}}/api/admin/accounts?username={{agent1_username}}&page=1&page_size=1
Authorization: Bearer {{admin_token}}
HTTP 200
[Captures]
shop1_id: jsonpath "$.data.items[0].shop_id"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.items" count >= 1
jsonpath "$.data.items[0].username" == "{{agent1_username}}"
jsonpath "$.data.items[0].user_type" == 3
# ══════════════════════════════════════════════════════════════
# 第 6a 步:平台→一级代理 创建系列授权(设置固定佣金 + 强充)
# 幂等处理:如已存在则跳过,通过列表查询获取 grant_id
# ══════════════════════════════════════════════════════════════
# [FINDING C-3] 创建授权接口:请求传了 packages 但创建响应不含 packages 数组
# 需通过 GET 详情才能看到 packages这里用 HTTP * 兼容幂等(重跑时可能 409
POST {{base_url}}/api/admin/shop-series-grants
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"shop_id": {{shop1_id}},
"series_id": {{series_id}},
"one_time_commission_amount": 3000,
"enable_force_recharge": true,
"force_recharge_amount": 5000,
"packages": [
{
"package_id": {{package_id}},
"cost_price": 10000
}
]
}
HTTP *
# 查询获取 grant_id无论创建成功或已存在
GET {{base_url}}/api/admin/shop-series-grants?shop_id={{shop1_id}}&series_id={{series_id}}&page=1&page_size=1
Authorization: Bearer {{admin_token}}
HTTP 200
[Captures]
grant1_id: jsonpath "$.data.items[0].id"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.items" count >= 1
jsonpath "$.data.items[0].shop_id" == {{shop1_id}}
# ── 第 6b 步:验证一级代理授权详情 ──
GET {{base_url}}/api/admin/shop-series-grants/{{grant1_id}}
Authorization: Bearer {{admin_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.id" == {{grant1_id}}
jsonpath "$.data.shop_id" == {{shop1_id}}
jsonpath "$.data.shop_name" == "Hurl一级代理店铺"
jsonpath "$.data.series_id" == {{series_id}}
jsonpath "$.data.series_name" == "Hurl测试系列"
jsonpath "$.data.series_code" isString
jsonpath "$.data.commission_type" == "fixed"
jsonpath "$.data.one_time_commission_amount" == 3000
jsonpath "$.data.commission_tiers" isList
jsonpath "$.data.force_recharge_locked" isBoolean
jsonpath "$.data.force_recharge_enabled" == true
jsonpath "$.data.force_recharge_amount" == 5000
jsonpath "$.data.allocator_shop_id" == 0
jsonpath "$.data.allocator_shop_name" isString
jsonpath "$.data.status" == 1
jsonpath "$.data.packages" isList
jsonpath "$.data.packages" count >= 1
jsonpath "$.data.packages[0].package_id" == {{package_id}}
jsonpath "$.data.packages[0].package_name" == "Hurl测试套餐-月包30G"
jsonpath "$.data.packages[0].package_code" isString
jsonpath "$.data.packages[0].cost_price" == 10000
jsonpath "$.data.packages[0].shelf_status" isInteger
jsonpath "$.data.packages[0].status" isInteger
# ══════════════════════════════════════════════════════════════
# 第 7 步:创建二级代理店铺(挂在一级代理下)
# 幂等处理:如果已存在则跳过创建,通过账号查询获取 shop_id
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/admin/shops
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"shop_name": "Hurl二级代理店铺",
"shop_code": "HURL-SHOP2-{{newUuid}}",
"parent_id": {{shop1_id}},
"contact_name": "测试联系人2",
"contact_phone": "13800000002",
"province": "湖南省",
"city": "长沙市",
"district": "天心区",
"address": "测试地址二级",
"default_role_id": {{test_role_id}},
"init_password": "{{agent2_password}}",
"init_username": "{{agent2_username}}",
"init_phone": "{{agent2_phone}}"
}
HTTP *
# 通过账号查询获取 shop_id无论创建成功或已存在
GET {{base_url}}/api/admin/accounts?username={{agent2_username}}&page=1&page_size=1
Authorization: Bearer {{admin_token}}
HTTP 200
[Captures]
shop2_id: jsonpath "$.data.items[0].shop_id"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.items" count >= 1
jsonpath "$.data.items[0].username" == "{{agent2_username}}"
jsonpath "$.data.items[0].user_type" == 3
# ══════════════════════════════════════════════════════════════
# 第 8a 步:一级代理登录
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/auth/login
Content-Type: application/json
{
"username": "{{agent1_username}}",
"password": "{{agent1_password}}",
"device": "web"
}
HTTP 200
[Captures]
agent1_token: jsonpath "$.data.access_token"
agent1_shop_id: jsonpath "$.data.user.shop_id"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.access_token" isString
jsonpath "$.data.user.user_type" == 3
jsonpath "$.data.user.shop_id" == {{shop1_id}}
# ══════════════════════════════════════════════════════════════
# 第 8b 步:一级代理→二级代理 创建系列授权(佣金更低)
# 幂等处理:如已存在则跳过,通过列表查询获取 grant_id
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/admin/shop-series-grants
Authorization: Bearer {{agent1_token}}
Content-Type: application/json
{
"shop_id": {{shop2_id}},
"series_id": {{series_id}},
"one_time_commission_amount": 2000,
"enable_force_recharge": true,
"force_recharge_amount": 5000,
"packages": [
{
"package_id": {{package_id}},
"cost_price": 12000
}
]
}
HTTP *
# 查询获取 grant_id无论创建成功或已存在
GET {{base_url}}/api/admin/shop-series-grants?shop_id={{shop2_id}}&series_id={{series_id}}&page=1&page_size=1
Authorization: Bearer {{agent1_token}}
HTTP 200
[Captures]
grant2_id: jsonpath "$.data.items[0].id"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.items" count >= 1
# ══════════════════════════════════════════════════════════════
# 第 9a 步:一级代理修改零售价 → 15000 分150 元)
# ══════════════════════════════════════════════════════════════
PATCH {{base_url}}/api/admin/packages/{{package_id}}/retail-price
Authorization: Bearer {{agent1_token}}
Content-Type: application/json
{
"retail_price": 15000
}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
# ── 第 9b 步:一级代理查看套餐 → 验证零售价=15000 ──
# [FINDING C-1] 套餐详情接口应包含 one_time_commission_amountDTO 定义且列表接口有)
GET {{base_url}}/api/admin/packages/{{package_id}}
Authorization: Bearer {{agent1_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.id" == {{package_id}}
jsonpath "$.data.package_name" == "Hurl测试套餐-月包30G"
jsonpath "$.data.retail_price" == 15000
jsonpath "$.data.cost_price" == 10000
jsonpath "$.data.one_time_commission_amount" == 3000
jsonpath "$.data.profit_margin" exists
# ══════════════════════════════════════════════════════════════
# 第 10a 步:二级代理登录
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/auth/login
Content-Type: application/json
{
"username": "{{agent2_username}}",
"password": "{{agent2_password}}",
"device": "web"
}
HTTP 200
[Captures]
agent2_token: jsonpath "$.data.access_token"
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.access_token" isString
jsonpath "$.data.user.user_type" == 3
jsonpath "$.data.user.shop_id" == {{shop2_id}}
# ══════════════════════════════════════════════════════════════
# 第 10b 步:二级代理修改零售价 → 18000 分180 元)
# ══════════════════════════════════════════════════════════════
PATCH {{base_url}}/api/admin/packages/{{package_id}}/retail-price
Authorization: Bearer {{agent2_token}}
Content-Type: application/json
{
"retail_price": 18000
}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
# ── 第 10c 步:二级代理查看套餐 → 验证零售价=18000与一级不同 ──
# [FINDING C-1] 同上,详情接口应包含 one_time_commission_amount
GET {{base_url}}/api/admin/packages/{{package_id}}
Authorization: Bearer {{agent2_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.id" == {{package_id}}
# 关键断言:二级代理看到的零售价 != 一级代理18000 vs 15000
jsonpath "$.data.retail_price" == 18000
jsonpath "$.data.cost_price" == 12000
jsonpath "$.data.one_time_commission_amount" == 2000
jsonpath "$.data.profit_margin" exists
# ── 第 10d 步:回到一级代理视角,确认零售价未被二级覆盖 ──
GET {{base_url}}/api/admin/packages/{{package_id}}
Authorization: Bearer {{agent1_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
# 一级代理的零售价仍然是 15000与二级代理互不影响
jsonpath "$.data.retail_price" == 15000
jsonpath "$.data.cost_price" == 10000
# ══════════════════════════════════════════════════════════════
# 第 11 步:平台身份 - 批量调价(给一级代理加价 500 分)
# ══════════════════════════════════════════════════════════════
POST {{base_url}}/api/admin/shop-package-batch-pricing
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"shop_id": {{shop1_id}},
"series_id": {{series_id}},
"price_adjustment": {
"type": "fixed",
"value": 500
},
"change_reason": "Hurl测试批量调价"
}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.updated_count" isInteger
jsonpath "$.data.updated_count" >= 1
jsonpath "$.data.affected_ids" isList
# ── 验证调价后代理仍可正常查看套餐 ──
GET {{base_url}}/api/admin/packages/{{package_id}}
Authorization: Bearer {{agent1_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.id" == {{package_id}}
jsonpath "$.data.cost_price" isInteger
# ══════════════════════════════════════════════════════════════
# 第 12 步:平台身份 - 批量分配套餐
# ══════════════════════════════════════════════════════════════
# [FINDING C-2] 批量分配对已有授权的店铺返回 500应返回业务错误码
POST {{base_url}}/api/admin/shop-package-batch-allocations
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"shop_id": {{shop2_id}},
"series_id": {{series_id}},
"price_adjustment": {
"type": "percent",
"value": 100
},
"one_time_commission_amount": 1500
}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
# ══════════════════════════════════════════════════════════════
# 第 13 步:强充配置验证
# ══════════════════════════════════════════════════════════════
# 更新一级代理授权:调整佣金金额
# 注意force_recharge_locked=true 时强充金额由系列配置控制grant 级别无法修改
PUT {{base_url}}/api/admin/shop-series-grants/{{grant1_id}}
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"one_time_commission_amount": 3500,
"enable_force_recharge": true,
"force_recharge_amount": 6000
}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.one_time_commission_amount" == 3500
jsonpath "$.data.force_recharge_enabled" == true
# 强充金额因 locked=true 保持系列配置值 5000不会变为 6000
jsonpath "$.data.force_recharge_amount" == 5000
jsonpath "$.data.force_recharge_locked" == true
# 验证更新持久化成功
GET {{base_url}}/api/admin/shop-series-grants/{{grant1_id}}
Authorization: Bearer {{admin_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.one_time_commission_amount" == 3500
jsonpath "$.data.force_recharge_enabled" == true
jsonpath "$.data.force_recharge_amount" == 5000
jsonpath "$.data.force_recharge_locked" == true
# ══════════════════════════════════════════════════════════════
# 第 14 步:代理佣金概览验证(一级代理视角)
# ══════════════════════════════════════════════════════════════
GET {{base_url}}/api/admin/my/commission-summary
Authorization: Bearer {{agent1_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data" isObject
# ══════════════════════════════════════════════════════════════
# 第 15 步:验证授权套餐详情(有下级分配时不可修改成本价)
# ══════════════════════════════════════════════════════════════
GET {{base_url}}/api/admin/shop-series-grants/{{grant1_id}}
Authorization: Bearer {{admin_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.packages" isList
jsonpath "$.data.packages" count >= 1
jsonpath "$.data.packages[0].package_id" isInteger
jsonpath "$.data.packages[0].package_name" isString
jsonpath "$.data.packages[0].cost_price" isInteger
# ══════════════════════════════════════════════════════════════
# 第 16 步:系列授权列表查询
# ══════════════════════════════════════════════════════════════
GET {{base_url}}/api/admin/shop-series-grants?shop_id={{shop1_id}}
Authorization: Bearer {{admin_token}}
HTTP 200
[Asserts]
jsonpath "$.code" == 0
jsonpath "$.data.items" isList
jsonpath "$.data.total" isInteger
jsonpath "$.data.total" >= 1
jsonpath "$.data.page" isInteger
jsonpath "$.data.size" isInteger
jsonpath "$.data.items[0].id" isInteger
jsonpath "$.data.items[0].shop_id" == {{shop1_id}}
jsonpath "$.data.items[0].shop_name" isString
jsonpath "$.data.items[0].series_id" isInteger
jsonpath "$.data.items[0].series_name" isString
jsonpath "$.data.items[0].commission_type" isString
jsonpath "$.data.items[0].one_time_commission_amount" isInteger
jsonpath "$.data.items[0].force_recharge_enabled" isBoolean
jsonpath "$.data.items[0].force_recharge_locked" isBoolean
jsonpath "$.data.items[0].force_recharge_amount" isInteger
jsonpath "$.data.items[0].allocator_shop_id" isInteger
jsonpath "$.data.items[0].allocator_shop_name" isString
jsonpath "$.data.items[0].package_count" isInteger
jsonpath "$.data.items[0].status" isInteger
jsonpath "$.data.items[0].created_at" isString
# ══════════════════════════════════════════════════════════════
# 异 常 测 试
# ══════════════════════════════════════════════════════════════
# ── 异常 1未认证访问无 token ──
GET {{base_url}}/api/admin/packages
HTTP 401
[Asserts]
jsonpath "$.code" == 1002
# ── 异常 2参数校验失败缺少必填字段 ──
POST {{base_url}}/api/admin/packages
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"package_name": ""
}
HTTP 400
[Asserts]
jsonpath "$.code" == 1001
# ── 异常 3参数校验 - 创建套餐系列编码为空触发冲突 ──
POST {{base_url}}/api/admin/package-series
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"series_name": ""
}
HTTP 409
[Asserts]
jsonpath "$.code" isInteger
jsonpath "$.code" != 0
# [FINDING C-4] 创建授权不校验目标店铺是否存在shop_id=9999999 也能创建成功
# 预期应返回 404实际返回 200 + 创建了无效授权记录
POST {{base_url}}/api/admin/shop-series-grants
Authorization: Bearer {{admin_token}}
Content-Type: application/json
{
"shop_id": 9999999,
"series_id": {{series_id}},
"one_time_commission_amount": 1000
}
HTTP 404
[Asserts]
jsonpath "$.code" != 0
# ── 异常 5二级代理越权 - 尝试给一级代理的店铺分配 ──
# 一级代理已有该系列授权所以返回冲突409而非越权403
# 但实际上二级代理本就无权操作上级店铺,应优先返回 403
POST {{base_url}}/api/admin/shop-series-grants
Authorization: Bearer {{agent2_token}}
Content-Type: application/json
{
"shop_id": {{shop1_id}},
"series_id": {{series_id}},
"one_time_commission_amount": 1000
}
HTTP 409
[Asserts]
jsonpath "$.code" isInteger
jsonpath "$.code" != 0
# ── 异常 6过期/无效 Token ──
GET {{base_url}}/api/admin/packages
Authorization: Bearer invalid_token_12345
HTTP 401
[Asserts]
jsonpath "$.code" == 1003