mirror of
https://github.com/sstent/FitTrack_ReportGenerator.git
synced 2026-01-27 17:42:28 +00:00
This commit introduces the initial version of the FitTrack Report Generator, a FastAPI application for analyzing workout files. Key features include: - Parsing of FIT, TCX, and GPX workout files. - Analysis of power, heart rate, speed, and elevation data. - Generation of summary reports and charts. - REST API for single and batch workout analysis. The project structure has been set up with a `src` directory for core logic, an `api` directory for the FastAPI application, and a `tests` directory for unit, integration, and contract tests. The development workflow is configured to use Docker and modern Python tooling.
111 lines
4.2 KiB
Python
111 lines
4.2 KiB
Python
import pytest
|
|
import sys
|
|
from unittest.mock import Mock, patch, MagicMock
|
|
|
|
# Add the project root to the Python path
|
|
sys.path.insert(0, '/app')
|
|
|
|
from garminsync.database import sync_database, Activity, get_activity_metrics
|
|
|
|
def test_sync_database_with_valid_activities():
|
|
"""Test sync_database with valid API response"""
|
|
mock_client = Mock()
|
|
mock_client.get_activities.return_value = [
|
|
{"activityId": 12345, "startTimeLocal": "2023-01-01T10:00:00"},
|
|
{"activityId": 67890, "startTimeLocal": "2023-01-02T11:00:00"}
|
|
]
|
|
|
|
mock_session = MagicMock()
|
|
mock_session.query.return_value.filter_by.return_value.first.return_value = None
|
|
|
|
with patch('garminsync.database.get_session', return_value=mock_session), \
|
|
patch('garminsync.database.get_activity_metrics', return_value={
|
|
"activityType": {"typeKey": "running"},
|
|
"summaryDTO": {
|
|
"duration": 3600,
|
|
"distance": 10.0,
|
|
"maxHR": 180,
|
|
"calories": 400
|
|
}
|
|
}):
|
|
|
|
sync_database(mock_client)
|
|
|
|
# Verify activities processed
|
|
assert mock_session.add.call_count == 2
|
|
assert mock_session.commit.called
|
|
|
|
def test_sync_database_with_none_activities():
|
|
"""Test sync_database with None response from API"""
|
|
mock_client = Mock()
|
|
mock_client.get_activities.return_value = None
|
|
|
|
mock_session = MagicMock()
|
|
|
|
with patch('garminsync.database.get_session', return_value=mock_session):
|
|
sync_database(mock_client)
|
|
mock_session.add.assert_not_called()
|
|
|
|
def test_sync_database_with_missing_fields():
|
|
"""Test sync_database with activities missing required fields"""
|
|
mock_client = Mock()
|
|
mock_client.get_activities.return_value = [
|
|
{"activityId": 12345},
|
|
{"startTimeLocal": "2023-01-02T11:00:00"},
|
|
{"activityId": 67890, "startTimeLocal": "2023-01-03T12:00:00"}
|
|
]
|
|
|
|
# Create a mock that returns None for existing activity
|
|
mock_session = MagicMock()
|
|
mock_session.query.return_value.filter_by.return_value.first.return_value = None
|
|
|
|
with patch('garminsync.database.get_session', return_value=mock_session), \
|
|
patch('garminsync.database.get_activity_metrics', return_value={
|
|
"summaryDTO": {"duration": 3600.0}
|
|
}):
|
|
sync_database(mock_client)
|
|
# Only valid activity should be added
|
|
assert mock_session.add.call_count == 1
|
|
added_activity = mock_session.add.call_args[0][0]
|
|
assert added_activity.activity_id == 67890
|
|
|
|
def test_sync_database_with_existing_activities():
|
|
"""Test sync_database doesn't duplicate existing activities"""
|
|
mock_client = Mock()
|
|
mock_client.get_activities.return_value = [
|
|
{"activityId": 12345, "startTimeLocal": "2023-01-01T10:00:00"}
|
|
]
|
|
|
|
mock_session = MagicMock()
|
|
mock_session.query.return_value.filter_by.return_value.first.return_value = Mock()
|
|
|
|
with patch('garminsync.database.get_session', return_value=mock_session), \
|
|
patch('garminsync.database.get_activity_metrics', return_value={
|
|
"summaryDTO": {"duration": 3600.0}
|
|
}):
|
|
sync_database(mock_client)
|
|
mock_session.add.assert_not_called()
|
|
|
|
def test_sync_database_with_invalid_activity_data():
|
|
"""Test sync_database with invalid activity data types"""
|
|
mock_client = Mock()
|
|
mock_client.get_activities.return_value = [
|
|
"invalid data",
|
|
None,
|
|
{"activityId": 12345, "startTimeLocal": "2023-01-01T10:00:00"}
|
|
]
|
|
|
|
# Create a mock that returns None for existing activity
|
|
mock_session = MagicMock()
|
|
mock_session.query.return_value.filter_by.return_value.first.return_value = None
|
|
|
|
with patch('garminsync.database.get_session', return_value=mock_session), \
|
|
patch('garminsync.database.get_activity_metrics', return_value={
|
|
"summaryDTO": {"duration": 3600.0}
|
|
}):
|
|
sync_database(mock_client)
|
|
# Only valid activity should be added
|
|
assert mock_session.add.call_count == 1
|
|
added_activity = mock_session.add.call_args[0][0]
|
|
assert added_activity.activity_id == 12345
|