AgentSkillsCN

Api Integration Testing

使用curl测试.NET API端点,以验证JWT身份认证、CRUD操作、业务隔离性,以及是否符合整洁架构规范。

SKILL.md
--- frontmatter
description: Test .NET API endpoints with curl to validate JWT authentication, CRUD operations, business isolation, and Clean Architecture compliance

API Integration Testing Skill

Use this skill to perform integration testing of .NET microservices using curl and command-line tools.

When to Use

  • After implementing API endpoints
  • After fixing backend bugs
  • Before deploying backend changes
  • During QA validation
  • For security testing

What This Skill Does

1. JWT Authentication Testing

Validates security implementation:

  • Test endpoints without token (expect 401)
  • Test with invalid token (expect 401)
  • Test with wrong role (expect 403)
  • Test with correct role (expect 200)

2. CRUD Operations Testing

Tests all API operations:

  • CREATE: POST request creates resource
  • READ: GET request returns data
  • UPDATE: PUT request modifies resource
  • DELETE: DELETE request removes resource

3. Business Isolation Testing

Verifies multi-tenancy security:

  • Cannot access other business data
  • Queries filter by business_id from JWT
  • Cross-business access returns 404

4. Validation Testing

Checks input validation:

  • Missing required fields return 400
  • Invalid formats return 400
  • Error messages are user-friendly

5. Health Check Testing

Verifies monitoring:

  • /health endpoint responds 200
  • Database connectivity checked

Testing Tools

Bash Commands Available

  • curl - HTTP requests to API
  • dotnet build - Compile verification
  • dotnet test - Run unit tests
  • docker-compose - Start services
  • jq - Parse JSON responses (if available)

Expected Inputs

Testing Workflow

Step 1: Build Verification

bash
cd {context}/{context}-api
dotnet build

Expected: 0 errors, 0 warnings

Step 2: Start Service

bash
docker-compose up -d {context}_api

Expected: Container starts successfully

Step 3: Test Health

bash
curl -f http://localhost:{port}/health

Expected: HTTP 200

Step 4: Test Authentication

bash
# No token (should fail)
curl -i http://localhost:{port}/api/{context}/endpoint
# Expected: 401 Unauthorized

# Invalid token (should fail)
curl -i -H "Authorization: Bearer invalid" \
  http://localhost:{port}/api/{context}/endpoint
# Expected: 401 Unauthorized

# Valid token (should succeed)
curl -i -H "Authorization: Bearer ${VALID_TOKEN}" \
  http://localhost:{port}/api/{context}/endpoint
# Expected: 200 OK

Step 5: Test CRUD

bash
# CREATE
curl -X POST \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"name":"Test","value":123}' \
  http://localhost:{port}/api/{context}/items

# READ
curl -H "Authorization: Bearer ${TOKEN}" \
  http://localhost:{port}/api/{context}/items/{id}

# UPDATE
curl -X PUT \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"name":"Updated","value":456}' \
  http://localhost:{port}/api/{context}/items/{id}

# DELETE
curl -X DELETE \
  -H "Authorization: Bearer ${TOKEN}" \
  http://localhost:{port}/api/{context}/items/{id}

Step 6: Test Business Isolation

bash
# Create with Business A token
ITEM_ID=$(curl -X POST \
  -H "Authorization: Bearer ${BUSINESS_A_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"name":"A Item"}' \
  http://localhost:{port}/api/{context}/items | jq -r '.id')

# Try to access with Business B token (should fail)
curl -i -H "Authorization: Bearer ${BUSINESS_B_TOKEN}" \
  http://localhost:{port}/api/{context}/items/${ITEM_ID}
# Expected: 404 Not Found

Step 7: Test Validation

bash
# Missing required field
curl -i -X POST \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"value":123}' \
  http://localhost:{port}/api/{context}/items
# Expected: 400 Bad Request with validation error

Step 8: Verify Clean Architecture

bash
# Check response is DTO, not entity
# Should NOT have:
# - EF Core navigation properties
# - Internal business logic methods
# - Audit fields (CreatedAt, UpdatedAt)

# Should have:
# - Only data properties
# - Clean, simple structure

Test Scripts Examples

Example 1: Schedule API Test

bash
#!/bin/bash
API_URL="http://localhost:8003/api/scheduling"
TOKEN="eyJhbGc..." # Valid JWT token

echo "Testing Schedule API..."

# Test health
echo "1. Health check..."
curl -f ${API_URL:0:-15}/health || echo "FAIL: Health check"

# Test auth
echo "2. Auth test (no token)..."
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" ${API_URL}/schedules)
[ "$RESPONSE" = "401" ] && echo "PASS" || echo "FAIL: Expected 401, got $RESPONSE"

# Test CREATE
echo "3. Create schedule..."
CREATED=$(curl -X POST \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"employeeId":"123","date":"2025-01-20","startTime":"09:00","endTime":"17:00"}' \
  ${API_URL}/schedules)
SCHEDULE_ID=$(echo $CREATED | jq -r '.id')
echo "Created schedule: $SCHEDULE_ID"

# Test READ
echo "4. Read schedule..."
curl -H "Authorization: Bearer ${TOKEN}" \
  ${API_URL}/schedules/${SCHEDULE_ID} | jq '.'

# Test UPDATE
echo "5. Update schedule..."
curl -X PUT \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"employeeId":"123","date":"2025-01-20","startTime":"09:00","endTime":"18:00"}' \
  ${API_URL}/schedules/${SCHEDULE_ID} | jq '.'

# Test DELETE
echo "6. Delete schedule..."
curl -X DELETE \
  -H "Authorization: Bearer ${TOKEN}" \
  ${API_URL}/schedules/${SCHEDULE_ID}

# Verify deleted
echo "7. Verify deleted..."
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer ${TOKEN}" \
  ${API_URL}/schedules/${SCHEDULE_ID})
[ "$RESPONSE" = "404" ] && echo "PASS: Deleted" || echo "FAIL: Still exists"

echo "Tests complete!"

Example 2: Business Isolation Test

bash
#!/bin/bash
API_URL="http://localhost:8003/api/scheduling"
BUSINESS_A_TOKEN="token_for_business_a"
BUSINESS_B_TOKEN="token_for_business_b"

echo "Testing business isolation..."

# Create schedule with Business A
SCHEDULE_ID=$(curl -X POST \
  -H "Authorization: Bearer ${BUSINESS_A_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"employeeId":"123","date":"2025-01-20"}' \
  ${API_URL}/schedules | jq -r '.id')

echo "Created schedule $SCHEDULE_ID for Business A"

# Try to access with Business B (should fail)
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer ${BUSINESS_B_TOKEN}" \
  ${API_URL}/schedules/${SCHEDULE_ID})

if [ "$RESPONSE" = "404" ]; then
  echo "PASS: Business B cannot access Business A data"
else
  echo "FAIL: Business B can access Business A data (Security issue!)"
  exit 1
fi

Validation Checklist

  • Build succeeds (dotnet build)
  • Tests pass (dotnet test)
  • Health check responds 200
  • JWT required (401 without token)
  • Authorization enforced (403 wrong role)
  • CREATE returns 201
  • READ returns 200
  • UPDATE returns 200
  • DELETE returns 204/200
  • Business isolation works (404 for other business)
  • Validation returns 400
  • Error messages user-friendly
  • Swagger documentation correct

Deliverables

  • Test execution results
  • Pass/fail for each test case
  • HTTP response codes captured
  • Error messages (if any)
  • Security test results
  • Recommendations for fixes

Common Test Failures

401 when token provided

Cause: Token validation misconfigured Check: JWT_SECRET, Issuer, Audience in appsettings.json

403 for correct role

Cause: Policy not matching claim Check: Authorization policy definition, claim names

Can access other business data

Cause: Missing business_id filter Fix: CRITICAL SECURITY ISSUE - Add filtering immediately

500 errors

Cause: Unhandled exceptions Check: Application logs, add try-catch, validation

This skill ensures comprehensive API testing covering functionality, security, and architectural compliance.