chore: 删除卡价格验证 hurl 测试文件
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m14s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m14s
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
SHELL := /bin/bash
|
||||
ENV ?= dev
|
||||
HURL_OPTS := --variables-file env/$(ENV).env --test
|
||||
HURL_OPTS := --variables-file env/$(ENV).env --file-root . --test
|
||||
|
||||
.PHONY: test test-flows test-modules test-negative report clean
|
||||
|
||||
|
||||
@@ -1,381 +0,0 @@
|
||||
# ============================================================
|
||||
# 测试:卡导入 → 分配 → C 端价格验证
|
||||
# 生成时间:2026-03-30
|
||||
# 涉及模块:auth, iot_card(import), shop, package_series, package,
|
||||
# shop_series_grant, shop_package_allocation, client_auth, client_asset
|
||||
# ============================================================
|
||||
# 流程:
|
||||
# 1. 平台管理员登录
|
||||
# 2. 查询运营商列表,获取 carrier_id
|
||||
# 3. 获取对象存储上传 URL(purpose=iot_import)
|
||||
# 4. 上传 Excel 文件(IoT 卡测试数据)到预签名 URL
|
||||
# 5. 提交卡导入任务
|
||||
# 6. 轮询导入任务直到完成(status=3)
|
||||
# 7. 获取一级代理店铺 ID(shop1_id)
|
||||
# 8. 获取二级代理店铺 ID(shop2_id)
|
||||
# 9. 获取套餐系列 ID(series_id)和套餐 ID(package_id)
|
||||
# 10. 分配 ICCID_1 给一级代理(shop1)
|
||||
# 11. 分配 ICCID_2 给二级代理(shop2)
|
||||
# 12. 绑定两张卡到套餐系列
|
||||
# 13. C 端测试登录(ICCID_1)
|
||||
# 14. 验证 ICCID_1 的可购套餐 → retail_price = 一级代理零售价(15000)
|
||||
# 15. C 端测试登录(ICCID_2)
|
||||
# 16. 验证 ICCID_2 的可购套餐 → retail_price = 二级代理零售价(18000)
|
||||
# ============================================================
|
||||
# 前置条件:
|
||||
# 1. 已运行 package-resource-full-flow.hurl(创建了 shop1/shop2/series/package)
|
||||
# 2. 开启 logging.development=true(服务配置)
|
||||
# 3. 已配置对象存储(S3/MinIO),步骤 3-4 依赖对象存储上传
|
||||
# 4. env 文件中已配置 agent1_username/agent2_username
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 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 "$.data.access_token" isString
|
||||
jsonpath "$.data.user.user_type" == 1
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 2 步:查询运营商列表,获取第一个可用 carrier_id
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
GET {{base_url}}/api/admin/carriers?page=1&page_size=1&status=1
|
||||
Authorization: Bearer {{admin_token}}
|
||||
HTTP 200
|
||||
[Captures]
|
||||
carrier_id: jsonpath "$.data.items[0].id"
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.items" count >= 1
|
||||
jsonpath "$.data.items[0].id" isInteger
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 3 步:获取对象存储上传 URL(IoT 卡导入 Excel)
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
POST {{base_url}}/api/admin/storage/upload-url
|
||||
Authorization: Bearer {{admin_token}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"file_name": "hurl-test-cards.xlsx",
|
||||
"content_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"purpose": "iot_import"
|
||||
}
|
||||
HTTP 200
|
||||
[Captures]
|
||||
upload_url: jsonpath "$.data.upload_url"
|
||||
file_key: jsonpath "$.data.file_key"
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.upload_url" isString
|
||||
jsonpath "$.data.file_key" isString
|
||||
jsonpath "$.data.expires_in" isInteger
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 4 步:上传 Excel 文件到预签名 URL
|
||||
# 文件路径相对于 Hurl 运行目录(tests/hurl/)
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
PUT {{upload_url}}
|
||||
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||
file,testdata/hurl-test-cards.xlsx;
|
||||
HTTP 200
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 5 步:提交 IoT 卡导入任务
|
||||
# 导入 Excel 包含 ICCID_1(HURL-TEST-CARD-001)和 ICCID_2(HURL-TEST-CARD-002)
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
POST {{base_url}}/api/admin/iot-cards/import
|
||||
Authorization: Bearer {{admin_token}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"carrier_id": {{carrier_id}},
|
||||
"batch_no": "HURL-PRICE-TEST",
|
||||
"file_key": "{{file_key}}"
|
||||
}
|
||||
HTTP 200
|
||||
[Captures]
|
||||
import_task_id: jsonpath "$.data.task_id"
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.task_id" isInteger
|
||||
jsonpath "$.data.task_no" isString
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 6 步:轮询导入任务,等待完成(status=3 表示已完成)
|
||||
# 注:Hurl 不支持循环轮询,这里做 3 次间隔查询覆盖大多数场景
|
||||
# 如需更长等待,可手动重跑此步骤
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
# 第 1 次查询(立即)
|
||||
GET {{base_url}}/api/admin/iot-cards/import-tasks/{{import_task_id}}
|
||||
Authorization: Bearer {{admin_token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.id" == {{import_task_id}}
|
||||
jsonpath "$.data.status" isInteger
|
||||
|
||||
# 等待 2 秒后第 2 次查询(Hurl 通过 delay 选项实现)
|
||||
GET {{base_url}}/api/admin/iot-cards/import-tasks/{{import_task_id}}
|
||||
Authorization: Bearer {{admin_token}}
|
||||
[Options]
|
||||
delay: 2000
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
|
||||
# 等待 2 秒后第 3 次查询,断言任务成功完成
|
||||
GET {{base_url}}/api/admin/iot-cards/import-tasks/{{import_task_id}}
|
||||
Authorization: Bearer {{admin_token}}
|
||||
[Options]
|
||||
delay: 2000
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.status" == 3
|
||||
jsonpath "$.data.success_count" >= 1
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 7 步:获取一级代理店铺 ID(shop1_id)
|
||||
# 依赖 package-resource-full-flow.hurl 已创建 agent1_username 账号
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
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
|
||||
jsonpath "$.data.items[0].shop_id" isInteger
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 8 步:获取二级代理店铺 ID(shop2_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
|
||||
jsonpath "$.data.items[0].shop_id" isInteger
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 9 步:获取套餐系列 ID 和套餐 ID
|
||||
# 依赖 package-resource-full-flow.hurl 创建的 "Hurl测试系列"
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
# 获取套餐系列(按名称模糊匹配,取最新创建的)
|
||||
GET {{base_url}}/api/admin/package-series?series_name=Hurl%E6%B5%8B%E8%AF%95%E7%B3%BB%E5%88%97&page=1&page_size=1
|
||||
Authorization: Bearer {{admin_token}}
|
||||
HTTP 200
|
||||
[Captures]
|
||||
series_id: jsonpath "$.data.items[0].id"
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.items" count >= 1
|
||||
jsonpath "$.data.items[0].series_name" == "Hurl测试系列"
|
||||
|
||||
# 获取该系列下的套餐(取最新的)
|
||||
GET {{base_url}}/api/admin/packages?series_id={{series_id}}&page=1&page_size=1
|
||||
Authorization: Bearer {{admin_token}}
|
||||
HTTP 200
|
||||
[Captures]
|
||||
package_id: jsonpath "$.data.items[0].id"
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.items" count >= 1
|
||||
jsonpath "$.data.items[0].series_id" == {{series_id}}
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 10 步:分配 ICCID_1(8986001234560001)给一级代理(shop1)
|
||||
# 幂等处理:HTTP * 兼容已分配场景
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
POST {{base_url}}/api/admin/iot-cards/standalone/allocate
|
||||
Authorization: Bearer {{admin_token}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"to_shop_id": {{shop1_id}},
|
||||
"selection_type": "list",
|
||||
"iccids": ["{{test_iccid_1}}"],
|
||||
"remark": "Hurl 价格验证测试 - 一级代理"
|
||||
}
|
||||
HTTP *
|
||||
[Asserts]
|
||||
jsonpath "$.code" isInteger
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 11 步:分配 ICCID_2(8986001234560002)给二级代理(shop2)
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
POST {{base_url}}/api/admin/iot-cards/standalone/allocate
|
||||
Authorization: Bearer {{admin_token}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"to_shop_id": {{shop2_id}},
|
||||
"selection_type": "list",
|
||||
"iccids": ["{{test_iccid_2}}"],
|
||||
"remark": "Hurl 价格验证测试 - 二级代理"
|
||||
}
|
||||
HTTP *
|
||||
[Asserts]
|
||||
jsonpath "$.code" isInteger
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 12 步:绑定两张卡到套餐系列(series_binding)
|
||||
# 卡需要绑定套餐系列才能在 C 端看到可购套餐
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
PATCH {{base_url}}/api/admin/iot-cards/series-binding
|
||||
Authorization: Bearer {{admin_token}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"iccids": ["{{test_iccid_1}}", "{{test_iccid_2}}"],
|
||||
"series_id": {{series_id}}
|
||||
}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.success_count" >= 1
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 13 步:C 端测试登录(ICCID_1,归属一级代理)
|
||||
# 调用开发环境专用接口,传入 ICCID 自动绑定测试客户并签发 JWT
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
POST {{base_url}}/api/c/v1/auth/dev-login
|
||||
Content-Type: application/json
|
||||
{
|
||||
"identifier": "{{test_iccid_1}}"
|
||||
}
|
||||
HTTP 200
|
||||
[Captures]
|
||||
customer1_token: jsonpath "$.data.token"
|
||||
customer1_id: jsonpath "$.data.customer_id"
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.token" isString
|
||||
jsonpath "$.data.customer_id" isInteger
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 14 步:验证 ICCID_1 的可购套餐价格 = 一级代理零售价(15000 分)
|
||||
# retail_price 来自一级代理在 shop_package_allocation 中设置的零售价
|
||||
# 前置条件:package-resource-full-flow.hurl 中一级代理已设置零售价 15000
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
GET {{base_url}}/api/c/v1/asset/packages?identifier={{test_iccid_1}}
|
||||
Authorization: Bearer {{customer1_token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.packages" isList
|
||||
jsonpath "$.data.packages" count >= 1
|
||||
# 关键断言:一级代理归属的卡,C 端看到的是一级代理设置的零售价 15000
|
||||
jsonpath "$.data.packages[0].retail_price" == 15000
|
||||
jsonpath "$.data.packages[0].package_id" == {{package_id}}
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 15 步:C 端测试登录(ICCID_2,归属二级代理)
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
POST {{base_url}}/api/c/v1/auth/dev-login
|
||||
Content-Type: application/json
|
||||
{
|
||||
"identifier": "{{test_iccid_2}}"
|
||||
}
|
||||
HTTP 200
|
||||
[Captures]
|
||||
customer2_token: jsonpath "$.data.token"
|
||||
customer2_id: jsonpath "$.data.customer_id"
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.token" isString
|
||||
jsonpath "$.data.customer_id" isInteger
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 16 步:验证 ICCID_2 的可购套餐价格 = 二级代理零售价(18000 分)
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
GET {{base_url}}/api/c/v1/asset/packages?identifier={{test_iccid_2}}
|
||||
Authorization: Bearer {{customer2_token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.packages" isList
|
||||
jsonpath "$.data.packages" count >= 1
|
||||
# 关键断言:二级代理归属的卡,C 端看到的是二级代理设置的零售价 18000(与一级代理不同!)
|
||||
jsonpath "$.data.packages[0].retail_price" == 18000
|
||||
jsonpath "$.data.packages[0].package_id" == {{package_id}}
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 17 步:用两个 token 访问对方的卡(越权验证)
|
||||
# customer1 不应能查询 ICCID_2 的套餐(未绑定该资产)
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
GET {{base_url}}/api/c/v1/asset/packages?identifier={{test_iccid_2}}
|
||||
Authorization: Bearer {{customer1_token}}
|
||||
HTTP 403
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 1005
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
# 第 18 步:验证同一套餐两个代理视角价格确实不同(一致性检查)
|
||||
# ══════════════════════════════════════════════════════════════
|
||||
|
||||
GET {{base_url}}/api/c/v1/asset/info?identifier={{test_iccid_1}}
|
||||
Authorization: Bearer {{customer1_token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.asset_type" == "card"
|
||||
jsonpath "$.data.iccid" == "{{test_iccid_1}}"
|
||||
|
||||
GET {{base_url}}/api/c/v1/asset/info?identifier={{test_iccid_2}}
|
||||
Authorization: Bearer {{customer2_token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.code" == 0
|
||||
jsonpath "$.data.asset_type" == "card"
|
||||
jsonpath "$.data.iccid" == "{{test_iccid_2}}"
|
||||
BIN
tests/hurl/testdata/hurl-test-cards.xlsx
vendored
BIN
tests/hurl/testdata/hurl-test-cards.xlsx
vendored
Binary file not shown.
Reference in New Issue
Block a user