#!/bin/bash # Bookmann Integration Test Script # This script performs a full integration test of the Bookmann API set -e BASE_URL="http://localhost:8765/api" RESULTS_FILE="integration_test_results.txt" echo "========================================" | tee $RESULTS_FILE echo "Bookmann Integration Test Run" | tee -a $RESULTS_FILE echo "Started at: $(date)" | tee -a $RESULTS_FILE echo "========================================" | tee -a $RESULTS_FILE echo "" | tee -a $RESULTS_FILE # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Helper functions pass() { echo -e "${GREEN}✓ PASS${NC}: $1" | tee -a $RESULTS_FILE } fail() { echo -e "${RED}✗ FAIL${NC}: $1" | tee -a $RESULTS_FILE } info() { echo -e "${YELLOW}→ INFO${NC}: $1" | tee -a $RESULTS_FILE } section() { echo "" | tee -a $RESULTS_FILE echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | tee -a $RESULTS_FILE echo " $1" | tee -a $RESULTS_FILE echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" | tee -a $RESULTS_FILE } # Test counters TOTAL_TESTS=0 PASSED_TESTS=0 FAILED_TESTS=0 run_test() { local test_name="$1" local test_command="$2" local expected_code="$3" TOTAL_TESTS=$((TOTAL_TESTS + 1)) info "Running: $test_name" RESPONSE=$(eval "$test_command" 2>&1) STATUS_CODE=$(echo "$RESPONSE" | grep "HTTP Status:" | awk '{print $3}') if [ "$STATUS_CODE" == "$expected_code" ]; then pass "$test_name" PASSED_TESTS=$((PASSED_TESTS + 1)) return 0 else fail "$test_name (Expected: $expected_code, Got: $STATUS_CODE)" FAILED_TESTS=$((FAILED_TESTS + 1)) echo "Response: $RESPONSE" | tee -a $RESULTS_FILE return 1 fi } # Check if server is running check_server() { section "Checking Server Availability" if curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/auth/profile" > /dev/null 2>&1; then pass "Server is running" return 0 else fail "Server is not running at $BASE_URL" return 1 fi } # Main test sequence main() { # Check server if ! check_server; then echo "" | tee -a $RESULTS_FILE echo "ERROR: Server is not running. Please start the server first." | tee -a $RESULTS_FILE echo "Run: docker-compose up -d" | tee -a $RESULTS_FILE exit 1 fi # Step 1: Create first user (should be admin) section "Step 1: Create First User (Should be Admin)" ADMIN_EMAIL="admin@integration.test" ADMIN_USERNAME="admin" ADMIN_PASSWORD="AdminPass123!" RESPONSE=$(curl -s -w "\nHTTP Status: %{http_code}" \ -X POST "$BASE_URL/auth/register" \ -H "Content-Type: application/json" \ -d "{ \"email\": \"$ADMIN_EMAIL\", \"username\": \"$ADMIN_USERNAME\", \"password\": \"$ADMIN_PASSWORD\", \"first_name\": \"Admin\", \"last_name\": \"User\" }") HTTP_STATUS=$(echo "$RESPONSE" | grep "HTTP Status:" | awk '{print $3}') BODY=$(echo "$RESPONSE" | grep -v "HTTP Status:") if [ "$HTTP_STATUS" == "201" ]; then USER_ROLE=$(echo "$BODY" | jq -r '.user.role // empty') if [ "$USER_ROLE" == "admin" ]; then pass "First user created with admin role" PASSED_TESTS=$((PASSED_TESTS + 1)) else fail "First user does not have admin role (got: $USER_ROLE)" FAILED_TESTS=$((FAILED_TESTS + 1)) fi TOTAL_TESTS=$((TOTAL_TESTS + 1)) else fail "Failed to create first user (HTTP $HTTP_STATUS)" FAILED_TESTS=$((FAILED_TESTS + 1)) TOTAL_TESTS=$((TOTAL_TESTS + 1)) echo "Response: $BODY" | tee -a $RESULTS_FILE fi # Login as admin section "Login as Admin" ADMIN_TOKEN=$(curl -s -X POST "$BASE_URL/auth/login" \ -H "Content-Type: application/json" \ -d "{ \"login\": \"$ADMIN_EMAIL\", \"password\": \"$ADMIN_PASSWORD\" }" | jq -r '.access_token // empty') if [ -n "$ADMIN_TOKEN" ] && [ "$ADMIN_TOKEN" != "null" ]; then pass "Admin login successful" PASSED_TESTS=$((PASSED_TESTS + 1)) else fail "Failed to login as admin" FAILED_TESTS=$((FAILED_TESTS + 1)) echo "Cannot continue without admin token" | tee -a $RESULTS_FILE exit 1 fi TOTAL_TESTS=$((TOTAL_TESTS + 1)) # Step 2: Create first library with ebook type section "Step 2: Create First Library with eBook Type" LIBRARY_RESPONSE=$(curl -s -w "\nHTTP Status: %{http_code}" \ -X POST "$BASE_URL/libraries" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{ "name": "Integration Test Library", "description": "Library for integration testing", "type": "ebook" }') LIB_STATUS=$(echo "$LIBRARY_RESPONSE" | grep "HTTP Status:" | awk '{print $3}') LIB_BODY=$(echo "$LIBRARY_RESPONSE" | grep -v "HTTP Status:") if [ "$LIB_STATUS" == "201" ]; then LIBRARY_ID=$(echo "$LIB_BODY" | jq -r '.id // empty') if [ -n "$LIBRARY_ID" ]; then pass "Library created successfully (ID: $LIBRARY_ID)" PASSED_TESTS=$((PASSED_TESTS + 1)) else fail "Library created but no ID returned" FAILED_TESTS=$((FAILED_TESTS + 1)) fi TOTAL_TESTS=$((TOTAL_TESTS + 1)) else fail "Failed to create library (HTTP $LIB_STATUS)" FAILED_TESTS=$((FAILED_TESTS + 1)) TOTAL_TESTS=$((TOTAL_TESTS + 1)) echo "Response: $LIB_BODY" | tee -a $RESULTS_FILE exit 1 fi # Step 3: Add /app/uploads folder to the library section "Step 3: Add /app/uploads Folder to Library" FOLDER_RESPONSE=$(curl -s -w "\nHTTP Status: %{http_code}" \ -X POST "$BASE_URL/libraries/$LIBRARY_ID/folders" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{ "folder_path": "/app/uploads" }') FOLDER_STATUS=$(echo "$FOLDER_RESPONSE" | grep "HTTP Status:" | awk '{print $3}') if [ "$FOLDER_STATUS" == "201" ] || [ "$FOLDER_STATUS" == "200" ]; then pass "Folder added to library" PASSED_TESTS=$((PASSED_TESTS + 1)) else fail "Failed to add folder to library (HTTP $FOLDER_STATUS)" FAILED_TESTS=$((FAILED_TESTS + 1)) echo "Response: $(echo "$FOLDER_RESPONSE" | grep -v "HTTP Status:")" | tee -a $RESULTS_FILE fi TOTAL_TESTS=$((TOTAL_TESTS + 1)) # Step 4: Scan the library section "Step 4: Scan Library" SCAN_RESPONSE=$(curl -s -w "\nHTTP Status: %{http_code}" \ -X POST "$BASE_URL/libraries/$LIBRARY_ID/scan" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -d '{}') SCAN_STATUS=$(echo "$SCAN_RESPONSE" | grep "HTTP Status:" | awk '{print $3}') SCAN_BODY=$(echo "$SCAN_RESPONSE" | grep -v "HTTP Status:") if [ "$SCAN_STATUS" == "200" ] || [ "$SCAN_STATUS" == "202" ]; then pass "Library scan initiated" PASSED_TESTS=$((PASSED_TESTS + 1)) info "Waiting 5 seconds for scan to complete..." sleep 5 else fail "Failed to scan library (HTTP $SCAN_STATUS)" FAILED_TESTS=$((FAILED_TESTS + 1)) echo "Response: $SCAN_BODY" | tee -a $RESULTS_FILE fi TOTAL_TESTS=$((TOTAL_TESTS + 1)) # Step 5: List media items section "Step 5: List Media Items" MEDIA_RESPONSE=$(curl -s -w "\nHTTP Status: %{http_code}" \ -X GET "$BASE_URL/libraries/$LIBRARY_ID/media-items?limit=50&offset=0" \ -H "Authorization: Bearer $ADMIN_TOKEN") MEDIA_STATUS=$(echo "$MEDIA_RESPONSE" | grep "HTTP Status:" | awk '{print $3}') MEDIA_BODY=$(echo "$MEDIA_RESPONSE" | grep -v "HTTP Status:") if [ "$MEDIA_STATUS" == "200" ]; then pass "Media items listed successfully" PASSED_TESTS=$((PASSED_TESTS + 1)) MEDIA_COUNT=$(echo "$MEDIA_BODY" | jq '.total // 0') info "Found $MEDIA_COUNT media items" # Display first few items if [ "$MEDIA_COUNT" -gt 0 ]; then echo "" | tee -a $RESULTS_FILE echo "Sample media items:" | tee -a $RESULTS_FILE echo "$MEDIA_BODY" | jq -r '.media_items[0:3] | .[] | " - \(.title) by \(.author // "Unknown")"' | tee -a $RESULTS_FILE fi else fail "Failed to list media items (HTTP $MEDIA_STATUS)" FAILED_TESTS=$((FAILED_TESTS + 1)) echo "Response: $MEDIA_BODY" | tee -a $RESULTS_FILE fi TOTAL_TESTS=$((TOTAL_TESTS + 1)) # Step 6: Test Device Registration section "Step 6: Device Registration" DEVICE_RESPONSE=$(curl -s -w "\nHTTP Status: %{http_code}" \ -X POST "$BASE_URL/devices/register" \ -H "Content-Type: application/json" \ -d '{ "device_name": "Test Kindle Paperwhite", "device_type": "koreader", "device_identifier": "kindle-test-hw-12345" }') DEVICE_STATUS=$(echo "$DEVICE_RESPONSE" | grep "HTTP Status:" | awk '{print $3}') DEVICE_BODY=$(echo "$DEVICE_RESPONSE" | grep -v "HTTP Status:") if [ "$DEVICE_STATUS" == "201" ]; then pass "Device registration initiated" PASSED_TESTS=$((PASSED_TESTS + 1)) REGISTRATION_ID=$(echo "$DEVICE_BODY" | jq -r '.registration_id // empty') info "Registration ID: $REGISTRATION_ID" # Check registration status STATUS_RESPONSE=$(curl -s -w "\nHTTP Status: %{http_code}" \ -X POST "$BASE_URL/devices/register/status" \ -H "Content-Type: application/json" \ -d "{\"registration_id\": \"$REGISTRATION_ID\"}") STATUS_BODY=$(echo "$STATUS_RESPONSE" | grep -v "HTTP Status:") REG_STATUS=$(echo "$STATUS_BODY" | jq -r '.status // empty') if [ "$REG_STATUS" == "pending" ]; then pass "Registration status is pending as expected" PASSED_TESTS=$((PASSED_TESTS + 1)) else fail "Registration status should be pending (got: $REG_STATUS)" FAILED_TESTS=$((FAILED_TESTS + 1)) fi TOTAL_TESTS=$((TOTAL_TESTS + 1)) else fail "Failed to initiate device registration (HTTP $DEVICE_STATUS)" FAILED_TESTS=$((FAILED_TESTS + 1)) echo "Response: $DEVICE_BODY" | tee -a $RESULTS_FILE fi TOTAL_TESTS=$((TOTAL_TESTS + 1)) # Step 7: List devices section "Step 7: List User Devices" LIST_DEVICES_RESPONSE=$(curl -s -w "\nHTTP Status: %{http_code}" \ -X GET "$BASE_URL/devices" \ -H "Authorization: Bearer $ADMIN_TOKEN") LIST_DEVICES_STATUS=$(echo "$LIST_DEVICES_RESPONSE" | grep "HTTP Status:" | awk '{print $3}') if [ "$LIST_DEVICES_STATUS" == "200" ]; then pass "Devices listed successfully" PASSED_TESTS=$((PASSED_TESTS + 1)) else fail "Failed to list devices (HTTP $LIST_DEVICES_STATUS)" FAILED_TESTS=$((FAILED_TESTS + 1)) fi TOTAL_TESTS=$((TOTAL_TESTS + 1)) # Print summary section "Test Summary" echo "" | tee -a $RESULTS_FILE echo "Total Tests: $TOTAL_TESTS" | tee -a $RESULTS_FILE echo "Passed: $PASSED_TESTS" | tee -a $RESULTS_FILE echo "Failed: $FAILED_TESTS" | tee -a $RESULTS_FILE echo "" | tee -a $RESULTS_FILE if [ $FAILED_TESTS -eq 0 ]; then echo -e "${GREEN}All tests passed!${NC}" | tee -a $RESULTS_FILE else PERCENT=$((PASSED_TESTS * 100 / TOTAL_TESTS)) echo -e "${YELLOW}Pass rate: ${PERCENT}%${NC}" | tee -a $RESULTS_FILE fi echo "" | tee -a $RESULTS_FILE echo "Completed at: $(date)" | tee -a $RESULTS_FILE echo "========================================" | tee -a $RESULTS_FILE # Exit with error if any tests failed if [ $FAILED_TESTS -gt 0 ]; then exit 1 fi } # Run main function main