"""Test API routes""" import pytest class TestAuthRoutes: """Test authentication routes""" @pytest.mark.auth def test_register_success(self, client): """Test successful user registration""" response = client.post( "/api/auth/register", json={ "email": "newuser@example.com", "password": "password123", "username": "newuser", "first_name": "New", "last_name": "User", }, ) assert response.status_code == 201 data = response.get_json() assert data["email"] == "newuser@example.com" assert data["username"] == "newuser" assert "password" not in data assert "password_hash" not in data @pytest.mark.auth def test_register_missing_fields(self, client): """Test registration with missing required fields""" response = client.post( "/api/auth/register", json={"email": "newuser@example.com"} ) assert response.status_code == 400 data = response.get_json() assert "error" in data @pytest.mark.auth def test_register_duplicate_email(self, client, regular_user): """Test registration with duplicate email""" response = client.post( "/api/auth/register", json={"email": regular_user.email, "password": "password123"}, ) assert response.status_code == 400 data = response.get_json() assert "already exists" in data["error"].lower() @pytest.mark.auth def test_login_success(self, client, regular_user): """Test successful login""" response = client.post( "/api/auth/login", json={"email": regular_user.email, "password": "password123"}, ) assert response.status_code == 200 data = response.get_json() assert "access_token" in data assert "refresh_token" in data assert data["user"]["email"] == regular_user.email @pytest.mark.auth @pytest.mark.parametrize( "email,password,expected_status", [ ("wrong@example.com", "password123", 401), ("user@example.com", "wrongpassword", 401), (None, "password123", 400), ("user@example.com", None, 400), ], ) def test_login_validation( self, client, regular_user, email, password, expected_status ): """Test login with various invalid inputs""" login_data = {} if email is not None: login_data["email"] = email if password is not None: login_data["password"] = password response = client.post("/api/auth/login", json=login_data) assert response.status_code == expected_status @pytest.mark.auth def test_login_inactive_user(self, client, inactive_user): """Test login with inactive user""" response = client.post( "/api/auth/login", json={"email": inactive_user.email, "password": "password123"}, ) assert response.status_code == 401 data = response.get_json() assert "inactive" in data["error"].lower() @pytest.mark.auth def test_get_current_user(self, client, auth_headers, regular_user): """Test getting current user""" response = client.get("/api/users/me", headers=auth_headers) assert response.status_code == 200 data = response.get_json() assert data["email"] == regular_user.email @pytest.mark.auth def test_get_current_user_unauthorized(self, client): """Test getting current user without authentication""" response = client.get("/api/users/me") assert response.status_code == 401 # class TestProductRoutes: # """Test product routes""" # @pytest.mark.product # def test_get_products(self, app, client, products): # """Test getting all products""" # from app.models import Product # before_count = Product.query.count() # response = client.get("/api/products") # assert response.status_code == 200 # data = response.get_json() # assert len(data) == before_count # @pytest.mark.product # def test_get_products_empty(self, client): # """Test getting products when none exist""" # from app.models import Product # before_count = Product.query.count() # response = client.get("/api/products") # assert response.status_code == 200 # data = response.get_json() # assert len(data) == before_count # @pytest.mark.product # def test_get_single_product(self, client, product): # """Test getting a single product""" # response = client.get(f"/api/products/{product.id}") # assert response.status_code == 200 # data = response.get_json() # assert data["id"] == product.id # assert data["name"] == product.name # @pytest.mark.product # def test_get_product_not_found(self, client): # """Test getting non-existent product""" # response = client.get("/api/products/999") # assert response.status_code == 404 # @pytest.mark.product # def test_create_product_admin(self, client, admin_headers): # """Test creating product as admin""" # response = client.post( # "/api/products", # headers=admin_headers, # json={ # "name": "New Product", # "description": "A new product", # "price": 29.99, # "stock": 10, # }, # ) # assert response.status_code == 201 # data = response.get_json() # assert data["name"] == "New Product" # assert data["price"] == 29.99 # @pytest.mark.product # def test_create_product_regular_user(self, client, auth_headers): # """Test creating product as regular user (should fail)""" # response = client.post( # "/api/products", # headers=auth_headers, # json={"name": "New Product", "price": 29.99}, # ) # assert response.status_code == 403 # data = response.get_json() # assert "admin" in data["error"].lower() # @pytest.mark.product # def test_create_product_unauthorized(self, client): # """Test creating product without authentication""" # response = client.post( # "/api/products", json={"name": "New Product", "price": 29.99} # ) # assert response.status_code == 401 # @pytest.mark.product # def test_create_product_validation_error(self, client, admin_headers): # """Test creating product with invalid data""" # response = client.post( # "/api/products", # headers=admin_headers, # json={"name": "New Product", "price": -10.99}, # ) # assert response.status_code == 400 # data = response.get_json() # assert "Validation error" in data["error"] # @pytest.mark.product # def test_create_product_missing_required_fields(self, client, admin_headers): # """Test creating product with missing required fields""" # response = client.post( # "/api/products", # headers=admin_headers, # json={"description": "Missing name and price"}, # ) # assert response.status_code == 400 # data = response.get_json() # assert "Validation error" in data["error"] # @pytest.mark.product # def test_create_product_minimal_data(self, client, admin_headers): # """Test creating product with minimal valid data""" # response = client.post( # "/api/products", # headers=admin_headers, # json={"name": "Minimal Product", "price": 19.99}, # ) # assert response.status_code == 201 # data = response.get_json() # assert data["name"] == "Minimal Product" # assert data["stock"] == 0 # Default value # @pytest.mark.product # def test_update_product_admin(self, client, admin_headers, product): # """Test updating product as admin""" # response = client.put( # f"/api/products/{product.id}", # headers=admin_headers, # json={"name": "Updated Product", "price": 39.99}, # ) # assert response.status_code == 200 # data = response.get_json() # assert data["name"] == "Updated Product" # assert data["price"] == 39.99 # @pytest.mark.product # def test_delete_product_admin(self, client, admin_headers, product): # """Test deleting product as admin""" # response = client.delete(f"/api/products/{product.id}", headers=admin_headers) # assert response.status_code == 200 # # Verify product is deleted # response = client.get(f"/api/products/{product.id}") # assert response.status_code == 404 # class TestOrderRoutes: # """Test order routes""" # @pytest.mark.order # def test_get_orders(self, client, auth_headers, order): # """Test getting orders for current user""" # response = client.get("/api/orders", headers=auth_headers) # assert response.status_code == 200 # data = response.get_json() # assert len(data) >= 1 # @pytest.mark.order # def test_get_orders_unauthorized(self, client): # """Test getting orders without authentication""" # response = client.get("/api/orders") # assert response.status_code == 401 # @pytest.mark.order # def test_create_order(self, client, auth_headers, products): # """Test creating an order""" # response = client.post( # "/api/orders", # headers=auth_headers, # json={ # "items": [ # {"product_id": products[0].id, "quantity": 2}, # {"product_id": products[1].id, "quantity": 1}, # ], # "shipping_address": "123 Test St", # }, # ) # assert response.status_code == 201 # data = response.get_json() # assert "id" in data # assert len(data["items"]) == 2 # @pytest.mark.order # def test_create_order_insufficient_stock( # self, client, auth_headers, db_session, products # ): # """Test creating order with insufficient stock""" # # Set stock to 0 # products[0].stock = 0 # db_session.commit() # response = client.post( # "/api/orders", # headers=auth_headers, # json={"items": [{"product_id": products[0].id, "quantity": 2}]}, # ) # assert response.status_code == 400 # data = response.get_json() # assert "insufficient" in data["error"].lower() # @pytest.mark.order # def test_get_single_order(self, client, auth_headers, order): # """Test getting a single order""" # response = client.get(f"/api/orders/{order.id}", headers=auth_headers) # print("test_get_single_order", response.get_json()) # assert response.status_code == 200 # data = response.get_json() # assert data["id"] == order.id # @pytest.mark.order # def test_get_other_users_order(self, client, admin_headers, regular_user, # products): # """Test admin accessing another user's order""" # # Create an order for regular_user # client.post( # "/api/auth/login", # json={"email": regular_user.email, "password": "password123"}, # ) # # Admin should be able to access any order # # This test assumes order exists, adjust as needed # pass