carvite / api /test /main.py
Khan19970's picture
Upload 57 files
c411a0f verified
from __future__ import annotations
import os
import sys
import shutil
from pathlib import Path
import pytest
from fastapi.testclient import TestClient
# -----------------------------------------------------------------------------
# Paths
# -----------------------------------------------------------------------------
THIS_FILE = Path(__file__).resolve()
TESTS_DIR = THIS_FILE.parent
MOCK_DIR = TESTS_DIR / "mock"
TEST_IMAGES_DIR = TESTS_DIR / "images"
TEST_INPUT_DIR = TEST_IMAGES_DIR / "input"
TEST_OUTPUT_DIR = TEST_IMAGES_DIR / "output"
API_DIR = THIS_FILE.parents[1] # -> api/
sys.path.insert(0, str(API_DIR))
# Tell the app to write under api/test/images instead of ./images
os.environ["IMAGE_BASE_DIR"] = str(TEST_IMAGES_DIR)
import src.main as api_module # noqa: E402
# -----------------------------------------------------------------------------
# helpers
# -----------------------------------------------------------------------------
def _reset_test_images_dir() -> None:
"""Delete api/test/images if it exists, then recreate input/output."""
if TEST_IMAGES_DIR.exists():
shutil.rmtree(TEST_IMAGES_DIR)
TEST_INPUT_DIR.mkdir(parents=True, exist_ok=True)
TEST_OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
# -----------------------------------------------------------------------------
# fixtures
# -----------------------------------------------------------------------------
@pytest.fixture(autouse=True)
def _clean_fs_before_each_test(request: pytest.FixtureRequest):
"""
Runs before EVERY test, EXCEPT the final 'zz' test (so artifacts remain after suite).
"""
if request.node.name == "test_zz_upload_image_saves_files_in_input_and_output_folders":
return
_reset_test_images_dir()
@pytest.fixture
def client() -> TestClient:
return TestClient(api_module.app)
# -----------------------------------------------------------------------------
# tests
# -----------------------------------------------------------------------------
def test_hello_world_endpoint(client: TestClient):
res = client.get("/")
assert res.status_code == 200
assert res.json() == {"Hello": "World"}
def test_non_image_uploaded_returns_400_and_saves_nothing(client: TestClient):
pdf_path = MOCK_DIR / "sample.pdf"
assert pdf_path.exists(), f"Missing mock pdf: {pdf_path}"
files = {"image": (pdf_path.name, pdf_path.read_bytes(), "application/pdf")}
res = client.post("/upload-image", files=files)
assert res.status_code == 400, res.text
assert res.json()["detail"] == "File is not an image."
assert list(TEST_INPUT_DIR.glob("*")) == []
assert list(TEST_OUTPUT_DIR.glob("*")) == []
def test_invalid_extension_returns_400_and_saves_nothing(client: TestClient):
bad_path = MOCK_DIR / "bad.txt"
assert bad_path.exists(), f"Missing bad file: {bad_path}"
files = {"image": (bad_path.name, bad_path.read_bytes(), "image/png")}
res = client.post("/upload-image", files=files)
assert res.status_code == 400, res.text
assert res.json()["detail"] == "Invalid file extension."
assert list(TEST_INPUT_DIR.glob("*")) == []
assert list(TEST_OUTPUT_DIR.glob("*")) == []
def test_missing_image_returns_422(client: TestClient):
res = client.post("/upload-image", files={})
assert res.status_code == 422
def test_zz_upload_image_saves_files_in_input_and_output_folders(client: TestClient):
"""
Real integration run:
- start clean
- send sample.jpg
- verify 1 file in input and 1 in output
- leave artifacts so you can visually inspect output image after the suite
"""
# IMPORTANT: ensure this test starts clean
_reset_test_images_dir()
img_path = MOCK_DIR / "sample.jpg"
assert img_path.exists(), f"Missing mock image: {img_path}"
files = {"image": (img_path.name, img_path.read_bytes(), "image/jpeg")}
res = client.post("/upload-image", files=files)
assert res.status_code == 200, res.text
input_files = list(TEST_INPUT_DIR.glob("*"))
output_files = list(TEST_OUTPUT_DIR.glob("*"))
assert len(input_files) == 1, f"Expected 1 input file, found: {input_files}"
assert len(output_files) == 1, f"Expected 1 output file, found: {output_files}"
assert input_files[0].name == "sample.jpg"
assert output_files[0].name == "sample_processed.png"