mirror of
https://github.com/sstent/FitTrack_ReportGenerator.git
synced 2026-01-26 09:02:26 +00:00
152 lines
5.1 KiB
Python
152 lines
5.1 KiB
Python
import pytest
|
|
from fastapi.testclient import TestClient
|
|
from api.main import app
|
|
from uuid import UUID, uuid4
|
|
from unittest.mock import patch, AsyncMock
|
|
import httpx
|
|
from src.core.workout_data import WorkoutData, WorkoutMetadata, PowerData, HeartRateData, SpeedData, ElevationData
|
|
import pandas as pd
|
|
from datetime import datetime, timedelta
|
|
|
|
client = TestClient(app)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_workout_data():
|
|
# Create a mock WorkoutData object
|
|
timestamps = pd.to_datetime(
|
|
[datetime(2025, 1, 1, 10, 0, 0) + timedelta(seconds=i) for i in range(600)]
|
|
)
|
|
power = pd.Series([150 + 50 * (i % 10) for i in range(600)], index=timestamps)
|
|
|
|
time_series_data = pd.DataFrame({"power": power})
|
|
|
|
metadata = WorkoutMetadata(
|
|
start_time=datetime(2025, 1, 1, 10, 0, 0),
|
|
duration=timedelta(minutes=10),
|
|
device="Garmin",
|
|
file_type="FIT",
|
|
)
|
|
|
|
power_data = PowerData(
|
|
raw_power_stream=power.tolist(),
|
|
average_power=power.mean(),
|
|
normalized_power=power.mean() * 1.05, # Dummy value
|
|
intensity_factor=0.8,
|
|
training_stress_score=50,
|
|
zone_distribution={"Z1": 100, "Z2": 200, "Z3": 300},
|
|
)
|
|
|
|
return WorkoutData(
|
|
metadata=metadata,
|
|
time_series_data=time_series_data,
|
|
power_data=power_data,
|
|
heart_rate_data=HeartRateData(),
|
|
speed_data=SpeedData(),
|
|
elevation_data=ElevationData(),
|
|
)
|
|
|
|
|
|
@patch("api.routers.analysis.CentralDBClient")
|
|
@patch("api.routers.analysis.FitParser")
|
|
async def test_get_analysis_charts_success(
|
|
mock_fit_parser,
|
|
mock_centraldb_client,
|
|
mock_workout_data,
|
|
client,
|
|
):
|
|
mock_centraldb_instance = AsyncMock()
|
|
mock_centraldb_instance.retrieve_chart = AsyncMock(
|
|
side_effect=httpx.HTTPStatusError(
|
|
"", request=None, response=httpx.Response(status_code=404)
|
|
)
|
|
)
|
|
mock_centraldb_instance.download_fit_file = AsyncMock(
|
|
return_value=b"dummy_fit_content"
|
|
)
|
|
mock_centraldb_instance.upload_chart = AsyncMock()
|
|
mock_centraldb_instance.get_analysis_artifact = AsyncMock(
|
|
side_effect=httpx.HTTPStatusError(
|
|
"", request=None, response=httpx.Response(status_code=404)
|
|
)
|
|
)
|
|
mock_centraldb_instance.create_analysis_artifact = AsyncMock()
|
|
mock_centraldb_client.return_value = mock_centraldb_instance
|
|
|
|
mock_fit_parser.return_value.parse.return_value = mock_workout_data
|
|
|
|
analysis_id = uuid4()
|
|
chart_type = "power_curve"
|
|
response = client.get(f"/api/analysis/{analysis_id}/charts?chart_type={chart_type}")
|
|
|
|
assert response.status_code == 200
|
|
assert response.headers["content-type"] == "image/png"
|
|
assert len(response.content) > 0
|
|
|
|
|
|
@patch("api.routers.analysis.CentralDBClient")
|
|
@patch("api.routers.analysis.FitParser")
|
|
async def test_get_analysis_charts_not_found(
|
|
mock_fit_parser, mock_centraldb_client, client
|
|
):
|
|
mock_centraldb_instance = AsyncMock()
|
|
mock_centraldb_instance.retrieve_chart = AsyncMock(
|
|
side_effect=httpx.HTTPStatusError(
|
|
"", request=None, response=httpx.Response(status_code=404)
|
|
)
|
|
)
|
|
mock_centraldb_instance.download_fit_file = AsyncMock(
|
|
side_effect=httpx.HTTPStatusError(
|
|
"", request=None, response=httpx.Response(status_code=404)
|
|
)
|
|
)
|
|
mock_centraldb_client.return_value = mock_centraldb_instance
|
|
|
|
analysis_id = uuid4()
|
|
chart_type = "power_curve"
|
|
response = client.get(f"/api/analysis/{analysis_id}/charts?chart_type={chart_type}")
|
|
|
|
assert response.status_code == 404
|
|
assert response.json()["code"] == "CHART_RETRIEVAL_ERROR"
|
|
|
|
|
|
@patch("api.routers.analysis.CentralDBClient")
|
|
@patch("api.routers.analysis.FitParser")
|
|
async def test_get_analysis_charts_chart_type_not_found(
|
|
mock_fit_parser, mock_centraldb_client, client
|
|
):
|
|
mock_centraldb_instance = AsyncMock()
|
|
mock_centraldb_instance.retrieve_chart = AsyncMock(
|
|
side_effect=httpx.HTTPStatusError(
|
|
"", request=None, response=httpx.Response(status_code=404)
|
|
)
|
|
)
|
|
mock_centraldb_instance.download_fit_file = AsyncMock(
|
|
return_value=b"dummy_fit_content"
|
|
)
|
|
mock_centraldb_client.return_value = mock_centraldb_instance
|
|
|
|
analysis_id = uuid4()
|
|
chart_type = "invalid_chart_type"
|
|
response = client.get(f"/api/analysis/{analysis_id}/charts?chart_type={chart_type}")
|
|
|
|
assert response.status_code == 400
|
|
assert response.json()["code"] == "INVALID_CHART_TYPE"
|
|
|
|
|
|
@patch("api.routers.analysis.CentralDBClient")
|
|
async def test_get_analysis_charts_retrieval_error(mock_centraldb_client, client):
|
|
mock_centraldb_instance = AsyncMock()
|
|
mock_centraldb_instance.retrieve_chart = AsyncMock(
|
|
side_effect=httpx.HTTPStatusError(
|
|
"", request=None, response=httpx.Response(status_code=500)
|
|
)
|
|
)
|
|
mock_centraldb_client.return_value = mock_centraldb_instance
|
|
|
|
analysis_id = uuid4()
|
|
chart_type = "power_curve"
|
|
response = client.get(f"/api/analysis/{analysis_id}/charts?chart_type={chart_type}")
|
|
|
|
assert response.status_code == 500
|
|
assert response.json()["code"] == "CHART_RETRIEVAL_ERROR" |