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 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 @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), ) workout.max_speed = 10 workout.ave_speed = 10 workout.moving = workout.duration 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), ) workout.moving = workout.duration 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), ) workout.ave_speed = float(workout.distance) / (1024 / 3600) workout.moving = workout.duration 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), ) workout.ave_speed = float(workout.distance) / (3456 / 3600) workout.moving = workout.duration 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), ) workout.ave_speed = float(workout.distance) / (1024 / 3600) workout.moving = workout.duration 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), ) workout.ave_speed = float(workout.distance) / (600 / 3600) workout.moving = workout.duration 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), ) workout.ave_speed = float(workout.distance) / (1000 / 3600) workout.moving = workout.duration 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), ) workout.ave_speed = float(workout.distance) / (6000 / 3600) workout.moving = workout.duration 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), ) workout.ave_speed = float(workout.distance) / (3000 / 3600) workout.moving = workout.duration 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), ) workout.moving = workout.duration 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)) )