Todo_App / tests /test_backend.py
Abdullahcoder54's picture
Push the app
697c967
"""
Backend API Test Suite for Todo List App Phase II
This test suite verifies all backend functionality including:
- Authentication endpoints (register, login, logout)
- Task management endpoints (CRUD operations)
- User management endpoints
- JWT authentication and authorization
- Database connectivity
"""
import requests
import json
from datetime import datetime
# Base URL for the backend API
BASE_URL = "http://localhost:8000"
def test_health_check():
"""Test the health check endpoint"""
print("Testing health check endpoint...")
try:
response = requests.get(f"{BASE_URL}/")
print(f"Health check: {response.status_code} - {response.json()}")
return response.status_code == 200
except Exception as e:
print(f"Health check failed: {e}")
return False
def test_register_user():
"""Test user registration"""
print("Testing user registration...")
try:
# Generate unique email for testing
timestamp = str(int(datetime.now().timestamp()))
user_data = {
"email": f"testuser_{timestamp}@example.com",
"password": "securepassword123",
"name": f"Test User {timestamp}"
}
response = requests.post(f"{BASE_URL}/api/auth/register",
json=user_data,
headers={"Content-Type": "application/json"})
print(f"Registration: {response.status_code}")
if response.status_code == 201:
result = response.json()
print(f"User registered successfully: {result['user']['email']}")
return result['token'], result['user']['id']
else:
print(f"Registration failed: {response.status_code} - {response.text}")
return None, None
except Exception as e:
print(f"Registration test failed: {e}")
return None, None
def test_login_user():
"""Test user login"""
print("Testing user login...")
try:
# First register a user to login with
timestamp = str(int(datetime.now().timestamp()))
register_data = {
"email": f"login_test_{timestamp}@example.com",
"password": "securepassword123",
"name": f"Login Test {timestamp}"
}
register_response = requests.post(f"{BASE_URL}/api/auth/register",
json=register_data,
headers={"Content-Type": "application/json"})
if register_response.status_code != 201:
print(f"Failed to create test user for login: {register_response.status_code}")
return None
# Now try to login with the same credentials
login_data = {
"email": register_data["email"],
"password": register_data["password"]
}
response = requests.post(f"{BASE_URL}/api/auth/login",
json=login_data,
headers={"Content-Type": "application/json"})
print(f"Login: {response.status_code}")
if response.status_code == 200:
result = response.json()
print(f"User logged in successfully: {result['user']['email']}")
return result['token']
else:
print(f"Login failed: {response.status_code} - {response.text}")
return None
except Exception as e:
print(f"Login test failed: {e}")
return None
def test_task_crud_operations(token, user_id):
"""Test all task CRUD operations with authentication"""
print("Testing task CRUD operations...")
if not token:
print("No valid token provided for task operations")
return False
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# Test 1: Create a task
print(" Creating task...")
task_data = {
"title": "Test Task",
"description": "This is a test task",
"completed": False
}
try:
response = requests.post(f"{BASE_URL}/api/{user_id}/tasks",
json=task_data,
headers=headers)
print(f" Create task: {response.status_code}")
if response.status_code != 201:
print(f" Create task failed: {response.text}")
return False
created_task = response.json()
task_id = created_task['id']
print(f" Task created with ID: {task_id}")
# Test 2: Get all tasks for user
print(" Getting all tasks...")
response = requests.get(f"{BASE_URL}/api/{user_id}/tasks", headers=headers)
print(f" Get tasks: {response.status_code}")
if response.status_code != 200:
print(f" Get tasks failed: {response.text}")
return False
tasks = response.json()
print(f" Retrieved {len(tasks)} tasks")
# Test 3: Get specific task
print(" Getting specific task...")
response = requests.get(f"{BASE_URL}/api/{user_id}/tasks/{task_id}", headers=headers)
print(f" Get specific task: {response.status_code}")
if response.status_code != 200:
print(f" Get specific task failed: {response.text}")
return False
retrieved_task = response.json()
print(f" Retrieved task: {retrieved_task['title']}")
# Test 4: Update task
print(" Updating task...")
update_data = {
"title": "Updated Test Task",
"description": "This is an updated test task",
"completed": True
}
response = requests.put(f"{BASE_URL}/api/{user_id}/tasks/{task_id}",
json=update_data,
headers=headers)
print(f" Update task: {response.status_code}")
if response.status_code != 200:
print(f" Update task failed: {response.text}")
return False
updated_task = response.json()
print(f" Task updated: {updated_task['title']}")
# Test 5: Update task completion status
print(" Updating task completion status...")
completion_data = {"completed": False}
response = requests.patch(f"{BASE_URL}/api/{user_id}/tasks/{task_id}/complete",
json=completion_data,
headers=headers)
print(f" Update completion: {response.status_code}")
if response.status_code != 200:
print(f" Update completion failed: {response.text}")
return False
completed_task = response.json()
print(f" Completion updated: {completed_task['completed']}")
# Test 6: Delete task
print(" Deleting task...")
response = requests.delete(f"{BASE_URL}/api/{user_id}/tasks/{task_id}", headers=headers)
print(f" Delete task: {response.status_code}")
if response.status_code != 204:
print(f" Delete task failed: {response.text}")
return False
print(" Task deleted successfully")
return True
except Exception as e:
print(f"Task CRUD operations test failed: {e}")
return False
def test_logout_user(token):
"""Test user logout"""
print("Testing user logout...")
if not token:
print("No valid token provided for logout")
return False
try:
headers = {
"Authorization": f"Bearer {token}"
}
response = requests.post(f"{BASE_URL}/api/auth/logout", headers=headers)
print(f"Logout: {response.status_code}")
if response.status_code == 200:
print("User logged out successfully")
return True
else:
print(f"Logout failed: {response.text}")
return False
except Exception as e:
print(f"Logout test failed: {e}")
return False
def test_invalid_token():
"""Test API with invalid token"""
print("Testing API with invalid token...")
try:
headers = {
"Authorization": "Bearer invalid_token_here"
}
# Try to access a protected endpoint
response = requests.get(f"{BASE_URL}/api/1/tasks", headers=headers)
print(f"Invalid token test: {response.status_code}")
# Should return 401 for invalid token
return response.status_code == 401
except Exception as e:
print(f"Invalid token test failed: {e}")
return False
def run_all_tests():
"""Run all backend tests"""
print("=" * 60)
print("Starting Backend API Tests")
print("=" * 60)
results = {}
# Test 1: Health check
results['health_check'] = test_health_check()
# Test 2: User registration
token, user_id = test_register_user()
results['registration'] = token is not None
# Test 3: User login
login_token = test_login_user()
results['login'] = login_token is not None
# Test 4: Task CRUD operations (if we have a valid token from registration)
if token and user_id:
results['task_crud'] = test_task_crud_operations(token, user_id)
else:
results['task_crud'] = False
print("Skipping task CRUD tests - no valid token from registration")
# Test 5: Logout (if we have a valid login token)
if login_token:
results['logout'] = test_logout_user(login_token)
else:
results['logout'] = False
print("Skipping logout test - no valid login token")
# Test 6: Invalid token handling
results['invalid_token'] = test_invalid_token()
print("=" * 60)
print("Test Results Summary:")
print("=" * 60)
all_passed = True
for test_name, result in results.items():
status = "PASS" if result else "FAIL"
print(f"{test_name:20}: {status}")
if not result:
all_passed = False
print("=" * 60)
print(f"Overall Result: {'ALL TESTS PASSED' if all_passed else 'SOME TESTS FAILED'}")
print("=" * 60)
return all_passed
if __name__ == "__main__":
run_all_tests()