Files
FitTrack2/FitnessSync/backend/tests/unit/test_bike_matching.py
2026-01-14 05:39:16 -08:00

70 lines
2.1 KiB
Python

import pytest
from unittest.mock import MagicMock
from sqlalchemy.orm import Session
from src.services.bike_matching import match_activity_to_bike, calculate_observed_ratio
from src.models import Activity, BikeSetup
@pytest.fixture
def mock_db():
db = MagicMock(spec=Session)
# Mock bike setups
# 1. 50/15 => 3.33
# 2. 48/16 => 3.00
# 3. 52/11 => 4.72
setup1 = BikeSetup(id=1, frame="Fixie", chainring=50, rear_cog=15, name="Fixie A")
setup2 = BikeSetup(id=2, frame="Commuter", chainring=48, rear_cog=16, name="City")
setup3 = BikeSetup(id=3, frame="Road", chainring=52, rear_cog=11, name="Race")
db.query.return_value.all.return_value = [setup1, setup2, setup3]
return db
def test_calculate_observed_ratio():
# Ratio = (Speed * 60) / (Cadence * 2.1)
# Speed 10m/s (36kmh), Cadence 90
# Ratio = 600 / (90 * 2.1) = 600 / 189 = 3.17
ratio = calculate_observed_ratio(10, 90)
assert abs(ratio - 3.17) < 0.01
def test_match_activity_success(mock_db):
# Setup 2 is 48/16 = 3.0
# Target: Speed for Ratio 3.0 at 90 RPM
# Speed = (3.0 * 90 * 2.1) / 60 = 567 / 60 = 9.45 m/s
activity = Activity(
id=101,
activity_type='cycling',
avg_speed=9.45,
avg_cadence=90,
streams=None # valid attribute
)
match, confidence = match_activity_to_bike(mock_db, activity)
assert match is not None
assert match.id == 2 # Commuter (Ratio 3.0)
def test_match_activity_indoor_ignored(mock_db):
activity = Activity(
id=102,
activity_type='Indoor Cycling',
avg_speed=9.45,
avg_cadence=90,
streams=None
)
match, confidence = match_activity_to_bike(mock_db, activity)
assert match is None
def test_match_activity_no_match(mock_db):
# Ratio 1.0 (Very low gear)
# Speed = 3.15 m/s at 90 RPM
activity = Activity(
id=103,
activity_type='cycling',
avg_speed=3.15,
avg_cadence=90,
streams=None
)
match, confidence = match_activity_to_bike(mock_db, activity)
assert match is None