import datetime import os from typing import Generator, Optional import pytest from fittrackee import create_app, db from fittrackee.application.models import AppConfig from fittrackee.application.utils import update_app_config_from_database from fittrackee.users.models import User from fittrackee.workouts.models import Sport, Workout, WorkoutSegment os.environ['FLASK_ENV'] = 'testing' os.environ['APP_SETTINGS'] = 'fittrackee.config.TestingConfig' # to avoid resetting dev database during tests os.environ['DATABASE_URL'] = os.environ['DATABASE_TEST_URL'] def get_app_config(with_config: Optional[bool] = False) -> Optional[AppConfig]: if with_config: config = AppConfig() config.gpx_limit_import = 10 config.max_single_file_size = 1 * 1024 * 1024 config.max_zip_file_size = 1 * 1024 * 1024 * 10 config.max_users = 100 db.session.add(config) db.session.commit() return config else: return None def get_app(with_config: Optional[bool] = False) -> Generator: app = create_app() with app.app_context(): db.create_all() app_db_config = get_app_config(with_config) if app_db_config: update_app_config_from_database(app, app_db_config) yield app db.session.remove() db.drop_all() # close unused idle connections => avoid the following error: # FATAL: remaining connection slots are reserved for non-replication # superuser connections db.engine.dispose() return app @pytest.fixture def app(monkeypatch: pytest.MonkeyPatch) -> Generator: monkeypatch.setenv('EMAIL_URL', 'smtp://none:none@0.0.0.0:1025') if os.getenv('TILE_SERVER_URL'): monkeypatch.delenv('TILE_SERVER_URL') if os.getenv('MAP_ATTRIBUTION'): monkeypatch.delenv('MAP_ATTRIBUTION') yield from get_app(with_config=True) @pytest.fixture def app_no_config() -> Generator: yield from get_app(with_config=False) @pytest.fixture def app_ssl(monkeypatch: pytest.MonkeyPatch) -> Generator: monkeypatch.setenv('EMAIL_URL', 'smtp://none:none@0.0.0.0:1025?ssl=True') yield from get_app(with_config=True) @pytest.fixture def app_tls(monkeypatch: pytest.MonkeyPatch) -> Generator: monkeypatch.setenv('EMAIL_URL', 'smtp://none:none@0.0.0.0:1025?tls=True') yield from get_app(with_config=True) @pytest.fixture() def app_config() -> AppConfig: config = AppConfig() config.gpx_limit_import = 10 config.max_single_file_size = 1048576 config.max_zip_file_size = 10485760 config.max_users = 0 db.session.add(config) db.session.commit() return config @pytest.fixture() def user_1() -> User: user = User(username='test', email='test@test.com', password='12345678') db.session.add(user) db.session.commit() return user @pytest.fixture() def user_1_admin() -> User: admin = User( username='admin', email='admin@example.com', password='12345678' ) admin.admin = True db.session.add(admin) db.session.commit() return admin @pytest.fixture() def user_1_full() -> User: user = User(username='test', email='test@test.com', password='12345678') user.first_name = 'John' user.last_name = 'Doe' user.bio = 'just a random guy' user.location = 'somewhere' user.language = 'en' user.timezone = 'America/New_York' user.birth_date = datetime.datetime.strptime('01/01/1980', '%d/%m/%Y') db.session.add(user) db.session.commit() return user @pytest.fixture() def user_1_paris() -> User: user = User(username='test', email='test@test.com', password='12345678') user.timezone = 'Europe/Paris' db.session.add(user) db.session.commit() return user @pytest.fixture() def user_2() -> User: user = User(username='toto', email='toto@toto.com', password='87654321') db.session.add(user) db.session.commit() return user @pytest.fixture() def user_2_admin() -> User: user = User(username='toto', email='toto@toto.com', password='87654321') user.admin = True db.session.add(user) db.session.commit() return user @pytest.fixture() def user_3() -> User: user = User(username='sam', email='sam@test.com', password='12345678') user.weekm = True db.session.add(user) db.session.commit() return user @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') 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 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 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 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 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 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 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' ' ' ' ' ' ' ' ' '' )