diff --git a/app/tests/test_category.py b/app/tests/test_category.py new file mode 100644 index 0000000000000000000000000000000000000000..ecd8f2ca9dfa016ba105d5c4a0febcd6a389e93f --- /dev/null +++ b/app/tests/test_category.py @@ -0,0 +1,212 @@ +import pytest +from fastapi.testclient import TestClient +from sqlmodel import Session +from app.backend.models.models import User, Category +from app.backend.utils.hashing import create_access_token + + +def create_test_admin(session: Session) -> User: + """Helper function to create an admin user""" + admin = User( + username="admin", + email="admin@test.com", + password="hashed_password", + phone_number="1234567890", + role="admin", + ) + session.add(admin) + session.commit() + session.refresh(admin) + return admin + + +def create_test_user(session: Session) -> User: + """Helper function to create a regular user""" + user = User( + username="user", + email="user@test.com", + password="hashed_password", + phone_number="1234567890", + role="buyer", + ) + session.add(user) + session.commit() + session.refresh(user) + return user + + +def get_auth_headers(user: User) -> dict: + """Helper function to create authorization headers""" + access_token = create_access_token({"sub": str(user.id)}) + return {"Authorization": f"Bearer {access_token}"} + + +def test_create_category(client: TestClient, db_session: Session): + # Create admin user and get auth headers + admin = create_test_admin(db_session) + headers = get_auth_headers(admin) + + # Test successful category creation + response = client.post( + "/category/create", headers=headers, data={"name": "Electronics"} + ) + assert response.status_code == 200 + assert response.json()["name"] == "Electronics" + + # Test duplicate category creation + response = client.post( + "/category/create", headers=headers, data={"name": "Electronics"} + ) + assert response.status_code == 400 + assert "already exists" in response.json()["detail"] + + +def test_create_category_unauthorized(client: TestClient, db_session: Session): + # Create regular user and get auth headers + user = create_test_user(db_session) + headers = get_auth_headers(user) + + # Test category creation with non-admin user + response = client.post( + "/category/create", headers=headers, data={"name": "Electronics"} + ) + assert response.status_code == 403 + assert "Admin access required" in response.json()["detail"] + + +def test_get_category(client: TestClient, db_session: Session): + # Create a category first + admin = create_test_admin(db_session) + category = Category(name="Electronics") + db_session.add(category) + db_session.commit() + db_session.refresh(category) + + # Test getting the category + response = client.get(f"/category/get/{category.id}") + assert response.status_code == 200 + assert response.json()["name"] == "Electronics" + + # Test getting non-existent category + response = client.get("/category/get/999") + assert response.status_code == 404 + + +def test_update_category(client: TestClient, db_session: Session): + # Create admin and category + admin = create_test_admin(db_session) + headers = get_auth_headers(admin) + + category = Category(name="Electronics") + db_session.add(category) + db_session.commit() + db_session.refresh(category) + + # Test successful update + response = client.put( + f"/category/put/{category.id}", + headers=headers, + data={"name": "New Electronics"}, + ) + assert response.status_code == 200 + assert response.json()["name"] == "New Electronics" + + # Test update with duplicate name + category2 = Category(name="Computers") + db_session.add(category2) + db_session.commit() + + response = client.put( + f"/category/put/{category.id}", headers=headers, data={"name": "Computers"} + ) + assert response.status_code == 400 + assert "already exists" in response.json()["detail"] + + +def test_update_category_unauthorized(client: TestClient, db_session: Session): + # Create regular user and category + user = create_test_user(db_session) + headers = get_auth_headers(user) + + category = Category(name="Electronics") + db_session.add(category) + db_session.commit() + db_session.refresh(category) + + # Test update with non-admin user + response = client.put( + f"/category/put/{category.id}", + headers=headers, + data={"name": "New Electronics"}, + ) + assert response.status_code == 403 + assert "Admin access required" in response.json()["detail"] + + # Test update without authentication + response = client.put( + f"/category/put/{category.id}", data={"name": "New Electronics"} + ) + assert response.status_code == 401 + assert "Not authenticated" in response.json()["detail"] + + +def test_delete_category(client: TestClient, db_session: Session): + # Create admin and category + admin = create_test_admin(db_session) + headers = get_auth_headers(admin) + + category = Category(name="Electronics") + db_session.add(category) + db_session.commit() + db_session.refresh(category) + + # Test successful deletion + response = client.delete(f"/category/delete/{category.id}", headers=headers) + assert response.status_code == 200 + assert "deleted successfully" in response.json()["message"] + + # Test deleting non-existent category + response = client.delete("/category/delete/999", headers=headers) + assert response.status_code == 404 + + +def test_delete_category_unauthorized(client: TestClient, db_session: Session): + # Create regular user and category + user = create_test_user(db_session) + headers = get_auth_headers(user) + + category = Category(name="Electronics") + db_session.add(category) + db_session.commit() + db_session.refresh(category) + + # Test deletion with non-admin user + response = client.delete(f"/category/delete/{category.id}", headers=headers) + assert response.status_code == 403 + assert "Admin access required" in response.json()["detail"] + + # Test deletion without authentication + response = client.delete(f"/category/delete/{category.id}") + assert response.status_code == 401 + assert "Not authenticated" in response.json()["detail"] + + +def test_get_all_categories(client: TestClient, db_session: Session): + # Create some categories + categories = [ + Category(name="Electronics"), + Category(name="Clothing"), + Category(name="Books"), + ] + for category in categories: + db_session.add(category) + db_session.commit() + + # Test getting all categories + response = client.get("/category") + assert response.status_code == 200 + assert len(response.json()) == 3 + category_names = [cat["name"] for cat in response.json()] + assert "Electronics" in category_names + assert "Clothing" in category_names + assert "Books" in category_names