mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-23 02:06:36 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import pytest
|
||||
import io
|
||||
from fastapi.testclient import TestClient
|
||||
from unittest.mock import Mock
|
||||
from fastapi import FastAPI
|
||||
|
||||
from f01_flight_api import router, get_lifecycle_manager
|
||||
from f02_1_flight_lifecycle_manager import FlightLifecycleManager
|
||||
|
||||
# --- Setup ---
|
||||
|
||||
app = FastAPI()
|
||||
app.include_router(router)
|
||||
mock_manager = Mock(spec=FlightLifecycleManager)
|
||||
app.dependency_overrides[get_lifecycle_manager] = lambda: mock_manager
|
||||
client = TestClient(app)
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_mocks():
|
||||
mock_manager.reset_mock()
|
||||
mock_manager.queue_images.return_value = True
|
||||
|
||||
def create_dummy_file(filename: str, content: bytes = b"dummy_image_data", content_type: str = "image/jpeg"):
|
||||
return ("images", (filename, content, content_type))
|
||||
|
||||
# --- Unit Tests ---
|
||||
|
||||
class TestUnitImageUpload:
|
||||
"""Unit tests defined in 01.02_feature_image_upload.md"""
|
||||
|
||||
def test_batch_size_validation(self):
|
||||
flight_id = "flight_123"
|
||||
|
||||
# 1. Too few (9 images) -> 400
|
||||
files_too_few = [create_dummy_file(f"AD{i:06d}.jpg") for i in range(1, 10)]
|
||||
resp = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 1, "end_sequence": 9, "batch_number": 1}, files=files_too_few)
|
||||
assert resp.status_code == 400
|
||||
assert "between 10 and 50" in resp.json()["detail"]
|
||||
|
||||
# 2. Too many (51 images) -> 400
|
||||
files_too_many = [create_dummy_file(f"AD{i:06d}.jpg") for i in range(1, 52)]
|
||||
resp = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 1, "end_sequence": 51, "batch_number": 1}, files=files_too_many)
|
||||
assert resp.status_code == 400
|
||||
|
||||
# 3. Exactly 10 (Accepted)
|
||||
files_valid = [create_dummy_file(f"AD{i:06d}.jpg") for i in range(1, 11)]
|
||||
resp = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 1, "end_sequence": 10, "batch_number": 1}, files=files_valid)
|
||||
assert resp.status_code == 202
|
||||
assert resp.json()["accepted"] is True
|
||||
assert len(resp.json()["sequences"]) == 10
|
||||
|
||||
def test_sequence_validation(self):
|
||||
flight_id = "flight_123"
|
||||
files = [create_dummy_file(f"AD{i:06d}.jpg") for i in range(100, 110)]
|
||||
|
||||
# 1. Valid sequence
|
||||
resp = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 100, "end_sequence": 109, "batch_number": 1}, files=files)
|
||||
assert resp.status_code == 202
|
||||
|
||||
# 2. Invalid sequence (start > end)
|
||||
resp = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 110, "end_sequence": 100, "batch_number": 1}, files=files)
|
||||
assert resp.status_code == 400
|
||||
|
||||
# 3. Gap in sequence (mismatch between count and sequence span)
|
||||
resp = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 100, "end_sequence": 115, "batch_number": 1}, files=files)
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_image_format_validation(self):
|
||||
flight_id = "flight_123"
|
||||
|
||||
# 1. Invalid format (Text file)
|
||||
files = [create_dummy_file(f"AD{i:06d}.jpg") for i in range(1, 10)]
|
||||
files.append(create_dummy_file("AD000010.txt", content_type="text/plain"))
|
||||
|
||||
resp = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 1, "end_sequence": 10, "batch_number": 1}, files=files)
|
||||
assert resp.status_code == 400
|
||||
assert "Invalid image format" in resp.json()["detail"]
|
||||
|
||||
def test_size_limits(self):
|
||||
flight_id = "flight_123"
|
||||
|
||||
# Simulate 500MB+ payload by mocking read
|
||||
# FastAPI validates the actual bytes read. We will construct 10 files of 51MB each
|
||||
large_content = b"0" * (51 * 1024 * 1024)
|
||||
files = [create_dummy_file(f"AD{i:06d}.jpg", content=large_content) for i in range(1, 11)]
|
||||
|
||||
resp = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 1, "end_sequence": 10, "batch_number": 1}, files=files)
|
||||
assert resp.status_code == 413
|
||||
assert "exceeds 500MB" in resp.json()["detail"]
|
||||
|
||||
# --- Integration Tests ---
|
||||
|
||||
class TestIntegrationImageUpload:
|
||||
"""Integration tests defined in 01.02_feature_image_upload.md"""
|
||||
|
||||
def test_sequential_batch_uploads(self):
|
||||
flight_id = "flight_123"
|
||||
|
||||
# Batch 1 (1-15)
|
||||
files_1 = [create_dummy_file(f"AD{i:06d}.jpg") for i in range(1, 16)]
|
||||
resp1 = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 1, "end_sequence": 15, "batch_number": 1}, files=files_1)
|
||||
|
||||
assert resp1.status_code == 202
|
||||
assert resp1.json()["next_expected"] == 16
|
||||
|
||||
# Batch 2 (16-30)
|
||||
files_2 = [create_dummy_file(f"AD{i:06d}.jpg") for i in range(16, 31)]
|
||||
resp2 = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 16, "end_sequence": 30, "batch_number": 2}, files=files_2)
|
||||
|
||||
assert resp2.status_code == 202
|
||||
assert resp2.json()["next_expected"] == 31
|
||||
assert mock_manager.queue_images.call_count == 2
|
||||
|
||||
def test_concurrent_uploads_to_same_flight(self):
|
||||
"""Simulates parallel handling (FastAPI inherently handles concurrent requests)."""
|
||||
flight_id = "flight_123"
|
||||
files_1 = [create_dummy_file(f"AD{i:06d}.jpg") for i in range(1, 11)]
|
||||
files_2 = [create_dummy_file(f"AD{i:06d}.jpg") for i in range(11, 21)]
|
||||
|
||||
r1 = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 1, "end_sequence": 10, "batch_number": 1}, files=files_1)
|
||||
r2 = client.post(f"/api/v1/flights/{flight_id}/images/batch", data={"start_sequence": 11, "end_sequence": 20, "batch_number": 2}, files=files_2)
|
||||
|
||||
assert r1.status_code == 202
|
||||
assert r2.status_code == 202
|
||||
assert mock_manager.queue_images.call_count == 2
|
||||
Reference in New Issue
Block a user