From e7b05feb453bca5be8a94ce9968a4b3f144da951 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 5 Jun 2018 18:16:53 +0200 Subject: [PATCH] API: display user statistics in profile - #9 --- mpwo_api/mpwo_api/tests/test_auth_api.py | 43 +++++++++++++++++++++ mpwo_api/mpwo_api/tests/test_users_model.py | 4 ++ mpwo_api/mpwo_api/users/models.py | 21 +++++++++- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/mpwo_api/mpwo_api/tests/test_auth_api.py b/mpwo_api/mpwo_api/tests/test_auth_api.py index 46f192f2..83ad44e2 100644 --- a/mpwo_api/mpwo_api/tests/test_auth_api.py +++ b/mpwo_api/mpwo_api/tests/test_auth_api.py @@ -397,6 +397,10 @@ def test_user_profile_minimal(app, user_1): assert data['data']['email'] == 'test@test.com' assert data['data']['created_at'] assert not data['data']['admin'] + assert data['data']['nb_activities'] == 0 + assert data['data']['nb_sports'] == 0 + assert data['data']['total_distance'] == 0 + assert data['data']['total_duration'] == '0:00:00' assert response.status_code == 200 @@ -430,6 +434,45 @@ def test_user_profile_full(app, user_1_full): assert data['data']['birth_date'] assert data['data']['bio'] == 'just a random guy' assert data['data']['location'] == 'somewhere' + assert data['data']['nb_activities'] == 0 + assert data['data']['nb_sports'] == 0 + assert data['data']['total_distance'] == 0 + assert data['data']['total_duration'] == '0:00:00' + assert response.status_code == 200 + + +def test_user_profile_with_activities( + app, user_1, sport_1_cycling, sport_2_running, + activity_cycling_user_1, activity_running_user_1 +): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict( + email='test@test.com', + password='12345678' + )), + content_type='application/json' + ) + response = client.get( + '/api/auth/profile', + headers=dict( + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'success' + assert data['data'] is not None + assert data['data']['username'] == 'test' + assert data['data']['email'] == 'test@test.com' + assert data['data']['created_at'] + assert not data['data']['admin'] + assert data['data']['nb_activities'] == 2 + assert data['data']['nb_sports'] == 2 + assert data['data']['total_distance'] == 22 + assert data['data']['total_duration'] == '1:57:04' assert response.status_code == 200 diff --git a/mpwo_api/mpwo_api/tests/test_users_model.py b/mpwo_api/mpwo_api/tests/test_users_model.py index 8df4caef..86ee1cba 100644 --- a/mpwo_api/mpwo_api/tests/test_users_model.py +++ b/mpwo_api/mpwo_api/tests/test_users_model.py @@ -12,3 +12,7 @@ def test_user_model(app, user_1): assert serialized_user['location'] is None assert serialized_user['birth_date'] is None assert serialized_user['picture'] is False + assert serialized_user['nb_activities'] == 0 + assert serialized_user['nb_sports'] == 0 + assert serialized_user['total_distance'] == 0 + assert serialized_user['total_duration'] == '0:00:00' diff --git a/mpwo_api/mpwo_api/users/models.py b/mpwo_api/mpwo_api/users/models.py index aca9899c..9f8cc5ea 100644 --- a/mpwo_api/mpwo_api/users/models.py +++ b/mpwo_api/mpwo_api/users/models.py @@ -3,6 +3,9 @@ import datetime import jwt from flask import current_app from mpwo_api import bcrypt, db +from sqlalchemy import func + +from ..activities.models import Activity class User(db.Model): @@ -81,6 +84,18 @@ class User(db.Model): return 'Invalid token. Please log in again.' def serialize(self): + nb_activity = Activity.query.filter( + Activity.user_id == self.id + ).count() + sports = db.session.query( + func.count(Activity.sport_id) + ).group_by( + Activity.sport_id + ).all() + total = db.session.query( + func.sum(Activity.distance), + func.sum(Activity.duration) + ).first() return { 'id': self.id, 'username': self.username, @@ -92,5 +107,9 @@ class User(db.Model): 'bio': self.bio, 'location': self.location, 'birth_date': self.birth_date, - 'picture': self.picture is not None + 'picture': self.picture is not None, + 'nb_activities': nb_activity, + 'nb_sports': len(sports), + 'total_distance': float(total[0]) if total[0] else 0, + 'total_duration': str(total[1]) if total[1] else "0:00:00", }