284 lines
10 KiB
Python
284 lines
10 KiB
Python
|
|
import requests
|
||
|
|
import sys
|
||
|
|
import json
|
||
|
|
from datetime import datetime
|
||
|
|
|
||
|
|
class TechZoneAPITester:
|
||
|
|
def __init__(self, base_url="https://dev-foundry.preview.emergentagent.com/api"):
|
||
|
|
self.base_url = base_url
|
||
|
|
self.token = None
|
||
|
|
self.user_id = None
|
||
|
|
self.tests_run = 0
|
||
|
|
self.tests_passed = 0
|
||
|
|
self.test_results = []
|
||
|
|
|
||
|
|
def log_test(self, name, success, details=""):
|
||
|
|
"""Log test result"""
|
||
|
|
self.tests_run += 1
|
||
|
|
if success:
|
||
|
|
self.tests_passed += 1
|
||
|
|
|
||
|
|
result = {
|
||
|
|
"test": name,
|
||
|
|
"success": success,
|
||
|
|
"details": details,
|
||
|
|
"timestamp": datetime.now().isoformat()
|
||
|
|
}
|
||
|
|
self.test_results.append(result)
|
||
|
|
|
||
|
|
status = "✅ PASS" if success else "❌ FAIL"
|
||
|
|
print(f"{status} - {name}")
|
||
|
|
if details:
|
||
|
|
print(f" Details: {details}")
|
||
|
|
|
||
|
|
def run_test(self, name, method, endpoint, expected_status, data=None, headers=None):
|
||
|
|
"""Run a single API test"""
|
||
|
|
url = f"{self.base_url}/{endpoint}"
|
||
|
|
test_headers = {'Content-Type': 'application/json'}
|
||
|
|
|
||
|
|
if self.token:
|
||
|
|
test_headers['Authorization'] = f'Bearer {self.token}'
|
||
|
|
|
||
|
|
if headers:
|
||
|
|
test_headers.update(headers)
|
||
|
|
|
||
|
|
try:
|
||
|
|
if method == 'GET':
|
||
|
|
response = requests.get(url, headers=test_headers, timeout=10)
|
||
|
|
elif method == 'POST':
|
||
|
|
response = requests.post(url, json=data, headers=test_headers, timeout=10)
|
||
|
|
elif method == 'PUT':
|
||
|
|
response = requests.put(url, json=data, headers=test_headers, timeout=10)
|
||
|
|
elif method == 'DELETE':
|
||
|
|
response = requests.delete(url, headers=test_headers, timeout=10)
|
||
|
|
|
||
|
|
success = response.status_code == expected_status
|
||
|
|
details = f"Status: {response.status_code}, Expected: {expected_status}"
|
||
|
|
|
||
|
|
if not success:
|
||
|
|
try:
|
||
|
|
error_data = response.json()
|
||
|
|
details += f", Response: {error_data}"
|
||
|
|
except:
|
||
|
|
details += f", Response: {response.text[:200]}"
|
||
|
|
|
||
|
|
self.log_test(name, success, details)
|
||
|
|
|
||
|
|
if success:
|
||
|
|
try:
|
||
|
|
return response.json()
|
||
|
|
except:
|
||
|
|
return {"status": "success"}
|
||
|
|
return None
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
self.log_test(name, False, f"Error: {str(e)}")
|
||
|
|
return None
|
||
|
|
|
||
|
|
def test_root_endpoint(self):
|
||
|
|
"""Test root API endpoint"""
|
||
|
|
return self.run_test("Root API", "GET", "", 200)
|
||
|
|
|
||
|
|
def test_seed_data(self):
|
||
|
|
"""Test seeding data"""
|
||
|
|
return self.run_test("Seed Data", "POST", "seed", 200)
|
||
|
|
|
||
|
|
def test_user_registration(self):
|
||
|
|
"""Test user registration"""
|
||
|
|
test_user_data = {
|
||
|
|
"name": f"Test User {datetime.now().strftime('%H%M%S')}",
|
||
|
|
"email": f"test_{datetime.now().strftime('%H%M%S')}@example.com",
|
||
|
|
"password": "testpass123"
|
||
|
|
}
|
||
|
|
|
||
|
|
response = self.run_test("User Registration", "POST", "auth/register", 200, test_user_data)
|
||
|
|
if response and 'access_token' in response:
|
||
|
|
self.token = response['access_token']
|
||
|
|
self.user_id = response['user']['id']
|
||
|
|
return True
|
||
|
|
return False
|
||
|
|
|
||
|
|
def test_user_login(self):
|
||
|
|
"""Test user login with admin credentials"""
|
||
|
|
login_data = {
|
||
|
|
"email": "admin@techzone.com",
|
||
|
|
"password": "admin123"
|
||
|
|
}
|
||
|
|
|
||
|
|
response = self.run_test("User Login (Admin)", "POST", "auth/login", 200, login_data)
|
||
|
|
if response and 'access_token' in response:
|
||
|
|
self.token = response['access_token']
|
||
|
|
self.user_id = response['user']['id']
|
||
|
|
return True
|
||
|
|
return False
|
||
|
|
|
||
|
|
def test_get_current_user(self):
|
||
|
|
"""Test getting current user info"""
|
||
|
|
return self.run_test("Get Current User", "GET", "auth/me", 200)
|
||
|
|
|
||
|
|
def test_get_products(self):
|
||
|
|
"""Test getting all products"""
|
||
|
|
response = self.run_test("Get All Products", "GET", "products", 200)
|
||
|
|
return response is not None
|
||
|
|
|
||
|
|
def test_get_products_with_filters(self):
|
||
|
|
"""Test getting products with filters"""
|
||
|
|
# Test category filter
|
||
|
|
self.run_test("Get Products by Category", "GET", "products?category=phones", 200)
|
||
|
|
|
||
|
|
# Test search filter
|
||
|
|
self.run_test("Get Products by Search", "GET", "products?search=iPhone", 200)
|
||
|
|
|
||
|
|
# Test price filter
|
||
|
|
self.run_test("Get Products by Price", "GET", "products?min_price=100&max_price=1000", 200)
|
||
|
|
|
||
|
|
def test_get_product_detail(self):
|
||
|
|
"""Test getting product details"""
|
||
|
|
# First get products to get an ID
|
||
|
|
products_response = self.run_test("Get Products for Detail Test", "GET", "products", 200)
|
||
|
|
if products_response and len(products_response) > 0:
|
||
|
|
product_id = products_response[0]['id']
|
||
|
|
return self.run_test("Get Product Detail", "GET", f"products/{product_id}", 200)
|
||
|
|
return False
|
||
|
|
|
||
|
|
def test_get_categories(self):
|
||
|
|
"""Test getting product categories"""
|
||
|
|
return self.run_test("Get Product Categories", "GET", "products/categories/list", 200)
|
||
|
|
|
||
|
|
def test_get_services(self):
|
||
|
|
"""Test getting all services"""
|
||
|
|
response = self.run_test("Get All Services", "GET", "services", 200)
|
||
|
|
return response is not None
|
||
|
|
|
||
|
|
def test_get_services_with_filter(self):
|
||
|
|
"""Test getting services with category filter"""
|
||
|
|
self.run_test("Get Services by Category", "GET", "services?category=repair", 200)
|
||
|
|
|
||
|
|
def test_get_service_detail(self):
|
||
|
|
"""Test getting service details"""
|
||
|
|
# First get services to get an ID
|
||
|
|
services_response = self.run_test("Get Services for Detail Test", "GET", "services", 200)
|
||
|
|
if services_response and len(services_response) > 0:
|
||
|
|
service_id = services_response[0]['id']
|
||
|
|
return self.run_test("Get Service Detail", "GET", f"services/{service_id}", 200)
|
||
|
|
return False
|
||
|
|
|
||
|
|
def test_cart_operations(self):
|
||
|
|
"""Test cart operations (requires authentication)"""
|
||
|
|
if not self.token:
|
||
|
|
self.log_test("Cart Operations", False, "No authentication token")
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Get a product ID first
|
||
|
|
products_response = self.run_test("Get Products for Cart Test", "GET", "products", 200)
|
||
|
|
if not products_response or len(products_response) == 0:
|
||
|
|
self.log_test("Cart Operations", False, "No products available")
|
||
|
|
return False
|
||
|
|
|
||
|
|
product_id = products_response[0]['id']
|
||
|
|
|
||
|
|
# Test adding to cart
|
||
|
|
add_cart_data = {"product_id": product_id, "quantity": 2}
|
||
|
|
self.run_test("Add to Cart", "POST", "cart/add", 200, add_cart_data)
|
||
|
|
|
||
|
|
# Test getting cart
|
||
|
|
cart_response = self.run_test("Get Cart", "GET", "cart", 200)
|
||
|
|
|
||
|
|
# Test clearing cart
|
||
|
|
self.run_test("Clear Cart", "DELETE", "cart", 200)
|
||
|
|
|
||
|
|
return True
|
||
|
|
|
||
|
|
def test_contact_form(self):
|
||
|
|
"""Test contact form submission"""
|
||
|
|
contact_data = {
|
||
|
|
"name": "Test User",
|
||
|
|
"email": "test@example.com",
|
||
|
|
"subject": "Test Subject",
|
||
|
|
"message": "This is a test message from automated testing."
|
||
|
|
}
|
||
|
|
|
||
|
|
return self.run_test("Contact Form Submission", "POST", "contact", 200, contact_data)
|
||
|
|
|
||
|
|
def test_service_booking(self):
|
||
|
|
"""Test service booking"""
|
||
|
|
# First get a service ID
|
||
|
|
services_response = self.run_test("Get Services for Booking Test", "GET", "services", 200)
|
||
|
|
if not services_response or len(services_response) == 0:
|
||
|
|
self.log_test("Service Booking", False, "No services available")
|
||
|
|
return False
|
||
|
|
|
||
|
|
service_id = services_response[0]['id']
|
||
|
|
|
||
|
|
booking_data = {
|
||
|
|
"service_id": service_id,
|
||
|
|
"name": "Test Customer",
|
||
|
|
"email": "customer@example.com",
|
||
|
|
"phone": "+1234567890",
|
||
|
|
"preferred_date": "2024-12-25",
|
||
|
|
"notes": "Test booking from automated testing"
|
||
|
|
}
|
||
|
|
|
||
|
|
return self.run_test("Service Booking", "POST", "services/book", 200, booking_data)
|
||
|
|
|
||
|
|
def run_all_tests(self):
|
||
|
|
"""Run all API tests"""
|
||
|
|
print("🚀 Starting TechZone API Tests...")
|
||
|
|
print(f"📍 Testing against: {self.base_url}")
|
||
|
|
print("=" * 50)
|
||
|
|
|
||
|
|
# Test basic endpoints
|
||
|
|
self.test_root_endpoint()
|
||
|
|
self.test_seed_data()
|
||
|
|
|
||
|
|
# Test authentication
|
||
|
|
auth_success = self.test_user_registration()
|
||
|
|
if not auth_success:
|
||
|
|
# Try admin login if registration fails
|
||
|
|
auth_success = self.test_user_login()
|
||
|
|
|
||
|
|
if auth_success:
|
||
|
|
self.test_get_current_user()
|
||
|
|
|
||
|
|
# Test products
|
||
|
|
self.test_get_products()
|
||
|
|
self.test_get_products_with_filters()
|
||
|
|
self.test_get_product_detail()
|
||
|
|
self.test_get_categories()
|
||
|
|
|
||
|
|
# Test services
|
||
|
|
self.test_get_services()
|
||
|
|
self.test_get_services_with_filter()
|
||
|
|
self.test_get_service_detail()
|
||
|
|
|
||
|
|
# Test cart (requires auth)
|
||
|
|
if self.token:
|
||
|
|
self.test_cart_operations()
|
||
|
|
|
||
|
|
# Test contact form
|
||
|
|
self.test_contact_form()
|
||
|
|
|
||
|
|
# Test service booking
|
||
|
|
self.test_service_booking()
|
||
|
|
|
||
|
|
# Print summary
|
||
|
|
print("=" * 50)
|
||
|
|
print(f"📊 Tests completed: {self.tests_passed}/{self.tests_run}")
|
||
|
|
success_rate = (self.tests_passed / self.tests_run * 100) if self.tests_run > 0 else 0
|
||
|
|
print(f"📈 Success rate: {success_rate:.1f}%")
|
||
|
|
|
||
|
|
if self.tests_passed < self.tests_run:
|
||
|
|
print("\n❌ Failed tests:")
|
||
|
|
for result in self.test_results:
|
||
|
|
if not result['success']:
|
||
|
|
print(f" - {result['test']}: {result['details']}")
|
||
|
|
|
||
|
|
return self.tests_passed == self.tests_run
|
||
|
|
|
||
|
|
def main():
|
||
|
|
tester = TechZoneAPITester()
|
||
|
|
success = tester.run_all_tests()
|
||
|
|
return 0 if success else 1
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
sys.exit(main())
|