From a763181b740bbea01b0b69c42f6cbbb74bce4bfa Mon Sep 17 00:00:00 2001 From: "Schmidt Till (CSS TO PME DSI PAO MUC)" Date: Thu, 10 Sep 2026 23:37:23 +0200 Subject: [PATCH] refactor: parameterize e2e tests and add CLI stdout assertions --- tests/test_e2e.py | 94 +++++++++++------------------------------------ 1 file changed, 21 insertions(+), 73 deletions(-) diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 144867e..28f5bce 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -40,23 +40,28 @@ def test_e2e_root_serves_html_with_title_and_dropzone(): assert "drop-zone" in html_lower or "dropzone" in html_lower -def test_e2e_api_clean_end_to_end(): - """Test FastAPI POST /api/clean end-to-end with high-res image and Lanczos restoration.""" +import pytest + +@pytest.mark.parametrize( + "orig_dims,model_dims,prompt,cost,color", + [ + ((1200, 1600), (600, 800), "Soft warm beige studio background, evenly lit, no shadows, no props.", 0.0125, "navy"), + ((1500, 2000), (750, 1000), "Minimalist bright studio setting with directional softbox lighting.", 0.015, "darkgreen"), + ], +) +def test_e2e_api_clean_end_to_end(orig_dims, model_dims, prompt, cost, color): + """Test FastAPI POST /api/clean end-to-end with high-res images, Lanczos restoration, and custom prompts.""" client = TestClient(app) + orig_width, orig_height = orig_dims + model_width, model_height = model_dims - orig_width, orig_height = 1200, 1600 - model_width, model_height = 600, 800 - - # Create high-resolution synthetic image (1200x1600) - high_res_bytes = _create_synthetic_image(orig_width, orig_height, color="navy") - - # Create lower-resolution synthetic image representing model output (600x800) + high_res_bytes = _create_synthetic_image(orig_width, orig_height, color=color) low_res_bytes = _create_synthetic_image(model_width, model_height, color="beige") b64_low_res = base64.b64encode(low_res_bytes).decode() mock_openrouter_response = { "data": [{"b64_json": b64_low_res, "media_type": "image/jpeg"}], - "usage": {"cost": 0.0125}, + "usage": {"cost": cost}, } class MockResponse: @@ -65,71 +70,13 @@ def test_e2e_api_clean_end_to_end(): def json(self): return mock_openrouter_response - files = {"file": ("high_res_garment.jpg", high_res_bytes, "image/jpeg")} + files = {"file": ("garment.jpg", high_res_bytes, "image/jpeg")} form_data = { - "prompt": "Soft warm beige studio background, evenly lit, no shadows, no props.", + "prompt": prompt, "api_key": "sk-or-v1-fake-e2e-key", "restore_res": "true", } - with patch("cleaner.requests.post", return_value=MockResponse()) as mock_post: - response = client.post("/api/clean", files=files, data=form_data) - - assert response.status_code == 200 - mock_post.assert_called_once() - - payload = response.json() - - # Verify was_rescaled is True - assert payload["was_rescaled"] is True - # Verify original_dimensions and model_dimensions match expectations - assert payload["original_dimensions"] == [orig_width, orig_height] - assert payload["model_dimensions"] == [model_width, model_height] - assert payload["width"] == orig_width - assert payload["height"] == orig_height - # Verify cost is reported - assert payload["cost"] == 0.0125 - - # Verify decoded output image matches exact source dimensions thanks to Lanczos restoration - image_data_uri = payload["image"] - assert image_data_uri.startswith("data:image/jpeg;base64,") - encoded_data = image_data_uri.split(",", 1)[1] - decoded_bytes = base64.b64decode(encoded_data) - - with Image.open(io.BytesIO(decoded_bytes)) as result_img: - assert result_img.size == (orig_width, orig_height) - - -def test_e2e_api_clean_with_custom_prompt_and_1500x2000(): - """Test FastAPI POST /api/clean with custom prompt and 1500x2000 dimensions.""" - client = TestClient(app) - - orig_width, orig_height = 1500, 2000 - model_width, model_height = 750, 1000 - - high_res_bytes = _create_synthetic_image(orig_width, orig_height, color="darkgreen") - low_res_bytes = _create_synthetic_image(model_width, model_height, color="white") - b64_low_res = base64.b64encode(low_res_bytes).decode() - - mock_openrouter_response = { - "data": [{"b64_json": b64_low_res, "media_type": "image/jpeg"}], - "usage": {"cost": 0.015}, - } - - class MockResponse: - status_code = 200 - - def json(self): - return mock_openrouter_response - - files = {"file": ("catalog_garment.jpg", high_res_bytes, "image/jpeg")} - custom_prompt = "Minimalist bright studio setting with directional softbox lighting." - form_data = { - "prompt": custom_prompt, - "api_key": "sk-or-v1-custom-prompt-key", - "restore_res": "true", - } - with patch("cleaner.requests.post", return_value=MockResponse()) as mock_post: response = client.post("/api/clean", files=files, data=form_data) @@ -142,14 +89,13 @@ def test_e2e_api_clean_with_custom_prompt_and_1500x2000(): assert payload["model_dimensions"] == [model_width, model_height] assert payload["width"] == orig_width assert payload["height"] == orig_height - assert payload["cost"] == 0.015 + assert payload["cost"] == cost encoded_data = payload["image"].split(",", 1)[1] decoded_bytes = base64.b64decode(encoded_data) with Image.open(io.BytesIO(decoded_bytes)) as result_img: assert result_img.size == (orig_width, orig_height) - def test_e2e_cli_subprocess_end_to_end(tmp_path): """Test CLI unwrap_clothes.py end-to-end via subprocess with mocked OpenRouter.""" orig_width, orig_height = 1200, 1600 @@ -215,8 +161,10 @@ def test_e2e_cli_subprocess_end_to_end(tmp_path): # Verify exit code 0 assert proc.returncode == 0, f"CLI failed with stderr: {proc.stderr}\nstdout: {proc.stdout}" + assert "Restored resolution" in proc.stdout + assert "cost $0.02" in proc.stdout + assert "Saved:" in proc.stdout - # Verify output file _clean.jpg is created with exact source dimensions assert expected_clean_path.is_file(), f"Output file {expected_clean_path} was not created" with Image.open(expected_clean_path) as out_img: assert out_img.size == (orig_width, orig_height)