ether-docs/04-TESTING/api/ops/test-ops.sh

358 lines
13 KiB
Bash
Executable File
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.

#!/bin/bash
BASE_URL="http://localhost:8080/api"
TOKEN=""
PROJECT_ID=""
PASS_COUNT=0
FAIL_COUNT=0
TOTAL_COUNT=0
assert_eq() {
local actual="$1"
local expected="$2"
local name="$3"
TOTAL_COUNT=$((TOTAL_COUNT + 1))
if [ "$actual" = "$expected" ]; then
echo " PASS: $name"
PASS_COUNT=$((PASS_COUNT + 1))
else
echo " FAIL: $name (expected=$expected, actual=$actual)"
FAIL_COUNT=$((FAIL_COUNT + 1))
fi
}
assert_contains() {
local haystack="$1"
local needle="$2"
local name="$3"
TOTAL_COUNT=$((TOTAL_COUNT + 1))
if echo "$haystack" | grep -q "$needle"; then
echo " PASS: $name"
PASS_COUNT=$((PASS_COUNT + 1))
else
echo " FAIL: $name (expected to contain: $needle)"
FAIL_COUNT=$((FAIL_COUNT + 1))
fi
}
login() {
echo "=== 登录获取Token ==="
local response=$(curl -s -X POST "$BASE_URL/auth/login" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}')
TOKEN=$(echo "$response" | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
if [ -z "$TOKEN" ]; then
echo "FATAL: 登录失败无法获取Token"
exit 1
fi
echo "Token获取成功"
}
setup_project() {
echo "=== 创建测试项目 ==="
local response=$(curl -s -X POST "$BASE_URL/mdm/projects" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: " \
-d "{\"code\":\"TEST-OPS-$$\",\"name\":\"OPS测试项目\",\"projectType\":\"RESIDENTIAL\"}")
PROJECT_ID=$(echo "$response" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
if [ -z "$PROJECT_ID" ]; then
echo "FATAL: 创建测试项目失败"
exit 1
fi
echo "测试项目创建成功: $PROJECT_ID"
}
test_create_work_order() {
echo "--- TC-OPS-001: 创建工单 ---"
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/wo/work-orders" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d "{\"title\":\"测试工单-$$\",\"source\":\"MANUAL\",\"type\":\"REPAIR\",\"priority\":\"MEDIUM\",\"description\":\"API测试工单\"}")
local status=$(echo "$response" | tail -n 1)
local body=$(echo "$response" | head -n -1)
assert_eq "$status" "201" "TC-OPS-001: 创建工单返回201"
assert_contains "$body" '"workNo"' "TC-OPS-001: 响应包含workNo"
WORK_ORDER_ID=$(echo "$body" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
}
test_query_work_orders() {
echo "--- TC-OPS-002: 查询工单列表 ---"
local response=$(curl -s -w "\n%{http_code}" -X GET "$BASE_URL/wo/work-orders?projectId=$PROJECT_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-002: 查询工单列表返回200"
}
test_assign_work_order() {
echo "--- TC-OPS-003: 工单派单 ---"
if [ -z "$WORK_ORDER_ID" ]; then
echo " SKIP: TC-OPS-003 (无工单ID)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/wo/work-orders/$WORK_ORDER_ID/assign" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d '{"assignedTo":"test_maintainer","assignedDate":"2026-05-18"}')
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-003: 工单派单返回200"
}
test_start_work_order() {
echo "--- TC-OPS-004: 工单开始执行 ---"
if [ -z "$WORK_ORDER_ID" ]; then
echo " SKIP: TC-OPS-004 (无工单ID)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/wo/work-orders/$WORK_ORDER_ID/start" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-004: 工单开始执行返回200"
}
test_complete_work_order() {
echo "--- TC-OPS-005: 工单完成 ---"
if [ -z "$WORK_ORDER_ID" ]; then
echo " SKIP: TC-OPS-005 (无工单ID)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/wo/work-orders/$WORK_ORDER_ID/complete" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d '{"faultCause":"测试故障原因","solution":"测试解决方案","result":"已修复","laborCost":100,"partsCost":50}')
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-005: 工单完成返回200"
}
test_verify_work_order() {
echo "--- TC-OPS-006: 工单验收 ---"
if [ -z "$WORK_ORDER_ID" ]; then
echo " SKIP: TC-OPS-006 (无工单ID)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/wo/work-orders/$WORK_ORDER_ID/verify" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d '{"verifiedBy":"admin","rating":5,"remark":"验收通过"}')
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-006: 工单验收返回200"
}
test_cancel_completed_work_order() {
echo "--- TC-OPS-007: 工单取消-已完成拒绝 ---"
if [ -z "$WORK_ORDER_ID" ]; then
echo " SKIP: TC-OPS-007 (无工单ID)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/wo/work-orders/$WORK_ORDER_ID/cancel" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "400" "TC-OPS-007: 已完成工单取消返回400"
}
test_work_order_statistics() {
echo "--- TC-OPS-008: 工单统计 ---"
local response=$(curl -s -w "\n%{http_code}" -X GET "$BASE_URL/wo/work-orders/statistics?projectId=$PROJECT_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-008: 工单统计返回200"
}
test_create_maintenance_task() {
echo "--- TC-OPS-009: 创建维保任务 ---"
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/wo/maintenance-tasks" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d "{\"equipmentId\":\"00000000-0000-0000-0000-000000000000\",\"taskType\":\"PREVENTIVE\",\"triggerType\":\"MANUAL\",\"title\":\"测试维保任务-$$\"}")
local status=$(echo "$response" | tail -n 1)
local body=$(echo "$response" | head -n -1)
if [ "$status" = "201" ] || [ "$status" = "200" ]; then
assert_eq "$status" "$status" "TC-OPS-009: 创建维保任务成功"
MAINT_TASK_ID=$(echo "$body" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
else
assert_contains "$body" "equipment" "TC-OPS-009: 创建维保任务(设备不存在时返回错误)"
fi
}
test_spare_part_crud() {
echo "--- TC-OPS-010: 备件CRUD ---"
local create_response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/ops/spare-parts" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d "{\"partCode\":\"TEST-SP-$$_$RANDOM\",\"partName\":\"测试备件\",\"unit\":\"个\",\"safeStock\":10,\"currentStock\":100,\"unitPrice\":25.00}")
local create_status=$(echo "$create_response" | tail -n 1)
local create_body=$(echo "$create_response" | head -n -1)
assert_eq "$create_status" "201" "TC-OPS-010: 创建备件返回201"
SPARE_PART_ID=$(echo "$create_body" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
}
test_spare_part_in_stock() {
echo "--- TC-OPS-011: 备件入库 ---"
if [ -z "$SPARE_PART_ID" ]; then
echo " SKIP: TC-OPS-011 (无备件ID)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/ops/spare-parts/in-stock" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d "{\"sparePartId\":\"$SPARE_PART_ID\",\"quantity\":50,\"operator\":\"admin\",\"remark\":\"API测试入库\"}")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-011: 备件入库返回200"
}
test_spare_part_out_stock() {
echo "--- TC-OPS-012: 备件出库 ---"
if [ -z "$SPARE_PART_ID" ]; then
echo " SKIP: TC-OPS-012 (无备件ID)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/ops/spare-parts/out-stock" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d "{\"sparePartId\":\"$SPARE_PART_ID\",\"quantity\":10,\"operator\":\"admin\",\"remark\":\"API测试出库\"}")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-012: 备件出库返回200"
}
test_spare_part_out_stock_insufficient() {
echo "--- TC-OPS-013: 备件出库-库存不足 ---"
if [ -z "$SPARE_PART_ID" ]; then
echo " SKIP: TC-OPS-013 (无备件ID)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/ops/spare-parts/out-stock" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d "{\"sparePartId\":\"$SPARE_PART_ID\",\"quantity\":99999,\"operator\":\"admin\",\"remark\":\"库存不足测试\"}")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "400" "TC-OPS-013: 库存不足出库返回400"
}
test_low_stock_warning() {
echo "--- TC-OPS-014: 低库存预警 ---"
local response=$(curl -s -w "\n%{http_code}" -X GET "$BASE_URL/ops/spare-parts/low-stock?projectId=$PROJECT_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-014: 低库存预警返回200"
}
test_energy_consumption() {
echo "--- TC-OPS-015: 能耗抄表录入 ---"
local meter_response=$(curl -s -X POST "$BASE_URL/ops/energy/meters" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d "{\"meterName\":\"测试计量点-$$\",\"energyType\":\"LIGHTING\",\"unitPrice\":0.85}")
local meter_id=$(echo "$meter_response" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
if [ -z "$meter_id" ]; then
echo " SKIP: TC-OPS-015 (无法创建计量点)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/ops/energy/consumption" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d "{\"meterId\":\"$meter_id\",\"currentReading\":100,\"recordedBy\":\"admin\"}")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "201" "TC-OPS-015: 能耗抄表录入返回201"
ENERGY_METER_ID="$meter_id"
}
test_energy_decreasing_reading() {
echo "--- TC-OPS-016: 能耗抄表-读数递减 ---"
if [ -z "$ENERGY_METER_ID" ]; then
echo " SKIP: TC-OPS-016 (无计量点ID)"
return
fi
local response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/ops/energy/consumption" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID" \
-d "{\"meterId\":\"$ENERGY_METER_ID\",\"currentReading\":50,\"recordedBy\":\"admin\"}")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "400" "TC-OPS-016: 读数递减返回400"
}
test_maintenance_plan() {
echo "--- TC-OPS-017: 维保计划管理 ---"
local response=$(curl -s -w "\n%{http_code}" -X GET "$BASE_URL/wo/maintenance-plans?projectId=$PROJECT_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Project-ID: $PROJECT_ID")
local status=$(echo "$response" | tail -n 1)
assert_eq "$status" "200" "TC-OPS-017: 查询维保计划返回200"
}
cleanup() {
echo "=== 清理测试数据 ==="
if [ -n "$PROJECT_ID" ]; then
curl -s -X DELETE "$BASE_URL/mdm/projects/$PROJECT_ID" \
-H "Authorization: Bearer $TOKEN" > /dev/null 2>&1
fi
}
print_summary() {
echo ""
echo "=========================================="
echo " Ops Domain API Test Summary"
echo "=========================================="
echo " Total: $TOTAL_COUNT"
echo " Passed: $PASS_COUNT"
echo " Failed: $FAIL_COUNT"
if [ "$TOTAL_COUNT" -gt 0 ]; then
local rate=$(echo "scale=1; $PASS_COUNT * 100 / $TOTAL_COUNT" | bc)
echo " Rate: ${rate}%"
fi
echo "=========================================="
if [ "$FAIL_COUNT" -gt 0 ]; then
return 1
fi
return 0
}
WORK_ORDER_ID=""
MAINT_TASK_ID=""
SPARE_PART_ID=""
ENERGY_METER_ID=""
echo "=========================================="
echo " Ether PMS - Ops Domain API Tests"
echo "=========================================="
echo ""
login
setup_project
test_create_work_order
test_query_work_orders
test_assign_work_order
test_start_work_order
test_complete_work_order
test_verify_work_order
test_cancel_completed_work_order
test_work_order_statistics
test_create_maintenance_task
test_spare_part_crud
test_spare_part_in_stock
test_spare_part_out_stock
test_spare_part_out_stock_insufficient
test_low_stock_warning
test_energy_consumption
test_energy_decreasing_reading
test_maintenance_plan
cleanup
print_summary