style: apply black and isort formatting across entire codebase
- Standardize quote style (single to double quotes) - Reorder and group imports alphabetically - Fix line breaks and indentation for consistency - Apply PEP 8 formatting standards Also updated Makefile to exclude both venv and .venv from code quality checks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -20,22 +20,26 @@ Requirements:
|
||||
* Customer: username=customer, password=customer123, vendor_id=1
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
from typing import Dict, Optional
|
||||
|
||||
import requests
|
||||
|
||||
BASE_URL = "http://localhost:8000"
|
||||
|
||||
|
||||
class Color:
|
||||
"""Terminal colors for pretty output"""
|
||||
GREEN = '\033[92m'
|
||||
RED = '\033[91m'
|
||||
YELLOW = '\033[93m'
|
||||
BLUE = '\033[94m'
|
||||
MAGENTA = '\033[95m'
|
||||
CYAN = '\033[96m'
|
||||
BOLD = '\033[1m'
|
||||
END = '\033[0m'
|
||||
|
||||
GREEN = "\033[92m"
|
||||
RED = "\033[91m"
|
||||
YELLOW = "\033[93m"
|
||||
BLUE = "\033[94m"
|
||||
MAGENTA = "\033[95m"
|
||||
CYAN = "\033[96m"
|
||||
BOLD = "\033[1m"
|
||||
END = "\033[0m"
|
||||
|
||||
|
||||
def print_section(name: str):
|
||||
"""Print section header"""
|
||||
@@ -43,66 +47,70 @@ def print_section(name: str):
|
||||
print(f" {name}")
|
||||
print(f"{'═' * 60}{Color.END}")
|
||||
|
||||
|
||||
def print_test(name: str):
|
||||
"""Print test name"""
|
||||
print(f"\n{Color.BOLD}{Color.BLUE}🧪 Test: {name}{Color.END}")
|
||||
|
||||
|
||||
def print_success(message: str):
|
||||
"""Print success message"""
|
||||
print(f"{Color.GREEN}✅ {message}{Color.END}")
|
||||
|
||||
|
||||
def print_error(message: str):
|
||||
"""Print error message"""
|
||||
print(f"{Color.RED}❌ {message}{Color.END}")
|
||||
|
||||
|
||||
def print_info(message: str):
|
||||
"""Print info message"""
|
||||
print(f"{Color.YELLOW}ℹ️ {message}{Color.END}")
|
||||
|
||||
|
||||
def print_warning(message: str):
|
||||
"""Print warning message"""
|
||||
print(f"{Color.MAGENTA}⚠️ {message}{Color.END}")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# ADMIN AUTHENTICATION TESTS
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def test_admin_login() -> Optional[Dict]:
|
||||
"""Test admin login and cookie configuration"""
|
||||
print_test("Admin Login")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/api/v1/admin/auth/login",
|
||||
json={"username": "admin", "password": "admin123"}
|
||||
json={"username": "admin", "password": "admin123"},
|
||||
)
|
||||
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
cookies = response.cookies
|
||||
|
||||
|
||||
if "access_token" in data:
|
||||
print_success("Admin login successful")
|
||||
print_success(f"Received access token: {data['access_token'][:20]}...")
|
||||
else:
|
||||
print_error("No access token in response")
|
||||
return None
|
||||
|
||||
|
||||
if "admin_token" in cookies:
|
||||
print_success("admin_token cookie set")
|
||||
print_info("Cookie path should be /admin (verify in browser)")
|
||||
else:
|
||||
print_error("admin_token cookie NOT set")
|
||||
|
||||
return {
|
||||
"token": data["access_token"],
|
||||
"user": data.get("user", {})
|
||||
}
|
||||
|
||||
return {"token": data["access_token"], "user": data.get("user", {})}
|
||||
else:
|
||||
print_error(f"Login failed: {response.status_code}")
|
||||
print_error(f"Response: {response.text}")
|
||||
return None
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception during admin login: {str(e)}")
|
||||
return None
|
||||
@@ -111,13 +119,13 @@ def test_admin_login() -> Optional[Dict]:
|
||||
def test_admin_cannot_access_vendor_api(admin_token: str):
|
||||
"""Test that admin token cannot access vendor API"""
|
||||
print_test("Admin Token on Vendor API (Should Block)")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{BASE_URL}/api/v1/vendor/TESTVENDOR/products",
|
||||
headers={"Authorization": f"Bearer {admin_token}"}
|
||||
headers={"Authorization": f"Bearer {admin_token}"},
|
||||
)
|
||||
|
||||
|
||||
if response.status_code in [401, 403]:
|
||||
data = response.json()
|
||||
print_success("Admin correctly blocked from vendor API")
|
||||
@@ -129,7 +137,7 @@ def test_admin_cannot_access_vendor_api(admin_token: str):
|
||||
else:
|
||||
print_warning(f"Unexpected status code: {response.status_code}")
|
||||
return False
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception: {str(e)}")
|
||||
return False
|
||||
@@ -138,13 +146,13 @@ def test_admin_cannot_access_vendor_api(admin_token: str):
|
||||
def test_admin_cannot_access_customer_api(admin_token: str):
|
||||
"""Test that admin token cannot access customer account pages"""
|
||||
print_test("Admin Token on Customer API (Should Block)")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{BASE_URL}/shop/account/dashboard",
|
||||
headers={"Authorization": f"Bearer {admin_token}"}
|
||||
headers={"Authorization": f"Bearer {admin_token}"},
|
||||
)
|
||||
|
||||
|
||||
# Customer pages may return HTML or JSON error
|
||||
if response.status_code in [401, 403]:
|
||||
print_success("Admin correctly blocked from customer pages")
|
||||
@@ -155,7 +163,7 @@ def test_admin_cannot_access_customer_api(admin_token: str):
|
||||
else:
|
||||
print_warning(f"Unexpected status code: {response.status_code}")
|
||||
return False
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception: {str(e)}")
|
||||
return False
|
||||
@@ -165,46 +173,47 @@ def test_admin_cannot_access_customer_api(admin_token: str):
|
||||
# VENDOR AUTHENTICATION TESTS
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def test_vendor_login() -> Optional[Dict]:
|
||||
"""Test vendor login and cookie configuration"""
|
||||
print_test("Vendor Login")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/api/v1/vendor/auth/login",
|
||||
json={"username": "vendor", "password": "vendor123"}
|
||||
json={"username": "vendor", "password": "vendor123"},
|
||||
)
|
||||
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
cookies = response.cookies
|
||||
|
||||
|
||||
if "access_token" in data:
|
||||
print_success("Vendor login successful")
|
||||
print_success(f"Received access token: {data['access_token'][:20]}...")
|
||||
else:
|
||||
print_error("No access token in response")
|
||||
return None
|
||||
|
||||
|
||||
if "vendor_token" in cookies:
|
||||
print_success("vendor_token cookie set")
|
||||
print_info("Cookie path should be /vendor (verify in browser)")
|
||||
else:
|
||||
print_error("vendor_token cookie NOT set")
|
||||
|
||||
|
||||
if "vendor" in data:
|
||||
print_success(f"Vendor: {data['vendor'].get('vendor_code', 'N/A')}")
|
||||
|
||||
|
||||
return {
|
||||
"token": data["access_token"],
|
||||
"user": data.get("user", {}),
|
||||
"vendor": data.get("vendor", {})
|
||||
"vendor": data.get("vendor", {}),
|
||||
}
|
||||
else:
|
||||
print_error(f"Login failed: {response.status_code}")
|
||||
print_error(f"Response: {response.text}")
|
||||
return None
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception during vendor login: {str(e)}")
|
||||
return None
|
||||
@@ -213,13 +222,13 @@ def test_vendor_login() -> Optional[Dict]:
|
||||
def test_vendor_cannot_access_admin_api(vendor_token: str):
|
||||
"""Test that vendor token cannot access admin API"""
|
||||
print_test("Vendor Token on Admin API (Should Block)")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{BASE_URL}/api/v1/admin/vendors",
|
||||
headers={"Authorization": f"Bearer {vendor_token}"}
|
||||
headers={"Authorization": f"Bearer {vendor_token}"},
|
||||
)
|
||||
|
||||
|
||||
if response.status_code in [401, 403]:
|
||||
data = response.json()
|
||||
print_success("Vendor correctly blocked from admin API")
|
||||
@@ -231,7 +240,7 @@ def test_vendor_cannot_access_admin_api(vendor_token: str):
|
||||
else:
|
||||
print_warning(f"Unexpected status code: {response.status_code}")
|
||||
return False
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception: {str(e)}")
|
||||
return False
|
||||
@@ -240,13 +249,13 @@ def test_vendor_cannot_access_admin_api(vendor_token: str):
|
||||
def test_vendor_cannot_access_customer_api(vendor_token: str):
|
||||
"""Test that vendor token cannot access customer account pages"""
|
||||
print_test("Vendor Token on Customer API (Should Block)")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{BASE_URL}/shop/account/dashboard",
|
||||
headers={"Authorization": f"Bearer {vendor_token}"}
|
||||
headers={"Authorization": f"Bearer {vendor_token}"},
|
||||
)
|
||||
|
||||
|
||||
if response.status_code in [401, 403]:
|
||||
print_success("Vendor correctly blocked from customer pages")
|
||||
return True
|
||||
@@ -256,7 +265,7 @@ def test_vendor_cannot_access_customer_api(vendor_token: str):
|
||||
else:
|
||||
print_warning(f"Unexpected status code: {response.status_code}")
|
||||
return False
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception: {str(e)}")
|
||||
return False
|
||||
@@ -266,42 +275,40 @@ def test_vendor_cannot_access_customer_api(vendor_token: str):
|
||||
# CUSTOMER AUTHENTICATION TESTS
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def test_customer_login() -> Optional[Dict]:
|
||||
"""Test customer login and cookie configuration"""
|
||||
print_test("Customer Login")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/api/v1/public/vendors/1/customers/login",
|
||||
json={"username": "customer", "password": "customer123"}
|
||||
json={"username": "customer", "password": "customer123"},
|
||||
)
|
||||
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
cookies = response.cookies
|
||||
|
||||
|
||||
if "access_token" in data:
|
||||
print_success("Customer login successful")
|
||||
print_success(f"Received access token: {data['access_token'][:20]}...")
|
||||
else:
|
||||
print_error("No access token in response")
|
||||
return None
|
||||
|
||||
|
||||
if "customer_token" in cookies:
|
||||
print_success("customer_token cookie set")
|
||||
print_info("Cookie path should be /shop (verify in browser)")
|
||||
else:
|
||||
print_error("customer_token cookie NOT set")
|
||||
|
||||
return {
|
||||
"token": data["access_token"],
|
||||
"user": data.get("user", {})
|
||||
}
|
||||
|
||||
return {"token": data["access_token"], "user": data.get("user", {})}
|
||||
else:
|
||||
print_error(f"Login failed: {response.status_code}")
|
||||
print_error(f"Response: {response.text}")
|
||||
return None
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception during customer login: {str(e)}")
|
||||
return None
|
||||
@@ -310,13 +317,13 @@ def test_customer_login() -> Optional[Dict]:
|
||||
def test_customer_cannot_access_admin_api(customer_token: str):
|
||||
"""Test that customer token cannot access admin API"""
|
||||
print_test("Customer Token on Admin API (Should Block)")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{BASE_URL}/api/v1/admin/vendors",
|
||||
headers={"Authorization": f"Bearer {customer_token}"}
|
||||
headers={"Authorization": f"Bearer {customer_token}"},
|
||||
)
|
||||
|
||||
|
||||
if response.status_code in [401, 403]:
|
||||
data = response.json()
|
||||
print_success("Customer correctly blocked from admin API")
|
||||
@@ -328,7 +335,7 @@ def test_customer_cannot_access_admin_api(customer_token: str):
|
||||
else:
|
||||
print_warning(f"Unexpected status code: {response.status_code}")
|
||||
return False
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception: {str(e)}")
|
||||
return False
|
||||
@@ -337,13 +344,13 @@ def test_customer_cannot_access_admin_api(customer_token: str):
|
||||
def test_customer_cannot_access_vendor_api(customer_token: str):
|
||||
"""Test that customer token cannot access vendor API"""
|
||||
print_test("Customer Token on Vendor API (Should Block)")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{BASE_URL}/api/v1/vendor/TESTVENDOR/products",
|
||||
headers={"Authorization": f"Bearer {customer_token}"}
|
||||
headers={"Authorization": f"Bearer {customer_token}"},
|
||||
)
|
||||
|
||||
|
||||
if response.status_code in [401, 403]:
|
||||
data = response.json()
|
||||
print_success("Customer correctly blocked from vendor API")
|
||||
@@ -355,7 +362,7 @@ def test_customer_cannot_access_vendor_api(customer_token: str):
|
||||
else:
|
||||
print_warning(f"Unexpected status code: {response.status_code}")
|
||||
return False
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception: {str(e)}")
|
||||
return False
|
||||
@@ -364,17 +371,17 @@ def test_customer_cannot_access_vendor_api(customer_token: str):
|
||||
def test_public_shop_access():
|
||||
"""Test that public shop pages are accessible without authentication"""
|
||||
print_test("Public Shop Access (No Auth Required)")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(f"{BASE_URL}/shop/products")
|
||||
|
||||
|
||||
if response.status_code == 200:
|
||||
print_success("Public shop pages accessible without auth")
|
||||
return True
|
||||
else:
|
||||
print_error(f"Failed to access public shop: {response.status_code}")
|
||||
return False
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception: {str(e)}")
|
||||
return False
|
||||
@@ -383,10 +390,10 @@ def test_public_shop_access():
|
||||
def test_health_check():
|
||||
"""Test health check endpoint"""
|
||||
print_test("Health Check")
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(f"{BASE_URL}/health")
|
||||
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print_success("Health check passed")
|
||||
@@ -395,7 +402,7 @@ def test_health_check():
|
||||
else:
|
||||
print_error(f"Health check failed: {response.status_code}")
|
||||
return False
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print_error(f"Exception: {str(e)}")
|
||||
return False
|
||||
@@ -405,19 +412,16 @@ def test_health_check():
|
||||
# MAIN TEST RUNNER
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def main():
|
||||
"""Run all tests"""
|
||||
print(f"\n{Color.BOLD}{Color.CYAN}{'═' * 60}")
|
||||
print(f" 🔒 COMPLETE AUTHENTICATION SYSTEM TEST SUITE")
|
||||
print(f"{'═' * 60}{Color.END}")
|
||||
print(f"Testing server at: {BASE_URL}")
|
||||
|
||||
results = {
|
||||
"passed": 0,
|
||||
"failed": 0,
|
||||
"total": 0
|
||||
}
|
||||
|
||||
|
||||
results = {"passed": 0, "failed": 0, "total": 0}
|
||||
|
||||
# Health check first
|
||||
print_section("🏥 System Health")
|
||||
results["total"] += 1
|
||||
@@ -427,12 +431,12 @@ def main():
|
||||
results["failed"] += 1
|
||||
print_error("Server not responding. Is it running?")
|
||||
return
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# ADMIN TESTS
|
||||
# ========================================================================
|
||||
print_section("👤 Admin Authentication Tests")
|
||||
|
||||
|
||||
# Admin login
|
||||
results["total"] += 1
|
||||
admin_auth = test_admin_login()
|
||||
@@ -441,7 +445,7 @@ def main():
|
||||
else:
|
||||
results["failed"] += 1
|
||||
admin_auth = None
|
||||
|
||||
|
||||
# Admin cross-context tests
|
||||
if admin_auth:
|
||||
results["total"] += 1
|
||||
@@ -449,18 +453,18 @@ def main():
|
||||
results["passed"] += 1
|
||||
else:
|
||||
results["failed"] += 1
|
||||
|
||||
|
||||
results["total"] += 1
|
||||
if test_admin_cannot_access_customer_api(admin_auth["token"]):
|
||||
results["passed"] += 1
|
||||
else:
|
||||
results["failed"] += 1
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# VENDOR TESTS
|
||||
# ========================================================================
|
||||
print_section("🏪 Vendor Authentication Tests")
|
||||
|
||||
|
||||
# Vendor login
|
||||
results["total"] += 1
|
||||
vendor_auth = test_vendor_login()
|
||||
@@ -469,7 +473,7 @@ def main():
|
||||
else:
|
||||
results["failed"] += 1
|
||||
vendor_auth = None
|
||||
|
||||
|
||||
# Vendor cross-context tests
|
||||
if vendor_auth:
|
||||
results["total"] += 1
|
||||
@@ -477,25 +481,25 @@ def main():
|
||||
results["passed"] += 1
|
||||
else:
|
||||
results["failed"] += 1
|
||||
|
||||
|
||||
results["total"] += 1
|
||||
if test_vendor_cannot_access_customer_api(vendor_auth["token"]):
|
||||
results["passed"] += 1
|
||||
else:
|
||||
results["failed"] += 1
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# CUSTOMER TESTS
|
||||
# ========================================================================
|
||||
print_section("🛒 Customer Authentication Tests")
|
||||
|
||||
|
||||
# Public shop access
|
||||
results["total"] += 1
|
||||
if test_public_shop_access():
|
||||
results["passed"] += 1
|
||||
else:
|
||||
results["failed"] += 1
|
||||
|
||||
|
||||
# Customer login
|
||||
results["total"] += 1
|
||||
customer_auth = test_customer_login()
|
||||
@@ -504,7 +508,7 @@ def main():
|
||||
else:
|
||||
results["failed"] += 1
|
||||
customer_auth = None
|
||||
|
||||
|
||||
# Customer cross-context tests
|
||||
if customer_auth:
|
||||
results["total"] += 1
|
||||
@@ -512,29 +516,31 @@ def main():
|
||||
results["passed"] += 1
|
||||
else:
|
||||
results["failed"] += 1
|
||||
|
||||
|
||||
results["total"] += 1
|
||||
if test_customer_cannot_access_vendor_api(customer_auth["token"]):
|
||||
results["passed"] += 1
|
||||
else:
|
||||
results["failed"] += 1
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# RESULTS
|
||||
# ========================================================================
|
||||
print_section("📊 Test Results")
|
||||
print(f"\n{Color.BOLD}Total Tests: {results['total']}{Color.END}")
|
||||
print_success(f"Passed: {results['passed']}")
|
||||
if results['failed'] > 0:
|
||||
if results["failed"] > 0:
|
||||
print_error(f"Failed: {results['failed']}")
|
||||
|
||||
if results['failed'] == 0:
|
||||
|
||||
if results["failed"] == 0:
|
||||
print(f"\n{Color.GREEN}{Color.BOLD}🎉 ALL TESTS PASSED!{Color.END}")
|
||||
print(f"{Color.GREEN}Your authentication system is properly isolated!{Color.END}")
|
||||
print(
|
||||
f"{Color.GREEN}Your authentication system is properly isolated!{Color.END}"
|
||||
)
|
||||
else:
|
||||
print(f"\n{Color.RED}{Color.BOLD}⚠️ SOME TESTS FAILED{Color.END}")
|
||||
print(f"{Color.RED}Please review the output above.{Color.END}")
|
||||
|
||||
|
||||
# Browser tests reminder
|
||||
print_section("🌐 Manual Browser Tests")
|
||||
print("Please also verify in browser:")
|
||||
|
||||
Reference in New Issue
Block a user