67 lines
2.0 KiB
Python
67 lines
2.0 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
|
|
)
|
|
|
|
match = 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
|
|
)
|
|
match = 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
|
|
)
|
|
match = match_activity_to_bike(mock_db, activity)
|
|
assert match is None
|