#!/usr/bin/env python3 """ Test script for the Todo API This script tests all the CRUD operations for the Todo API """ import requests import json import sys from typing import Dict, Any, Optional BASE_URL = "http://localhost:8000/api/v1" def print_success(message: str) -> None: """Print a success message in green color""" print(f"\033[92m✓ {message}\033[0m") def print_error(message: str) -> None: """Print an error message in red color""" print(f"\033[91m✗ {message}\033[0m") def print_info(message: str) -> None: """Print an info message in blue color""" print(f"\033[94m• {message}\033[0m") def test_health_endpoint() -> bool: """Test the health endpoint""" print_info("Testing health endpoint...") try: response = requests.get("http://localhost:8000/health") if response.status_code == 200: data = response.json() if data.get("status") == "healthy": print_success("Health endpoint is working") return True else: print_error(f"Health endpoint returned unexpected data: {data}") return False else: print_error(f"Health endpoint returned status code {response.status_code}") return False except Exception as e: print_error(f"Error testing health endpoint: {e}") return False def create_todo(title: str, description: Optional[str] = None, completed: bool = False) -> Dict[str, Any]: """Create a new todo and return the created todo data""" print_info(f"Creating todo: {title}") todo_data = { "title": title, "description": description, "completed": completed } response = requests.post(f"{BASE_URL}/todos/", json=todo_data) if response.status_code == 201: todo = response.json() print_success(f"Todo created with ID: {todo['id']}") return todo else: print_error(f"Failed to create todo. Status code: {response.status_code}") print_error(f"Response: {response.text}") return {} def get_todo(todo_id: int) -> Dict[str, Any]: """Get a specific todo by ID""" print_info(f"Getting todo with ID: {todo_id}") response = requests.get(f"{BASE_URL}/todos/{todo_id}") if response.status_code == 200: todo = response.json() print_success(f"Got todo: {todo['title']}") return todo else: print_error(f"Failed to get todo. Status code: {response.status_code}") print_error(f"Response: {response.text}") return {} def get_all_todos() -> list: """Get all todos""" print_info("Getting all todos") response = requests.get(f"{BASE_URL}/todos/") if response.status_code == 200: todos = response.json() print_success(f"Got {len(todos)} todos") return todos else: print_error(f"Failed to get todos. Status code: {response.status_code}") print_error(f"Response: {response.text}") return [] def update_todo(todo_id: int, data: Dict[str, Any]) -> Dict[str, Any]: """Update a specific todo""" print_info(f"Updating todo with ID: {todo_id}") response = requests.put(f"{BASE_URL}/todos/{todo_id}", json=data) if response.status_code == 200: todo = response.json() print_success(f"Updated todo: {todo['title']}") return todo else: print_error(f"Failed to update todo. Status code: {response.status_code}") print_error(f"Response: {response.text}") return {} def delete_todo(todo_id: int) -> bool: """Delete a specific todo""" print_info(f"Deleting todo with ID: {todo_id}") response = requests.delete(f"{BASE_URL}/todos/{todo_id}") if response.status_code == 204: print_success(f"Deleted todo with ID: {todo_id}") return True else: print_error(f"Failed to delete todo. Status code: {response.status_code}") print_error(f"Response: {response.text}") return False def run_tests() -> None: """Run all tests""" print_info("Starting API tests") # Test health endpoint if not test_health_endpoint(): print_error("Health endpoint test failed. Make sure the server is running.") sys.exit(1) # Test creating a todo todo = create_todo("Test Todo", "This is a test todo", False) if not todo: print_error("Failed to create todo. Stopping tests.") sys.exit(1) todo_id = todo["id"] # Test getting a specific todo get_todo(todo_id) # Test getting all todos get_all_todos() # Test updating a todo updated_todo = update_todo(todo_id, {"title": "Updated Test Todo", "completed": True}) if not updated_todo: print_error("Failed to update todo.") # Test deleting a todo if not delete_todo(todo_id): print_error("Failed to delete todo.") print_info("All tests completed") if __name__ == "__main__": run_tests()