Changeset 2f8a48f in OpenWorkouts-current for ow/tests


Ignore:
Timestamp:
Jan 25, 2019, 12:38:55 AM (5 years ago)
Author:
borja <borja@…>
Branches:
current, feature/docs, master
Children:
421f05f
Parents:
6d1b54b
Message:

(#7) Added several methods to the User model to gather some stats (yearly,

monthly, weekly).

Added two new utilities:

  • timedelta_to_hms (so we can print timedelta objects properly in template code)
  • get_week_days (returns a list of datetime objects for the days in the same week as a given day)

Added a template_helpers module, containing code that affects template
rendering.

Added timedelta_to_hms as a global to the default template rendering context

Refactored some code in the Workout model so it uses timedelta_to_hms instead
of running the same code twice.

Location:
ow/tests
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • ow/tests/models/test_user.py

    r6d1b54b r2f8a48f  
     1from decimal import Decimal
    12from datetime import datetime, timedelta, timezone
    23
     
    118119                   11: {'cycling': 1, 'running': 1}}
    119120        }
     121
     122    def test_stats(self, root):
     123        expected_no_stats = {
     124            'workouts': 0,
     125            'time': timedelta(seconds=0),
     126            'distance': Decimal(0),
     127            'elevation': Decimal(0),
     128            'sports': {}
     129        }
     130        # no stats
     131        assert root['john'].stats() == expected_no_stats
     132        # add a cycling workout
     133        workout = Workout(
     134            start=datetime(2018, 11, 25, 10, 00, tzinfo=timezone.utc),
     135            duration=timedelta(minutes=(60*4)),
     136            distance=115,
     137            sport='cycling')
     138        root['john'].add_workout(workout)
     139        # asking for a different year, future
     140        assert root['john'].stats(2019) == expected_no_stats
     141        # asking for a different year, past
     142        assert root['john'].stats(2016) == expected_no_stats
     143        # asking fot the year the workout is in
     144        assert root['john'].stats(2018) == {
     145            'workouts': 1,
     146            'time': timedelta(minutes=(60*4)),
     147            'distance': Decimal(115),
     148            'elevation': Decimal(0),
     149            'sports': {
     150                'cycling': {
     151                    'workouts': 1,
     152                    'time': timedelta(minutes=(60*4)),
     153                    'distance': Decimal(115),
     154                    'elevation': Decimal(0),
     155                }
     156            }
     157        }
     158        # add a second cycling workout
     159        workout = Workout(
     160            start=datetime(2018, 11, 26, 10, 00, tzinfo=timezone.utc),
     161            duration=timedelta(minutes=(60*3)),
     162            distance=100,
     163            sport='cycling')
     164        root['john'].add_workout(workout)
     165        assert root['john'].stats(2018) == {
     166            'workouts': 2,
     167            'time': timedelta(minutes=(60*7)),
     168            'distance': Decimal(215),
     169            'elevation': Decimal(0),
     170            'sports': {
     171                'cycling': {
     172                    'workouts': 2,
     173                    'time': timedelta(minutes=(60*7)),
     174                    'distance': Decimal(215),
     175                    'elevation': Decimal(0),
     176                }
     177            }
     178        }
     179        # add a running workout
     180        workout = Workout(
     181            start=datetime(2018, 11, 26, 16, 00, tzinfo=timezone.utc),
     182            duration=timedelta(minutes=(60)),
     183            distance=10,
     184            sport='running')
     185        root['john'].add_workout(workout)
     186        assert root['john'].stats(2018) == {
     187            'workouts': 3,
     188            'time': timedelta(minutes=(60*8)),
     189            'distance': Decimal(225),
     190            'elevation': Decimal(0),
     191            'sports': {
     192                'cycling': {
     193                    'workouts': 2,
     194                    'time': timedelta(minutes=(60*7)),
     195                    'distance': Decimal(215),
     196                    'elevation': Decimal(0),
     197                },
     198                'running': {
     199                    'workouts': 1,
     200                    'time': timedelta(minutes=(60)),
     201                    'distance': Decimal(10),
     202                    'elevation': Decimal(0),
     203                }
     204            }
     205        }
     206        # ensure the stats for future/past years did not change after
     207        # adding those workouts
     208        assert root['john'].stats(2019) == expected_no_stats
     209        assert root['john'].stats(2016) == expected_no_stats
     210
     211    def test_get_week_stats(self, root):
     212        expected_no_stats_per_day = {
     213            'workouts': 0,
     214            'time': timedelta(0),
     215            'distance': Decimal(0),
     216            'elevation': Decimal(0),
     217            'sports': {}
     218        }
     219
     220        expected_no_stats = {}
     221        for i in range(19, 26):
     222            day = datetime(2018, 11, i, 10, 00, tzinfo=timezone.utc)
     223            expected_no_stats[day] = expected_no_stats_per_day
     224
     225        day = datetime(2018, 11, 25, 10, 00, tzinfo=timezone.utc)
     226        assert root['john'].get_week_stats(day) == expected_no_stats
     227
     228        # add a cycling workout
     229        workout = Workout(
     230            start=datetime(2018, 11, 25, 10, 00, tzinfo=timezone.utc),
     231            duration=timedelta(minutes=(60*4)),
     232            distance=115,
     233            sport='cycling')
     234        root['john'].add_workout(workout)
     235
     236        # check a week in the future
     237        day = datetime(2019, 11, 25, 10, 00, tzinfo=timezone.utc)
     238        week_stats = root['john'].get_week_stats(day)
     239        for day in week_stats:
     240            assert week_stats[day] == expected_no_stats_per_day
     241
     242        # check a week in the past
     243        day = datetime(2017, 11, 25, 10, 00, tzinfo=timezone.utc)
     244        week_stats = root['john'].get_week_stats(day)
     245        for day in week_stats:
     246            assert week_stats[day] == expected_no_stats_per_day
     247
     248        # Check the week where the workout is
     249        day = datetime(2018, 11, 25, 10, 00, tzinfo=timezone.utc)
     250        week_stats = root['john'].get_week_stats(day)
     251        for day in week_stats:
     252            if day.day == 25:
     253                # this is the day where we have a workout
     254                assert week_stats[day] == {
     255                    'workouts': 1,
     256                    'time': timedelta(minutes=(60*4)),
     257                    'distance': Decimal(115),
     258                    'elevation': Decimal(0),
     259                    'sports': {
     260                        'cycling': {
     261                            'workouts': 1,
     262                            'time': timedelta(minutes=(60*4)),
     263                            'distance': Decimal(115),
     264                            'elevation': Decimal(0)
     265                        }
     266                    }
     267                }
     268            else:
     269                # day without workout
     270                assert week_stats[day] == expected_no_stats_per_day
     271
     272        # add a second cycling workout
     273        workout = Workout(
     274            start=datetime(2018, 11, 23, 10, 00, tzinfo=timezone.utc),
     275            duration=timedelta(minutes=(60*3)),
     276            distance=100,
     277            sport='cycling')
     278        root['john'].add_workout(workout)
     279        day = datetime(2018, 11, 25, 10, 00, tzinfo=timezone.utc)
     280        week_stats = root['john'].get_week_stats(day)
     281        for day in week_stats:
     282            if day.day == 25:
     283                # this is the day where we have a workout
     284                assert week_stats[day] == {
     285                    'workouts': 1,
     286                    'time': timedelta(minutes=(60*4)),
     287                    'distance': Decimal(115),
     288                    'elevation': Decimal(0),
     289                    'sports': {
     290                        'cycling': {
     291                            'workouts': 1,
     292                            'time': timedelta(minutes=(60*4)),
     293                            'distance': Decimal(115),
     294                            'elevation': Decimal(0)
     295                        }
     296                    }
     297                }
     298            elif day.day == 23:
     299                # this is the day where we have a workout
     300                assert week_stats[day] == {
     301                    'workouts': 1,
     302                    'time': timedelta(minutes=(60*3)),
     303                    'distance': Decimal(100),
     304                    'elevation': Decimal(0),
     305                    'sports': {
     306                        'cycling': {
     307                            'workouts': 1,
     308                            'time': timedelta(minutes=(60*3)),
     309                            'distance': Decimal(100),
     310                            'elevation': Decimal(0)
     311                        }
     312                    }
     313                }
     314            else:
     315                # day without workout
     316                assert week_stats[day] == expected_no_stats_per_day
     317
     318    def test_week_stats(self, root):
     319        expected_no_stats_per_day = {
     320            'workouts': 0,
     321            'time': timedelta(0),
     322            'distance': Decimal(0),
     323            'elevation': Decimal(0),
     324            'sports': {}
     325        }
     326
     327        # no workouts for the current week (this tests is for coverage
     328        # purposes mostly, as the main logic is tested in test_get_week_stats)
     329        day = datetime.now(timezone.utc)
     330        week_stats = root['john'].get_week_stats(day)
     331        for day in week_stats:
     332            assert week_stats[day] == expected_no_stats_per_day
     333
     334    def test_week_totals(self, root):
     335        # no data, empty totals
     336        assert root['john'].week_totals == {
     337            'distance': Decimal(0),
     338            'time': timedelta(0)
     339        }
  • ow/tests/test_utilities.py

    r6d1b54b r2f8a48f  
    11import os
    2 from datetime import timedelta
     2from datetime import timedelta, datetime
    33from unittest.mock import patch
    44from pyexpat import ExpatError
     
    2222    mps_to_kmph,
    2323    kmph_to_mps,
    24     save_map_screenshot
     24    save_map_screenshot,
     25    timedelta_to_hms,
     26    get_week_days
    2527)
    2628
     
    144146        assert not os.makedirs.called
    145147        subprocess.run.assert_called_once
     148
     149    def test_timedelta_to_hms(self):
     150        value = timedelta(seconds=0)
     151        assert timedelta_to_hms(value) == (0, 0, 0)
     152        value = timedelta(seconds=3600)
     153        assert timedelta_to_hms(value) == (1, 0, 0)
     154        value = timedelta(seconds=3900)
     155        assert timedelta_to_hms(value) == (1, 5, 0)
     156        value = timedelta(seconds=3940)
     157        assert timedelta_to_hms(value) == (1, 5, 40)
     158        value = timedelta(seconds=4)
     159        assert timedelta_to_hms(value) == (0, 0, 4)
     160        value = timedelta(seconds=150)
     161        assert timedelta_to_hms(value) == (0, 2, 30)
     162        # try now something that is not a timedelta
     163        with pytest.raises(AttributeError):
     164            timedelta_to_hms('not a timedelta')
     165
     166    def test_week_days(self):
     167        # get days from a monday, week starting on monday
     168        days = get_week_days(datetime(2019, 1, 21))
     169        assert len(days) == 7
     170        matches = [
     171            [days[0], datetime(2019, 1, 21)],
     172            [days[1], datetime(2019, 1, 22)],
     173            [days[2], datetime(2019, 1, 23)],
     174            [days[3], datetime(2019, 1, 24)],
     175            [days[4], datetime(2019, 1, 25)],
     176            [days[5], datetime(2019, 1, 26)],
     177            [days[6], datetime(2019, 1, 27)]
     178        ]
     179        for m in matches:
     180            assert m[0] == m[1]
     181        # get days from a wednesday, week starting on monday
     182        days = get_week_days(datetime(2019, 1, 23))
     183        assert len(days) == 7
     184        matches = [
     185            [days[0], datetime(2019, 1, 21)],
     186            [days[1], datetime(2019, 1, 22)],
     187            [days[2], datetime(2019, 1, 23)],
     188            [days[3], datetime(2019, 1, 24)],
     189            [days[4], datetime(2019, 1, 25)],
     190            [days[5], datetime(2019, 1, 26)],
     191            [days[6], datetime(2019, 1, 27)]
     192        ]
     193        for m in matches:
     194            assert m[0] == m[1]
     195        # get days from a monday, but week starting on sunday now
     196        days = get_week_days(datetime(2019, 1, 21), start_day=0)
     197        assert len(days) == 7
     198        matches = [
     199            [days[0], datetime(2019, 1, 20)],
     200            [days[1], datetime(2019, 1, 21)],
     201            [days[2], datetime(2019, 1, 22)],
     202            [days[3], datetime(2019, 1, 23)],
     203            [days[4], datetime(2019, 1, 24)],
     204            [days[5], datetime(2019, 1, 25)],
     205            [days[6], datetime(2019, 1, 26)]
     206        ]
     207        for m in matches:
     208            assert m[0] == m[1]
    146209
    147210
Note: See TracChangeset for help on using the changeset viewer.