kashafaman123/Phase_3_Back
0
1"""2API-based database verification test3Tests database functionality through the FastAPI endpoints4"""5import requests6import json7from datetime import datetime8 9BASE_URL = "http://localhost:7860"10 11print("=" * 80)12print("API-BASED DATABASE VERIFICATION TEST")13print("=" * 80)14 15# Step 1: Health check16print("\n[1] Testing health endpoint...")17try:18 response = requests.get(f"{BASE_URL}/health")19 if response.status_code == 200:20 print(f" ✓ Server is healthy: {response.json()}")21 else:22 print(f" ✗ Health check failed: {response.status_code}")23 exit(1)24except Exception as e:25 print(f" ✗ Cannot connect to server: {e}")26 print(" ! Please ensure backend server is running: uvicorn src.main:app --reload")27 exit(1)28 29# Step 2: Register a test user30print("\n[2] Testing user registration (SQLModel User table)...")31test_email = f"test_{datetime.now().timestamp()}@example.com"32test_password = "TestPassword123!"33 34try:35 response = requests.post(36 f"{BASE_URL}/api/auth/register",37 json={"email": test_email, "password": test_password}38 )39 40 if response.status_code == 201:41 user_data = response.json()42 print(f" ✓ User registered successfully")43 print(f" - User ID: {user_data.get('user_id')}")44 print(f" - Email: {user_data.get('email')}")45 user_id = user_data.get('user_id')46 access_token = user_data.get('access_token')47 elif response.status_code == 400:48 print(f" ! User may already exist or validation error")49 print(f" {response.json()}")50 # Try to login instead51 print("\n[2b] Attempting login with existing credentials...")52 response = requests.post(53 f"{BASE_URL}/api/auth/login",54 json={"email": test_email, "password": test_password}55 )56 if response.status_code == 200:57 user_data = response.json()58 user_id = user_data.get('user_id')59 access_token = user_data.get('access_token')60 print(f" ✓ Logged in successfully")61 else:62 print(f" ✗ Registration and login failed")63 exit(1)64 else:65 print(f" ✗ Registration failed: {response.status_code}")66 print(f" {response.text}")67 exit(1)68except Exception as e:69 print(f" ✗ Error during registration: {e}")70 exit(1)71 72# Step 3: Create a task73print("\n[3] Testing task creation (SQLModel Task table with foreign key)...")74headers = {"Authorization": f"Bearer {access_token}"}75 76try:77 task_data = {78 "title": "Database Verification Task",79 "description": "Testing SQLModel ORM data persistence",80 "completed": False81 }82 83 response = requests.post(84 f"{BASE_URL}/api/{user_id}/tasks",85 headers=headers,86 json=task_data87 )88 89 if response.status_code == 201:90 created_task = response.json()91 print(f" ✓ Task created successfully")92 print(f" - Task ID: {created_task.get('id')}")93 print(f" - Title: {created_task.get('title')}")94 print(f" - User ID (FK): {created_task.get('user_id')}")95 print(f" - Created At: {created_task.get('created_at')}")96 task_id = created_task.get('id')97 else:98 print(f" ✗ Task creation failed: {response.status_code}")99 print(f" {response.text}")100 exit(1)101except Exception as e:102 print(f" ✗ Error creating task: {e}")103 exit(1)104 105# Step 4: Retrieve the task106print("\n[4] Testing task retrieval (verifying data persisted)...")107try:108 response = requests.get(109 f"{BASE_URL}/api/{user_id}/tasks/{task_id}",110 headers=headers111 )112 113 if response.status_code == 200:114 retrieved_task = response.json()115 print(f" ✓ Task retrieved successfully")116 print(f" - Title matches: {retrieved_task.get('title') == task_data['title']}")117 print(f" - Description matches: {retrieved_task.get('description') == task_data['description']}")118 else:119 print(f" ✗ Task retrieval failed: {response.status_code}")120 exit(1)121except Exception as e:122 print(f" ✗ Error retrieving task: {e}")123 exit(1)124 125# Step 5: Update the task126print("\n[5] Testing task update (verifying updated_at auto-update)...")127try:128 update_data = {129 "title": "Updated Database Verification Task",130 "description": "Updated to verify SQLModel ORM updates",131 "completed": False132 }133 134 response = requests.put(135 f"{BASE_URL}/api/{user_id}/tasks/{task_id}",136 headers=headers,137 json=update_data138 )139 140 if response.status_code == 200:141 updated_task = response.json()142 print(f" ✓ Task updated successfully")143 print(f" - New Title: {updated_task.get('title')}")144 print(f" - Updated At: {updated_task.get('updated_at')}")145 146 # Verify updated_at changed147 if updated_task.get('updated_at') != created_task.get('updated_at'):148 print(f" - ✓ updated_at timestamp changed automatically")149 else:150 print(f" - ! updated_at timestamp did not change")151 else:152 print(f" ✗ Task update failed: {response.status_code}")153 exit(1)154except Exception as e:155 print(f" ✗ Error updating task: {e}")156 exit(1)157 158# Step 6: Toggle completion159print("\n[6] Testing completion toggle...")160try:161 response = requests.patch(162 f"{BASE_URL}/api/{user_id}/tasks/{task_id}/complete",163 headers=headers164 )165 166 if response.status_code == 200:167 toggled_task = response.json()168 print(f" ✓ Task completion toggled")169 print(f" - Completed: {toggled_task.get('completed')}")170 else:171 print(f" ✗ Toggle failed: {response.status_code}")172 exit(1)173except Exception as e:174 print(f" ✗ Error toggling task: {e}")175 exit(1)176 177# Step 7: List all tasks (verify user isolation)178print("\n[7] Testing task listing (verifying user isolation via JWT)...")179try:180 response = requests.get(181 f"{BASE_URL}/api/{user_id}/tasks",182 headers=headers183 )184 185 if response.status_code == 200:186 tasks = response.json()187 print(f" ✓ Retrieved {len(tasks)} task(s)")188 print(f" - All tasks belong to user: {all(t.get('user_id') == user_id for t in tasks)}")189 else:190 print(f" ✗ Task listing failed: {response.status_code}")191 exit(1)192except Exception as e:193 print(f" ✗ Error listing tasks: {e}")194 exit(1)195 196# Step 8: Delete the task197print("\n[8] Testing task deletion...")198try:199 response = requests.delete(200 f"{BASE_URL}/api/{user_id}/tasks/{task_id}",201 headers=headers202 )203 204 if response.status_code == 204:205 print(f" ✓ Task deleted successfully")206 207 # Verify task is gone208 response = requests.get(209 f"{BASE_URL}/api/{user_id}/tasks/{task_id}",210 headers=headers211 )212 if response.status_code == 404:213 print(f" ✓ Deletion verified (task no longer exists)")214 else:215 print(f" ! Task still exists after deletion")216 else:217 print(f" ✗ Task deletion failed: {response.status_code}")218 exit(1)219except Exception as e:220 print(f" ✗ Error deleting task: {e}")221 exit(1)222 223print("\n" + "=" * 80)224print("✅ ALL DATABASE VERIFICATION TESTS PASSED")225print("=" * 80)226print("\nVerified:")227print(" ✓ SQLModel ORM is properly configured")228print(" ✓ User table stores authentication data")229print(" ✓ Task table stores todo items")230print(" ✓ Foreign key relationship (task.user_id → user.id) works")231print(" ✓ Data persists in PostgreSQL database")232print(" ✓ CRUD operations function correctly")233print(" ✓ Auto-updating timestamps work")234print(" ✓ User isolation enforced via JWT")235print("\nConclusion: SQLModel ORM with Neon PostgreSQL is working perfectly!")236print("=" * 80)237 