Spaces:
Sleeping
Sleeping
| import pytest | |
| from fastapi.testclient import TestClient | |
| from unittest.mock import patch, MagicMock | |
| from app.main import app | |
| from app.models.wardrobe import WardrobeItem | |
| from app.models.user import User | |
| from app.core.security import get_password_hash | |
| from app.core.database import get_db | |
| from app.workers.tasks import analyze_wardrobe_item | |
| import io | |
| client = TestClient(app) | |
| def override_db(db_session): | |
| # Override get_db dependency in FastAPI app | |
| app.dependency_overrides[get_db] = lambda: db_session | |
| yield | |
| app.dependency_overrides.clear() | |
| def test_user(db_session): | |
| user = User(email="test_wardrobe@example.com", password_hash=get_password_hash("password123")) | |
| db_session.add(user) | |
| db_session.commit() | |
| db_session.refresh(user) | |
| from app.api.deps import get_current_user | |
| app.dependency_overrides[get_current_user] = lambda: user | |
| yield user | |
| app.dependency_overrides.clear() | |
| def test_upload_wardrobe_item_success(db_session, test_user): | |
| # Construct a dummy JPEG file with valid Magic Bytes signature | |
| dummy_file = io.BytesIO(b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xd9") | |
| with patch("app.api.v1.wardrobe.storage_service.upload_file", return_value="http://localhost:8002/static/dummy.jpg") as mock_upload: | |
| with patch("app.api.v1.wardrobe.analyze_wardrobe_item.delay") as mock_delay: | |
| response = client.post( | |
| "/api/v1/wardrobe/upload", | |
| files={"file": ("test.jpg", dummy_file, "image/jpeg")} | |
| ) | |
| assert response.status_code == 201 | |
| data = response.json() | |
| assert data["category"] == "DETECTING" | |
| assert data["image_url"] == "http://localhost:8002/static/dummy.jpg" | |
| mock_upload.assert_called_once() | |
| mock_delay.assert_called_once_with(data["id"]) | |
| def test_upload_file_too_large(db_session, test_user): | |
| # Make a dummy file that exceeds 8MB | |
| huge_file = io.BytesIO(b"\xff\xd8\xff" + b"\x00" * (8 * 1024 * 1024 + 1)) | |
| response = client.post( | |
| "/api/v1/wardrobe/upload", | |
| files={"file": ("test.jpg", huge_file, "image/jpeg")} | |
| ) | |
| assert response.status_code == 413 | |
| assert "vượt quá" in response.json()["detail"] | |
| def test_upload_invalid_extension(db_session, test_user): | |
| dummy_file = io.BytesIO(b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xd9") | |
| response = client.post( | |
| "/api/v1/wardrobe/upload", | |
| files={"file": ("test.txt", dummy_file, "text/plain")} | |
| ) | |
| assert response.status_code == 400 | |
| assert "Định dạng tệp" in response.json()["detail"] | |
| def test_upload_invalid_signature(db_session, test_user): | |
| invalid_file = io.BytesIO(b"NotAJpegRealSignatureText") | |
| response = client.post( | |
| "/api/v1/wardrobe/upload", | |
| files={"file": ("test.jpg", invalid_file, "image/jpeg")} | |
| ) | |
| assert response.status_code == 400 | |
| assert "Nội dung tệp tin" in response.json()["detail"] | |
| def test_get_wardrobe_items(db_session, test_user): | |
| item1 = WardrobeItem(user_id=test_user.id, category="shirt", image_url="url1") | |
| item2 = WardrobeItem(user_id=test_user.id, category="pants", image_url="url2") | |
| db_session.add(item1) | |
| db_session.add(item2) | |
| db_session.commit() | |
| response = client.get("/api/v1/wardrobe/items") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert len(data) == 2 | |
| assert {d["category"] for d in data} == {"shirt", "pants"} | |
| def test_delete_wardrobe_item(db_session, test_user): | |
| item = WardrobeItem(user_id=test_user.id, category="shirt", image_url="http://localhost:8002/static/users/id/raw/test.jpg") | |
| db_session.add(item) | |
| db_session.commit() | |
| db_session.refresh(item) | |
| with patch("app.api.v1.wardrobe.storage_service.delete_file", return_value=True) as mock_delete: | |
| response = client.delete(f"/api/v1/wardrobe/items/{item.id}") | |
| assert response.status_code == 200 | |
| assert response.json()["status"] == "success" | |
| mock_delete.assert_called_once() | |