import requests import time import json import sys BASE_URL = "http://localhost:8000" def log_test(name, status, details=""): icon = "āœ…" if status == "PASS" else "āŒ" print(f"{icon} [{name}] - {details}") def run_api_suite(): print(f"\nšŸš€ Starting API Testing Suite (Postman-style logic)\n" + "-"*50) # 1. AUTHENTICATION TEST try: login_res = requests.post(f"{BASE_URL}/users/login", json={ "username": "Admin", "password": "admin" }) if login_res.status_code == 200: token = login_res.json()["access_token"] log_test("Auth: Admin Login", "PASS", f"Status: {login_res.status_code}") else: log_test("Auth: Admin Login", "FAIL", f"Status: {login_res.status_code}") return except Exception as e: log_test("Auth: Admin Login", "FAIL", str(e)) return headers = {"Authorization": f"Bearer {token}"} # 2. STATUS CODES & CRUD try: item_res = requests.get(f"{BASE_URL}/items/", headers=headers) if item_res.status_code == 200: log_test("Items: List All", "PASS", f"Returned {len(item_res.json())} items") else: log_test("Items: List All", "FAIL", f"Status: {item_res.status_code}") except Exception as e: log_test("Items: List All", "FAIL", str(e)) # 3. RATE LIMITING TEST (Security Policy) print("\nā³ Testing Rate Limiting (Anti Brute-Force)...") limit_hit = False for i in range(12): # More than the 5/min limit res = requests.post(f"{BASE_URL}/users/login", json={"username": "fake", "password": "fake"}) if res.status_code == 429: limit_hit = True log_test("Security: Rate Limiter", "PASS", f"Blocked at attempt {i+1} (429 Too Many Requests)") break if not limit_hit: log_test("Security: Rate Limiter", "FAIL", "Limiter did not trigger after 12 quick requests") # 4. RBAC PROTECTION # Create a test item to delete test_item = requests.post(f"{BASE_URL}/items/", headers=headers, json={ "barcode": "API-TEST-999", "name": "API Test Item", "category": "Testing", "quantity": 10, "min_quantity": 1 }) if test_item.status_code == 201: item_id = test_item.json()["id"] log_test("Items: Create test resource", "PASS", f"ID: {item_id}") # Now try to delete it (as Admin - should pass) del_res = requests.delete(f"{BASE_URL}/items/{item_id}", headers=headers) if del_res.status_code == 200: log_test("RBAC: Admin Delete", "PASS", "Resource purged successfully") else: log_test("RBAC: Admin Delete", "FAIL", f"Status: {del_res.status_code}") else: # Check if it already exists from previous failed run if test_item.status_code == 400: log_test("Items: Create test resource", "PASS", "Resource already exists") else: log_test("Items: Create test resource", "FAIL", f"Status: {test_item.status_code}") # 5. ERROR STATES unauth_res = requests.get(f"{BASE_URL}/items/stats") if unauth_res.status_code == 401: log_test("Security: Unauth Block", "PASS", "Blocked 401 Unauthorized") else: log_test("Security: Unauth Block", "FAIL", f"Server allowed access! Status: {unauth_res.status_code}") print("\n" + "-"*50 + "\nšŸ API Test Suite Finished.") if __name__ == "__main__": run_api_suite()