v0.1.1 api with fiber added, basic functionlity tested

This commit is contained in:
2025-10-27 05:16:08 -04:00
parent 8ba4357920
commit b98ea83012
9 changed files with 941 additions and 8 deletions

241
test/test-api.sh Executable file
View File

@ -0,0 +1,241 @@
#!/usr/bin/env bash
# FILE: test/test-api.sh
# Chess API Test Suite
# Requires: curl, jq (optional for pretty output)
BASE_URL="http://localhost:8080"
API_URL="${BASE_URL}/api/v1"
# Configurable delay between API calls (in seconds)
API_DELAY=${API_DELAY:-0.2} # Default 200ms between calls
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Test counters
PASS=0
FAIL=0
# Helper functions
test_case() {
echo -e "\n${YELLOW}TEST: $1${NC}"
sleep $API_DELAY # Add delay before each test
}
assert_status() {
local expected=$1
local actual=$2
local test_name=$3
if [ "$actual" = "$expected" ]; then
echo -e "${GREEN}$test_name: HTTP $actual${NC}"
((PASS++))
else
echo -e "${RED}$test_name: Expected HTTP $expected, got $actual${NC}"
((FAIL++))
fi
}
api_request() {
local method=$1
local url=$2
shift 2
curl -s "$@" -X "$method" "$url"
local status=$?
sleep $API_DELAY
return $status
}
# Start tests
echo "=== Chess API Test Suite ==="
echo "Server: $BASE_URL"
echo "Starting tests..."
# Test 1: Health check
test_case "Health Check"
STATUS=$(api_request GET "$BASE_URL/health" -o /dev/null -w "%{http_code}")
assert_status 200 "$STATUS" "Health endpoint"
# Test 2: Create human vs computer game
test_case "Create Human vs Computer Game"
GAME_RESPONSE=$(api_request POST "$API_URL/games" \
-H "Content-Type: application/json" \
-d '{"white": 0, "black": 1}')
GAME_ID=$(echo "$GAME_RESPONSE" | grep -o '"gameId":"[^"]*' | cut -d'"' -f4)
STATUS=$(api_request POST "$API_URL/games" \
-o /dev/null -w "%{http_code}" \
-H "Content-Type: application/json" \
-d '{"white": 0, "black": 1}')
assert_status 201 "$STATUS" "Create game"
echo "Game ID: $GAME_ID"
# Test 3: Make valid human move
test_case "Make Valid Human Move"
STATUS=$(api_request POST "$API_URL/games/$GAME_ID/moves" \
-o /dev/null -w "%{http_code}" \
-H "Content-Type: application/json" \
-d '{"move": "e2e4"}')
assert_status 200 "$STATUS" "Valid move e2e4"
# Test 4: Get game state (should auto-execute computer move)
test_case "Get Game State (Auto-Execute Computer)"
RESPONSE=$(api_request GET "$API_URL/games/$GAME_ID")
STATUS=$(api_request GET "$API_URL/games/$GAME_ID" -o /dev/null -w "%{http_code}")
assert_status 200 "$STATUS" "Get game state"
echo "Current turn: $(echo "$RESPONSE" | grep -o '"turn":"[^"]*' | cut -d'"' -f4)"
# Test 5: Make invalid human move
test_case "Make Invalid Human Move"
STATUS=$(api_request POST "$API_URL/games/$GAME_ID/moves" \
-o /dev/null -w "%{http_code}" \
-H "Content-Type: application/json" \
-d '{"move": "e2e5"}')
assert_status 400 "$STATUS" "Invalid move e2e5"
# Test 6: Undo last move
test_case "Undo Last Move"
STATUS=$(api_request POST "$API_URL/games/$GAME_ID/undo" \
-o /dev/null -w "%{http_code}" \
-H "Content-Type: application/json" \
-d '{"count": 2}')
assert_status 200 "$STATUS" "Undo 2 moves"
# Test 7: Get ASCII board
test_case "Get ASCII Board"
BOARD_RESPONSE=$(api_request GET "$API_URL/games/$GAME_ID/board")
STATUS=$(api_request GET "$API_URL/games/$GAME_ID/board" -o /dev/null -w "%{http_code}")
assert_status 200 "$STATUS" "Get board"
echo "$BOARD_RESPONSE" | grep -o '"board":"[^"]*' | cut -d'"' -f4 | sed 's/\\n/\n/g'
# Test 8: Delete game
test_case "Delete Game"
STATUS=$(api_request DELETE "$API_URL/games/$GAME_ID" -o /dev/null -w "%{http_code}")
assert_status 204 "$STATUS" "Delete game"
# Test 9: Create computer vs computer game
test_case "Create Computer vs Computer Game"
COMP_RESPONSE=$(api_request POST "$API_URL/games" \
-H "Content-Type: application/json" \
-d '{"white": 1, "black": 1}')
COMP_ID=$(echo "$COMP_RESPONSE" | grep -o '"gameId":"[^"]*' | cut -d'"' -f4)
echo "Computer game ID: $COMP_ID"
# Test 10: Multiple GET requests to observe progress
test_case "Computer vs Computer Progress"
for i in {1..3}; do
RESPONSE=$(api_request GET "$API_URL/games/$COMP_ID")
MOVES=$(echo "$RESPONSE" | grep -o '"moves":\[[^]]*' | cut -d'[' -f2 | cut -d']' -f1)
STATE=$(echo "$RESPONSE" | grep -o '"state":"[^"]*' | cut -d'"' -f4)
echo "Move $i - State: $STATE, Moves made: $(echo "$MOVES" | grep -o ',' | wc -l)"
if [ "$STATE" != "ongoing" ]; then
echo "Game ended: $STATE"
break
fi
done
# Test 11: Clean up computer game
api_request DELETE "$API_URL/games/$COMP_ID" > /dev/null
# Test 12: Rate limiting - 2 requests within 1 second
test_case "Rate Limiting - Rapid Requests"
STATUS1=$(curl -s -o /dev/null -w "%{http_code}" "$API_URL/games/test")
STATUS2=$(curl -s -o /dev/null -w "%{http_code}" "$API_URL/games/test")
assert_status 404 "$STATUS1" "First request"
assert_status 429 "$STATUS2" "Second request (rate limited)"
echo "Test will fail in dev mode as rate limiter is permissive."
# Test 13: Wait and retry after rate limit
test_case "Rate Limit Recovery"
sleep 1.5
STATUS=$(api_request GET "$API_URL/games/test" -o /dev/null -w "%{http_code}")
assert_status 404 "$STATUS" "Request after waiting"
# Test 14: Test with X-Forwarded-For (different IPs)
test_case "Rate Limiting with Different IPs"
STATUS1=$(api_request GET "$API_URL/games/test" -o /dev/null -w "%{http_code}" -H "X-Forwarded-For: 192.168.1.1")
STATUS2=$(api_request GET "$API_URL/games/test" -o /dev/null -w "%{http_code}" -H "X-Forwarded-For: 192.168.1.2")
assert_status 404 "$STATUS1" "IP 192.168.1.1"
assert_status 404 "$STATUS2" "IP 192.168.1.2 (different IP)"
# Test 15: Invalid JSON body
test_case "Invalid JSON Body"
STATUS=$(api_request POST "$API_URL/games" \
-o /dev/null -w "%{http_code}" \
-H "Content-Type: application/json" \
-d 'invalid json')
assert_status 400 "$STATUS" "Invalid JSON"
# Test 16: Wrong Content-Type header
test_case "Wrong Content-Type Header"
STATUS=$(api_request POST "$API_URL/games" \
-o /dev/null -w "%{http_code}" \
-H "Content-Type: text/plain" \
-d '{"white": 0, "black": 1}')
assert_status 415 "$STATUS" "Wrong Content-Type"
# Test 17: Non-existent gameId
test_case "Non-existent Game ID"
STATUS=$(api_request GET "$API_URL/games/non-existent-id" -o /dev/null -w "%{http_code}")
assert_status 404 "$STATUS" "Game not found"
# Test 18: Create game to test end conditions
test_case "Move When Game Over"
ENDGAME_RESPONSE=$(api_request POST "$API_URL/games" \
-H "Content-Type: application/json" \
-d '{"white": 0, "black": 0, "fen": "7k/5Q2/5K2/8/8/8/8/8 w - - 0 1"}')
ENDGAME_ID=$(echo "$ENDGAME_RESPONSE" | grep -o '"gameId":"[^"]*' | cut -d'"' -f4)
# Make checkmate move
api_request POST "$API_URL/games/$ENDGAME_ID/moves" \
-H "Content-Type: application/json" \
-d '{"move": "f7g7"}' > /dev/null
# Try to make another move after checkmate
STATUS=$(api_request POST "$API_URL/games/$ENDGAME_ID/moves" \
-o /dev/null -w "%{http_code}" \
-H "Content-Type: application/json" \
-d '{"move": "h8h7"}')
assert_status 400 "$STATUS" "Move after game over"
# Clean up
api_request DELETE "$API_URL/games/$ENDGAME_ID" > /dev/null
# Test 19: Move when not player's turn - Use human vs human game
test_case "Move When Not Player's Turn"
# Create human vs human game so no automatic moves happen
TURN_RESPONSE=$(api_request POST "$API_URL/games" \
-H "Content-Type: application/json" \
-d '{"white": 0, "black": 0}') # BOTH are human players
TURN_ID=$(echo "$TURN_RESPONSE" | grep -o '"gameId":"[^"]*' | cut -d'"' -f4)
# White moves
api_request POST "$API_URL/games/$TURN_ID/moves" \
-H "Content-Type: application/json" \
-d '{"move": "e2e4"}' > /dev/null
# Now it's black's turn, try to move as white again (should fail)
STATUS=$(api_request POST "$API_URL/games/$TURN_ID/moves" \
-o /dev/null -w "%{http_code}" \
-H "Content-Type: application/json" \
-d '{"move": "d2d4"}')
assert_status 400 "$STATUS" "Move when not turn"
# Clean up
api_request DELETE "$API_URL/games/$TURN_ID" > /dev/null
# Summary
echo -e "\n=== Test Summary ==="
echo -e "${GREEN}Passed: $PASS${NC}"
echo -e "${RED}Failed: $FAIL${NC}"
if [ $FAIL -eq 0 ]; then
echo -e "\n${GREEN}All tests passed!${NC}"
exit 0
else
echo -e "\n${RED}Some tests failed${NC}"
exit 1
fi