import datetime from io import BytesIO from typing import Generator from unittest.mock import Mock, patch from uuid import uuid4 import pytest from PIL import Image from werkzeug.datastructures import FileStorage from fittrackee import db from fittrackee.workouts.models import Sport, Workout, WorkoutSegment from fittrackee.workouts.utils.maps import StaticMap byte_io = BytesIO() Image.new('RGB', (256, 256)).save(byte_io, 'PNG') byte_image = byte_io.getvalue() @pytest.fixture(scope='session', autouse=True) def static_map_get_mock() -> Generator: # to avoid unnecessary requests calls through staticmap m = Mock(return_value=(200, byte_image)) with patch.object(StaticMap, 'get', m) as _fixture: yield _fixture @pytest.fixture() def sport_1_cycling() -> Sport: sport = Sport(label='Cycling') db.session.add(sport) db.session.commit() return sport @pytest.fixture() def sport_1_cycling_inactive() -> Sport: sport = Sport(label='Cycling') sport.is_active = False db.session.add(sport) db.session.commit() return sport @pytest.fixture() def sport_2_running() -> Sport: sport = Sport(label='Running') sport.stopped_speed_threshold = 0.1 db.session.add(sport) db.session.commit() return sport def update_workout(workout: Workout) -> None: workout.ave_speed = float(workout.distance) / ( workout.duration.seconds / 3600 ) workout.max_speed = workout.ave_speed workout.moving = workout.duration @pytest.fixture() def workout_cycling_user_1() -> Workout: workout = Workout( user_id=1, sport_id=1, workout_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'), distance=10, duration=datetime.timedelta(seconds=3600), ) update_workout(workout) db.session.add(workout) db.session.commit() return workout @pytest.fixture() def workout_cycling_user_1_segment( workout_cycling_user_1: Workout, ) -> WorkoutSegment: workout_segment = WorkoutSegment( workout_id=workout_cycling_user_1.id, workout_uuid=workout_cycling_user_1.uuid, segment_id=0, ) workout_segment.duration = datetime.timedelta(seconds=6000) workout_segment.moving = workout_segment.duration workout_segment.distance = 5 db.session.add(workout_segment) db.session.commit() return workout_segment @pytest.fixture() def workout_running_user_1() -> Workout: workout = Workout( user_id=1, sport_id=2, workout_date=datetime.datetime.strptime('01/04/2018', '%d/%m/%Y'), distance=12, duration=datetime.timedelta(seconds=6000), ) update_workout(workout) db.session.add(workout) db.session.commit() return workout @pytest.fixture() def seven_workouts_user_1() -> Workout: workout = Workout( user_id=1, sport_id=1, workout_date=datetime.datetime.strptime('20/03/2017', '%d/%m/%Y'), distance=5, duration=datetime.timedelta(seconds=1024), ) update_workout(workout) workout.ascent = 120 workout.descent = 200 db.session.add(workout) db.session.flush() workout = Workout( user_id=1, sport_id=1, workout_date=datetime.datetime.strptime('01/06/2017', '%d/%m/%Y'), distance=10, duration=datetime.timedelta(seconds=3456), ) update_workout(workout) workout.ascent = 100 workout.descent = 80 db.session.add(workout) db.session.flush() workout = Workout( user_id=1, sport_id=1, workout_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'), distance=10, duration=datetime.timedelta(seconds=1024), ) update_workout(workout) workout.ascent = 80 workout.descent = 100 db.session.add(workout) db.session.flush() workout = Workout( user_id=1, sport_id=1, workout_date=datetime.datetime.strptime('23/02/2018', '%d/%m/%Y'), distance=1, duration=datetime.timedelta(seconds=600), ) update_workout(workout) workout.ascent = 120 workout.descent = 180 db.session.add(workout) db.session.flush() workout = Workout( user_id=1, sport_id=1, workout_date=datetime.datetime.strptime('23/02/2018', '%d/%m/%Y'), distance=10, duration=datetime.timedelta(seconds=1000), ) update_workout(workout) workout.ascent = 100 workout.descent = 200 db.session.add(workout) db.session.flush() workout = Workout( user_id=1, sport_id=1, workout_date=datetime.datetime.strptime('01/04/2018', '%d/%m/%Y'), distance=8, duration=datetime.timedelta(seconds=6000), ) update_workout(workout) workout.ascent = 40 workout.descent = 20 db.session.add(workout) db.session.flush() workout = Workout( user_id=1, sport_id=1, workout_date=datetime.datetime.strptime('09/05/2018', '%d/%m/%Y'), distance=10, duration=datetime.timedelta(seconds=3000), ) update_workout(workout) db.session.add(workout) db.session.commit() return workout @pytest.fixture() def workout_cycling_user_2() -> Workout: workout = Workout( user_id=2, sport_id=1, workout_date=datetime.datetime.strptime('23/01/2018', '%d/%m/%Y'), distance=15, duration=datetime.timedelta(seconds=3600), ) update_workout(workout) db.session.add(workout) db.session.commit() return workout @pytest.fixture() def gpx_file() -> str: return ( '' '' # noqa ' ' ' ' ' just a workout' ' ' ' ' ' 998' ' ' ' ' ' ' ' 998' ' ' ' ' ' ' ' 994' ' ' ' ' ' ' ' 994' ' ' ' ' ' ' ' 994' ' ' ' ' ' ' ' 993' ' ' ' ' ' ' ' 992' ' ' ' ' ' ' ' 992' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 986' ' ' ' ' ' ' ' 986' ' ' ' ' ' ' ' 986' ' ' ' ' ' ' ' 985' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 979' ' ' ' ' ' ' ' 981' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 979' ' ' ' ' ' ' ' 979' ' ' ' ' ' ' ' 975' ' ' ' ' ' ' ' ' '' ) @pytest.fixture() def gpx_file_wo_name() -> str: return ( '' '' # noqa ' ' ' ' ' ' ' ' ' 998' ' ' ' ' ' ' ' 998' ' ' ' ' ' ' ' 994' ' ' ' ' ' ' ' 994' ' ' ' ' ' ' ' 994' ' ' ' ' ' ' ' 993' ' ' ' ' ' ' ' 992' ' ' ' ' ' ' ' 992' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 986' ' ' ' ' ' ' ' 986' ' ' ' ' ' ' ' 986' ' ' ' ' ' ' ' 985' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 979' ' ' ' ' ' ' ' 981' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 979' ' ' ' ' ' ' ' 979' ' ' ' ' ' ' ' 975' ' ' ' ' ' ' ' ' '' ) @pytest.fixture() def gpx_file_wo_track() -> str: return ( '' '' # noqa ' ' '' ) @pytest.fixture() def gpx_file_invalid_xml() -> str: return ( '' '' # noqa ' ' ) @pytest.fixture() def gpx_file_with_segments() -> str: return ( '' '' # noqa ' ' ' ' ' just a workout' ' ' ' ' ' 998' ' ' ' ' ' ' ' 998' ' ' ' ' ' ' ' 994' ' ' ' ' ' ' ' 994' ' ' ' ' ' ' ' 994' ' ' ' ' ' ' ' 993' ' ' ' ' ' ' ' 992' ' ' ' ' ' ' ' 992' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 987' ' ' ' ' ' ' ' 986' ' ' ' ' ' ' ' 986' ' ' ' ' ' ' ' 986' ' ' ' ' ' ' ' 985' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 979' ' ' ' ' ' ' ' 981' ' ' ' ' ' ' ' 980' ' ' ' ' ' ' ' 979' ' ' ' ' ' ' ' 979' ' ' ' ' ' ' ' 975' ' ' ' ' ' ' ' ' '' ) @pytest.fixture() def gpx_file_storage(gpx_file: str) -> FileStorage: return FileStorage( filename=f'{uuid4().hex}.gpx', stream=BytesIO(str.encode(gpx_file)) )