diff --git a/docs/api/activities.html b/docs/api/activities.html index ce3daab5..47187bb2 100644 --- a/docs/api/activities.html +++ b/docs/api/activities.html @@ -415,14 +415,17 @@
Status Codes
@@ -485,14 +488,17 @@
Status Codes
diff --git a/fittrackee_api/fittrackee_api/activities/activities.py b/fittrackee_api/fittrackee_api/activities/activities.py index bbb1a062..e5bdf85d 100644 --- a/fittrackee_api/fittrackee_api/activities/activities.py +++ b/fittrackee_api/fittrackee_api/activities/activities.py @@ -390,8 +390,8 @@ def get_activity_data(auth_user_id, activity_id, data_type, segment_id=None): return jsonify(response_object), code if not activity.gpx or activity.gpx == '': message = f'No gpx file for this activity (id: {activity_id})' - response_object = {'status': 'fail', 'message': message} - return jsonify(response_object), 400 + response_object = {'status': 'error', 'message': message} + return jsonify(response_object), 404 try: absolute_gpx_filepath = get_absolute_file_path(activity.gpx) @@ -470,12 +470,13 @@ def get_activity_gpx(auth_user_id, activity_id): :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success - :statuscode 400: no gpx file for this activity :statuscode 401: - Provide a valid auth token. - Signature expired. Please log in again. - Invalid token. Please log in again. - :statuscode 404: activity not found + :statuscode 404: + - activity not found + - no gpx file for this activity :statuscode 500: """ @@ -537,12 +538,13 @@ def get_activity_chart_data(auth_user_id, activity_id): :reqheader Authorization: OAuth 2.0 Bearer Token :statuscode 200: success - :statuscode 400: no gpx file for this activity :statuscode 401: - Provide a valid auth token. - Signature expired. Please log in again. - Invalid token. Please log in again. - :statuscode 404: activity not found + :statuscode 404: + - activity not found + - no gpx file for this activity :statuscode 500: """ @@ -703,7 +705,7 @@ def get_map(map_id): activity = Activity.query.filter_by(map_id=map_id).first() if not activity: response_object = { - 'status': 'fail', + 'status': 'error', 'message': 'Map does not exist', } return jsonify(response_object), 404 diff --git a/fittrackee_api/fittrackee_api/tests/conftest.py b/fittrackee_api/fittrackee_api/tests/conftest.py index 1fd865ba..dff48f54 100644 --- a/fittrackee_api/fittrackee_api/tests/conftest.py +++ b/fittrackee_api/fittrackee_api/tests/conftest.py @@ -168,7 +168,7 @@ def activity_cycling_user_1(): sport_id=1, activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'), distance=10, - duration=datetime.timedelta(seconds=1024), + duration=datetime.timedelta(seconds=3600), ) activity.max_speed = 10 activity.ave_speed = 10 diff --git a/fittrackee_api/fittrackee_api/tests/test_activities_api_0_get.py b/fittrackee_api/fittrackee_api/tests/test_activities_api_0_get.py index 019afb0d..db299271 100644 --- a/fittrackee_api/fittrackee_api/tests/test_activities_api_0_get.py +++ b/fittrackee_api/fittrackee_api/tests/test_activities_api_0_get.py @@ -1,843 +1,924 @@ import json -def test_get_all_activities_for_authenticated_user( - app, - user_1, - user_2, - sport_1_cycling, - sport_2_running, - activity_cycling_user_1, - activity_cycling_user_2, - 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/activities', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 2 - - assert 'creation_date' in data['data']['activities'][0] - assert ( - 'Sun, 01 Apr 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert 'test' == data['data']['activities'][0]['user'] - assert 2 == data['data']['activities'][0]['sport_id'] - assert 12.0 == data['data']['activities'][0]['distance'] - assert '1:40:00' == data['data']['activities'][0]['duration'] - - assert 'creation_date' in data['data']['activities'][1] - assert ( - 'Mon, 01 Jan 2018 00:00:00 GMT' - == data['data']['activities'][1]['activity_date'] - ) - assert 'test' == data['data']['activities'][1]['user'] - assert 1 == data['data']['activities'][1]['sport_id'] - assert 10.0 == data['data']['activities'][1]['distance'] - assert '0:17:04' == data['data']['activities'][1]['duration'] - - -def test_get_activities_for_authenticated_user_no_activity( - app, - user_1, - user_2, - 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='toto@toto.com', password='87654321')), - content_type='application/json', - ) - response = client.get( - '/api/activities', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 0 - - -def test_get_activities_for_authenticated_user_no_authentication(app): - client = app.test_client() - response = client.get('/api/activities') - data = json.loads(response.data.decode()) - - assert response.status_code == 401 - assert 'error' in data['status'] - assert 'Provide a valid auth token.' in data['message'] - - -def test_get_activities_pagination( - app, user_1, sport_1_cycling, seven_activities_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/activities', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 5 - assert 'creation_date' in data['data']['activities'][0] - assert ( - 'Wed, 09 May 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert '0:50:00' == data['data']['activities'][0]['duration'] - assert 'creation_date' in data['data']['activities'][4] - assert ( - 'Mon, 01 Jan 2018 00:00:00 GMT' - == data['data']['activities'][4]['activity_date'] - ) - assert '0:17:04' == data['data']['activities'][4]['duration'] - - response = client.get( - '/api/activities?page=1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 5 - assert 'creation_date' in data['data']['activities'][0] - assert ( - 'Wed, 09 May 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert '0:50:00' == data['data']['activities'][0]['duration'] - assert 'creation_date' in data['data']['activities'][4] - assert ( - 'Mon, 01 Jan 2018 00:00:00 GMT' - == data['data']['activities'][4]['activity_date'] - ) - assert '0:17:04' == data['data']['activities'][4]['duration'] - - response = client.get( - '/api/activities?page=2', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 2 - assert 'creation_date' in data['data']['activities'][0] - assert ( - 'Thu, 01 Jun 2017 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert '0:57:36' == data['data']['activities'][0]['duration'] - assert 'creation_date' in data['data']['activities'][1] - assert ( - 'Mon, 20 Mar 2017 00:00:00 GMT' - == data['data']['activities'][1]['activity_date'] - ) - assert '0:17:04' == data['data']['activities'][1]['duration'] - - response = client.get( - '/api/activities?page=3', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 0 - - -def test_get_activities_pagination_error( - app, user_1, sport_1_cycling, seven_activities_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/activities?page=A', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert ( - 'Error. Please try again or contact the administrator.' - in data['message'] - ) - - -def test_get_activities_date_filter( - app, user_1, sport_1_cycling, seven_activities_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/activities?from=2018-02-01&to=2018-02-28', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 2 - assert 'creation_date' in data['data']['activities'][0] - assert ( - 'Fri, 23 Feb 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert '0:10:00' == data['data']['activities'][0]['duration'] - assert 'creation_date' in data['data']['activities'][1] - assert ( - 'Fri, 23 Feb 2018 00:00:00 GMT' - == data['data']['activities'][1]['activity_date'] - ) - assert '0:16:40' == data['data']['activities'][1]['duration'] - - -def test_get_activities_date_filter_no_results( - app, user_1, sport_1_cycling, seven_activities_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/activities?from=2018-03-01&to=2018-03-30', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 0 - - -def test_get_activities_date_filter_from( - app, user_1, sport_1_cycling, seven_activities_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/activities?from=2018-04-01', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 2 - assert 'creation_date' in data['data']['activities'][0] - assert ( - 'Wed, 09 May 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert ( - 'Sun, 01 Apr 2018 00:00:00 GMT' - == data['data']['activities'][1]['activity_date'] - ) - - -def test_get_activities_date_filter_to( - app, user_1, sport_1_cycling, seven_activities_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/activities?to=2017-12-31', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 2 - assert ( - 'Thu, 01 Jun 2017 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert ( - 'Mon, 20 Mar 2017 00:00:00 GMT' - == data['data']['activities'][1]['activity_date'] - ) - - -def test_get_activities_date_filter_paginate( - app, user_1, sport_1_cycling, seven_activities_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/activities?from=2017-01-01&page=2', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 2 - assert ( - 'Thu, 01 Jun 2017 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert ( - 'Mon, 20 Mar 2017 00:00:00 GMT' - == data['data']['activities'][1]['activity_date'] - ) - - -def test_get_activities_order( - app, user_1, sport_1_cycling, seven_activities_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/activities?order=asc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 5 - assert ( - 'Mon, 20 Mar 2017 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert ( - 'Fri, 23 Feb 2018 00:00:00 GMT' - == data['data']['activities'][4]['activity_date'] - ) - - -def test_get_activities_date_filter_paginate_order( - app, user_1, sport_1_cycling, seven_activities_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/activities?from=2017-01-01&page=2&order=asc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 2 - assert ( - 'Sun, 01 Apr 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert ( - 'Wed, 09 May 2018 00:00:00 GMT' - == data['data']['activities'][1]['activity_date'] - ) - - -def test_get_activities_distance_filter( - app, user_1, sport_1_cycling, seven_activities_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/activities?distance_from=5&distance_to=8', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 2 - assert ( - 'Sun, 01 Apr 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert ( - 'Mon, 20 Mar 2017 00:00:00 GMT' - == data['data']['activities'][1]['activity_date'] - ) - - -def test_get_activities_duration_filter( - app, user_1, sport_1_cycling, seven_activities_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/activities?duration_from=00:52&duration_to=01:20', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert ( - 'Thu, 01 Jun 2017 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - - -def test_get_activities_ave_speed_filter( - app, user_1, sport_1_cycling, seven_activities_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/activities?ave_speed_from=5&ave_speed_to=10', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert ( - 'Fri, 23 Feb 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - - -def test_get_activities_max_speed_filter( - app, - user_1, - sport_1_cycling, - sport_2_running, - activity_cycling_user_1, - activity_running_user_1, -): - activity_cycling_user_1.max_speed = 25 - activity_running_user_1.max_speed = 11 - 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/activities?max_speed_from=10&max_speed_to=20', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert ( - 'Sun, 01 Apr 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - - -def test_get_activities_sport_filter( - app, - user_1, - sport_1_cycling, - seven_activities_user_1, - sport_2_running, - 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/activities?sport_id=2', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert ( - 'Sun, 01 Apr 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - - -def test_get_an_activity( - app, user_1, sport_1_cycling, activity_cycling_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/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - - assert 'creation_date' in data['data']['activities'][0] - assert ( - 'Mon, 01 Jan 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert 'test' == data['data']['activities'][0]['user'] - assert 1 == data['data']['activities'][0]['sport_id'] - assert 10.0 == data['data']['activities'][0]['distance'] - assert '0:17:04' == data['data']['activities'][0]['duration'] - - -def test_get_an_activity_different_user( - app, user_1, user_2, sport_1_cycling, activity_cycling_user_2 -): - - 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/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_get_activities_per_page( - app, user_1, sport_1_cycling, seven_activities_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/activities?per_page=10', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 7 - assert ( - 'Wed, 09 May 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert ( - 'Mon, 20 Mar 2017 00:00:00 GMT' - == data['data']['activities'][6]['activity_date'] - ) - - response = client.get( - '/api/activities?per_page=3', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 3 - assert ( - 'Wed, 09 May 2018 00:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert ( - 'Fri, 23 Feb 2018 00:00:00 GMT' - == data['data']['activities'][2]['activity_date'] - ) - - -def test_get_an_activity_invalid_id(app, 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/activities/11', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'not found' in data['status'] - assert len(data['data']['activities']) == 0 - - -def test_get_an_activity_no_activity_no_gpx(app, 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/activities/11/gpx', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'not found' in data['status'] - assert 'Activity not found (id: 11)' in data['message'] - assert data['data']['gpx'] == '' - - response = client.get( - '/api/activities/11/chart_data', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'not found' in data['status'] - assert 'Activity not found (id: 11)' in data['message'] - assert data['data']['chart_data'] == '' - - -def test_get_an_activity_activity_no_gpx( - app, user_1, sport_1_cycling, activity_cycling_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/activities/1/gpx', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert 'fail' in data['status'] - assert 'No gpx file for this activity (id: 1)' in data['message'] - - response = client.get( - '/api/activities/1/chart_data', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert 'fail' in data['status'] - assert 'No gpx file for this activity (id: 1)' in data['message'] - - -def test_get_an_activity_activity_invalid_gpx( - app, user_1, sport_1_cycling, activity_cycling_user_1 -): - activity_cycling_user_1.gpx = "some path" - 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/activities/1/gpx', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert 'internal error' in data['message'] - assert 'data' not in data - - response = client.get( - '/api/activities/1/chart_data', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert 'internal error' in data['message'] - assert 'data' not in data - - -def test_get_map_no_activity(app, 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/activities/map/123', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'fail' in data['status'] - assert 'Map does not exist' in data['message'] +class TestGetActivities: + def test_it_gets_all_activities_for_authenticated_user( + self, + app, + user_1, + user_2, + sport_1_cycling, + sport_2_running, + activity_cycling_user_1, + activity_cycling_user_2, + 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/activities', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 2 + assert 'creation_date' in data['data']['activities'][0] + assert ( + 'Sun, 01 Apr 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert 'test' == data['data']['activities'][0]['user'] + assert 2 == data['data']['activities'][0]['sport_id'] + assert 12.0 == data['data']['activities'][0]['distance'] + assert '1:40:00' == data['data']['activities'][0]['duration'] + + assert 'creation_date' in data['data']['activities'][1] + assert ( + 'Mon, 01 Jan 2018 00:00:00 GMT' + == data['data']['activities'][1]['activity_date'] + ) + assert 'test' == data['data']['activities'][1]['user'] + assert 1 == data['data']['activities'][1]['sport_id'] + assert 10.0 == data['data']['activities'][1]['distance'] + assert '1:00:00' == data['data']['activities'][1]['duration'] + + def test_it_gets_no_activities_for_authenticated_user_with_no_activities( + self, + app, + user_1, + user_2, + 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='toto@toto.com', password='87654321')), + content_type='application/json', + ) + + response = client.get( + '/api/activities', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 0 + + def test_it_returns_401_if_user_is_not_authenticated(self, app): + client = app.test_client() + + response = client.get('/api/activities') + + data = json.loads(response.data.decode()) + assert response.status_code == 401 + assert 'error' in data['status'] + assert 'Provide a valid auth token.' in data['message'] + + +class TestGetActivitiesWithPagination: + def test_it_gets_activities_with_default_pagination( + self, app, user_1, sport_1_cycling, seven_activities_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/activities', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 5 + assert 'creation_date' in data['data']['activities'][0] + assert ( + 'Wed, 09 May 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert '0:50:00' == data['data']['activities'][0]['duration'] + assert 'creation_date' in data['data']['activities'][4] + assert ( + 'Mon, 01 Jan 2018 00:00:00 GMT' + == data['data']['activities'][4]['activity_date'] + ) + assert '0:17:04' == data['data']['activities'][4]['duration'] + + def test_it_gets_first_page( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?page=1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 5 + assert 'creation_date' in data['data']['activities'][0] + assert ( + 'Wed, 09 May 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert '0:50:00' == data['data']['activities'][0]['duration'] + assert 'creation_date' in data['data']['activities'][4] + assert ( + 'Mon, 01 Jan 2018 00:00:00 GMT' + == data['data']['activities'][4]['activity_date'] + ) + assert '0:17:04' == data['data']['activities'][4]['duration'] + + def test_it_gets_second_page( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?page=2', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 2 + assert 'creation_date' in data['data']['activities'][0] + assert ( + 'Thu, 01 Jun 2017 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert '0:57:36' == data['data']['activities'][0]['duration'] + assert 'creation_date' in data['data']['activities'][1] + assert ( + 'Mon, 20 Mar 2017 00:00:00 GMT' + == data['data']['activities'][1]['activity_date'] + ) + assert '0:17:04' == data['data']['activities'][1]['duration'] + + def test_it_gets_empty_third_page( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?page=3', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 0 + + def test_it_returns_error_on_invalid_page_value( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?page=A', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert ( + 'Error. Please try again or contact the administrator.' + in data['message'] + ) + + def test_it_gets_5_activities_per_page( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?per_page=10', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 7 + assert ( + 'Wed, 09 May 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert ( + 'Mon, 20 Mar 2017 00:00:00 GMT' + == data['data']['activities'][6]['activity_date'] + ) + + def test_it_gets_3_activities_per_page( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?per_page=3', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 3 + assert ( + 'Wed, 09 May 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert ( + 'Fri, 23 Feb 2018 00:00:00 GMT' + == data['data']['activities'][2]['activity_date'] + ) + + +class TestGetActivitiesWithFilters: + def test_it_gets_activities_with_date_filter( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?from=2018-02-01&to=2018-02-28', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 2 + assert 'creation_date' in data['data']['activities'][0] + assert ( + 'Fri, 23 Feb 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert '0:10:00' == data['data']['activities'][0]['duration'] + assert 'creation_date' in data['data']['activities'][1] + assert ( + 'Fri, 23 Feb 2018 00:00:00 GMT' + == data['data']['activities'][1]['activity_date'] + ) + assert '0:16:40' == data['data']['activities'][1]['duration'] + + def test_it_gets_no_activities_with_date_filter( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?from=2018-03-01&to=2018-03-30', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 0 + + def test_if_gets_activities_with_date_filter_from( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?from=2018-04-01', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 2 + assert 'creation_date' in data['data']['activities'][0] + assert ( + 'Wed, 09 May 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert ( + 'Sun, 01 Apr 2018 00:00:00 GMT' + == data['data']['activities'][1]['activity_date'] + ) + + def test_it_gets_activities_with_date_filter_to( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?to=2017-12-31', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 2 + assert ( + 'Thu, 01 Jun 2017 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert ( + 'Mon, 20 Mar 2017 00:00:00 GMT' + == data['data']['activities'][1]['activity_date'] + ) + + def test_it_gets_activities_with_ascending_order( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?order=asc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 5 + assert ( + 'Mon, 20 Mar 2017 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert ( + 'Fri, 23 Feb 2018 00:00:00 GMT' + == data['data']['activities'][4]['activity_date'] + ) + + def test_it_gets_activities_with_distance_filter( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?distance_from=5&distance_to=8', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 2 + assert ( + 'Sun, 01 Apr 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert ( + 'Mon, 20 Mar 2017 00:00:00 GMT' + == data['data']['activities'][1]['activity_date'] + ) + + def test_it_gets_activities_with_duration_filter( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?duration_from=00:52&duration_to=01:20', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert ( + 'Thu, 01 Jun 2017 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + + def test_it_gets_activities_with_average_speed_filter( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?ave_speed_from=5&ave_speed_to=10', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert ( + 'Fri, 23 Feb 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + + def test_it_gets_activities_with_max_speed_filter( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + activity_cycling_user_1, + activity_running_user_1, + ): + activity_cycling_user_1.max_speed = 25 + activity_running_user_1.max_speed = 11 + 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/activities?max_speed_from=10&max_speed_to=20', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert ( + 'Sun, 01 Apr 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + + def test_it_gets_activities_with_sport_filter( + self, + app, + user_1, + sport_1_cycling, + seven_activities_user_1, + sport_2_running, + 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/activities?sport_id=2', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert ( + 'Sun, 01 Apr 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + + +class TestGetActivitiesWithFiltersAndPagination: + def test_it_gets_page_2_with_date_filter( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?from=2017-01-01&page=2', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 2 + assert ( + 'Thu, 01 Jun 2017 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert ( + 'Mon, 20 Mar 2017 00:00:00 GMT' + == data['data']['activities'][1]['activity_date'] + ) + + def test_it_get_page_2_with_date_filter_and_ascending_order( + self, app, user_1, sport_1_cycling, seven_activities_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/activities?from=2017-01-01&page=2&order=asc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 2 + assert ( + 'Sun, 01 Apr 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert ( + 'Wed, 09 May 2018 00:00:00 GMT' + == data['data']['activities'][1]['activity_date'] + ) + + +class TestGetActivity: + def test_it_gets_an_activity( + self, app, user_1, sport_1_cycling, activity_cycling_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/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'creation_date' in data['data']['activities'][0] + assert ( + 'Mon, 01 Jan 2018 00:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert 'test' == data['data']['activities'][0]['user'] + assert 1 == data['data']['activities'][0]['sport_id'] + assert 10.0 == data['data']['activities'][0]['distance'] + assert '1:00:00' == data['data']['activities'][0]['duration'] + + def test_it_returns_403_if_activity_belongs_to_a_different_user( + self, app, user_1, user_2, sport_1_cycling, activity_cycling_user_2 + ): + 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/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 403 + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] + + def test_it_returns_404_if_activity_does_not_exist(self, app, 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/activities/11', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert len(data['data']['activities']) == 0 + + def test_it_returns_404_on_getting_gpx_if_activity_does_not_exist( + self, app, 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/activities/11/gpx', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert 'Activity not found (id: 11)' in data['message'] + assert data['data']['gpx'] == '' + + def test_it_returns_404_on_getting_chart_data_if_activity_does_not_exist( + self, app, 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/activities/11/chart_data', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert 'Activity not found (id: 11)' in data['message'] + assert data['data']['chart_data'] == '' + + def test_it_returns_404_on_getting_gpx_if_activity_have_no_gpx( + self, app, user_1, sport_1_cycling, activity_cycling_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/activities/1/gpx', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'error' in data['status'] + assert 'No gpx file for this activity (id: 1)' in data['message'] + + def test_it_returns_404_if_activity_have_no_chart_data( + self, app, user_1, sport_1_cycling, activity_cycling_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/activities/1/chart_data', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'error' in data['status'] + assert 'No gpx file for this activity (id: 1)' in data['message'] + + def test_it_returns_500_on_getting_gpx_if_an_activity_has_invalid_gpx_pathname( # noqa + self, app, user_1, sport_1_cycling, activity_cycling_user_1 + ): + activity_cycling_user_1.gpx = "some path" + 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/activities/1/gpx', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert 'internal error' in data['message'] + assert 'data' not in data + + def test_it_returns_500_on_getting_chart_data_if_an_activity_has_invalid_gpx_pathname( # noqa + self, app, user_1, sport_1_cycling, activity_cycling_user_1 + ): + activity_cycling_user_1.gpx = "some path" + 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/activities/1/chart_data', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert 'internal error' in data['message'] + assert 'data' not in data + + def test_it_returns_404_if_activity_has_no_map(self, app, 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/activities/map/123', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 404 + assert 'error' in data['status'] + assert 'Map does not exist' in data['message'] diff --git a/fittrackee_api/fittrackee_api/tests/test_activities_api_1_post.py b/fittrackee_api/fittrackee_api/tests/test_activities_api_1_post.py index c5765c9f..8e2b98ef 100644 --- a/fittrackee_api/fittrackee_api/tests/test_activities_api_1_post.py +++ b/fittrackee_api/fittrackee_api/tests/test_activities_api_1_post.py @@ -85,7 +85,7 @@ def assert_activity_data_with_gpx_segments(data): assert data['data']['activities'][0]['max_alt'] == 998.0 assert ( data['data']['activities'][0]['max_speed'] is None - ) # not enough points # noqa + ) # not enough points assert data['data']['activities'][0]['min_alt'] == 975.0 assert data['data']['activities'][0]['moving'] == '0:03:55' assert data['data']['activities'][0]['pauses'] == '0:00:15' @@ -197,1082 +197,21 @@ def assert_activity_data_wo_gpx(data): assert records[3]['value'] == 10.0 -def test_add_an_activity_gpx(app, user_1, sport_1_cycling, gpx_file): - 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.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 201 - assert 'created' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'just an activity' == data['data']['activities'][0]['title'] - assert_activity_data_with_gpx(data) - - -def activity_assertion(app, user_1, sport_1_cycling, gpx_file, with_segments): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.get( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'just an activity' == data['data']['activities'][0]['title'] - if with_segments: - assert_activity_data_with_gpx_segments(data) - else: - assert_activity_data_with_gpx(data) - - map_id = data['data']['activities'][0]['map'] - - response = client.get( - '/api/activities/1/gpx', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert '' in data['message'] - assert len(data['data']['gpx']) != '' - - response = client.get( - '/api/activities/1/gpx/segment/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert '' in data['message'] - assert len(data['data']['gpx']) != '' - - response = client.get( - f'/api/activities/map/{map_id}', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - assert response.status_code == 200 - - # error case in the same test to avoid generate a new map file - activity = Activity.query.filter_by(id=1).first() - activity.map = 'incorrect path' - - assert response.status_code == 200 - assert 'success' in data['status'] - assert '' in data['message'] - assert len(data['data']['gpx']) != '' - - response = client.get( - f'/api/activities/map/{map_id}', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert data['status'] == 'error' - assert data['message'] == 'internal error.' - - -def test_get_an_activity_with_gpx(app, user_1, sport_1_cycling, gpx_file): - return activity_assertion(app, user_1, sport_1_cycling, gpx_file, False) - - -def test_get_an_activity_with_gpx_segments( - app, user_1, sport_1_cycling, gpx_file_with_segments -): - return activity_assertion( - app, user_1, sport_1_cycling, gpx_file_with_segments, True - ) - - -def test_get_an_activity_with_gpx_different_user( - app, user_1, user_2, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='toto@toto.com', password='87654321')), - content_type='application/json', - ) - response = client.get( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - response = client.get( - '/api/activities/1/gpx', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_get_chart_data_activty_with_gpx( - app, user_1, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.get( - '/api/activities/1/chart_data', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['message'] == '' - assert data['data']['chart_data'] != '' - - response = client.get( - '/api/activities/1/chart_data/segment/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['message'] == '' - assert data['data']['chart_data'] != '' - - response = client.get( - '/api/activities/1/chart_data/segment/0', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert data['message'] == 'Incorrect segment id' - assert 'data' not in data - - response = client.get( - '/api/activities/1/chart_data/segment/999999', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'not found' in data['status'] - assert data['message'] == 'No segment with id \'999999\'' - assert 'data' not in data - - -def test_get_chart_data_activty_with_gpx_different_user( - app, user_1, user_2, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='toto@toto.com', password='87654321')), - content_type='application/json', - ) - response = client.get( - '/api/activities/1/chart_data', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - response = client.get( - '/api/activities/1/chart_data/segment/0', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - response = client.get( - '/api/activities/1/chart_data/segment/999999', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_add_an_activity_with_gpx_without_name( - app, user_1, sport_1_cycling, gpx_file_wo_name -): - 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.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file_wo_name)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 201 - assert 'created' in data['status'] - assert len(data['data']['activities']) == 1 - assert ( - 'Cycling - 2018-03-13 12:44:45' - == data['data']['activities'][0]['title'] - ) - assert_activity_data_with_gpx(data) - - -def test_add_an_activity_with_gpx_without_name_timezone( - app, user_1, sport_1_cycling, gpx_file_wo_name -): - user_1.timezone = 'Europe/Paris' - 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.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file_wo_name)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 201 - assert 'created' in data['status'] - assert len(data['data']['activities']) == 1 - assert ( - 'Cycling - 2018-03-13 13:44:45' - == data['data']['activities'][0]['title'] - ) - assert_activity_data_with_gpx(data) - - -def test_get_an_activity_with_gpx_notes( - app, user_1, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1, "notes": "test activity"}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.get( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'just an activity' == data['data']['activities'][0]['title'] - assert 'test activity' == data['data']['activities'][0]['notes'] - - -def test_add_an_activity_with_gpx_invalid_file( - app, user_1, sport_1_cycling, gpx_file_wo_track -): - 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.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file_wo_track)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert 'Error during gpx file parsing.' in data['message'] - assert 'data' not in data - - -def test_add_an_activity_with_gpx_invalid_xml( - app, user_1, sport_1_cycling, gpx_file_invalid_xml -): - 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.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file_invalid_xml)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert 'Error during gpx file parsing.' in data['message'] - assert 'data' not in data - - -def test_add_an_activity_gpx_invalid_extension( - app, user_1, sport_1_cycling, gpx_file -): - 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.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.png'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert data['status'] == 'fail' - assert data['message'] == 'File extension not allowed.' - - -def test_add_an_activity_gpx_no_sport_id( - app, user_1, sport_1_cycling, gpx_file -): - 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.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), data='{}' - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert data['status'] == 'error' - assert data['message'] == 'Invalid payload.' - - -def test_add_an_activity_gpx_incorrect_sport_id( - app, user_1, sport_1_cycling, gpx_file -): - 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.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 2}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert data['status'] == 'error' - assert data['message'] == 'Sport id: 2 does not exist' - - -def test_add_an_activity_gpx_no_file(app, user_1, sport_1_cycling): - 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.post( - '/api/activities', - data=dict(data='{}'), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert data['status'] == 'fail' - assert data['message'] == 'No file part.' - - -def test_add_an_activity_no_gpx(app, user_1, sport_1_cycling): - 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.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-15 14:05', - distance=10, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 201 - assert 'created' in data['status'] - assert len(data['data']['activities']) == 1 - assert_activity_data_wo_gpx(data) - - -def test_get_an_activity_wo_gpx(app, user_1, sport_1_cycling): - 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', - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-15 14:05', - distance=10, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert_activity_data_wo_gpx(data) - - -def test_get_an_activity_wo_gpx_notes(app, user_1, sport_1_cycling): - 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', - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-15 14:05', - distance=10, - notes="new test with notes", - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'new test with notes' == data['data']['activities'][0]['notes'] - - -def test_get_an_activity_wo_gpx_with_timezone(app, user_1, sport_1_cycling): - user_1.timezone = 'Europe/Paris' - 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', - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-15 14:05', - distance=10, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert ( - data['data']['activities'][0]['activity_date'] - == 'Tue, 15 May 2018 12:05:00 GMT' - ) - assert ( - data['data']['activities'][0]['title'] - == 'Cycling - 2018-05-15 14:05:00' - ) - - -def test_get_activities_date_filter_with_timezone_new_york( - app, user_1_full, sport_1_cycling -): - 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', - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-01-01 00:00', - distance=10, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/activities?from=2018-01-01&to=2018-01-31', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert ( - 'Mon, 01 Jan 2018 05:00:00 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert ( - 'Cycling - 2018-01-01 00:00:00' - == data['data']['activities'][0]['title'] - ) - - -def test_get_activities_date_filter_with_timezone_paris( - app, user_1_paris, sport_1_cycling, activity_cycling_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', - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2017-31-12 23:59', - distance=10, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-01-01 00:00', - distance=10, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - activity_cycling_user_1.activity_date = datetime.strptime( - '31/01/2018 21:59:59', '%d/%m/%Y %H:%M:%S' - ) - activity_cycling_user_1.title = 'Test' - - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-02-01 00:00', - distance=10, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/activities?from=2018-01-01&to=2018-01-31', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 2 - assert ( - 'Wed, 31 Jan 2018 21:59:59 GMT' - == data['data']['activities'][0]['activity_date'] - ) - assert 'Test' == data['data']['activities'][0]['title'] - assert ( - 'Sun, 31 Dec 2017 23:00:00 GMT' - == data['data']['activities'][1]['activity_date'] - ) - assert ( - 'Cycling - 2018-01-01 00:00:00' - == data['data']['activities'][1]['title'] - ) - - -def test_add_an_activity_no_gpx_invalid_payload(app, user_1, sport_1_cycling): - 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.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps(dict(sport_id=1, duration=3600, distance=10)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert 'error' in data['status'] - assert 'Invalid payload.' in data['message'] - - -def test_add_an_activity_no_gpx_error(app, user_1, sport_1_cycling): - 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.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, duration=3600, activity_date='15/2018', distance=10 - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'fail' in data['status'] - assert 'Error during activity save.' in data['message'] - - -def test_add_activity_zero_value( - app, user_1, sport_1_cycling, sport_2_running -): - 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.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=0, - activity_date='2018-05-14 14:05', - distance=0, - title='Activity test', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 201 - assert 'created' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'creation_date' in data['data']['activities'][0] - assert ( - data['data']['activities'][0]['activity_date'] - == 'Mon, 14 May 2018 14:05:00 GMT' - ) - assert data['data']['activities'][0]['user'] == 'test' - assert data['data']['activities'][0]['sport_id'] == 1 - assert data['data']['activities'][0]['duration'] is None - assert data['data']['activities'][0]['title'] == 'Activity test' # noqa - assert data['data']['activities'][0]['ascent'] is None - assert data['data']['activities'][0]['ave_speed'] is None - assert data['data']['activities'][0]['descent'] is None - assert data['data']['activities'][0]['distance'] is None - assert data['data']['activities'][0]['max_alt'] is None - assert data['data']['activities'][0]['max_speed'] is None - assert data['data']['activities'][0]['min_alt'] is None - assert data['data']['activities'][0]['moving'] is None - assert data['data']['activities'][0]['pauses'] is None - assert data['data']['activities'][0]['with_gpx'] is False - - assert len(data['data']['activities'][0]['segments']) == 0 - assert len(data['data']['activities'][0]['records']) == 0 - - -def test_get_an_activity_with_zip(app, user_1, sport_1_cycling): - file_path = os.path.join(app.root_path, 'tests/files/gpx_test.zip') - # 'gpx_test.zip' contains 3 gpx files (same data) and 1 non-gpx file - - with open(file_path, 'rb') as zip_file: +class TestPostActivityWithGpx: + def test_it_adds_an_activity_with_gpx_file( + self, app, user_1, sport_1_cycling, gpx_file + ): 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.post( - '/api/activities', - data=dict(file=(zip_file, 'gpx_test.zip'), data='{"sport_id": 1}'), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - assert response.status_code == 201 - assert 'created' in data['status'] - assert len(data['data']['activities']) == 3 - assert 'just an activity' == data['data']['activities'][0]['title'] - assert_activity_data_with_gpx(data) - - -def test_get_an_activity_with_zip_folder(app, user_1, sport_1_cycling): - file_path = os.path.join(app.root_path, 'tests/files/gpx_test_folder.zip') - # 'gpx_test_folder.zip' contains 3 gpx files (same data) and 1 non-gpx file - # in a folder - - with open(file_path, 'rb') as zip_file: - 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.post( '/api/activities', data=dict( - file=(zip_file, 'gpx_test_folder.zip'), data='{"sport_id": 1}' - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert 'fail' in data['status'] - assert len(data['data']['activities']) == 0 - - -def test_get_an_activity_with_zip_incorrect_file(app, user_1, sport_1_cycling): - file_path = os.path.join( - app.root_path, 'tests/files/gpx_test_incorrect.zip' - ) - # 'gpx_test_incorrect.zip' contains 2 gpx files, one is incorrect - - with open(file_path, 'rb') as zip_file: - 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.post( - '/api/activities', - data=dict( - file=(zip_file, 'gpx_test_incorrect.zip'), + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), data='{"sport_id": 1}', ), headers=dict( @@ -1281,9 +220,1103 @@ def test_get_an_activity_with_zip_incorrect_file(app, user_1, sport_1_cycling): + json.loads(resp_login.data.decode())['auth_token'], ), ) + + data = json.loads(response.data.decode()) + assert response.status_code == 201 + assert 'created' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'just an activity' == data['data']['activities'][0]['title'] + assert_activity_data_with_gpx(data) + + def test_it_adds_an_activity_with_gpx_without_name( + self, app, user_1, sport_1_cycling, gpx_file_wo_name + ): + 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.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file_wo_name)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 201 + assert 'created' in data['status'] + assert len(data['data']['activities']) == 1 + assert ( + 'Cycling - 2018-03-13 12:44:45' + == data['data']['activities'][0]['title'] + ) + assert_activity_data_with_gpx(data) + + def test_it_adds_an_activity_with_gpx_without_name_timezone( + self, app, user_1, sport_1_cycling, gpx_file_wo_name + ): + user_1.timezone = 'Europe/Paris' + 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.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file_wo_name)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 201 + assert 'created' in data['status'] + assert len(data['data']['activities']) == 1 + assert ( + 'Cycling - 2018-03-13 13:44:45' + == data['data']['activities'][0]['title'] + ) + assert_activity_data_with_gpx(data) + + def test_it_adds_get_an_activity_with_gpx_notes( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1, "notes": "test activity"}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + response = client.get( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'just an activity' == data['data']['activities'][0]['title'] + assert 'test activity' == data['data']['activities'][0]['notes'] + + def test_it_returns_500_if_gpx_file_has_not_tracks( + self, app, user_1, sport_1_cycling, gpx_file_wo_track + ): + 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.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file_wo_track)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) assert response.status_code == 500 assert 'error' in data['status'] assert 'Error during gpx file parsing.' in data['message'] assert 'data' not in data + + def test_it_returns_500_if_gpx_has_invalid_xml( + self, app, user_1, sport_1_cycling, gpx_file_invalid_xml + ): + 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.post( + '/api/activities', + data=dict( + file=( + BytesIO(str.encode(gpx_file_invalid_xml)), + 'example.gpx', + ), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert 'Error during gpx file parsing.' in data['message'] + assert 'data' not in data + + def test_it_returns_400_if_activity_gpx_has_invalid_extension( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.png'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert data['status'] == 'fail' + assert data['message'] == 'File extension not allowed.' + + def test_it_returns_400_if_sport_id_is_not_provided( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), data='{}' + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert data['status'] == 'error' + assert data['message'] == 'Invalid payload.' + + def test_it_returns_500_if_sport_id_does_not_exists( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 2}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert data['status'] == 'error' + assert data['message'] == 'Sport id: 2 does not exist' + + def test_returns_400_if_no_gpx_file_is_provided( + self, app, user_1, sport_1_cycling + ): + 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.post( + '/api/activities', + data=dict(data='{}'), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert data['status'] == 'fail' + assert data['message'] == 'No file part.' + + +class TestPostActivityWithoutGpx: + def test_it_adds_an_activity_without_gpx( + self, app, user_1, sport_1_cycling + ): + 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.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-05-15 14:05', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 201 + assert 'created' in data['status'] + assert len(data['data']['activities']) == 1 + assert_activity_data_wo_gpx(data) + + def test_it_returns_400_if_activity_date_is_missing( + self, app, user_1, sport_1_cycling + ): + 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.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps(dict(sport_id=1, duration=3600, distance=10)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'error' in data['status'] + assert 'Invalid payload.' in data['message'] + + def test_it_returns_500_if_activity_format_is_invalid( + self, app, user_1, sport_1_cycling + ): + 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.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='15/2018', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'fail' in data['status'] + assert 'Error during activity save.' in data['message'] + + def test_it_adds_activity_with_zero_value( + self, app, user_1, sport_1_cycling, sport_2_running + ): + 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.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=0, + activity_date='2018-05-14 14:05', + distance=0, + title='Activity test', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 201 + assert 'created' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'creation_date' in data['data']['activities'][0] + assert ( + data['data']['activities'][0]['activity_date'] + == 'Mon, 14 May 2018 14:05:00 GMT' + ) + assert data['data']['activities'][0]['user'] == 'test' + assert data['data']['activities'][0]['sport_id'] == 1 + assert data['data']['activities'][0]['duration'] is None + assert data['data']['activities'][0]['title'] == 'Activity test' + assert data['data']['activities'][0]['ascent'] is None + assert data['data']['activities'][0]['ave_speed'] is None + assert data['data']['activities'][0]['descent'] is None + assert data['data']['activities'][0]['distance'] is None + assert data['data']['activities'][0]['max_alt'] is None + assert data['data']['activities'][0]['max_speed'] is None + assert data['data']['activities'][0]['min_alt'] is None + assert data['data']['activities'][0]['moving'] is None + assert data['data']['activities'][0]['pauses'] is None + assert data['data']['activities'][0]['with_gpx'] is False + + assert len(data['data']['activities'][0]['segments']) == 0 + assert len(data['data']['activities'][0]['records']) == 0 + + +class TestPostActivityWithZipArchive: + def test_it_adds_activities_with_zip_archive( + self, app, user_1, sport_1_cycling + ): + file_path = os.path.join(app.root_path, 'tests/files/gpx_test.zip') + # 'gpx_test.zip' contains 3 gpx files (same data) and 1 non-gpx file + with open(file_path, 'rb') as zip_file: + 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.post( + '/api/activities', + data=dict( + file=(zip_file, 'gpx_test.zip'), data='{"sport_id": 1}' + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 201 + assert 'created' in data['status'] + assert len(data['data']['activities']) == 3 + assert 'just an activity' == data['data']['activities'][0]['title'] + assert_activity_data_with_gpx(data) + + def test_it_returns_400_if_folder_is_present_in_zpi_archive( + self, app, user_1, sport_1_cycling + ): + file_path = os.path.join( + app.root_path, 'tests/files/gpx_test_folder.zip' + ) + # 'gpx_test_folder.zip' contains 3 gpx files (same data) and 1 non-gpx + # file in a folder + with open(file_path, 'rb') as zip_file: + 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.post( + '/api/activities', + data=dict( + file=(zip_file, 'gpx_test_folder.zip'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'fail' in data['status'] + assert len(data['data']['activities']) == 0 + + def test_it_returns_500_if_one_fle_in_zip_archive_is_invalid( + self, app, user_1, sport_1_cycling + ): + file_path = os.path.join( + app.root_path, 'tests/files/gpx_test_incorrect.zip' + ) + # 'gpx_test_incorrect.zip' contains 2 gpx files, one is incorrect + with open(file_path, 'rb') as zip_file: + 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.post( + '/api/activities', + data=dict( + file=(zip_file, 'gpx_test_incorrect.zip'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert 'Error during gpx file parsing.' in data['message'] + assert 'data' not in data + + +class TestPostAndGetActivityWithGpx: + @staticmethod + def activity_assertion(app, gpx_file, with_segments): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + response = client.get( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'just an activity' == data['data']['activities'][0]['title'] + if with_segments: + assert_activity_data_with_gpx_segments(data) + else: + assert_activity_data_with_gpx(data) + map_id = data['data']['activities'][0]['map'] + + response = client.get( + '/api/activities/1/gpx', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert '' in data['message'] + assert len(data['data']['gpx']) != '' + + response = client.get( + '/api/activities/1/gpx/segment/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert '' in data['message'] + assert len(data['data']['gpx']) != '' + + response = client.get( + f'/api/activities/map/{map_id}', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + assert response.status_code == 200 + + # error case in the same test to avoid generate a new map file + activity = Activity.query.filter_by(id=1).first() + activity.map = 'incorrect path' + + assert response.status_code == 200 + assert 'success' in data['status'] + assert '' in data['message'] + assert len(data['data']['gpx']) != '' + + response = client.get( + f'/api/activities/map/{map_id}', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 500 + assert data['status'] == 'error' + assert data['message'] == 'internal error.' + + def test_it_gets_an_activity_created_with_gpx( + self, app, user_1, sport_1_cycling, gpx_file + ): + return self.activity_assertion(app, gpx_file, False) + + def test_it_gets_an_activity_created_with_gpx_with_segments( + self, app, user_1, sport_1_cycling, gpx_file_with_segments + ): + return self.activity_assertion(app, gpx_file_with_segments, True) + + def test_it_gets_chart_data_for_an_activity_created_with_gpx( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + response = client.get( + '/api/activities/1/chart_data', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['message'] == '' + assert data['data']['chart_data'] != '' + + def test_it_gets_segment_chart_data_for_an_activity_created_with_gpx( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + response = client.get( + '/api/activities/1/chart_data/segment/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['message'] == '' + assert data['data']['chart_data'] != '' + + def test_it_returns_403_on_getting_chart_data_if_activity_belongs_to_another_user( # noqa + self, app, user_1, user_2, sport_1_cycling, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict(email='toto@toto.com', password='87654321')), + content_type='application/json', + ) + response = client.get( + '/api/activities/1/chart_data', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 403 + assert 'error' in data['status'] + assert data['message'] == 'You do not have permissions.' + + def test_it_returns_500_on_invalid_segment_id( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + response = client.get( + '/api/activities/1/chart_data/segment/0', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert data['message'] == 'Incorrect segment id' + assert 'data' not in data + + def test_it_returns_404_if_segment_id_does_not_exist( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + response = client.get( + '/api/activities/1/chart_data/segment/999999', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert data['message'] == 'No segment with id \'999999\'' + assert 'data' not in data + + +class TestPostAndGetActivityWithoutGpx: + def test_it_add_and_gets_an_activity_wo_gpx( + self, app, user_1, sport_1_cycling + ): + 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', + ) + + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-05-15 14:05', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert_activity_data_wo_gpx(data) + + def test_it_adds_and_gets_an_activity_wo_gpx_notes( + self, app, user_1, sport_1_cycling + ): + 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', + ) + + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-05-15 14:05', + distance=10, + notes="new test with notes", + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'new test with notes' == data['data']['activities'][0]['notes'] + + +class TestPostAndGetActivityUsingTimezones: + def test_it_add_and_gets_an_activity_wo_gpx_with_timezone( + self, app, user_1, sport_1_cycling + ): + user_1.timezone = 'Europe/Paris' + 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', + ) + + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-05-15 14:05', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert ( + data['data']['activities'][0]['activity_date'] + == 'Tue, 15 May 2018 12:05:00 GMT' + ) + assert ( + data['data']['activities'][0]['title'] + == 'Cycling - 2018-05-15 14:05:00' + ) + + def test_it_adds_and_gets_activities_date_filter_with_timezone_new_york( + self, app, user_1_full, sport_1_cycling + ): + 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', + ) + + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-01-01 00:00', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/activities?from=2018-01-01&to=2018-01-31', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert ( + 'Mon, 01 Jan 2018 05:00:00 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert ( + 'Cycling - 2018-01-01 00:00:00' + == data['data']['activities'][0]['title'] + ) + + def test_it_adds_and_gets_activities_date_filter_with_timezone_paris( + self, app, user_1_paris, sport_1_cycling, activity_cycling_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', + ) + + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2017-31-12 23:59', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-01-01 00:00', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + activity_cycling_user_1.activity_date = datetime.strptime( + '31/01/2018 21:59:59', '%d/%m/%Y %H:%M:%S' + ) + activity_cycling_user_1.title = 'Test' + + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-02-01 00:00', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/activities?from=2018-01-01&to=2018-01-31', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 2 + assert ( + 'Wed, 31 Jan 2018 21:59:59 GMT' + == data['data']['activities'][0]['activity_date'] + ) + assert 'Test' == data['data']['activities'][0]['title'] + assert ( + 'Sun, 31 Dec 2017 23:00:00 GMT' + == data['data']['activities'][1]['activity_date'] + ) + assert ( + 'Cycling - 2018-01-01 00:00:00' + == data['data']['activities'][1]['title'] + ) diff --git a/fittrackee_api/fittrackee_api/tests/test_activities_api_2_patch.py b/fittrackee_api/fittrackee_api/tests/test_activities_api_2_patch.py index 428950bb..a9a02105 100644 --- a/fittrackee_api/fittrackee_api/tests/test_activities_api_2_patch.py +++ b/fittrackee_api/fittrackee_api/tests/test_activities_api_2_patch.py @@ -9,7 +9,7 @@ def assert_activity_data_with_gpx(data): assert ( 'Tue, 13 Mar 2018 12:44:45 GMT' == data['data']['activities'][0]['activity_date'] - ) # noqa + ) assert 'test' == data['data']['activities'][0]['user'] assert '0:04:10' == data['data']['activities'][0]['duration'] assert data['data']['activities'][0]['ascent'] == 0.4 @@ -47,903 +47,722 @@ def assert_activity_data_with_gpx(data): assert records[3]['value'] == 4.61 -def test_edit_an_activity_with_gpx( - app, user_1, sport_1_cycling, sport_2_running, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict(sport_id=2, title="Activity test")), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 2 == data['data']['activities'][0]['sport_id'] - assert data['data']['activities'][0]['title'] == 'Activity test' - assert_activity_data_with_gpx(data) - - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict(notes="test notes")), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert data['data']['activities'][0]['title'] == 'Activity test' - assert data['data']['activities'][0]['notes'] == 'test notes' - - -def test_edit_an_activity_with_gpx_different_user( - app, user_1, user_2, sport_1_cycling, sport_2_running, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='toto@toto.com', password='87654321')), - content_type='application/json', - ) - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict(sport_id=2, title="Activity test")), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_edit_an_activity_with_gpx_partial( - app, user_1, sport_1_cycling, sport_2_running, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict(sport_id=2)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 2 == data['data']['activities'][0]['sport_id'] - assert data['data']['activities'][0]['title'] == 'just an activity' - assert_activity_data_with_gpx(data) - - -def test_edit_an_activity_with_gpx_invalid_payload( - app, user_1, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict()), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert 'error' in data['status'] - assert 'Invalid payload.' in data['message'] - - -def test_edit_an_activity_with_gpx_incorrect_data( - app, user_1, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict(sport_id=2)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert ( - 'Error. Please try again or contact the administrator.' - in data['message'] - ) # noqa - - -def test_edit_an_activity_wo_gpx( - app, user_1, sport_1_cycling, sport_2_running -): - 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.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-14 14:05', - distance=7, - title='Activity test', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 201 - assert 'created' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'creation_date' in data['data']['activities'][0] - assert ( - data['data']['activities'][0]['activity_date'] - == 'Mon, 14 May 2018 14:05:00 GMT' - ) # noqa - assert data['data']['activities'][0]['user'] == 'test' - assert data['data']['activities'][0]['sport_id'] == 1 - assert data['data']['activities'][0]['duration'] == '1:00:00' - assert data['data']['activities'][0]['title'] == 'Activity test' # noqa - assert data['data']['activities'][0]['ascent'] is None - assert data['data']['activities'][0]['ave_speed'] == 7.0 - assert data['data']['activities'][0]['descent'] is None - assert data['data']['activities'][0]['distance'] == 7.0 - assert data['data']['activities'][0]['max_alt'] is None - assert data['data']['activities'][0]['max_speed'] == 7.0 - assert data['data']['activities'][0]['min_alt'] is None - assert data['data']['activities'][0]['moving'] == '1:00:00' - assert data['data']['activities'][0]['pauses'] is None - assert data['data']['activities'][0]['with_gpx'] is False - assert data['data']['activities'][0]['map'] is None - assert data['data']['activities'][0]['weather_start'] is None - assert data['data']['activities'][0]['weather_end'] is None - assert data['data']['activities'][0]['notes'] is None - - records = data['data']['activities'][0]['records'] - assert len(records) == 4 - assert records[0]['sport_id'] == 1 - assert records[0]['activity_id'] == 1 - assert records[0]['record_type'] == 'MS' - assert records[0]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[0]['value'] == 7.0 - assert records[1]['sport_id'] == 1 - assert records[1]['activity_id'] == 1 - assert records[1]['record_type'] == 'LD' - assert records[1]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[1]['value'] == '1:00:00' - assert records[2]['sport_id'] == 1 - assert records[2]['activity_id'] == 1 - assert records[2]['record_type'] == 'FD' - assert records[2]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[2]['value'] == 7.0 - assert records[3]['sport_id'] == 1 - assert records[3]['activity_id'] == 1 - assert records[3]['record_type'] == 'AS' - assert records[3]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[3]['value'] == 7.0 - - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps( - dict( - sport_id=2, - duration=3600, - activity_date='2018-05-15 15:05', - distance=8, - title='Activity test', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'creation_date' in data['data']['activities'][0] - assert ( - data['data']['activities'][0]['activity_date'] - == 'Tue, 15 May 2018 15:05:00 GMT' - ) # noqa - assert data['data']['activities'][0]['user'] == 'test' - assert data['data']['activities'][0]['sport_id'] == 2 - assert data['data']['activities'][0]['duration'] == '1:00:00' - assert data['data']['activities'][0]['title'] == 'Activity test' - assert data['data']['activities'][0]['ascent'] is None - assert data['data']['activities'][0]['ave_speed'] == 8.0 - assert data['data']['activities'][0]['descent'] is None - assert data['data']['activities'][0]['distance'] == 8.0 - assert data['data']['activities'][0]['max_alt'] is None - assert data['data']['activities'][0]['max_speed'] == 8.0 - assert data['data']['activities'][0]['min_alt'] is None - assert data['data']['activities'][0]['moving'] == '1:00:00' - assert data['data']['activities'][0]['pauses'] is None - assert data['data']['activities'][0]['with_gpx'] is False - assert data['data']['activities'][0]['map'] is None - assert data['data']['activities'][0]['weather_start'] is None - assert data['data']['activities'][0]['weather_end'] is None - assert data['data']['activities'][0]['notes'] is None - - records = data['data']['activities'][0]['records'] - assert len(records) == 4 - assert records[0]['sport_id'] == 2 - assert records[0]['activity_id'] == 1 - assert records[0]['record_type'] == 'MS' - assert records[0]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' - assert records[0]['value'] == 8.0 - assert records[1]['sport_id'] == 2 - assert records[1]['activity_id'] == 1 - assert records[1]['record_type'] == 'LD' - assert records[1]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' - assert records[1]['value'] == '1:00:00' - assert records[2]['sport_id'] == 2 - assert records[2]['activity_id'] == 1 - assert records[2]['record_type'] == 'FD' - assert records[2]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' - assert records[2]['value'] == 8.0 - assert records[3]['sport_id'] == 2 - assert records[3]['activity_id'] == 1 - assert records[3]['record_type'] == 'AS' - assert records[3]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' - assert records[3]['value'] == 8.0 - - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict(notes='test notes')), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'creation_date' in data['data']['activities'][0] - assert ( - data['data']['activities'][0]['activity_date'] - == 'Tue, 15 May 2018 15:05:00 GMT' - ) # noqa - assert data['data']['activities'][0]['user'] == 'test' - assert data['data']['activities'][0]['sport_id'] == 2 - assert data['data']['activities'][0]['duration'] == '1:00:00' - assert data['data']['activities'][0]['title'] == 'Activity test' - assert data['data']['activities'][0]['ascent'] is None - assert data['data']['activities'][0]['ave_speed'] == 8.0 - assert data['data']['activities'][0]['descent'] is None - assert data['data']['activities'][0]['distance'] == 8.0 - assert data['data']['activities'][0]['max_alt'] is None - assert data['data']['activities'][0]['max_speed'] == 8.0 - assert data['data']['activities'][0]['min_alt'] is None - assert data['data']['activities'][0]['moving'] == '1:00:00' - assert data['data']['activities'][0]['pauses'] is None - assert data['data']['activities'][0]['with_gpx'] is False - assert data['data']['activities'][0]['map'] is None - assert data['data']['activities'][0]['weather_start'] is None - assert data['data']['activities'][0]['weather_end'] is None - assert data['data']['activities'][0]['notes'] == 'test notes' - - records = data['data']['activities'][0]['records'] - assert len(records) == 4 - assert records[0]['sport_id'] == 2 - assert records[0]['activity_id'] == 1 - assert records[0]['record_type'] == 'MS' - assert records[0]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' - assert records[0]['value'] == 8.0 - assert records[1]['sport_id'] == 2 - assert records[1]['activity_id'] == 1 - assert records[1]['record_type'] == 'LD' - assert records[1]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' - assert records[1]['value'] == '1:00:00' - assert records[2]['sport_id'] == 2 - assert records[2]['activity_id'] == 1 - assert records[2]['record_type'] == 'FD' - assert records[2]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' - assert records[2]['value'] == 8.0 - assert records[3]['sport_id'] == 2 - assert records[3]['activity_id'] == 1 - assert records[3]['record_type'] == 'AS' - assert records[3]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' - assert records[3]['value'] == 8.0 - - -def test_edit_an_activity_wo_gpx_different_user( - app, user_1, user_2, sport_1_cycling -): - 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', - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-14 14:05', - distance=7, - title='Activity test', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='toto@toto.com', password='87654321')), - content_type='application/json', - ) - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps( - dict( - sport_id=2, - duration=3600, - activity_date='2018-05-15 15:05', - distance=8, - title='Activity test', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_edit_an_activity_wo_gpx_timezone( - app, user_1_paris, sport_1_cycling, sport_2_running -): - 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.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-14 14:05', - distance=7, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 201 - assert 'created' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'creation_date' in data['data']['activities'][0] - assert ( - data['data']['activities'][0]['activity_date'] - == 'Mon, 14 May 2018 12:05:00 GMT' - ) # noqa - assert data['data']['activities'][0]['user'] == 'test' - assert data['data']['activities'][0]['sport_id'] == 1 - assert data['data']['activities'][0]['duration'] == '1:00:00' - assert ( - data['data']['activities'][0]['title'] - == 'Cycling - 2018-05-14 14:05:00' - ) # noqa - assert data['data']['activities'][0]['ascent'] is None - assert data['data']['activities'][0]['ave_speed'] == 7.0 - assert data['data']['activities'][0]['descent'] is None - assert data['data']['activities'][0]['distance'] == 7.0 - assert data['data']['activities'][0]['max_alt'] is None - assert data['data']['activities'][0]['max_speed'] == 7.0 - assert data['data']['activities'][0]['min_alt'] is None - assert data['data']['activities'][0]['moving'] == '1:00:00' - assert data['data']['activities'][0]['pauses'] is None - assert data['data']['activities'][0]['with_gpx'] is False - - records = data['data']['activities'][0]['records'] - assert len(records) == 4 - assert records[0]['sport_id'] == 1 - assert records[0]['activity_id'] == 1 - assert records[0]['record_type'] == 'MS' - assert records[0]['activity_date'] == 'Mon, 14 May 2018 12:05:00 GMT' - assert records[0]['value'] == 7.0 - assert records[1]['sport_id'] == 1 - assert records[1]['activity_id'] == 1 - assert records[1]['record_type'] == 'LD' - assert records[1]['activity_date'] == 'Mon, 14 May 2018 12:05:00 GMT' - assert records[1]['value'] == '1:00:00' - assert records[2]['sport_id'] == 1 - assert records[2]['activity_id'] == 1 - assert records[2]['record_type'] == 'FD' - assert records[2]['activity_date'] == 'Mon, 14 May 2018 12:05:00 GMT' - assert records[2]['value'] == 7.0 - assert records[3]['sport_id'] == 1 - assert records[3]['activity_id'] == 1 - assert records[3]['record_type'] == 'AS' - assert records[3]['activity_date'] == 'Mon, 14 May 2018 12:05:00 GMT' - assert records[3]['value'] == 7.0 - - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps( - dict( - sport_id=2, - duration=3600, - activity_date='2018-05-15 15:05', - distance=8, - title='Activity test', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'creation_date' in data['data']['activities'][0] - assert ( - data['data']['activities'][0]['activity_date'] - == 'Tue, 15 May 2018 13:05:00 GMT' - ) # noqa - assert data['data']['activities'][0]['user'] == 'test' - assert data['data']['activities'][0]['sport_id'] == 2 - assert data['data']['activities'][0]['duration'] == '1:00:00' - assert data['data']['activities'][0]['title'] == 'Activity test' # noqa - assert data['data']['activities'][0]['ascent'] is None - assert data['data']['activities'][0]['ave_speed'] == 8.0 - assert data['data']['activities'][0]['descent'] is None - assert data['data']['activities'][0]['distance'] == 8.0 - assert data['data']['activities'][0]['max_alt'] is None - assert data['data']['activities'][0]['max_speed'] == 8.0 - assert data['data']['activities'][0]['min_alt'] is None - assert data['data']['activities'][0]['moving'] == '1:00:00' - assert data['data']['activities'][0]['pauses'] is None - assert data['data']['activities'][0]['with_gpx'] is False - - records = data['data']['activities'][0]['records'] - assert len(records) == 4 - assert records[0]['sport_id'] == 2 - assert records[0]['activity_id'] == 1 - assert records[0]['record_type'] == 'MS' - assert records[0]['activity_date'] == 'Tue, 15 May 2018 13:05:00 GMT' - assert records[0]['value'] == 8.0 - assert records[1]['sport_id'] == 2 - assert records[1]['activity_id'] == 1 - assert records[1]['record_type'] == 'LD' - assert records[1]['activity_date'] == 'Tue, 15 May 2018 13:05:00 GMT' - assert records[1]['value'] == '1:00:00' - assert records[2]['sport_id'] == 2 - assert records[2]['activity_id'] == 1 - assert records[2]['record_type'] == 'FD' - assert records[2]['activity_date'] == 'Tue, 15 May 2018 13:05:00 GMT' - assert records[2]['value'] == 8.0 - assert records[3]['sport_id'] == 2 - assert records[3]['activity_id'] == 1 - assert records[3]['record_type'] == 'AS' - assert records[3]['activity_date'] == 'Tue, 15 May 2018 13:05:00 GMT' - assert records[3]['value'] == 8.0 - - -def test_edit_an_activity_wo_gpx_partial(app, user_1, sport_1_cycling): - 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.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-14 14:05', - distance=7, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 201 - assert 'created' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'creation_date' in data['data']['activities'][0] - assert ( - data['data']['activities'][0]['activity_date'] - == 'Mon, 14 May 2018 14:05:00 GMT' - ) # noqa - assert data['data']['activities'][0]['user'] == 'test' - assert data['data']['activities'][0]['sport_id'] == 1 - assert data['data']['activities'][0]['duration'] == '1:00:00' - assert ( - data['data']['activities'][0]['title'] - == 'Cycling - 2018-05-14 14:05:00' - ) # noqa - assert data['data']['activities'][0]['ascent'] is None - assert data['data']['activities'][0]['ave_speed'] == 7.0 - assert data['data']['activities'][0]['descent'] is None - assert data['data']['activities'][0]['distance'] == 7.0 - assert data['data']['activities'][0]['max_alt'] is None - assert data['data']['activities'][0]['max_speed'] == 7.0 - assert data['data']['activities'][0]['min_alt'] is None - assert data['data']['activities'][0]['moving'] == '1:00:00' - assert data['data']['activities'][0]['pauses'] is None - assert data['data']['activities'][0]['with_gpx'] is False - - records = data['data']['activities'][0]['records'] - assert len(records) == 4 - assert records[0]['sport_id'] == 1 - assert records[0]['activity_id'] == 1 - assert records[0]['record_type'] == 'MS' - assert records[0]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[0]['value'] == 7.0 - assert records[1]['sport_id'] == 1 - assert records[1]['activity_id'] == 1 - assert records[1]['record_type'] == 'LD' - assert records[1]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[1]['value'] == '1:00:00' - assert records[2]['sport_id'] == 1 - assert records[2]['activity_id'] == 1 - assert records[2]['record_type'] == 'FD' - assert records[2]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[2]['value'] == 7.0 - assert records[3]['sport_id'] == 1 - assert records[3]['activity_id'] == 1 - assert records[3]['record_type'] == 'AS' - assert records[3]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[3]['value'] == 7.0 - - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict(sport_id=1, distance=10)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 'creation_date' in data['data']['activities'][0] - assert ( - data['data']['activities'][0]['activity_date'] - == 'Mon, 14 May 2018 14:05:00 GMT' - ) # noqa - assert data['data']['activities'][0]['user'] == 'test' - assert data['data']['activities'][0]['sport_id'] == 1 - assert data['data']['activities'][0]['duration'] == '1:00:00' - assert ( - data['data']['activities'][0]['title'] - == 'Cycling - 2018-05-14 14:05:00' - ) # noqa - assert data['data']['activities'][0]['ascent'] is None - assert data['data']['activities'][0]['ave_speed'] == 10.0 - assert data['data']['activities'][0]['descent'] is None - assert data['data']['activities'][0]['distance'] == 10.0 - assert data['data']['activities'][0]['max_alt'] is None - assert data['data']['activities'][0]['max_speed'] == 10.0 - assert data['data']['activities'][0]['min_alt'] is None - assert data['data']['activities'][0]['moving'] == '1:00:00' - assert data['data']['activities'][0]['pauses'] is None - assert data['data']['activities'][0]['with_gpx'] is False - - records = data['data']['activities'][0]['records'] - assert len(records) == 4 - assert records[0]['sport_id'] == 1 - assert records[0]['activity_id'] == 1 - assert records[0]['record_type'] == 'MS' - assert records[0]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[0]['value'] == 10.0 - assert records[1]['sport_id'] == 1 - assert records[1]['activity_id'] == 1 - assert records[1]['record_type'] == 'LD' - assert records[1]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[1]['value'] == '1:00:00' - assert records[2]['sport_id'] == 1 - assert records[2]['activity_id'] == 1 - assert records[2]['record_type'] == 'FD' - assert records[2]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[2]['value'] == 10.0 - assert records[3]['sport_id'] == 1 - assert records[3]['activity_id'] == 1 - assert records[3]['record_type'] == 'AS' - assert records[3]['activity_date'] == 'Mon, 14 May 2018 14:05:00 GMT' - assert records[3]['value'] == 10.0 - - -def test_edit_an_activity_wo_gpx_invalid_payload( - app, user_1, sport_1_cycling, activity_cycling_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.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict()), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert 'error' in data['status'] - assert 'Invalid payload.' in data['message'] - - -def test_edit_an_activity_wo_gpx_incorrect_data( - app, user_1, sport_1_cycling, activity_cycling_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.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, duration=3600, activity_date='15/2018', distance=10 - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert ( - 'Error. Please try again or contact the administrator.' - in data['message'] - ) - - -def test_edit_an_activity_no_activity(app, user_1, sport_1_cycling): - 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.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-15 14:05', - distance=10, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'not found' in data['status'] - assert len(data['data']['activities']) == 0 - - -def test_refresh_an_activity_with_gpx( - app, user_1, sport_1_cycling, sport_2_running, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - - # Edit some activity data - activity = Activity.query.filter_by(id=1).first() - activity.ascent = 1000 - activity.min_alt = -100 - - response = client.patch( - '/api/activities/1', - content_type='application/json', - data=json.dumps(dict(refresh=True)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['activities']) == 1 - assert 1 == data['data']['activities'][0]['sport_id'] - assert 0.4 == data['data']['activities'][0]['ascent'] - assert 975.0 == data['data']['activities'][0]['min_alt'] +class TestEditActivityWithGpx: + def test_it_updates_title_for_an_activity_with_gpx( + self, app, user_1, sport_1_cycling, sport_2_running, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + response = client.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict(sport_id=2, title="Activity test")), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 2 == data['data']['activities'][0]['sport_id'] + assert data['data']['activities'][0]['title'] == 'Activity test' + assert_activity_data_with_gpx(data) + + def test_it_adds_notes_for_an_activity_with_gpx( + self, app, user_1, sport_1_cycling, sport_2_running, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + response = client.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict(notes="test notes")), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert data['data']['activities'][0]['title'] == 'just an activity' + assert data['data']['activities'][0]['notes'] == 'test notes' + + def test_it_raises_403_when_editing_an_activity_from_different_user( + self, app, user_1, user_2, sport_1_cycling, sport_2_running, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict(email='toto@toto.com', password='87654321')), + content_type='application/json', + ) + + response = client.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict(sport_id=2, title="Activity test")), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 403 + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] + + def test_it_updates_sport( + self, app, user_1, sport_1_cycling, sport_2_running, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + response = client.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict(sport_id=2)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 2 == data['data']['activities'][0]['sport_id'] + assert data['data']['activities'][0]['title'] == 'just an activity' + assert_activity_data_with_gpx(data) + + def test_it_returns_400_if_payload_is_empty( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + response = client.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict()), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'error' in data['status'] + assert 'Invalid payload.' in data['message'] + + def test_it_raises_500_if_sport_does_not_exists( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + response = client.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict(sport_id=2)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert ( + 'Error. Please try again or contact the administrator.' + in data['message'] + ) + + +class TestEditActivityWithoutGpx: + def test_it_updates_an_activity_wo_gpx( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + activity_cycling_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.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps( + dict( + sport_id=2, + duration=3600, + activity_date='2018-05-15 15:05', + distance=8, + title='Activity test', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'creation_date' in data['data']['activities'][0] + assert ( + data['data']['activities'][0]['activity_date'] + == 'Tue, 15 May 2018 15:05:00 GMT' + ) + assert data['data']['activities'][0]['user'] == 'test' + assert data['data']['activities'][0]['sport_id'] == 2 + assert data['data']['activities'][0]['duration'] == '1:00:00' + assert data['data']['activities'][0]['title'] == 'Activity test' + assert data['data']['activities'][0]['ascent'] is None + assert data['data']['activities'][0]['ave_speed'] == 8.0 + assert data['data']['activities'][0]['descent'] is None + assert data['data']['activities'][0]['distance'] == 8.0 + assert data['data']['activities'][0]['max_alt'] is None + assert data['data']['activities'][0]['max_speed'] == 8.0 + assert data['data']['activities'][0]['min_alt'] is None + assert data['data']['activities'][0]['moving'] == '1:00:00' + assert data['data']['activities'][0]['pauses'] is None + assert data['data']['activities'][0]['with_gpx'] is False + assert data['data']['activities'][0]['map'] is None + assert data['data']['activities'][0]['weather_start'] is None + assert data['data']['activities'][0]['weather_end'] is None + assert data['data']['activities'][0]['notes'] is None + + records = data['data']['activities'][0]['records'] + assert len(records) == 4 + assert records[0]['sport_id'] == 2 + assert records[0]['activity_id'] == 1 + assert records[0]['record_type'] == 'MS' + assert records[0]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' + assert records[0]['value'] == 8.0 + assert records[1]['sport_id'] == 2 + assert records[1]['activity_id'] == 1 + assert records[1]['record_type'] == 'LD' + assert records[1]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' + assert records[1]['value'] == '1:00:00' + assert records[2]['sport_id'] == 2 + assert records[2]['activity_id'] == 1 + assert records[2]['record_type'] == 'FD' + assert records[2]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' + assert records[2]['value'] == 8.0 + assert records[3]['sport_id'] == 2 + assert records[3]['activity_id'] == 1 + assert records[3]['record_type'] == 'AS' + assert records[3]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT' + assert records[3]['value'] == 8.0 + + def test_it_adds_notes_to_an_activity_wo_gpx( + self, app, user_1, sport_1_cycling, activity_cycling_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.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict(notes='test notes')), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'creation_date' in data['data']['activities'][0] + assert ( + data['data']['activities'][0]['activity_date'] + == 'Mon, 01 Jan 2018 00:00:00 GMT' + ) + assert data['data']['activities'][0]['user'] == 'test' + assert data['data']['activities'][0]['sport_id'] == 1 + assert data['data']['activities'][0]['duration'] == '1:00:00' + assert data['data']['activities'][0]['title'] is None + assert data['data']['activities'][0]['ascent'] is None + assert data['data']['activities'][0]['ave_speed'] == 10.0 + assert data['data']['activities'][0]['descent'] is None + assert data['data']['activities'][0]['distance'] == 10.0 + assert data['data']['activities'][0]['max_alt'] is None + assert data['data']['activities'][0]['max_speed'] == 10.0 + assert data['data']['activities'][0]['min_alt'] is None + assert data['data']['activities'][0]['moving'] == '1:00:00' + assert data['data']['activities'][0]['pauses'] is None + assert data['data']['activities'][0]['with_gpx'] is False + assert data['data']['activities'][0]['map'] is None + assert data['data']['activities'][0]['weather_start'] is None + assert data['data']['activities'][0]['weather_end'] is None + assert data['data']['activities'][0]['notes'] == 'test notes' + + records = data['data']['activities'][0]['records'] + assert len(records) == 4 + assert records[0]['sport_id'] == 1 + assert records[0]['activity_id'] == 1 + assert records[0]['record_type'] == 'MS' + assert records[0]['activity_date'] == 'Mon, 01 Jan 2018 00:00:00 GMT' + assert records[0]['value'] == 10.0 + assert records[1]['sport_id'] == 1 + assert records[1]['activity_id'] == 1 + assert records[1]['record_type'] == 'LD' + assert records[1]['activity_date'] == 'Mon, 01 Jan 2018 00:00:00 GMT' + assert records[1]['value'] == '1:00:00' + assert records[2]['sport_id'] == 1 + assert records[2]['activity_id'] == 1 + assert records[2]['record_type'] == 'FD' + assert records[2]['activity_date'] == 'Mon, 01 Jan 2018 00:00:00 GMT' + assert records[2]['value'] == 10.0 + assert records[3]['sport_id'] == 1 + assert records[3]['activity_id'] == 1 + assert records[3]['record_type'] == 'AS' + assert records[3]['activity_date'] == 'Mon, 01 Jan 2018 00:00:00 GMT' + assert records[3]['value'] == 10.0 + + def test_returns_403_when_editing_an_activity_wo_gpx_from_different_user( + self, app, user_1, user_2, sport_1_cycling, activity_cycling_user_2 + ): + 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.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps( + dict( + sport_id=2, + duration=3600, + activity_date='2018-05-15 15:05', + distance=8, + title='Activity test', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 403 + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] + + def test_it_updates_an_activity_wo_gpx_with_timezone( + self, + app, + user_1_paris, + sport_1_cycling, + sport_2_running, + activity_cycling_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.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps( + dict( + sport_id=2, + duration=3600, + activity_date='2018-05-15 15:05', + distance=8, + title='Activity test', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'creation_date' in data['data']['activities'][0] + assert ( + data['data']['activities'][0]['activity_date'] + == 'Tue, 15 May 2018 13:05:00 GMT' + ) + assert data['data']['activities'][0]['user'] == 'test' + assert data['data']['activities'][0]['sport_id'] == 2 + assert data['data']['activities'][0]['duration'] == '1:00:00' + assert data['data']['activities'][0]['title'] == 'Activity test' + assert data['data']['activities'][0]['ascent'] is None + assert data['data']['activities'][0]['ave_speed'] == 8.0 + assert data['data']['activities'][0]['descent'] is None + assert data['data']['activities'][0]['distance'] == 8.0 + assert data['data']['activities'][0]['max_alt'] is None + assert data['data']['activities'][0]['max_speed'] == 8.0 + assert data['data']['activities'][0]['min_alt'] is None + assert data['data']['activities'][0]['moving'] == '1:00:00' + assert data['data']['activities'][0]['pauses'] is None + assert data['data']['activities'][0]['with_gpx'] is False + + records = data['data']['activities'][0]['records'] + assert len(records) == 4 + assert records[0]['sport_id'] == 2 + assert records[0]['activity_id'] == 1 + assert records[0]['record_type'] == 'MS' + assert records[0]['activity_date'] == 'Tue, 15 May 2018 13:05:00 GMT' + assert records[0]['value'] == 8.0 + assert records[1]['sport_id'] == 2 + assert records[1]['activity_id'] == 1 + assert records[1]['record_type'] == 'LD' + assert records[1]['activity_date'] == 'Tue, 15 May 2018 13:05:00 GMT' + assert records[1]['value'] == '1:00:00' + assert records[2]['sport_id'] == 2 + assert records[2]['activity_id'] == 1 + assert records[2]['record_type'] == 'FD' + assert records[2]['activity_date'] == 'Tue, 15 May 2018 13:05:00 GMT' + assert records[2]['value'] == 8.0 + assert records[3]['sport_id'] == 2 + assert records[3]['activity_id'] == 1 + assert records[3]['record_type'] == 'AS' + assert records[3]['activity_date'] == 'Tue, 15 May 2018 13:05:00 GMT' + assert records[3]['value'] == 8.0 + + def test_it_updates_only_sport_and_distance_an_activity_wo_gpx( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + activity_cycling_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.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict(sport_id=2, distance=20)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 'creation_date' in data['data']['activities'][0] + assert ( + data['data']['activities'][0]['activity_date'] + == 'Mon, 01 Jan 2018 00:00:00 GMT' + ) + assert data['data']['activities'][0]['user'] == 'test' + assert data['data']['activities'][0]['sport_id'] == 2 + assert data['data']['activities'][0]['duration'] == '1:00:00' + assert data['data']['activities'][0]['title'] is None + assert data['data']['activities'][0]['ascent'] is None + assert data['data']['activities'][0]['ave_speed'] == 20.0 + assert data['data']['activities'][0]['descent'] is None + assert data['data']['activities'][0]['distance'] == 20.0 + assert data['data']['activities'][0]['max_alt'] is None + assert data['data']['activities'][0]['max_speed'] == 20.0 + assert data['data']['activities'][0]['min_alt'] is None + assert data['data']['activities'][0]['moving'] == '1:00:00' + assert data['data']['activities'][0]['pauses'] is None + assert data['data']['activities'][0]['with_gpx'] is False + + records = data['data']['activities'][0]['records'] + assert len(records) == 4 + assert records[0]['sport_id'] == 2 + assert records[0]['activity_id'] == 1 + assert records[0]['record_type'] == 'MS' + assert records[0]['activity_date'] == 'Mon, 01 Jan 2018 00:00:00 GMT' + assert records[0]['value'] == 20.0 + assert records[1]['sport_id'] == 2 + assert records[1]['activity_id'] == 1 + assert records[1]['record_type'] == 'LD' + assert records[1]['activity_date'] == 'Mon, 01 Jan 2018 00:00:00 GMT' + assert records[1]['value'] == '1:00:00' + assert records[2]['sport_id'] == 2 + assert records[2]['activity_id'] == 1 + assert records[2]['record_type'] == 'FD' + assert records[2]['activity_date'] == 'Mon, 01 Jan 2018 00:00:00 GMT' + assert records[2]['value'] == 20.0 + assert records[3]['sport_id'] == 2 + assert records[3]['activity_id'] == 1 + assert records[3]['record_type'] == 'AS' + assert records[3]['activity_date'] == 'Mon, 01 Jan 2018 00:00:00 GMT' + assert records[3]['value'] == 20.0 + + def test_it_returns_400_if_payload_is_empty( + self, app, user_1, sport_1_cycling, activity_cycling_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.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict()), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'error' in data['status'] + assert 'Invalid payload.' in data['message'] + + def test_it_returns_500_if_date_format_is_invalid( + self, app, user_1, sport_1_cycling, activity_cycling_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.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='15/2018', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + + assert response.status_code == 500 + assert 'error' in data['status'] + assert ( + 'Error. Please try again or contact the administrator.' + in data['message'] + ) + + def test_it_returns_404_if_edited_activity_doens_not_exists( + self, app, user_1, sport_1_cycling + ): + 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.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-05-15 14:05', + distance=10, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert len(data['data']['activities']) == 0 + + +class TestRefreshActivityWithGpx: + def test_refresh_an_activity_with_gpx( + self, app, user_1, sport_1_cycling, sport_2_running, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + # Edit some activity data + activity = Activity.query.filter_by(id=1).first() + activity.ascent = 1000 + activity.min_alt = -100 + + response = client.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict(refresh=True)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + assert 1 == data['data']['activities'][0]['sport_id'] + assert 0.4 == data['data']['activities'][0]['ascent'] + assert 975.0 == data['data']['activities'][0]['min_alt'] diff --git a/fittrackee_api/fittrackee_api/tests/test_activities_api_3_delete.py b/fittrackee_api/fittrackee_api/tests/test_activities_api_3_delete.py index de91105c..33e8f726 100644 --- a/fittrackee_api/fittrackee_api/tests/test_activities_api_3_delete.py +++ b/fittrackee_api/fittrackee_api/tests/test_activities_api_3_delete.py @@ -11,178 +11,178 @@ def get_gpx_filepath(activity_id): return activity.gpx -def test_delete_an_activity_with_gpx(app, user_1, sport_1_cycling, gpx_file): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.delete( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) +class TestDeleteActivityWithGpx: + def test_it_deletes_an_activity_with_gpx( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + response = client.delete( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert response.status_code == 204 + assert response.status_code == 204 + + def test_it_returns_403_when_deleting_an_activity_from_different_user( + self, app, user_1, user_2, sport_1_cycling, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict(email='toto@toto.com', password='87654321')), + content_type='application/json', + ) + response = client.delete( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + + assert response.status_code == 403 + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] + + def test_it_returns_404_if_activity_does_not_exist(self, app, 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.delete( + '/api/activities/9999', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + + def test_it_returns_500_when_deleting_an_activity_with_gpx_invalid_file( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + gpx_filepath = get_gpx_filepath(1) + gpx_filepath = get_absolute_file_path(gpx_filepath) + os.remove(gpx_filepath) + + response = client.delete( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + + assert response.status_code == 500 + assert 'error' in data['status'] + assert ( + 'Error. Please try again or contact the administrator.' + in data['message'] + ) -def test_delete_an_activity_with_gpx_different_user( - app, user_1, user_2, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='toto@toto.com', password='87654321')), - content_type='application/json', - ) - response = client.delete( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) +class TestDeleteActivityWithoutGpx: + def test_it_deletes_an_activity_wo_gpx( + self, app, user_1, sport_1_cycling, activity_cycling_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.delete( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + assert response.status_code == 204 - data = json.loads(response.data.decode()) + def test_it_returns_403_when_deleting_an_activity_from_different_user( + self, app, user_1, user_2, sport_1_cycling, activity_cycling_user_1 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict(email='toto@toto.com', password='87654321')), + content_type='application/json', + ) + response = client.delete( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] + data = json.loads(response.data.decode()) - -def test_delete_an_activity_wo_gpx( - app, user_1, sport_1_cycling, activity_cycling_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.delete( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - assert response.status_code == 204 - - -def test_delete_an_activity_wo_gpx_different_user( - app, user_1, user_2, sport_1_cycling, activity_cycling_user_1 -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='toto@toto.com', password='87654321')), - content_type='application/json', - ) - response = client.delete( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_delete_an_activity_no_activity(app, 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.delete( - '/api/activities/9999', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - assert response.status_code == 404 - assert 'not found' in data['status'] - - -def test_delete_an_activity_with_gpx_invalid_file( - app, user_1, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - - gpx_filepath = get_gpx_filepath(1) - gpx_filepath = get_absolute_file_path(gpx_filepath) - os.remove(gpx_filepath) - - response = client.delete( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert ( - 'Error. Please try again or contact the administrator.' - in data['message'] - ) + assert response.status_code == 403 + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] diff --git a/fittrackee_api/fittrackee_api/tests/test_activities_model.py b/fittrackee_api/fittrackee_api/tests/test_activities_model.py index ffd4a5bf..6d24ca65 100644 --- a/fittrackee_api/fittrackee_api/tests/test_activities_model.py +++ b/fittrackee_api/fittrackee_api/tests/test_activities_model.py @@ -1,53 +1,60 @@ -def test_add_activity(app, sport_1_cycling, user_1, activity_cycling_user_1): - activity_cycling_user_1.title = 'Test' +class TestActivityModel: + def test_activity_model( + self, app, sport_1_cycling, user_1, activity_cycling_user_1 + ): + activity_cycling_user_1.title = 'Test' - assert 1 == activity_cycling_user_1.id - assert 1 == activity_cycling_user_1.user_id - assert 1 == activity_cycling_user_1.sport_id - assert '2018-01-01 00:00:00' == str(activity_cycling_user_1.activity_date) - assert 10.0 == float(activity_cycling_user_1.distance) - assert '0:17:04' == str(activity_cycling_user_1.duration) - assert 'Test' == activity_cycling_user_1.title - assert '' == str( - activity_cycling_user_1 - ) # noqa + assert 1 == activity_cycling_user_1.id + assert 1 == activity_cycling_user_1.user_id + assert 1 == activity_cycling_user_1.sport_id + assert '2018-01-01 00:00:00' == str( + activity_cycling_user_1.activity_date + ) + assert 10.0 == float(activity_cycling_user_1.distance) + assert '1:00:00' == str(activity_cycling_user_1.duration) + assert 'Test' == activity_cycling_user_1.title + assert '' == str( + activity_cycling_user_1 + ) - serialized_activity = activity_cycling_user_1.serialize() - assert 1 == serialized_activity['id'] - assert 'test' == serialized_activity['user'] - assert 1 == serialized_activity['sport_id'] - assert serialized_activity['title'] == 'Test' - assert 'creation_date' in serialized_activity - assert serialized_activity['modification_date'] is not None - assert str(serialized_activity['activity_date']) == '2018-01-01 00:00:00' - assert serialized_activity['duration'] == '0:17:04' - assert serialized_activity['pauses'] is None - assert serialized_activity['moving'] == '0:17:04' - assert serialized_activity['distance'] == 10.0 - assert serialized_activity['max_alt'] is None - assert serialized_activity['descent'] is None - assert serialized_activity['ascent'] is None - assert serialized_activity['max_speed'] == 10.0 - assert serialized_activity['ave_speed'] == 10.0 - assert serialized_activity['with_gpx'] is False - assert serialized_activity['bounds'] == [] - assert serialized_activity['previous_activity'] is None - assert serialized_activity['next_activity'] is None - assert serialized_activity['segments'] == [] - assert serialized_activity['records'] != [] - assert serialized_activity['map'] is None - assert serialized_activity['weather_start'] is None - assert serialized_activity['weather_end'] is None - assert serialized_activity['notes'] is None + serialized_activity = activity_cycling_user_1.serialize() + assert 1 == serialized_activity['id'] + assert 'test' == serialized_activity['user'] + assert 1 == serialized_activity['sport_id'] + assert serialized_activity['title'] == 'Test' + assert 'creation_date' in serialized_activity + assert serialized_activity['modification_date'] is not None + assert ( + str(serialized_activity['activity_date']) == '2018-01-01 00:00:00' + ) + assert serialized_activity['duration'] == '1:00:00' + assert serialized_activity['pauses'] is None + assert serialized_activity['moving'] == '1:00:00' + assert serialized_activity['distance'] == 10.0 + assert serialized_activity['max_alt'] is None + assert serialized_activity['descent'] is None + assert serialized_activity['ascent'] is None + assert serialized_activity['max_speed'] == 10.0 + assert serialized_activity['ave_speed'] == 10.0 + assert serialized_activity['with_gpx'] is False + assert serialized_activity['bounds'] == [] + assert serialized_activity['previous_activity'] is None + assert serialized_activity['next_activity'] is None + assert serialized_activity['segments'] == [] + assert serialized_activity['records'] != [] + assert serialized_activity['map'] is None + assert serialized_activity['weather_start'] is None + assert serialized_activity['weather_end'] is None + assert serialized_activity['notes'] is None - -def test_add_segment( - app, - sport_1_cycling, - user_1, - activity_cycling_user_1, - activity_cycling_user_1_segment, -): - assert '' == str( - activity_cycling_user_1_segment - ) # noqa + def test_activity_segment_model( + self, + app, + sport_1_cycling, + user_1, + activity_cycling_user_1, + activity_cycling_user_1_segment, + ): + assert '' == str( + activity_cycling_user_1_segment + ) diff --git a/fittrackee_api/fittrackee_api/tests/test_app_config_api.py b/fittrackee_api/fittrackee_api/tests/test_app_config_api.py index 56b9475b..b50ba5d6 100644 --- a/fittrackee_api/fittrackee_api/tests/test_app_config_api.py +++ b/fittrackee_api/fittrackee_api/tests/test_app_config_api.py @@ -1,212 +1,222 @@ import json -def test_get_config(app, 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/config', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) +class TestGetConfig: + def test_it_gets_application_config(self, app, 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', + ) - assert response.status_code == 200 - assert 'success' in data['status'] + response = client.get( + '/api/config', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert data['data']['gpx_limit_import'] == 10 - assert data['data']['is_registration_enabled'] is True - assert data['data']['max_single_file_size'] == 1048576 - assert data['data']['max_zip_file_size'] == 10485760 - assert data['data']['max_users'] == 100 + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['gpx_limit_import'] == 10 + assert data['data']['is_registration_enabled'] is True + assert data['data']['max_single_file_size'] == 1048576 + assert data['data']['max_zip_file_size'] == 10485760 + assert data['data']['max_users'] == 100 + + def test_it_returns_error_if_application_has_no_config( + self, app_no_config, user_1_admin + ): + client = app_no_config.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.get( + '/api/config', + content_type='application/json', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert 'Error on getting configuration.' in data['message'] + + def test_it_returns_error_if_application_has_several_config( + self, app, app_config, user_1_admin + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.get( + '/api/config', + content_type='application/json', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert 'Error on getting configuration.' in data['message'] -def test_get_config_no_config(app_no_config, user_1_admin): - client = app_no_config.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/config', - content_type='application/json', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) +class TestUpdateConfig: + def test_it_updates_config_when_user_is_admin(self, app, user_1_admin): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + response = client.patch( + '/api/config', + content_type='application/json', + data=json.dumps(dict(gpx_limit_import=100, max_users=10)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) - assert response.status_code == 500 - assert 'error' in data['status'] - assert 'Error on getting configuration.' in data['message'] + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['gpx_limit_import'] == 100 + assert data['data']['is_registration_enabled'] is True + assert data['data']['max_single_file_size'] == 1048576 + assert data['data']['max_zip_file_size'] == 10485760 + assert data['data']['max_users'] == 10 + def test_it_updates_all_config(self, app, user_1_admin): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) -def test_get_config_several_config(app, app_config, user_1_admin): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/config', - content_type='application/json', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + response = client.patch( + '/api/config', + content_type='application/json', + data=json.dumps( + dict( + gpx_limit_import=20, + max_single_file_size=10000, + max_zip_file_size=25000, + max_users=50, + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert response.status_code == 500 - assert 'error' in data['status'] - assert 'Error on getting configuration.' in data['message'] + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['gpx_limit_import'] == 20 + assert data['data']['is_registration_enabled'] is True + assert data['data']['max_single_file_size'] == 10000 + assert data['data']['max_zip_file_size'] == 25000 + assert data['data']['max_users'] == 50 + def test_it_returns_403_when_user_is_not_an_admin(self, app, 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', + ) -def test_update_config_as_admin(app, user_1_admin): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/config', - content_type='application/json', - data=json.dumps(dict(gpx_limit_import=100, max_users=10)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + response = client.patch( + '/api/config', + content_type='application/json', + data=json.dumps(dict(gpx_limit_import=100, max_users=10)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['gpx_limit_import'] == 100 - assert data['data']['is_registration_enabled'] is True - assert data['data']['max_single_file_size'] == 1048576 - assert data['data']['max_zip_file_size'] == 10485760 - assert data['data']['max_users'] == 10 + data = json.loads(response.data.decode()) + assert response.status_code == 403 + assert 'success' not in data['status'] + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] + def test_it_returns_400_if_invalid_is_payload(self, app, user_1_admin): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) -def test_update_full_config_as_admin(app, user_1_admin): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/config', - content_type='application/json', - data=json.dumps( - dict( - gpx_limit_import=20, - max_single_file_size=10000, - max_zip_file_size=25000, - max_users=50, - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + response = client.patch( + '/api/config', + content_type='application/json', + data=json.dumps(dict()), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['gpx_limit_import'] == 20 - assert data['data']['is_registration_enabled'] is True - assert data['data']['max_single_file_size'] == 10000 - assert data['data']['max_zip_file_size'] == 25000 - assert data['data']['max_users'] == 50 + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'error' in data['status'] + assert 'Invalid payload.' in data['message'] + def test_it_returns_error_on_update_if_application_has_no_config( + self, app_no_config, user_1_admin + ): + client = app_no_config.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) -def test_update_config_not_admin(app, 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.patch( - '/api/config', - content_type='application/json', - data=json.dumps(dict(gpx_limit_import=100, max_users=10)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + response = client.patch( + '/api/config', + content_type='application/json', + data=json.dumps(dict(gpx_limit_import=100, max_users=10)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert response.status_code == 403 - assert 'success' not in data['status'] - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_update_config_invalid_payload(app, user_1_admin): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/config', - content_type='application/json', - data=json.dumps(dict()), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert 'error' in data['status'] - assert 'Invalid payload.' in data['message'] - - -def test_update_config_no_config(app_no_config, user_1_admin): - client = app_no_config.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/config', - content_type='application/json', - data=json.dumps(dict(gpx_limit_import=100, max_users=10)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert 'Error on updating configuration.' in data['message'] - - -def test_ping(app): - """ => Ensure the /ping route behaves correctly.""" - client = app.test_client() - response = client.get('/api/ping') - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'pong' in data['message'] - assert 'success' in data['status'] + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert 'Error on updating configuration.' in data['message'] diff --git a/fittrackee_api/fittrackee_api/tests/test_app_config_model.py b/fittrackee_api/fittrackee_api/tests/test_app_config_model.py index b9f1311c..82acbca7 100644 --- a/fittrackee_api/fittrackee_api/tests/test_app_config_model.py +++ b/fittrackee_api/fittrackee_api/tests/test_app_config_model.py @@ -1,13 +1,14 @@ from fittrackee_api.application.models import AppConfig -def test_application_config(app): - app_config = AppConfig.query.first() - assert 1 == app_config.id +class TestConfigModel: + def test_application_config(self, app): + app_config = AppConfig.query.first() + assert 1 == app_config.id - serialized_app_config = app_config.serialize() - assert serialized_app_config['gpx_limit_import'] == 10 - assert serialized_app_config['is_registration_enabled'] is True - assert serialized_app_config['max_single_file_size'] == 1048576 - assert serialized_app_config['max_zip_file_size'] == 10485760 - assert serialized_app_config['max_users'] == 100 + serialized_app_config = app_config.serialize() + assert serialized_app_config['gpx_limit_import'] == 10 + assert serialized_app_config['is_registration_enabled'] is True + assert serialized_app_config['max_single_file_size'] == 1048576 + assert serialized_app_config['max_zip_file_size'] == 10485760 + assert serialized_app_config['max_users'] == 100 diff --git a/fittrackee_api/fittrackee_api/tests/test_auth_api.py b/fittrackee_api/fittrackee_api/tests/test_auth_api.py index 1ad4e8f9..4b1909d8 100644 --- a/fittrackee_api/fittrackee_api/tests/test_auth_api.py +++ b/fittrackee_api/fittrackee_api/tests/test_auth_api.py @@ -3,903 +3,912 @@ import time from io import BytesIO -def test_user_registration(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='justatest', - email='test@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'success' - assert data['message'] == 'Successfully registered.' - assert data['auth_token'] - assert response.content_type == 'application/json' - assert response.status_code == 201 - - -def test_user_registration_user_already_exists(app, user_1): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='test', - email='test@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Sorry. That user already exists.' - assert response.content_type == 'application/json' - assert response.status_code == 400 - - -def test_user_registration_invalid_short_username(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='t', - email='test@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == "Username: 3 to 12 characters required.\n" - assert response.content_type == 'application/json' - assert response.status_code == 400 - - -def test_user_registration_invalid_long_username(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='testestestestestest', - email='test@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == "Username: 3 to 12 characters required.\n" - assert response.content_type == 'application/json' - assert response.status_code == 400 - - -def test_user_registration_invalid_email(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='test', - email='test@test', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == "Valid email must be provided.\n" - assert response.content_type == 'application/json' - assert response.status_code == 400 - - -def test_user_registration_invalid_short_password(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='test', - email='test@test.com', - password='1234567', - password_conf='1234567', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == "Password: 8 characters required.\n" - assert response.content_type == 'application/json' - assert response.status_code == 400 - - -def test_user_registration_mismatched_password(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='test', - email='test@test.com', - password='12345678', - password_conf='87654321', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert ( - data['message'] == "Password and password confirmation don\'t match.\n" - ) - assert response.content_type == 'application/json' - assert response.status_code == 400 - - -def test_user_registration_invalid_json(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps(dict()), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert response.status_code, 400 - assert 'Invalid payload.', data['message'] - assert 'error', data['status'] - - -def test_user_registration_invalid_json_keys_no_username(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - email='test@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert response.status_code == 400 - assert 'Invalid payload.' in data['message'] - assert 'error' in data['status'] - - -def test_user_registration_invalid_json_keys_no_email(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='test', password='12345678', password_conf='12345678' - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert response.status_code == 400 - assert 'Invalid payload.' in data['message'] - assert 'error' in data['status'] - - -def test_user_registration_invalid_json_keys_no_password(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='test', - email='test@test.com', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert response.status_code == 400 - assert 'Invalid payload.', data['message'] - assert 'error', data['status'] - - -def test_user_registration_invalid_json_keys_no_password_conf(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict(username='test', email='test@test.com', password='12345678') - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert response.status_code == 400 - assert 'Invalid payload.' in data['message'] - assert 'error' in data['status'] - - -def test_user_registration_invalid_data(app): - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username=1, - email='test@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert response.status_code == 500 - assert ( - 'Error. Please try again or contact the administrator.' - in data['message'] - ) - assert 'error' in data['status'] - - -def test_user_registration_max_users_exceeded( - app, user_1_admin, user_2, user_3 -): - client = app.test_client() - - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - client.patch( - '/api/config', - content_type='application/json', - data=json.dumps(dict(max_users=3, registration=True)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='user4', - email='user4@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - - assert response.content_type == 'application/json' - assert response.status_code == 403 - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Error. Registration is disabled.' - - -def test_login_registered_user(app, user_1): - client = app.test_client() - response = client.post( - '/api/auth/login', - data=json.dumps(dict(email='test@test.com', password='12345678')), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'success' - assert data['message'] == 'Successfully logged in.' - assert data['auth_token'] - assert response.content_type == 'application/json' - assert response.status_code == 200 - - -def test_login_no_registered_user(app): - client = app.test_client() - response = client.post( - '/api/auth/login', - data=json.dumps(dict(email='test@test.com', password='12345678')), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Invalid credentials.' - assert response.content_type == 'application/json' - assert response.status_code == 404 - - -def test_login_invalid_payload(app): - client = app.test_client() - response = client.post( - '/api/auth/login', - data=json.dumps(dict()), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Invalid payload.' - assert response.content_type == 'application/json' - assert response.status_code == 400 - - -def test_login_registered_user_invalid_password(app, user_1): - client = app.test_client() - response = client.post( - '/api/auth/login', - data=json.dumps(dict(email='test@test.com', password='123456789')), - content_type='application/json', - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Invalid credentials.' - assert response.content_type == 'application/json' - assert response.status_code == 404 - - -def test_logout(app, user_1): - client = app.test_client() - # user login - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='test@test.com', password='12345678')), - content_type='application/json', - ) - # valid token logout - response = client.get( - '/api/auth/logout', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'success' - assert data['message'] == 'Successfully logged out.' - assert response.status_code == 200 - - -def test_logout_expired_token(app, 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', - ) - # invalid token logout - time.sleep(4) - response = client.get( - '/api/auth/logout', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Signature expired. Please log in again.' - assert response.status_code == 401 - - -def test_logout_invalid(app): - client = app.test_client() - response = client.get( - '/api/auth/logout', headers=dict(Authorization='Bearer invalid') - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Invalid token. Please log in again.' - assert response.status_code == 401 - - -def test_logout_invalid_headers(app): - client = app.test_client() - response = client.get('/api/auth/logout', headers=dict()) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Provide a valid auth token.' - assert response.status_code == 401 - - -def test_user_profile_minimal(app, 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']['timezone'] is None - assert data['data']['weekm'] is False - assert data['data']['language'] is None - assert data['data']['nb_activities'] == 0 - assert data['data']['nb_sports'] == 0 - assert data['data']['sports_list'] == [] - assert data['data']['total_distance'] == 0 - assert data['data']['total_duration'] == '0:00:00' - assert response.status_code == 200 - - -def test_user_profile_full(app, user_1_full): - 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']['first_name'] == 'John' - assert data['data']['last_name'] == 'Doe' - assert data['data']['birth_date'] - assert data['data']['bio'] == 'just a random guy' - assert data['data']['location'] == 'somewhere' - assert data['data']['timezone'] == 'America/New_York' - assert data['data']['weekm'] is False - assert data['data']['language'] == 'en' - assert data['data']['nb_activities'] == 0 - assert data['data']['nb_sports'] == 0 - assert data['data']['sports_list'] == [] - 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']['timezone'] is None - assert data['data']['nb_activities'] == 2 - assert data['data']['nb_sports'] == 2 - assert data['data']['sports_list'] == [1, 2] - assert data['data']['total_distance'] == 22 - assert data['data']['total_duration'] == '1:57:04' - assert response.status_code == 200 - - -def test_invalid_profile(app): - client = app.test_client() - response = client.get( - '/api/auth/profile', headers=dict(Authorization='Bearer invalid') - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Invalid token. Please log in again.' - assert response.status_code == 401 - - -def test_user_profile_valid_update(app, 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.post( - '/api/auth/profile/edit', - content_type='application/json', - data=json.dumps( - dict( - first_name='John', - last_name='Doe', - location='Somewhere', - bio='Nothing to tell', - birth_date='1980-01-01', - password='87654321', - password_conf='87654321', - timezone='America/New_York', - weekm=True, - language='fr', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'success' - assert data['message'] == 'User profile updated.' - assert response.status_code == 200 - assert data['data']['username'] == 'test' - assert data['data']['email'] == 'test@test.com' - assert not data['data']['admin'] - assert data['data']['created_at'] - assert data['data']['first_name'] == 'John' - assert data['data']['last_name'] == 'Doe' - assert data['data']['birth_date'] - assert data['data']['bio'] == 'Nothing to tell' - assert data['data']['location'] == 'Somewhere' - assert data['data']['timezone'] == 'America/New_York' - assert data['data']['weekm'] is True - assert data['data']['language'] == 'fr' - assert data['data']['nb_activities'] == 0 - assert data['data']['nb_sports'] == 0 - assert data['data']['sports_list'] == [] - assert data['data']['total_distance'] == 0 - assert data['data']['total_duration'] == '0:00:00' - - -def test_user_profile_valid_update_without_password(app, 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.post( - '/api/auth/profile/edit', - content_type='application/json', - data=json.dumps( - dict( - first_name='John', - last_name='Doe', - location='Somewhere', - bio='Nothing to tell', - birth_date='1980-01-01', - timezone='America/New_York', - weekm=True, - language='fr', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'success' - assert data['message'] == 'User profile updated.' - assert response.status_code == 200 - assert data['data']['username'] == 'test' - assert data['data']['email'] == 'test@test.com' - assert not data['data']['admin'] - assert data['data']['created_at'] - assert data['data']['first_name'] == 'John' - assert data['data']['last_name'] == 'Doe' - assert data['data']['birth_date'] - assert data['data']['bio'] == 'Nothing to tell' - assert data['data']['location'] == 'Somewhere' - assert data['data']['timezone'] == 'America/New_York' - assert data['data']['weekm'] is True - assert data['data']['language'] == 'fr' - assert data['data']['nb_activities'] == 0 - assert data['data']['nb_sports'] == 0 - assert data['data']['sports_list'] == [] - assert data['data']['total_distance'] == 0 - assert data['data']['total_duration'] == '0:00:00' - - -def test_user_profile_invalid_update_with_missing_fields(app, 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.post( - '/api/auth/profile/edit', - content_type='application/json', - data=json.dumps(dict(first_name='John')), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Invalid payload.' - assert response.status_code == 400 - - -def test_user_profile_update_invalid_json(app, 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.post( - '/api/auth/profile/edit', - content_type='application/json', - data=json.dumps(dict()), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - assert response.status_code == 400 - assert 'Invalid payload.' in data['message'] - assert 'error' in data['status'] - - -def test_user_profile_invalid_password(app, 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.post( - '/api/auth/profile/edit', - content_type='application/json', - data=json.dumps( - dict( - first_name='John', - last_name='Doe', - location='Somewhere', - bio='just a random guy', - birth_date='1980-01-01', - password='87654321', - password_conf='876543210', - timezone='America/New_York', - weekm=True, - language='en', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert ( - data['message'] == 'Password and password confirmation don\'t match.\n' - ) - assert response.status_code == 400 - - -def test_user_profile_missing_password_conf(app, 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.post( - '/api/auth/profile/edit', - content_type='application/json', - data=json.dumps( - dict( - first_name='John', - last_name='Doe', - location='Somewhere', - bio='just a random guy', - birth_date='1980-01-01', - password='87654321', - timezone='America/New_York', - weekm=True, - language='en', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert ( - data['message'] == 'Password and password confirmation don\'t match.\n' - ) - assert response.status_code == 400 - - -def test_update_user_picture(app, 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.post( - '/api/auth/picture', - data=dict(file=(BytesIO(b'avatar'), 'avatar.png')), - headers=dict( - content_type='multipart/form-data', - authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'success' - assert data['message'] == 'User picture updated.' - assert response.status_code == 200 - assert 'avatar.png' in user_1.picture - - response = client.post( - '/api/auth/picture', - data=dict(file=(BytesIO(b'avatar2'), 'avatar2.png')), - headers=dict( - content_type='multipart/form-data', - authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'success' - assert data['message'] == 'User picture updated.' - assert response.status_code == 200 - assert 'avatar.png' not in user_1.picture - assert 'avatar2.png' in user_1.picture - - -def test_update_user_no_picture(app, 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.post( - '/api/auth/picture', - headers=dict( - content_type='multipart/form-data', - authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'fail' - assert data['message'] == 'No file part.' - assert response.status_code == 400 - - -def test_update_user_invalid_picture(app, 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.post( - '/api/auth/picture', - data=dict(file=(BytesIO(b'avatar'), 'avatar.bmp')), - headers=dict( - content_type='multipart/form-data', - authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - data = json.loads(response.data.decode()) - assert data['status'] == 'fail' - assert data['message'] == 'File extension not allowed.' - assert response.status_code == 400 - - -def test_it_disables_registration_on_user_registration( - app_no_config, app_config, user_1_admin, user_2 -): - app_config.max_users = 3 - client = app_no_config.test_client() - client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='sam', - email='sam@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='new', - email='new@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - assert response.status_code == 403 - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Error. Registration is disabled.' - - -def test_it_does_not_disable_registration_on_user_registration( - app_no_config, app_config, user_1_admin, user_2, -): - app_config.max_users = 4 - client = app_no_config.test_client() - client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='sam', - email='sam@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='new', - email='new@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - assert response.status_code == 201 +class TestUserRegistration: + def test_user_can_register(self, app): + client = app.test_client() + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='justatest', + email='test@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert data['status'] == 'success' + assert data['message'] == 'Successfully registered.' + assert data['auth_token'] + assert response.content_type == 'application/json' + assert response.status_code == 201 + + def test_it_returns_error_if_user_already_exists(self, app, user_1): + client = app.test_client() + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='test', + email='test@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Sorry. That user already exists.' + assert response.content_type == 'application/json' + assert response.status_code == 400 + + def test_it_returns_error_if_username_is_too_short(self, app): + client = app.test_client() + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='t', + email='test@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == "Username: 3 to 12 characters required.\n" + assert response.content_type == 'application/json' + assert response.status_code == 400 + + def test_it_returns_error_if_username_is_too_long(self, app): + client = app.test_client() + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='testestestestestest', + email='test@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == "Username: 3 to 12 characters required.\n" + assert response.content_type == 'application/json' + assert response.status_code == 400 + + def test_it_returns_error_if_email_is_invalid(self, app): + client = app.test_client() + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='test', + email='test@test', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == "Valid email must be provided.\n" + assert response.content_type == 'application/json' + assert response.status_code == 400 + + def test_it_returns_error_if_password_is_too_short(self, app): + client = app.test_client() + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='test', + email='test@test.com', + password='1234567', + password_conf='1234567', + ) + ), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == "Password: 8 characters required.\n" + assert response.content_type == 'application/json' + assert response.status_code == 400 + + def test_it_returns_error_if_passwords_mismatch(self, app): + client = app.test_client() + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='test', + email='test@test.com', + password='12345678', + password_conf='87654321', + ) + ), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert ( + data['message'] + == "Password and password confirmation don\'t match.\n" + ) + assert response.content_type == 'application/json' + assert response.status_code == 400 + + def test_it_returns_error_if_paylaod_is_invalid(self, app): + client = app.test_client() + response = client.post( + '/api/auth/register', + data=json.dumps(dict()), + content_type='application/json', + ) + data = json.loads(response.data.decode()) + assert response.status_code, 400 + assert 'Invalid payload.', data['message'] + assert 'error', data['status'] + + def test_it_returns_error_if_username_is_missing(self, app): + client = app.test_client() + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + email='test@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'Invalid payload.' in data['message'] + assert 'error' in data['status'] + + def test_it_returns_error_if_email_is_missing(self, app): + client = app.test_client() + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='test', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'Invalid payload.' in data['message'] + assert 'error' in data['status'] + + def test_it_returns_error_if_password_is_missing(self, app): + client = app.test_client() + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='test', + email='test@test.com', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'Invalid payload.', data['message'] + assert 'error', data['status'] + + def test_it_returns_error_if_password_confirmation_is_missing(self, app): + client = app.test_client() + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='test', email='test@test.com', password='12345678' + ) + ), + content_type='application/json', + ) + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'Invalid payload.' in data['message'] + assert 'error' in data['status'] + + def test_it_returns_error_if_username_is_invalid(self, app): + client = app.test_client() + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username=1, + email='test@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert ( + 'Error. Please try again or contact the administrator.' + in data['message'] + ) + assert 'error' in data['status'] + + +class TestUserLogin: + def test_user_can_register(self, app, user_1): + client = app.test_client() + response = client.post( + '/api/auth/login', + data=json.dumps(dict(email='test@test.com', password='12345678')), + content_type='application/json', + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'success' + assert data['message'] == 'Successfully logged in.' + assert data['auth_token'] + assert response.content_type == 'application/json' + assert response.status_code == 200 + + def test_it_returns_error_if_user_does_not_exists(self, app): + client = app.test_client() + response = client.post( + '/api/auth/login', + data=json.dumps(dict(email='test@test.com', password='12345678')), + content_type='application/json', + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Invalid credentials.' + assert response.content_type == 'application/json' + assert response.status_code == 404 + + def test_it_returns_error_on_invalid_payload(self, app): + client = app.test_client() + response = client.post( + '/api/auth/login', + data=json.dumps(dict()), + content_type='application/json', + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Invalid payload.' + assert response.content_type == 'application/json' + assert response.status_code == 400 + + def test_it_returns_error_if_password_is_invalid(self, app, user_1): + client = app.test_client() + + response = client.post( + '/api/auth/login', + data=json.dumps(dict(email='test@test.com', password='123456789')), + content_type='application/json', + ) + + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Invalid credentials.' + assert response.content_type == 'application/json' + assert response.status_code == 404 + + +class TestUserLogout: + def test_user_can_logout(self, app, 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/logout', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert data['status'] == 'success' + assert data['message'] == 'Successfully logged out.' + assert response.status_code == 200 + + def test_it_returns_error_with_expired_token(self, app, 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', + ) + # invalid token logout + time.sleep(4) + response = client.get( + '/api/auth/logout', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Signature expired. Please log in again.' + assert response.status_code == 401 + + def test_it_returns_error_with_invalid_token(self, app): + client = app.test_client() + response = client.get( + '/api/auth/logout', headers=dict(Authorization='Bearer invalid') + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Invalid token. Please log in again.' + assert response.status_code == 401 + + def test_it_returns_error_with_invalid_headers(self, app): + client = app.test_client() + response = client.get('/api/auth/logout', headers=dict()) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Provide a valid auth token.' + assert response.status_code == 401 + + +class TestUserProfile: + def test_it_returns_user_minimal_profile(self, app, 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']['timezone'] is None + assert data['data']['weekm'] is False + assert data['data']['language'] is None + assert data['data']['nb_activities'] == 0 + assert data['data']['nb_sports'] == 0 + assert data['data']['sports_list'] == [] + assert data['data']['total_distance'] == 0 + assert data['data']['total_duration'] == '0:00:00' + assert response.status_code == 200 + + def test_it_returns_user_full_profile(self, app, user_1_full): + 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']['first_name'] == 'John' + assert data['data']['last_name'] == 'Doe' + assert data['data']['birth_date'] + assert data['data']['bio'] == 'just a random guy' + assert data['data']['location'] == 'somewhere' + assert data['data']['timezone'] == 'America/New_York' + assert data['data']['weekm'] is False + assert data['data']['language'] == 'en' + assert data['data']['nb_activities'] == 0 + assert data['data']['nb_sports'] == 0 + assert data['data']['sports_list'] == [] + assert data['data']['total_distance'] == 0 + assert data['data']['total_duration'] == '0:00:00' + assert response.status_code == 200 + + def test_it_returns_user_profile_with_activities( + self, + 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']['timezone'] is None + assert data['data']['nb_activities'] == 2 + assert data['data']['nb_sports'] == 2 + assert data['data']['sports_list'] == [1, 2] + assert data['data']['total_distance'] == 22 + assert data['data']['total_duration'] == '2:40:00' + assert response.status_code == 200 + + def test_it_returns_error_if_headers_are_invalid(self, app): + client = app.test_client() + response = client.get( + '/api/auth/profile', headers=dict(Authorization='Bearer invalid') + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Invalid token. Please log in again.' + assert response.status_code == 401 + + +class TestUserProfileUpdate: + def test_it_updates_user_profile(self, app, 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.post( + '/api/auth/profile/edit', + content_type='application/json', + data=json.dumps( + dict( + first_name='John', + last_name='Doe', + location='Somewhere', + bio='Nothing to tell', + birth_date='1980-01-01', + password='87654321', + password_conf='87654321', + timezone='America/New_York', + weekm=True, + language='fr', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'success' + assert data['message'] == 'User profile updated.' + assert response.status_code == 200 + assert data['data']['username'] == 'test' + assert data['data']['email'] == 'test@test.com' + assert not data['data']['admin'] + assert data['data']['created_at'] + assert data['data']['first_name'] == 'John' + assert data['data']['last_name'] == 'Doe' + assert data['data']['birth_date'] + assert data['data']['bio'] == 'Nothing to tell' + assert data['data']['location'] == 'Somewhere' + assert data['data']['timezone'] == 'America/New_York' + assert data['data']['weekm'] is True + assert data['data']['language'] == 'fr' + assert data['data']['nb_activities'] == 0 + assert data['data']['nb_sports'] == 0 + assert data['data']['sports_list'] == [] + assert data['data']['total_distance'] == 0 + assert data['data']['total_duration'] == '0:00:00' + + def test_it_updates_user_profile_without_password(self, app, 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.post( + '/api/auth/profile/edit', + content_type='application/json', + data=json.dumps( + dict( + first_name='John', + last_name='Doe', + location='Somewhere', + bio='Nothing to tell', + birth_date='1980-01-01', + timezone='America/New_York', + weekm=True, + language='fr', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'success' + assert data['message'] == 'User profile updated.' + assert response.status_code == 200 + assert data['data']['username'] == 'test' + assert data['data']['email'] == 'test@test.com' + assert not data['data']['admin'] + assert data['data']['created_at'] + assert data['data']['first_name'] == 'John' + assert data['data']['last_name'] == 'Doe' + assert data['data']['birth_date'] + assert data['data']['bio'] == 'Nothing to tell' + assert data['data']['location'] == 'Somewhere' + assert data['data']['timezone'] == 'America/New_York' + assert data['data']['weekm'] is True + assert data['data']['language'] == 'fr' + assert data['data']['nb_activities'] == 0 + assert data['data']['nb_sports'] == 0 + assert data['data']['sports_list'] == [] + assert data['data']['total_distance'] == 0 + assert data['data']['total_duration'] == '0:00:00' + + def test_it_returns_error_if_fields_are_missing(self, app, 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.post( + '/api/auth/profile/edit', + content_type='application/json', + data=json.dumps(dict(first_name='John')), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Invalid payload.' + assert response.status_code == 400 + + def test_it_returns_error_if_payload_is_empty(self, app, 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.post( + '/api/auth/profile/edit', + content_type='application/json', + data=json.dumps(dict()), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'Invalid payload.' in data['message'] + assert 'error' in data['status'] + + def test_it_returns_error_if_passwords_mismatch(self, app, 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.post( + '/api/auth/profile/edit', + content_type='application/json', + data=json.dumps( + dict( + first_name='John', + last_name='Doe', + location='Somewhere', + bio='just a random guy', + birth_date='1980-01-01', + password='87654321', + password_conf='876543210', + timezone='America/New_York', + weekm=True, + language='en', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert ( + data['message'] + == 'Password and password confirmation don\'t match.\n' + ) + assert response.status_code == 400 + + def test_it_returns_error_if_password_confirmation_is_missing( + self, app, 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.post( + '/api/auth/profile/edit', + content_type='application/json', + data=json.dumps( + dict( + first_name='John', + last_name='Doe', + location='Somewhere', + bio='just a random guy', + birth_date='1980-01-01', + password='87654321', + timezone='America/New_York', + weekm=True, + language='en', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert ( + data['message'] + == 'Password and password confirmation don\'t match.\n' + ) + assert response.status_code == 400 + + +class TestUserPicture: + def test_it_updates_user_picture(self, app, 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.post( + '/api/auth/picture', + data=dict(file=(BytesIO(b'avatar'), 'avatar.png')), + headers=dict( + content_type='multipart/form-data', + authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'success' + assert data['message'] == 'User picture updated.' + assert response.status_code == 200 + assert 'avatar.png' in user_1.picture + + response = client.post( + '/api/auth/picture', + data=dict(file=(BytesIO(b'avatar2'), 'avatar2.png')), + headers=dict( + content_type='multipart/form-data', + authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'success' + assert data['message'] == 'User picture updated.' + assert response.status_code == 200 + assert 'avatar.png' not in user_1.picture + assert 'avatar2.png' in user_1.picture + + def test_it_returns_error_if_file_is_missing(self, app, 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.post( + '/api/auth/picture', + headers=dict( + content_type='multipart/form-data', + authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'fail' + assert data['message'] == 'No file part.' + assert response.status_code == 400 + + def test_it_returns_error_if_file_is_invalid(self, app, 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.post( + '/api/auth/picture', + data=dict(file=(BytesIO(b'avatar'), 'avatar.bmp')), + headers=dict( + content_type='multipart/form-data', + authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + data = json.loads(response.data.decode()) + assert data['status'] == 'fail' + assert data['message'] == 'File extension not allowed.' + assert response.status_code == 400 + + +class TestRegistrationConfiguration: + def test_it_returns_error_if_it_exceeds_max_users( + self, app, user_1_admin, user_2, user_3 + ): + client = app.test_client() + + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + client.patch( + '/api/config', + content_type='application/json', + data=json.dumps(dict(max_users=3, registration=True)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='user4', + email='user4@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + + assert response.content_type == 'application/json' + assert response.status_code == 403 + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Error. Registration is disabled.' + + def test_it_disables_registration_on_user_registration( + self, app_no_config, app_config, user_1_admin, user_2 + ): + app_config.max_users = 3 + client = app_no_config.test_client() + client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='sam', + email='sam@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='new', + email='new@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + assert response.status_code == 403 + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Error. Registration is disabled.' + + def test_it_does_not_disable_registration_on_user_registration( + self, app_no_config, app_config, user_1_admin, user_2, + ): + app_config.max_users = 4 + client = app_no_config.test_client() + client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='sam', + email='sam@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='new', + email='new@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + assert response.status_code == 201 diff --git a/fittrackee_api/fittrackee_api/tests/test_config.py b/fittrackee_api/fittrackee_api/tests/test_config.py index be67a421..58d4a5ee 100644 --- a/fittrackee_api/fittrackee_api/tests/test_config.py +++ b/fittrackee_api/fittrackee_api/tests/test_config.py @@ -1,20 +1,20 @@ import os -def test_development_config(app): - app.config.from_object('fittrackee_api.config.DevelopmentConfig') - assert app.config['DEBUG'] - assert not app.config['TESTING'] - assert app.config['SQLALCHEMY_DATABASE_URI'] == os.environ.get( - 'DATABASE_URL' - ) +class TestConfig: + def test_development_config(self, app): + app.config.from_object('fittrackee_api.config.DevelopmentConfig') + assert app.config['DEBUG'] + assert not app.config['TESTING'] + assert app.config['SQLALCHEMY_DATABASE_URI'] == os.environ.get( + 'DATABASE_URL' + ) - -def test_testing_config(app): - app.config.from_object('fittrackee_api.config.TestingConfig') - assert app.config['DEBUG'] - assert app.config['TESTING'] - assert not app.config['PRESERVE_CONTEXT_ON_EXCEPTION'] - assert app.config['SQLALCHEMY_DATABASE_URI'] == os.environ.get( - 'DATABASE_TEST_URL' - ) + def test_testing_config(self, app): + app.config.from_object('fittrackee_api.config.TestingConfig') + assert app.config['DEBUG'] + assert app.config['TESTING'] + assert not app.config['PRESERVE_CONTEXT_ON_EXCEPTION'] + assert app.config['SQLALCHEMY_DATABASE_URI'] == os.environ.get( + 'DATABASE_TEST_URL' + ) diff --git a/fittrackee_api/fittrackee_api/tests/test_health_check_api.py b/fittrackee_api/fittrackee_api/tests/test_health_check_api.py new file mode 100644 index 00000000..8ab16aab --- /dev/null +++ b/fittrackee_api/fittrackee_api/tests/test_health_check_api.py @@ -0,0 +1,12 @@ +import json + + +class TestHealthCheck: + def test_it_returns_pong_on_health_check(self, app): + """ => Ensure the /health_check route behaves correctly.""" + client = app.test_client() + response = client.get('/api/ping') + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'pong' in data['message'] + assert 'success' in data['status'] diff --git a/fittrackee_api/fittrackee_api/tests/test_records_api.py b/fittrackee_api/fittrackee_api/tests/test_records_api.py index b4744ac4..be125289 100644 --- a/fittrackee_api/fittrackee_api/tests/test_records_api.py +++ b/fittrackee_api/fittrackee_api/tests/test_records_api.py @@ -1,947 +1,946 @@ import json -def test_get_records_for_authenticated_user( - app, - user_1, - user_2, - sport_1_cycling, - sport_2_running, - activity_cycling_user_1, - activity_cycling_user_2, -): - 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/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 4 - - assert ( - 'Mon, 01 Jan 2018 00:00:00 GMT' - == data['data']['records'][0]['activity_date'] - ) - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 1 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 'value' in data['data']['records'][0] - - assert ( - 'Mon, 01 Jan 2018 00:00:00 GMT' - == data['data']['records'][1]['activity_date'] - ) - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 1 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 'value' in data['data']['records'][1] - - assert ( - 'Mon, 01 Jan 2018 00:00:00 GMT' - == data['data']['records'][2]['activity_date'] - ) - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 1 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert 'value' in data['data']['records'][2] - - assert ( - 'Mon, 01 Jan 2018 00:00:00 GMT' - == data['data']['records'][3]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][3]['user'] - assert 1 == data['data']['records'][3]['sport_id'] - assert 1 == data['data']['records'][3]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 'value' in data['data']['records'][3] - - -def test_get_records_no_activities_user_1( - app, - user_1, - user_2, - sport_1_cycling, - sport_2_running, - activity_cycling_user_2, -): - 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/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 0 - - -def test_add_activity_zero_value( - app, user_1, sport_1_cycling, sport_2_running -): - 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', - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=0, - activity_date='2018-05-14 14:05', - distance=0, - title='Activity test', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 0 - - -def test_get_records_after_activities_post_and_patch( - app, user_1, sport_1_cycling -): - 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', - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-14 14:05', - distance=7, - title='Activity test 1', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 4 - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 1 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 7.0 == data['data']['records'][0]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][1]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 1 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 7.0 == data['data']['records'][1]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][2]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 1 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert '1:00:00' == data['data']['records'][2]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][3]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][3]['user'] - assert 1 == data['data']['records'][3]['sport_id'] - assert 1 == data['data']['records'][3]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 7.0 == data['data']['records'][3]['value'] - - # Post activity with lower duration (same sport) - # => 2 new records: Average speed and Max speed - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3000, - activity_date='2018-05-15 14:05', - distance=7, - title='Activity test 2', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 4 - - assert ( - 'Tue, 15 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 2 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 8.4 == data['data']['records'][0]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][1]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 1 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 7.0 == data['data']['records'][1]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][2]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 1 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert '1:00:00' == data['data']['records'][2]['value'] - - assert ( - 'Tue, 15 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 2 == data['data']['records'][0]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 8.4 == data['data']['records'][3]['value'] - - # Post activity with no new records - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3500, - activity_date='2018-05-16 14:05', - distance=6.5, - title='Activity test 3', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 4 - - assert ( - 'Tue, 15 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 2 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 8.4 == data['data']['records'][0]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][1]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 1 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 7.0 == data['data']['records'][1]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][2]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 1 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert '1:00:00' == data['data']['records'][2]['value'] - - assert ( - 'Tue, 15 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 2 == data['data']['records'][0]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 8.4 == data['data']['records'][3]['value'] - - # Edit last activity - # 1 new record: Longest duration - client.patch( - '/api/activities/3', - content_type='application/json', - data=json.dumps(dict(duration=4000)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 4 - - assert ( - 'Tue, 15 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 2 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 8.4 == data['data']['records'][0]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][1]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 1 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 7.0 == data['data']['records'][1]['value'] - - assert ( - 'Wed, 16 May 2018 14:05:00 GMT' - == data['data']['records'][2]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 3 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert '1:06:40' == data['data']['records'][2]['value'] - - assert ( - 'Tue, 15 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 2 == data['data']['records'][0]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 8.4 == data['data']['records'][3]['value'] - - # delete activity 2 => AS and MS record update - client.delete( - '/api/activities/2', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 4 - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 1 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 7.0 == data['data']['records'][0]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][1]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 1 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 7.0 == data['data']['records'][1]['value'] - - assert ( - 'Wed, 16 May 2018 14:05:00 GMT' - == data['data']['records'][2]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 3 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert '1:06:40' == data['data']['records'][2]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][3]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][3]['user'] - assert 1 == data['data']['records'][3]['sport_id'] - assert 1 == data['data']['records'][3]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 7.0 == data['data']['records'][3]['value'] - - # add an activity with the same data as activity 1 except with a later date - # => no change in record - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-20 14:05', - distance=7, - title='Activity test 4', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 4 - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 1 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 7.0 == data['data']['records'][0]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][1]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 1 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 7.0 == data['data']['records'][1]['value'] - - assert ( - 'Wed, 16 May 2018 14:05:00 GMT' - == data['data']['records'][2]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 3 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert '1:06:40' == data['data']['records'][2]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][3]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][3]['user'] - assert 1 == data['data']['records'][3]['sport_id'] - assert 1 == data['data']['records'][3]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 7.0 == data['data']['records'][3]['value'] - - # add an activity with the same data as activity 1 except with - # an earlier date - # => record update (activity 5 replace activity 1) - - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-14 08:05', - distance=7, - title='Activity test 5', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 4 - - assert ( - 'Mon, 14 May 2018 08:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 5 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 7.0 == data['data']['records'][0]['value'] - - assert ( - 'Mon, 14 May 2018 08:05:00 GMT' - == data['data']['records'][1]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 5 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 7.0 == data['data']['records'][1]['value'] - - assert ( - 'Wed, 16 May 2018 14:05:00 GMT' - == data['data']['records'][2]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 3 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert '1:06:40' == data['data']['records'][2]['value'] - - assert ( - 'Mon, 14 May 2018 08:05:00 GMT' - == data['data']['records'][3]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][3]['user'] - assert 1 == data['data']['records'][3]['sport_id'] - assert 5 == data['data']['records'][3]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 7.0 == data['data']['records'][3]['value'] - - # delete all activities - no more records - client.delete( - '/api/activities/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - client.delete( - '/api/activities/3', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - client.delete( - '/api/activities/4', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - client.delete( - '/api/activities/5', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 0 - - -def test_get_records_after_sport_change( - app, user_1, sport_1_cycling, sport_2_running -): - 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', - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3600, - activity_date='2018-05-14 14:05', - distance=7, - title='Activity test 1', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=2, - duration=3600, - activity_date='2018-05-16 16:05', - distance=20, - title='Activity test 2', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=1, - duration=3000, - activity_date='2018-05-17 17:05', - distance=3, - title='Activity test 3', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - client.post( - '/api/activities/no_gpx', - content_type='application/json', - data=json.dumps( - dict( - sport_id=2, - duration=3000, - activity_date='2018-05-18 18:05', - distance=10, - title='Activity test 4', - ) - ), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 8 - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 1 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 7.0 == data['data']['records'][0]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][1]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 1 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 7.0 == data['data']['records'][1]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][2]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 1 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert '1:00:00' == data['data']['records'][2]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][3]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][3]['user'] - assert 1 == data['data']['records'][3]['sport_id'] - assert 1 == data['data']['records'][3]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 7.0 == data['data']['records'][3]['value'] - - assert ( - 'Wed, 16 May 2018 16:05:00 GMT' - == data['data']['records'][4]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][4]['user'] - assert 2 == data['data']['records'][4]['sport_id'] - assert 2 == data['data']['records'][4]['activity_id'] - assert 'AS' == data['data']['records'][4]['record_type'] - assert 20.0 == data['data']['records'][4]['value'] - - assert ( - 'Wed, 16 May 2018 16:05:00 GMT' - == data['data']['records'][5]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][5]['user'] - assert 2 == data['data']['records'][5]['sport_id'] - assert 2 == data['data']['records'][5]['activity_id'] - assert 'FD' == data['data']['records'][5]['record_type'] - assert 20.0 == data['data']['records'][5]['value'] - - assert ( - 'Wed, 16 May 2018 16:05:00 GMT' - == data['data']['records'][6]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][6]['user'] - assert 2 == data['data']['records'][6]['sport_id'] - assert 2 == data['data']['records'][6]['activity_id'] - assert 'LD' == data['data']['records'][6]['record_type'] - assert '1:00:00' == data['data']['records'][6]['value'] - - assert ( - 'Wed, 16 May 2018 16:05:00 GMT' - == data['data']['records'][7]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][7]['user'] - assert 2 == data['data']['records'][7]['sport_id'] - assert 2 == data['data']['records'][7]['activity_id'] - assert 'MS' == data['data']['records'][7]['record_type'] - assert 20.0 == data['data']['records'][7]['value'] - - client.patch( - '/api/activities/2', - content_type='application/json', - data=json.dumps(dict(sport_id=1)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.get( - '/api/records', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['records']) == 8 - - assert ( - 'Wed, 16 May 2018 16:05:00 GMT' - == data['data']['records'][0]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][0]['user'] - assert 1 == data['data']['records'][0]['sport_id'] - assert 2 == data['data']['records'][0]['activity_id'] - assert 'AS' == data['data']['records'][0]['record_type'] - assert 20.0 == data['data']['records'][0]['value'] - - assert ( - 'Wed, 16 May 2018 16:05:00 GMT' - == data['data']['records'][1]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][1]['user'] - assert 1 == data['data']['records'][1]['sport_id'] - assert 2 == data['data']['records'][1]['activity_id'] - assert 'FD' == data['data']['records'][1]['record_type'] - assert 20.0 == data['data']['records'][1]['value'] - - assert ( - 'Mon, 14 May 2018 14:05:00 GMT' - == data['data']['records'][2]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][2]['user'] - assert 1 == data['data']['records'][2]['sport_id'] - assert 1 == data['data']['records'][2]['activity_id'] - assert 'LD' == data['data']['records'][2]['record_type'] - assert '1:00:00' == data['data']['records'][2]['value'] - - assert ( - 'Wed, 16 May 2018 16:05:00 GMT' - == data['data']['records'][3]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][3]['user'] - assert 1 == data['data']['records'][3]['sport_id'] - assert 2 == data['data']['records'][3]['activity_id'] - assert 'MS' == data['data']['records'][3]['record_type'] - assert 20.0 == data['data']['records'][3]['value'] - - assert ( - 'Fri, 18 May 2018 18:05:00 GMT' - == data['data']['records'][4]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][4]['user'] - assert 2 == data['data']['records'][4]['sport_id'] - assert 4 == data['data']['records'][4]['activity_id'] - assert 'AS' == data['data']['records'][4]['record_type'] - assert 12.0 == data['data']['records'][4]['value'] - - assert ( - 'Fri, 18 May 2018 18:05:00 GMT' - == data['data']['records'][5]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][5]['user'] - assert 2 == data['data']['records'][5]['sport_id'] - assert 4 == data['data']['records'][5]['activity_id'] - assert 'FD' == data['data']['records'][5]['record_type'] - assert 10.0 == data['data']['records'][5]['value'] - - assert ( - 'Fri, 18 May 2018 18:05:00 GMT' - == data['data']['records'][6]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][6]['user'] - assert 2 == data['data']['records'][6]['sport_id'] - assert 4 == data['data']['records'][6]['activity_id'] - assert 'LD' == data['data']['records'][6]['record_type'] - assert '0:50:00' == data['data']['records'][6]['value'] - - assert ( - 'Fri, 18 May 2018 18:05:00 GMT' - == data['data']['records'][7]['activity_date'] - ) # noqa - assert 'test' == data['data']['records'][7]['user'] - assert 2 == data['data']['records'][7]['sport_id'] - assert 4 == data['data']['records'][7]['activity_id'] - assert 'MS' == data['data']['records'][7]['record_type'] - assert 12.0 == data['data']['records'][7]['value'] +class TestGetRecords: + def test_it_gets_records_for_authenticated_user( + self, + app, + user_1, + user_2, + sport_1_cycling, + sport_2_running, + activity_cycling_user_1, + activity_cycling_user_2, + ): + 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/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 4 + + assert ( + 'Mon, 01 Jan 2018 00:00:00 GMT' + == data['data']['records'][0]['activity_date'] + ) + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 1 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 'value' in data['data']['records'][0] + + assert ( + 'Mon, 01 Jan 2018 00:00:00 GMT' + == data['data']['records'][1]['activity_date'] + ) + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 1 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 'value' in data['data']['records'][1] + + assert ( + 'Mon, 01 Jan 2018 00:00:00 GMT' + == data['data']['records'][2]['activity_date'] + ) + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 1 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert 'value' in data['data']['records'][2] + + assert ( + 'Mon, 01 Jan 2018 00:00:00 GMT' + == data['data']['records'][3]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][3]['user'] + assert 1 == data['data']['records'][3]['sport_id'] + assert 1 == data['data']['records'][3]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 'value' in data['data']['records'][3] + + def test_it_gets_no_records_if_user_has_no_activity( + self, + app, + user_1, + user_2, + sport_1_cycling, + sport_2_running, + activity_cycling_user_2, + ): + 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/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 0 + + def test_it_gets_no_records_if_activity_has_zero_value( + self, app, user_1, sport_1_cycling, sport_2_running + ): + 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', + ) + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=0, + activity_date='2018-05-14 14:05', + distance=0, + title='Activity test', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 0 + + def test_it_gets_updated_records_after_activities_post_and_patch( + self, app, user_1, sport_1_cycling + ): + 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', + ) + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-05-14 14:05', + distance=7, + title='Activity test 1', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 4 + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 1 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 7.0 == data['data']['records'][0]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][1]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 1 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 7.0 == data['data']['records'][1]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][2]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 1 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert '1:00:00' == data['data']['records'][2]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][3]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][3]['user'] + assert 1 == data['data']['records'][3]['sport_id'] + assert 1 == data['data']['records'][3]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 7.0 == data['data']['records'][3]['value'] + + # Post activity with lower duration (same sport) + # => 2 new records: Average speed and Max speed + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3000, + activity_date='2018-05-15 14:05', + distance=7, + title='Activity test 2', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 4 + + assert ( + 'Tue, 15 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 2 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 8.4 == data['data']['records'][0]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][1]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 1 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 7.0 == data['data']['records'][1]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][2]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 1 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert '1:00:00' == data['data']['records'][2]['value'] + + assert ( + 'Tue, 15 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 2 == data['data']['records'][0]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 8.4 == data['data']['records'][3]['value'] + + # Post activity with no new records + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3500, + activity_date='2018-05-16 14:05', + distance=6.5, + title='Activity test 3', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 4 + + assert ( + 'Tue, 15 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 2 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 8.4 == data['data']['records'][0]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][1]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 1 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 7.0 == data['data']['records'][1]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][2]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 1 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert '1:00:00' == data['data']['records'][2]['value'] + + assert ( + 'Tue, 15 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 2 == data['data']['records'][0]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 8.4 == data['data']['records'][3]['value'] + + # Edit last activity + # 1 new record: Longest duration + client.patch( + '/api/activities/3', + content_type='application/json', + data=json.dumps(dict(duration=4000)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 4 + + assert ( + 'Tue, 15 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 2 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 8.4 == data['data']['records'][0]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][1]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 1 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 7.0 == data['data']['records'][1]['value'] + + assert ( + 'Wed, 16 May 2018 14:05:00 GMT' + == data['data']['records'][2]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 3 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert '1:06:40' == data['data']['records'][2]['value'] + + assert ( + 'Tue, 15 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 2 == data['data']['records'][0]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 8.4 == data['data']['records'][3]['value'] + + # delete activity 2 => AS and MS record update + client.delete( + '/api/activities/2', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 4 + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 1 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 7.0 == data['data']['records'][0]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][1]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 1 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 7.0 == data['data']['records'][1]['value'] + + assert ( + 'Wed, 16 May 2018 14:05:00 GMT' + == data['data']['records'][2]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 3 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert '1:06:40' == data['data']['records'][2]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][3]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][3]['user'] + assert 1 == data['data']['records'][3]['sport_id'] + assert 1 == data['data']['records'][3]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 7.0 == data['data']['records'][3]['value'] + + # add an activity with the same data as activity 1 except with a + # later date => no change in record + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-05-20 14:05', + distance=7, + title='Activity test 4', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 4 + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 1 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 7.0 == data['data']['records'][0]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][1]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 1 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 7.0 == data['data']['records'][1]['value'] + + assert ( + 'Wed, 16 May 2018 14:05:00 GMT' + == data['data']['records'][2]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 3 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert '1:06:40' == data['data']['records'][2]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][3]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][3]['user'] + assert 1 == data['data']['records'][3]['sport_id'] + assert 1 == data['data']['records'][3]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 7.0 == data['data']['records'][3]['value'] + + # add an activity with the same data as activity 1 except with + # an earlier date + # => record update (activity 5 replace activity 1) + + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-05-14 08:05', + distance=7, + title='Activity test 5', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 4 + + assert ( + 'Mon, 14 May 2018 08:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 5 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 7.0 == data['data']['records'][0]['value'] + + assert ( + 'Mon, 14 May 2018 08:05:00 GMT' + == data['data']['records'][1]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 5 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 7.0 == data['data']['records'][1]['value'] + + assert ( + 'Wed, 16 May 2018 14:05:00 GMT' + == data['data']['records'][2]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 3 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert '1:06:40' == data['data']['records'][2]['value'] + + assert ( + 'Mon, 14 May 2018 08:05:00 GMT' + == data['data']['records'][3]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][3]['user'] + assert 1 == data['data']['records'][3]['sport_id'] + assert 5 == data['data']['records'][3]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 7.0 == data['data']['records'][3]['value'] + + # delete all activities - no more records + client.delete( + '/api/activities/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + client.delete( + '/api/activities/3', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + client.delete( + '/api/activities/4', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + client.delete( + '/api/activities/5', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 0 + + def test_it_gets_updated_records_after_sport_change( + self, app, user_1, sport_1_cycling, sport_2_running + ): + 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', + ) + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3600, + activity_date='2018-05-14 14:05', + distance=7, + title='Activity test 1', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=2, + duration=3600, + activity_date='2018-05-16 16:05', + distance=20, + title='Activity test 2', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=1, + duration=3000, + activity_date='2018-05-17 17:05', + distance=3, + title='Activity test 3', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + client.post( + '/api/activities/no_gpx', + content_type='application/json', + data=json.dumps( + dict( + sport_id=2, + duration=3000, + activity_date='2018-05-18 18:05', + distance=10, + title='Activity test 4', + ) + ), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 8 + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 1 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 7.0 == data['data']['records'][0]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][1]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 1 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 7.0 == data['data']['records'][1]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][2]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 1 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert '1:00:00' == data['data']['records'][2]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][3]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][3]['user'] + assert 1 == data['data']['records'][3]['sport_id'] + assert 1 == data['data']['records'][3]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 7.0 == data['data']['records'][3]['value'] + + assert ( + 'Wed, 16 May 2018 16:05:00 GMT' + == data['data']['records'][4]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][4]['user'] + assert 2 == data['data']['records'][4]['sport_id'] + assert 2 == data['data']['records'][4]['activity_id'] + assert 'AS' == data['data']['records'][4]['record_type'] + assert 20.0 == data['data']['records'][4]['value'] + + assert ( + 'Wed, 16 May 2018 16:05:00 GMT' + == data['data']['records'][5]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][5]['user'] + assert 2 == data['data']['records'][5]['sport_id'] + assert 2 == data['data']['records'][5]['activity_id'] + assert 'FD' == data['data']['records'][5]['record_type'] + assert 20.0 == data['data']['records'][5]['value'] + + assert ( + 'Wed, 16 May 2018 16:05:00 GMT' + == data['data']['records'][6]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][6]['user'] + assert 2 == data['data']['records'][6]['sport_id'] + assert 2 == data['data']['records'][6]['activity_id'] + assert 'LD' == data['data']['records'][6]['record_type'] + assert '1:00:00' == data['data']['records'][6]['value'] + + assert ( + 'Wed, 16 May 2018 16:05:00 GMT' + == data['data']['records'][7]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][7]['user'] + assert 2 == data['data']['records'][7]['sport_id'] + assert 2 == data['data']['records'][7]['activity_id'] + assert 'MS' == data['data']['records'][7]['record_type'] + assert 20.0 == data['data']['records'][7]['value'] + + client.patch( + '/api/activities/2', + content_type='application/json', + data=json.dumps(dict(sport_id=1)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.get( + '/api/records', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['records']) == 8 + + assert ( + 'Wed, 16 May 2018 16:05:00 GMT' + == data['data']['records'][0]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][0]['user'] + assert 1 == data['data']['records'][0]['sport_id'] + assert 2 == data['data']['records'][0]['activity_id'] + assert 'AS' == data['data']['records'][0]['record_type'] + assert 20.0 == data['data']['records'][0]['value'] + + assert ( + 'Wed, 16 May 2018 16:05:00 GMT' + == data['data']['records'][1]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][1]['user'] + assert 1 == data['data']['records'][1]['sport_id'] + assert 2 == data['data']['records'][1]['activity_id'] + assert 'FD' == data['data']['records'][1]['record_type'] + assert 20.0 == data['data']['records'][1]['value'] + + assert ( + 'Mon, 14 May 2018 14:05:00 GMT' + == data['data']['records'][2]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][2]['user'] + assert 1 == data['data']['records'][2]['sport_id'] + assert 1 == data['data']['records'][2]['activity_id'] + assert 'LD' == data['data']['records'][2]['record_type'] + assert '1:00:00' == data['data']['records'][2]['value'] + + assert ( + 'Wed, 16 May 2018 16:05:00 GMT' + == data['data']['records'][3]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][3]['user'] + assert 1 == data['data']['records'][3]['sport_id'] + assert 2 == data['data']['records'][3]['activity_id'] + assert 'MS' == data['data']['records'][3]['record_type'] + assert 20.0 == data['data']['records'][3]['value'] + + assert ( + 'Fri, 18 May 2018 18:05:00 GMT' + == data['data']['records'][4]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][4]['user'] + assert 2 == data['data']['records'][4]['sport_id'] + assert 4 == data['data']['records'][4]['activity_id'] + assert 'AS' == data['data']['records'][4]['record_type'] + assert 12.0 == data['data']['records'][4]['value'] + + assert ( + 'Fri, 18 May 2018 18:05:00 GMT' + == data['data']['records'][5]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][5]['user'] + assert 2 == data['data']['records'][5]['sport_id'] + assert 4 == data['data']['records'][5]['activity_id'] + assert 'FD' == data['data']['records'][5]['record_type'] + assert 10.0 == data['data']['records'][5]['value'] + + assert ( + 'Fri, 18 May 2018 18:05:00 GMT' + == data['data']['records'][6]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][6]['user'] + assert 2 == data['data']['records'][6]['sport_id'] + assert 4 == data['data']['records'][6]['activity_id'] + assert 'LD' == data['data']['records'][6]['record_type'] + assert '0:50:00' == data['data']['records'][6]['value'] + + assert ( + 'Fri, 18 May 2018 18:05:00 GMT' + == data['data']['records'][7]['activity_date'] + ) # noqa + assert 'test' == data['data']['records'][7]['user'] + assert 2 == data['data']['records'][7]['sport_id'] + assert 4 == data['data']['records'][7]['activity_id'] + assert 'MS' == data['data']['records'][7]['record_type'] + assert 12.0 == data['data']['records'][7]['value'] diff --git a/fittrackee_api/fittrackee_api/tests/test_records_model.py b/fittrackee_api/fittrackee_api/tests/test_records_model.py index dfdd0ca4..8657f17c 100644 --- a/fittrackee_api/fittrackee_api/tests/test_records_model.py +++ b/fittrackee_api/fittrackee_api/tests/test_records_model.py @@ -3,130 +3,133 @@ import datetime from fittrackee_api.activities.models import Record -def test_record_model(app, user_1, sport_1_cycling, activity_cycling_user_1): - record_ld = Record.query.filter_by( - user_id=activity_cycling_user_1.user_id, - sport_id=activity_cycling_user_1.sport_id, - record_type='LD', - ).first() - assert 'test' == record_ld.user.username - assert 1 == record_ld.sport_id - assert 1 == record_ld.activity_id - assert 'LD' == record_ld.record_type - assert '2018-01-01 00:00:00' == str(record_ld.activity_date) - assert '' == str(record_ld) +class TestRecordModel: + def test_record_model( + self, app, user_1, sport_1_cycling, activity_cycling_user_1 + ): + record_ld = Record.query.filter_by( + user_id=activity_cycling_user_1.user_id, + sport_id=activity_cycling_user_1.sport_id, + record_type='LD', + ).first() + assert 'test' == record_ld.user.username + assert 1 == record_ld.sport_id + assert 1 == record_ld.activity_id + assert 'LD' == record_ld.record_type + assert '2018-01-01 00:00:00' == str(record_ld.activity_date) + assert '' == str(record_ld) - record_serialize = record_ld.serialize() - assert 'id' in record_serialize - assert 'user' in record_serialize - assert 'sport_id' in record_serialize - assert 'activity_id' in record_serialize - assert 'record_type' in record_serialize - assert 'activity_date' in record_serialize - assert 'value' in record_serialize + record_serialize = record_ld.serialize() + assert 'id' in record_serialize + assert 'user' in record_serialize + assert 'sport_id' in record_serialize + assert 'activity_id' in record_serialize + assert 'record_type' in record_serialize + assert 'activity_date' in record_serialize + assert 'value' in record_serialize + def test_record_model_with_none_value( + self, app, user_1, sport_1_cycling, activity_cycling_user_1 + ): + record_ld = Record.query.filter_by( + user_id=activity_cycling_user_1.user_id, + sport_id=activity_cycling_user_1.sport_id, + record_type='LD', + ).first() + record_ld.value = None + assert 'test' == record_ld.user.username + assert 1 == record_ld.sport_id + assert 1 == record_ld.activity_id + assert 'LD' == record_ld.record_type + assert '2018-01-01 00:00:00' == str(record_ld.activity_date) + assert '' == str(record_ld) + assert record_ld.value is None -def test_record_model_none_value( - app, user_1, sport_1_cycling, activity_cycling_user_1 -): - record_ld = Record.query.filter_by( - user_id=activity_cycling_user_1.user_id, - sport_id=activity_cycling_user_1.sport_id, - record_type='LD', - ).first() - record_ld.value = None - assert 'test' == record_ld.user.username - assert 1 == record_ld.sport_id - assert 1 == record_ld.activity_id - assert 'LD' == record_ld.record_type - assert '2018-01-01 00:00:00' == str(record_ld.activity_date) - assert '' == str(record_ld) - assert record_ld.value is None + record_serialize = record_ld.serialize() + assert record_serialize['value'] is None - record_serialize = record_ld.serialize() - assert record_serialize['value'] is None + def test_average_speed_records( + self, app, user_1, sport_1_cycling, activity_cycling_user_1 + ): + record_as = Record.query.filter_by( + user_id=activity_cycling_user_1.user_id, + sport_id=activity_cycling_user_1.sport_id, + record_type='AS', + ).first() + assert isinstance(record_as.value, float) + assert record_as.value == 10.0 + assert record_as._value == 1000 -def test_add_as_records(app, user_1, sport_1_cycling, activity_cycling_user_1): - record_as = Record.query.filter_by( - user_id=activity_cycling_user_1.user_id, - sport_id=activity_cycling_user_1.sport_id, - record_type='AS', - ).first() + record_serialize = record_as.serialize() + assert record_serialize.get('value') == 10.0 + assert isinstance(record_serialize.get('value'), float) - assert isinstance(record_as.value, float) - assert record_as.value == 10.0 - assert record_as._value == 1000 + def test_add_farest_distance_records( + self, app, user_1, sport_1_cycling, activity_cycling_user_1 + ): + record_fd = Record.query.filter_by( + user_id=activity_cycling_user_1.user_id, + sport_id=activity_cycling_user_1.sport_id, + record_type='FD', + ).first() - record_serialize = record_as.serialize() - assert record_serialize.get('value') == 10.0 - assert isinstance(record_serialize.get('value'), float) + assert isinstance(record_fd.value, float) + assert record_fd.value == 10.0 + assert record_fd._value == 10000 + record_serialize = record_fd.serialize() + assert record_serialize.get('value') == 10.0 + assert isinstance(record_serialize.get('value'), float) -def test_add_fd_records(app, user_1, sport_1_cycling, activity_cycling_user_1): - record_fd = Record.query.filter_by( - user_id=activity_cycling_user_1.user_id, - sport_id=activity_cycling_user_1.sport_id, - record_type='FD', - ).first() + def test_add_longest_duration_records( + self, app, user_1, sport_1_cycling, activity_cycling_user_1 + ): + record_ld = Record.query.filter_by( + user_id=activity_cycling_user_1.user_id, + sport_id=activity_cycling_user_1.sport_id, + record_type='LD', + ).first() - assert isinstance(record_fd.value, float) - assert record_fd.value == 10.0 - assert record_fd._value == 10000 + assert isinstance(record_ld.value, datetime.timedelta) + assert str(record_ld.value) == '1:00:00' + assert record_ld._value == 3600 - record_serialize = record_fd.serialize() - assert record_serialize.get('value') == 10.0 - assert isinstance(record_serialize.get('value'), float) + record_serialize = record_ld.serialize() + assert record_serialize.get('value') == '1:00:00' + assert isinstance(record_serialize.get('value'), str) + def test_add_longest_duration_records_with_zero( + self, app, user_1, sport_1_cycling, activity_cycling_user_1 + ): + record_ld = Record.query.filter_by( + user_id=activity_cycling_user_1.user_id, + sport_id=activity_cycling_user_1.sport_id, + record_type='LD', + ).first() + record_ld.value = datetime.timedelta(seconds=0) -def test_add_ld_records(app, user_1, sport_1_cycling, activity_cycling_user_1): - record_ld = Record.query.filter_by( - user_id=activity_cycling_user_1.user_id, - sport_id=activity_cycling_user_1.sport_id, - record_type='LD', - ).first() + assert isinstance(record_ld.value, datetime.timedelta) + assert str(record_ld.value) == '0:00:00' + assert record_ld._value == 0 - assert isinstance(record_ld.value, datetime.timedelta) - assert str(record_ld.value) == '0:17:04' - assert record_ld._value == 1024 + record_serialize = record_ld.serialize() + assert record_serialize.get('value') == '0:00:00' + assert isinstance(record_serialize.get('value'), str) - record_serialize = record_ld.serialize() - assert record_serialize.get('value') == '0:17:04' - assert isinstance(record_serialize.get('value'), str) + def test_max_speed_records_no_value( + self, app, user_1, sport_1_cycling, activity_cycling_user_1 + ): + record_ms = Record.query.filter_by( + user_id=activity_cycling_user_1.user_id, + sport_id=activity_cycling_user_1.sport_id, + record_type='MS', + ).first() + assert isinstance(record_ms.value, float) + assert record_ms.value == 10.0 + assert record_ms._value == 1000 -def test_add_ld_records_zero( - app, user_1, sport_1_cycling, activity_cycling_user_1 -): - record_ld = Record.query.filter_by( - user_id=activity_cycling_user_1.user_id, - sport_id=activity_cycling_user_1.sport_id, - record_type='LD', - ).first() - record_ld.value = datetime.timedelta(seconds=0) - - assert isinstance(record_ld.value, datetime.timedelta) - assert str(record_ld.value) == '0:00:00' - assert record_ld._value == 0 - - record_serialize = record_ld.serialize() - assert record_serialize.get('value') == '0:00:00' - assert isinstance(record_serialize.get('value'), str) - - -def test_add_ms_records_no_value( - app, user_1, sport_1_cycling, activity_cycling_user_1 -): - record_ms = Record.query.filter_by( - user_id=activity_cycling_user_1.user_id, - sport_id=activity_cycling_user_1.sport_id, - record_type='MS', - ).first() - - assert isinstance(record_ms.value, float) - assert record_ms.value == 10.0 - assert record_ms._value == 1000 - - record_serialize = record_ms.serialize() - assert record_serialize.get('value') == 10.0 - assert isinstance(record_serialize.get('value'), float) + record_serialize = record_ms.serialize() + assert record_serialize.get('value') == 10.0 + assert isinstance(record_serialize.get('value'), float) diff --git a/fittrackee_api/fittrackee_api/tests/test_sports_api.py b/fittrackee_api/fittrackee_api/tests/test_sports_api.py index fc8e7b3a..f4bddf79 100644 --- a/fittrackee_api/fittrackee_api/tests/test_sports_api.py +++ b/fittrackee_api/fittrackee_api/tests/test_sports_api.py @@ -30,339 +30,379 @@ expected_sport_1_cycling_inactive_admin_result = ( expected_sport_1_cycling_inactive_admin_result['has_activities'] = False -def test_get_all_sports(app, user_1, sport_1_cycling, sport_2_running): - 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/sports', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) +class TestGetSports: + def test_it_gets_all_sports( + self, app, user_1, sport_1_cycling, sport_2_running + ): + 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', + ) - assert response.status_code == 200 - assert 'success' in data['status'] + response = client.get( + '/api/sports', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert len(data['data']['sports']) == 2 - assert data['data']['sports'][0] == expected_sport_1_cycling_result - assert data['data']['sports'][1] == expected_sport_2_running_result + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['sports']) == 2 + assert data['data']['sports'][0] == expected_sport_1_cycling_result + assert data['data']['sports'][1] == expected_sport_2_running_result + + def test_it_gets_all_sports_with_inactive_one( + self, app, user_1, sport_1_cycling_inactive, sport_2_running + ): + 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/sports', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['sports']) == 2 + assert ( + data['data']['sports'][0] + == expected_sport_1_cycling_inactive_result + ) + assert data['data']['sports'][1] == expected_sport_2_running_result + + def test_it_gets_all_sports_with_admin_rights( + self, app, user_1_admin, sport_1_cycling_inactive, sport_2_running + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.get( + '/api/sports', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['sports']) == 2 + assert ( + data['data']['sports'][0] + == expected_sport_1_cycling_inactive_admin_result + ) + assert ( + data['data']['sports'][1] == expected_sport_2_running_admin_result + ) -def test_get_all_sports_with_inactive_one( - app, user_1, sport_1_cycling_inactive, sport_2_running -): - 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/sports', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) +class TestGetSport: + def test_it_gets_a_sport(self, app, user_1, sport_1_cycling): + 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', + ) - assert response.status_code == 200 - assert 'success' in data['status'] + response = client.get( + '/api/sports/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert len(data['data']['sports']) == 2 - assert ( - data['data']['sports'][0] == expected_sport_1_cycling_inactive_result - ) - assert data['data']['sports'][1] == expected_sport_2_running_result + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['sports']) == 1 + assert data['data']['sports'][0] == expected_sport_1_cycling_result + + def test_it_returns_404_if_sport_does_not_exist(self, app, 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/sports/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert len(data['data']['sports']) == 0 + + def test_it_gets_a_inactive_sport( + self, app, user_1, sport_1_cycling_inactive + ): + 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/sports/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + + assert len(data['data']['sports']) == 1 + assert ( + data['data']['sports'][0] + == expected_sport_1_cycling_inactive_result + ) + + def test_it_get_an_inactive_sport_with_admin_rights( + self, app, user_1_admin, sport_1_cycling_inactive + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + response = client.get( + '/api/sports/1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + + assert len(data['data']['sports']) == 1 + assert ( + data['data']['sports'][0] + == expected_sport_1_cycling_inactive_admin_result + ) -def test_get_all_sports_admin( - app, user_1_admin, sport_1_cycling_inactive, sport_2_running -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/sports', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) +class TestUpdateSport: + def test_it_disables_a_sport(self, app, user_1_admin, sport_1_cycling): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) - assert response.status_code == 200 - assert 'success' in data['status'] + response = client.patch( + '/api/sports/1', + content_type='application/json', + data=json.dumps(dict(is_active=False)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert len(data['data']['sports']) == 2 - assert ( - data['data']['sports'][0] - == expected_sport_1_cycling_inactive_admin_result - ) - assert data['data']['sports'][1] == expected_sport_2_running_admin_result + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['sports']) == 1 + assert data['data']['sports'][0]['is_active'] is False + assert data['data']['sports'][0]['has_activities'] is False + def test_it_enables_a_sport(self, app, user_1_admin, sport_1_cycling): + sport_1_cycling.is_active = False + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) -def test_get_a_sport(app, user_1, sport_1_cycling): - 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/sports/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + response = client.patch( + '/api/sports/1', + content_type='application/json', + data=json.dumps(dict(is_active=True)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert response.status_code == 200 - assert 'success' in data['status'] + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['sports']) == 1 + assert data['data']['sports'][0]['is_active'] is True + assert data['data']['sports'][0]['has_activities'] is False - assert len(data['data']['sports']) == 1 - assert data['data']['sports'][0] == expected_sport_1_cycling_result + def test_it_disables_a_sport_with_activities( + self, app, user_1_admin, sport_1_cycling, activity_cycling_user_1 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + response = client.patch( + '/api/sports/1', + content_type='application/json', + data=json.dumps(dict(is_active=False)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) -def test_get_a_sport_invalid(app, 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/sports/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['sports']) == 1 + assert data['data']['sports'][0]['is_active'] is False + assert data['data']['sports'][0]['has_activities'] is True - assert response.status_code == 404 - assert 'not found' in data['status'] - assert len(data['data']['sports']) == 0 + def test_it_enables_a_sport_with_activities( + self, app, user_1_admin, sport_1_cycling, activity_cycling_user_1 + ): + sport_1_cycling.is_active = False + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + response = client.patch( + '/api/sports/1', + content_type='application/json', + data=json.dumps(dict(is_active=True)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) -def test_get_a_inactive_sport(app, user_1, sport_1_cycling_inactive): - 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/sports/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['sports']) == 1 + assert data['data']['sports'][0]['is_active'] is True + assert data['data']['sports'][0]['has_activities'] is True - assert response.status_code == 200 - assert 'success' in data['status'] + def test_returns_error_if_user_has_no_admin_rights( + self, app, user_1, sport_1_cycling + ): + 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.patch( + '/api/sports/1', + content_type='application/json', + data=json.dumps(dict(is_active=False)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) - assert len(data['data']['sports']) == 1 - assert ( - data['data']['sports'][0] == expected_sport_1_cycling_inactive_result - ) + assert response.status_code == 403 + assert 'success' not in data['status'] + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] + def test_returns_error_if_payload_is_invalid(self, app, user_1_admin): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) -def test_get_a_inactive_sport_as_admin( - app, user_1_admin, sport_1_cycling_inactive -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/sports/1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + response = client.patch( + '/api/sports/1', + content_type='application/json', + data=json.dumps(dict()), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert response.status_code == 200 - assert 'success' in data['status'] + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'error' in data['status'] + assert 'Invalid payload.' in data['message'] - assert len(data['data']['sports']) == 1 - assert ( - data['data']['sports'][0] - == expected_sport_1_cycling_inactive_admin_result - ) + def test_it_returns_error_if_sport_does_not_exist(self, app, user_1_admin): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + response = client.patch( + '/api/sports/1', + content_type='application/json', + data=json.dumps(dict(is_active=False)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) - -def test_update_a_sport(app, user_1_admin, sport_1_cycling): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/sports/1', - content_type='application/json', - data=json.dumps(dict(is_active=False)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - - assert len(data['data']['sports']) == 1 - assert data['data']['sports'][0]['is_active'] is False - assert data['data']['sports'][0]['has_activities'] is False - - response = client.patch( - '/api/sports/1', - content_type='application/json', - data=json.dumps(dict(is_active=True)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - - assert len(data['data']['sports']) == 1 - assert data['data']['sports'][0]['is_active'] is True - assert data['data']['sports'][0]['has_activities'] is False - - -def test_update_a_sport_with_activities( - app, user_1_admin, sport_1_cycling, activity_cycling_user_1 -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/sports/1', - content_type='application/json', - data=json.dumps(dict(is_active=False)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - - assert len(data['data']['sports']) == 1 - assert data['data']['sports'][0]['is_active'] is False - assert data['data']['sports'][0]['has_activities'] is True - - response = client.patch( - '/api/sports/1', - content_type='application/json', - data=json.dumps(dict(is_active=True)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - - assert len(data['data']['sports']) == 1 - assert data['data']['sports'][0]['is_active'] is True - assert data['data']['sports'][0]['has_activities'] is True - - -def test_update_a_sport_not_admin(app, user_1, sport_1_cycling): - 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.patch( - '/api/sports/1', - content_type='application/json', - data=json.dumps(dict(is_active=False)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'success' not in data['status'] - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_update_a_sport_invalid_payload(app, user_1_admin): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/sports/1', - content_type='application/json', - data=json.dumps(dict()), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert 'error' in data['status'] - assert 'Invalid payload.' in data['message'] - - -def test_update_a_sport_invalid_id(app, user_1_admin): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/sports/1', - content_type='application/json', - data=json.dumps(dict(is_active=False)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'not found' in data['status'] - assert len(data['data']['sports']) == 0 + assert response.status_code == 404 + assert 'not found' in data['status'] + assert len(data['data']['sports']) == 0 diff --git a/fittrackee_api/fittrackee_api/tests/test_sports_model.py b/fittrackee_api/fittrackee_api/tests/test_sports_model.py index 4958f0de..c204a1e9 100644 --- a/fittrackee_api/fittrackee_api/tests/test_sports_model.py +++ b/fittrackee_api/fittrackee_api/tests/test_sports_model.py @@ -1,29 +1,28 @@ -def assert_sport_model(sport, is_admin=False): - assert 1 == sport.id - assert 'Cycling' == sport.label - assert '' == str(sport) +class TestSportModel: + @staticmethod + def assert_sport_model(sport, is_admin=False): + assert 1 == sport.id + assert 'Cycling' == sport.label + assert '' == str(sport) - serialized_sport = sport.serialize(is_admin) - assert 1 == serialized_sport['id'] - assert 'Cycling' == serialized_sport['label'] - assert serialized_sport['is_active'] is True - return serialized_sport + serialized_sport = sport.serialize(is_admin) + assert 1 == serialized_sport['id'] + assert 'Cycling' == serialized_sport['label'] + assert serialized_sport['is_active'] is True + return serialized_sport + def test_sport_model(self, app, sport_1_cycling): + serialized_sport = self.assert_sport_model(sport_1_cycling) + assert 'has_activities' not in serialized_sport -def test_sport_model(app, sport_1_cycling): - serialized_sport = assert_sport_model(sport_1_cycling) - assert 'has_activities' not in serialized_sport + def test_sport_model_with_activity( + self, app, sport_1_cycling, user_1, activity_cycling_user_1 + ): + serialized_sport = self.assert_sport_model(sport_1_cycling) + assert 'has_activities' not in serialized_sport - -def test_sport_model_with_activity( - app, sport_1_cycling, user_1, activity_cycling_user_1 -): - serialized_sport = assert_sport_model(sport_1_cycling) - assert 'has_activities' not in serialized_sport - - -def test_sport_model_with_activity_admin( - app, sport_1_cycling, user_1, activity_cycling_user_1 -): - serialized_sport = assert_sport_model(sport_1_cycling, True) - assert serialized_sport['has_activities'] is True + def test_sport_model_with_activity_as_admin( + self, app, sport_1_cycling, user_1, activity_cycling_user_1 + ): + serialized_sport = self.assert_sport_model(sport_1_cycling, True) + assert serialized_sport['has_activities'] is True diff --git a/fittrackee_api/fittrackee_api/tests/test_stats_api.py b/fittrackee_api/fittrackee_api/tests/test_stats_api.py index 9c3d6173..8b8ad680 100644 --- a/fittrackee_api/fittrackee_api/tests/test_stats_api.py +++ b/fittrackee_api/fittrackee_api/tests/test_stats_api.py @@ -1,186 +1,845 @@ import json -def test_get_stats_by_time_no_activities(app, 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( - f'/api/stats/{user_1.username}/by_time', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) +class TestGetStatsByTime: + def test_it_gets_no_stats_when_user_has_no_activities(self, app, 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', + ) - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == {} + response = client.get( + f'/api/stats/{user_1.username}/by_time', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == {} -def test_get_stats_by_time_no_user(app, 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( - f'/api/stats/1000/by_time', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + def test_it_returns_error_when_user_does_not_exists(self, app, 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', + ) - assert response.status_code == 404 - assert 'not found' in data['status'] - assert 'User does not exist.' in data['message'] + response = client.get( + f'/api/stats/1000/by_time', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert 'User does not exist.' in data['message'] -def test_get_stats_by_time_all_activities_error( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?from="2018-04-01&to=2018-04-30', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + def test_it_returns_error_if_date_format_is_invalid( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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', + ) - assert response.status_code == 500 - assert 'error' in data['status'] - assert ( - 'Error. Please try again or contact the administrator.' - in data['message'] - ) + response = client.get( + f'/api/stats/{user_1.username}/by_time?from="2018-04-01&to=2018-04-30', # noqa + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert ( + 'Error. Please try again or contact the administrator.' + in data['message'] + ) -def test_get_stats_by_time_all_activities_invalid_period( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=day', # noqa - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + def test_it_returns_error_if_period_is_invalid( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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', + ) - assert response.status_code == 400 - assert 'fail' in data['status'] - assert 'Invalid time period.' in data['message'] + response = client.get( + f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=day', # noqa + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'fail' in data['status'] + assert 'Invalid time period.' in data['message'] -def test_get_stats_by_time_all_activities( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + def test_it_gets_stats_by_time_all_activities( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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', + ) - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2017': { - '1': { - 'nb_activities': 2, - 'total_distance': 15.0, - 'total_duration': 4480, + response = client.get( + f'/api/stats/{user_1.username}/by_time', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2017': { + '1': { + 'nb_activities': 2, + 'total_distance': 15.0, + 'total_duration': 4480, + } + }, + '2018': { + '1': { + 'nb_activities': 5, + 'total_distance': 39.0, + 'total_duration': 11624, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + }, + } + + def test_it_gets_stats_for_april_2018( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30', # noqa + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2018': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, } - }, - '2018': { - '1': { - 'nb_activities': 5, - 'total_distance': 39.0, - 'total_duration': 11624, + } + + def test_it_gets_stats_for_april_2018_with_paris_timezone( + self, + app, + user_1_paris, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1_paris.username}/by_time?' + f'from=2018-04-01&to=2018-04-30', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2018': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + } + } + + def test_it_gets_stats_by_year( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_time?time=year', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2017': { + '1': { + 'nb_activities': 2, + 'total_distance': 15.0, + 'total_duration': 4480, + } }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, + '2018': { + '1': { + 'nb_activities': 5, + 'total_distance': 39.0, + 'total_duration': 11624, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, }, - }, - } + } + + def test_it_gets_stats_by_year_for_april_2018( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=year', # noqa + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2018': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + } + } + + def test_it_gets_stats_by_year_for_april_2018_with_paris_timezone( + self, + app, + user_1_paris, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1_paris.username}/by_time?from=2018-04-01&to=2018-04-30&time=year', # noqa + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2018': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + } + } + + def test_it_gets_stats_by_month( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_time?time=month', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2017-03': { + '1': { + 'nb_activities': 1, + 'total_distance': 5.0, + 'total_duration': 1024, + } + }, + '2017-06': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 3456, + } + }, + '2018-01': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 1024, + } + }, + '2018-02': { + '1': { + 'nb_activities': 2, + 'total_distance': 11.0, + 'total_duration': 1600, + } + }, + '2018-04': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + }, + '2018-05': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 3000, + } + }, + } + + def test_it_gets_stats_by_month_with_new_york_timezone( + self, + app, + user_1_full, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1_full.username}/by_time?time=month', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2017-03': { + '1': { + 'nb_activities': 1, + 'total_distance': 5.0, + 'total_duration': 1024, + } + }, + '2017-06': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 3456, + } + }, + '2018-01': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 1024, + } + }, + '2018-02': { + '1': { + 'nb_activities': 2, + 'total_distance': 11.0, + 'total_duration': 1600, + } + }, + '2018-04': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + }, + '2018-05': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 3000, + } + }, + } + + def test_it_gets_stats_by_month_for_april_2018( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=month', # noqa + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2018-04': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + } + } + + def test_it_gets_stats_by_week( + self, + app, + user_1_full, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1_full.username}/by_time?time=week', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2017-03-19': { + '1': { + 'nb_activities': 1, + 'total_distance': 5.0, + 'total_duration': 1024, + } + }, + '2017-05-28': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 3456, + } + }, + '2017-12-31': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 1024, + } + }, + '2018-02-18': { + '1': { + 'nb_activities': 2, + 'total_distance': 11.0, + 'total_duration': 1600, + } + }, + '2018-04-01': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + }, + '2018-05-06': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 3000, + } + }, + } + + def test_it_gets_stats_by_week_for_week_13( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=week', # noqa + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2018-04-01': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + } + } + + def test_if_get_stats_by_week_starting_with_monday( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_time?time=weekm', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2017-03-20': { + '1': { + 'nb_activities': 1, + 'total_distance': 5.0, + 'total_duration': 1024, + } + }, + '2017-05-29': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 3456, + } + }, + '2018-01-01': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 1024, + } + }, + '2018-02-19': { + '1': { + 'nb_activities': 2, + 'total_distance': 11.0, + 'total_duration': 1600, + } + }, + '2018-03-26': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + }, + '2018-05-07': { + '1': { + 'nb_activities': 1, + 'total_distance': 10.0, + 'total_duration': 3000, + } + }, + } + + def test_it_gets_stats_by_week_starting_with_monday_for_week_13( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=weekm', # noqa + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { + '2018-03-26': { + '1': { + 'nb_activities': 1, + 'total_distance': 8.0, + 'total_duration': 6000, + }, + '2': { + 'nb_activities': 1, + 'total_distance': 12.0, + 'total_duration': 6000, + }, + } + } -def test_get_stats_by_time_all_activities_april_2018( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) +class TestGetStatsBySport: + def test_it_gets_stats_by_sport( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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', + ) - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2018': { + response = client.get( + f'/api/stats/{user_1.username}/by_sport', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, + 'nb_activities': 7, + 'total_distance': 54.0, + 'total_duration': 16104, }, '2': { 'nb_activities': 1, @@ -188,853 +847,228 @@ def test_get_stats_by_time_all_activities_april_2018( 'total_duration': 6000, }, } - } + def test_it_get_stats_for_sport_1( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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', + ) -def test_get_stats_by_time_all_activities_april_2018_paris( - app, - user_1_paris, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1_paris.username}/by_time?' - f'from=2018-04-01&to=2018-04-30', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + response = client.get( + f'/api/stats/{user_1.username}/by_sport?sport_id=1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2018': { + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['statistics'] == { '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, + 'nb_activities': 7, + 'total_distance': 54.0, + 'total_duration': 16104, + } } - } + + def test_it_returns_errors_if_user_does_not_exist( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/1000/by_sport?sport_id=1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert 'User does not exist.' in data['message'] + + def test_it_returns_error_if_sport_does_not_exist( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_sport?sport_id=999', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert 'Sport does not exist.' in data['message'] + + def test_it_returns_error_if_sport_id_is_invalid( + self, + app, + user_1, + sport_1_cycling, + sport_2_running, + seven_activities_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( + f'/api/stats/{user_1.username}/by_sport?sport_id="999', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert ( + 'Error. Please try again or contact the administrator.' + in data['message'] + ) -def test_get_stats_by_year_all_activities( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?time=year', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) +class TestGetAllStats: + def test_it_returns_all_stats_when_users_have_no_activities( + self, app, user_1_admin, user_2 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2017': { - '1': { - 'nb_activities': 2, - 'total_distance': 15.0, - 'total_duration': 4480, - } - }, - '2018': { - '1': { - 'nb_activities': 5, - 'total_distance': 39.0, - 'total_duration': 11624, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - }, - } + response = client.get( + '/api/stats/all', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['activities'] == 0 + assert data['data']['sports'] == 0 + assert data['data']['users'] == 2 + assert 'uploads_dir_size' in data['data'] -def test_get_stats_by_year_all_activities_april_2018( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=year', # noqa - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + def test_it_gets_app_all_stats_with_activities( + self, + app, + user_1_admin, + user_2, + user_3, + sport_1_cycling, + sport_2_running, + activity_cycling_user_1, + activity_cycling_user_2, + activity_running_user_1, + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2018': { - '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - } - } + response = client.get( + '/api/stats/all', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert data['data']['activities'] == 3 + assert data['data']['sports'] == 2 + assert data['data']['users'] == 3 + assert 'uploads_dir_size' in data['data'] -def test_get_stats_by_year_all_activities_april_2018_paris( - app, - user_1_paris, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1_paris.username}/by_time?from=2018-04-01&to=2018-04-30&time=year', # noqa - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) + def test_it_returns_error_if_user_has_no_admin_rights( + self, + app, + user_1, + user_2, + user_3, + sport_1_cycling, + sport_2_running, + activity_cycling_user_1, + activity_cycling_user_2, + 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', + ) - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2018': { - '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - } - } + response = client.get( + '/api/stats/all', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) - -def test_get_stats_by_month_all_activities( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?time=month', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2017-03': { - '1': { - 'nb_activities': 1, - 'total_distance': 5.0, - 'total_duration': 1024, - } - }, - '2017-06': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 3456, - } - }, - '2018-01': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 1024, - } - }, - '2018-02': { - '1': { - 'nb_activities': 2, - 'total_distance': 11.0, - 'total_duration': 1600, - } - }, - '2018-04': { - '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - }, - '2018-05': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 3000, - } - }, - } - - -def test_get_stats_by_month_all_activities_new_york( - app, - user_1_full, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1_full.username}/by_time?time=month', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2017-03': { - '1': { - 'nb_activities': 1, - 'total_distance': 5.0, - 'total_duration': 1024, - } - }, - '2017-06': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 3456, - } - }, - '2018-01': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 1024, - } - }, - '2018-02': { - '1': { - 'nb_activities': 2, - 'total_distance': 11.0, - 'total_duration': 1600, - } - }, - '2018-04': { - '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - }, - '2018-05': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 3000, - } - }, - } - - -def test_get_stats_by_month_all_activities_april_2018( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=month', # noqa - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2018-04': { - '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - } - } - - -def test_get_stats_by_week_all_activities( - app, - user_1_full, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1_full.username}/by_time?time=week', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2017-03-19': { - '1': { - 'nb_activities': 1, - 'total_distance': 5.0, - 'total_duration': 1024, - } - }, - '2017-05-28': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 3456, - } - }, - '2017-12-31': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 1024, - } - }, - '2018-02-18': { - '1': { - 'nb_activities': 2, - 'total_distance': 11.0, - 'total_duration': 1600, - } - }, - '2018-04-01': { - '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - }, - '2018-05-06': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 3000, - } - }, - } - - -def test_get_stats_by_week_all_activities_week_13( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=week', # noqa - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2018-04-01': { - '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - } - } - - -def test_get_stats_by_weekm_all_activities( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?time=weekm', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2017-03-20': { - '1': { - 'nb_activities': 1, - 'total_distance': 5.0, - 'total_duration': 1024, - } - }, - '2017-05-29': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 3456, - } - }, - '2018-01-01': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 1024, - } - }, - '2018-02-19': { - '1': { - 'nb_activities': 2, - 'total_distance': 11.0, - 'total_duration': 1600, - } - }, - '2018-03-26': { - '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - }, - '2018-05-07': { - '1': { - 'nb_activities': 1, - 'total_distance': 10.0, - 'total_duration': 3000, - } - }, - } - - -def test_get_stats_by_weekm_all_activities_week_13( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_time?from=2018-04-01&to=2018-04-30&time=weekm', # noqa - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '2018-03-26': { - '1': { - 'nb_activities': 1, - 'total_distance': 8.0, - 'total_duration': 6000, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - } - } - - -def test_get_stats_by_sport_all_activities( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_sport', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '1': { - 'nb_activities': 7, - 'total_distance': 54.0, - 'total_duration': 16104, - }, - '2': { - 'nb_activities': 1, - 'total_distance': 12.0, - 'total_duration': 6000, - }, - } - - -def test_get_stats_by_sport_all_activities_sport_1( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_sport?sport_id=1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['statistics'] == { - '1': { - 'nb_activities': 7, - 'total_distance': 54.0, - 'total_duration': 16104, - } - } - - -def test_get_stats_by_sport_all_activities_invalid_user( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/1000/by_sport?sport_id=1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'not found' in data['status'] - assert 'User does not exist.' in data['message'] - - -def test_get_stats_by_sport_all_activities_invalid_sport( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_sport?sport_id=999', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'not found' in data['status'] - assert 'Sport does not exist.' in data['message'] - - -def test_get_stats_by_sport_all_activities_error( - app, - user_1, - sport_1_cycling, - sport_2_running, - seven_activities_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( - f'/api/stats/{user_1.username}/by_sport?sport_id="999', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert ( - 'Error. Please try again or contact the administrator.' - in data['message'] - ) - - -def test_get_app_stats_without_activities(app, user_1_admin): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/stats/all', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['activities'] == 0 - assert data['data']['sports'] == 0 - assert data['data']['users'] == 1 - assert 'uploads_dir_size' in data['data'] - - -def test_get_app_stats_with_activities( - app, - user_1_admin, - user_2, - user_3, - sport_1_cycling, - sport_2_running, - activity_cycling_user_1, - activity_cycling_user_2, - activity_running_user_1, -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/stats/all', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert data['data']['activities'] == 3 - assert data['data']['sports'] == 2 - assert data['data']['users'] == 3 - assert 'uploads_dir_size' in data['data'] - - -def test_get_app_stats_no_admin( - app, - user_1, - user_2, - user_3, - sport_1_cycling, - sport_2_running, - activity_cycling_user_1, - activity_cycling_user_2, - 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/stats/all', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'success' not in data['status'] - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] + data = json.loads(response.data.decode()) + assert response.status_code == 403 + assert 'success' not in data['status'] + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] diff --git a/fittrackee_api/fittrackee_api/tests/test_users_api.py b/fittrackee_api/fittrackee_api/tests/test_users_api.py index a27898cb..37f2bfbe 100644 --- a/fittrackee_api/fittrackee_api/tests/test_users_api.py +++ b/fittrackee_api/fittrackee_api/tests/test_users_api.py @@ -3,1319 +3,1367 @@ from datetime import datetime, timedelta from io import BytesIO from unittest.mock import patch -from fittrackee_api.users.models import User - - -def test_single_user(app, user_1, user_2): - """=> Get single user details""" - 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( - f'/api/users/{user_2.username}', - content_type='application/json', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert data['status'] == 'success' - assert len(data['data']['users']) == 1 - - user = data['data']['users'][0] - assert user['username'] == 'toto' - assert user['email'] == 'toto@toto.com' - assert user['created_at'] - assert not user['admin'] - assert user['first_name'] is None - assert user['last_name'] is None - assert user['birth_date'] is None - assert user['bio'] is None - assert user['location'] is None - assert user['timezone'] is None - assert user['weekm'] is False - assert user['language'] is None - assert user['nb_activities'] == 0 - assert user['nb_sports'] == 0 - assert user['sports_list'] == [] - assert user['total_distance'] == 0 - assert user['total_duration'] == '0:00:00' - - -def test_single_user_with_activities( - app, - user_1, - sport_1_cycling, - sport_2_running, - activity_cycling_user_1, - activity_running_user_1, -): - """=> Get single user details""" - 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( - f'/api/users/{user_1.username}', - content_type='application/json', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert data['status'] == 'success' - assert len(data['data']['users']) == 1 - - user = data['data']['users'][0] - assert user['username'] == 'test' - assert user['email'] == 'test@test.com' - assert user['created_at'] - assert not user['admin'] - assert user['first_name'] is None - assert user['last_name'] is None - assert user['birth_date'] is None - assert user['bio'] is None - assert user['location'] is None - assert user['timezone'] is None - assert user['weekm'] is False - assert user['language'] is None - assert user['nb_activities'] == 2 - assert user['nb_sports'] == 2 - assert user['sports_list'] == [1, 2] - assert user['total_distance'] == 22 - assert user['total_duration'] == '1:57:04' - - -def test_single_user_no_existing(app, user_1): - """=> Ensure error is thrown if the id does not exist.""" - 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/users/not_existing', - content_type='application/json', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'fail' in data['status'] - assert 'User does not exist.' in data['message'] - - -def test_users_list(app, user_1, user_2, user_3): - """=> Ensure get single user behaves correctly.""" - - 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/users', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - - assert len(data['data']['users']) == 3 - assert 'created_at' in data['data']['users'][0] - assert 'created_at' in data['data']['users'][1] - assert 'created_at' in data['data']['users'][2] - assert 'test' in data['data']['users'][0]['username'] - assert 'toto' in data['data']['users'][1]['username'] - assert 'sam' in data['data']['users'][2]['username'] - assert 'test@test.com' in data['data']['users'][0]['email'] - assert 'toto@toto.com' in data['data']['users'][1]['email'] - assert 'sam@test.com' in data['data']['users'][2]['email'] - assert data['data']['users'][0]['timezone'] is None - assert data['data']['users'][0]['weekm'] is False - assert data['data']['users'][0]['language'] is None - assert data['data']['users'][0]['nb_activities'] == 0 - assert data['data']['users'][0]['nb_sports'] == 0 - assert data['data']['users'][0]['sports_list'] == [] - assert data['data']['users'][0]['total_distance'] == 0 - assert data['data']['users'][0]['total_duration'] == '0:00:00' - assert data['data']['users'][1]['timezone'] is None - assert data['data']['users'][1]['weekm'] is False - assert data['data']['users'][1]['language'] is None - assert data['data']['users'][1]['nb_activities'] == 0 - assert data['data']['users'][1]['nb_sports'] == 0 - assert data['data']['users'][1]['sports_list'] == [] - assert data['data']['users'][1]['total_distance'] == 0 - assert data['data']['users'][1]['total_duration'] == '0:00:00' - assert data['data']['users'][2]['timezone'] is None - assert data['data']['users'][2]['weekm'] is True - assert data['data']['users'][2]['language'] is None - assert data['data']['users'][2]['nb_activities'] == 0 - assert data['data']['users'][2]['nb_sports'] == 0 - assert data['data']['users'][2]['sports_list'] == [] - assert data['data']['users'][2]['total_distance'] == 0 - assert data['data']['users'][2]['total_duration'] == '0:00:00' - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_users_list_with_activities( - app, - user_1, - user_2, - user_3, - sport_1_cycling, - activity_cycling_user_1, - sport_2_running, - activity_running_user_1, - activity_cycling_user_2, -): - - 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/users', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - - assert len(data['data']['users']) == 3 - assert 'created_at' in data['data']['users'][0] - assert 'created_at' in data['data']['users'][1] - assert 'created_at' in data['data']['users'][2] - assert 'test' in data['data']['users'][0]['username'] - assert 'toto' in data['data']['users'][1]['username'] - assert 'sam' in data['data']['users'][2]['username'] - assert 'test@test.com' in data['data']['users'][0]['email'] - assert 'toto@toto.com' in data['data']['users'][1]['email'] - assert 'sam@test.com' in data['data']['users'][2]['email'] - assert data['data']['users'][0]['timezone'] is None - assert data['data']['users'][0]['weekm'] is False - assert data['data']['users'][0]['nb_activities'] == 2 - assert data['data']['users'][0]['nb_sports'] == 2 - assert data['data']['users'][0]['sports_list'] == [1, 2] - assert data['data']['users'][0]['total_distance'] == 22.0 - assert data['data']['users'][0]['total_duration'] == '1:57:04' - assert data['data']['users'][1]['timezone'] is None - assert data['data']['users'][1]['weekm'] is False - assert data['data']['users'][1]['nb_activities'] == 1 - assert data['data']['users'][1]['nb_sports'] == 1 - assert data['data']['users'][1]['sports_list'] == [1] - assert data['data']['users'][1]['total_distance'] == 15 - assert data['data']['users'][1]['total_duration'] == '1:00:00' - assert data['data']['users'][2]['timezone'] is None - assert data['data']['users'][2]['weekm'] is True - assert data['data']['users'][2]['nb_activities'] == 0 - assert data['data']['users'][2]['nb_sports'] == 0 - assert data['data']['users'][2]['sports_list'] == [] - assert data['data']['users'][2]['total_distance'] == 0 - assert data['data']['users'][2]['total_duration'] == '0:00:00' - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -@patch('fittrackee_api.users.users.USER_PER_PAGE', 2) -def test_it_gets_first_page_on_users_list( - app, user_1, user_2, user_3, -): - 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/users?page=1', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 2 - assert data['pagination'] == { - 'has_next': True, - 'has_prev': False, - 'page': 1, - 'pages': 2, - 'total': 3, - } - - -@patch('fittrackee_api.users.users.USER_PER_PAGE', 2) -def test_it_gets_next_page_on_users_list( - app, user_1, user_2, user_3, -): - 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/users?page=2', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 1 - assert data['pagination'] == { - 'has_next': False, - 'has_prev': True, - 'page': 2, - 'pages': 2, - 'total': 3, - } - - -def test_it_gets_empty_next_page_on_users_list( - app, user_1, user_2, user_3, -): - 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/users?page=2', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 0 - assert data['pagination'] == { - 'has_next': False, - 'has_prev': True, - 'page': 2, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_user_list_with_2_per_page( - app, user_1, user_2, user_3, -): - 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/users?per_page=2', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 2 - assert data['pagination'] == { - 'has_next': True, - 'has_prev': False, - 'page': 1, - 'pages': 2, - 'total': 3, - } - - -def test_it_gets_next_page_on_user_list_with_2_per_page( - app, user_1, user_2, user_3, -): - 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/users?page=2&per_page=2', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 1 - assert data['pagination'] == { - 'has_next': False, - 'has_prev': True, - 'page': 2, - 'pages': 2, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_username(app, user_1, user_2, user_3): - 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/users?order_by=username', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'sam' in data['data']['users'][0]['username'] - assert 'test' in data['data']['users'][1]['username'] - assert 'toto' in data['data']['users'][2]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_username_ascending( - app, user_1, user_2, user_3 -): - 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/users?order_by=username&order=asc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'sam' in data['data']['users'][0]['username'] - assert 'test' in data['data']['users'][1]['username'] - assert 'toto' in data['data']['users'][2]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_username_descending( - app, user_1, user_2, user_3 -): - 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/users?order_by=username&order=desc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'toto' in data['data']['users'][0]['username'] - assert 'test' in data['data']['users'][1]['username'] - assert 'sam' in data['data']['users'][2]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_creation_date( - app, user_2, user_3, user_1_admin -): - user_2.created_at = datetime.utcnow() - timedelta(days=1) - user_3.created_at = datetime.utcnow() - timedelta(hours=1) - user_1_admin.created_at = datetime.utcnow() - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/users?order_by=created_at', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'toto' in data['data']['users'][0]['username'] - assert 'sam' in data['data']['users'][1]['username'] - assert 'admin' in data['data']['users'][2]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_creation_date_ascending( - app, user_2, user_3, user_1_admin -): - user_2.created_at = datetime.utcnow() - timedelta(days=1) - user_3.created_at = datetime.utcnow() - timedelta(hours=1) - user_1_admin.created_at = datetime.utcnow() - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/users?order_by=created_at&order=asc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'toto' in data['data']['users'][0]['username'] - assert 'sam' in data['data']['users'][1]['username'] - assert 'admin' in data['data']['users'][2]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_creation_date_descending( - app, user_2, user_3, user_1_admin -): - user_2.created_at = datetime.utcnow() - timedelta(days=1) - user_3.created_at = datetime.utcnow() - timedelta(hours=1) - user_1_admin.created_at = datetime.utcnow() - - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/users?order_by=created_at&order=desc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'admin' in data['data']['users'][0]['username'] - assert 'sam' in data['data']['users'][1]['username'] - assert 'toto' in data['data']['users'][2]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_admin_rights( - app, user_2, user_1_admin, user_3 -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/users?order_by=admin', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'toto' in data['data']['users'][0]['username'] - assert 'sam' in data['data']['users'][1]['username'] - assert 'admin' in data['data']['users'][2]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_admin_rights_ascending( - app, user_2, user_1_admin, user_3 -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/users?order_by=admin&order=asc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'toto' in data['data']['users'][0]['username'] - assert 'sam' in data['data']['users'][1]['username'] - assert 'admin' in data['data']['users'][2]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_admin_rights_descending( - app, user_2, user_3, user_1_admin -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.get( - '/api/users?order_by=admin&order=desc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'admin' in data['data']['users'][0]['username'] - assert 'toto' in data['data']['users'][1]['username'] - assert 'sam' in data['data']['users'][2]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_activities_count( - app, user_1, user_2, user_3, sport_1_cycling, activity_cycling_user_2, -): - 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/users?order_by=activities_count', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'test' in data['data']['users'][0]['username'] - assert 0 == data['data']['users'][0]['nb_activities'] - assert 'sam' in data['data']['users'][1]['username'] - assert 0 == data['data']['users'][1]['nb_activities'] - assert 'toto' in data['data']['users'][2]['username'] - assert 1 == data['data']['users'][2]['nb_activities'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_activities_count_ascending( - app, user_1, user_2, user_3, sport_1_cycling, activity_cycling_user_2, -): - 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/users?order_by=activities_count&order=asc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'test' in data['data']['users'][0]['username'] - assert 0 == data['data']['users'][0]['nb_activities'] - assert 'sam' in data['data']['users'][1]['username'] - assert 0 == data['data']['users'][1]['nb_activities'] - assert 'toto' in data['data']['users'][2]['username'] - assert 1 == data['data']['users'][2]['nb_activities'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_ordered_by_activities_count_descending( - app, user_1, user_2, user_3, sport_1_cycling, activity_cycling_user_2, -): - 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/users?order_by=activities_count&order=desc', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 3 - assert 'toto' in data['data']['users'][0]['username'] - assert 1 == data['data']['users'][0]['nb_activities'] - assert 'test' in data['data']['users'][1]['username'] - assert 0 == data['data']['users'][1]['nb_activities'] - assert 'sam' in data['data']['users'][2]['username'] - assert 0 == data['data']['users'][2]['nb_activities'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 3, - } - - -def test_it_gets_users_list_filtering_on_username(app, user_1, user_2, user_3): - 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/users?q=toto', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 1 - assert 'toto' in data['data']['users'][0]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 1, - 'total': 1, - } - - -def test_it_returns_empty_users_list_filtering_on_username( - app, user_1, user_2, user_3 -): - 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/users?q=not_existing', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 0 - assert data['pagination'] == { - 'has_next': False, - 'has_prev': False, - 'page': 1, - 'pages': 0, - 'total': 0, - } - - -def test_it_users_list_with_complex_query(app, user_1, user_2, user_3): - 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/users?order_by=username&order=desc&page=2&per_page=2', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 1 - assert 'sam' in data['data']['users'][0]['username'] - assert data['pagination'] == { - 'has_next': False, - 'has_prev': True, - 'page': 2, - 'pages': 2, - 'total': 3, - } - - -def test_encode_auth_token(app, user_1): - """=> Ensure correct auth token generation""" - auth_token = user_1.encode_auth_token(user_1.id) - assert isinstance(auth_token, bytes) - - -def test_decode_auth_token(app, user_1): - auth_token = user_1.encode_auth_token(user_1.id) - assert isinstance(auth_token, bytes) - assert User.decode_auth_token(auth_token) == user_1.id - - -def test_user_no_picture(app, user_1): - client = app.test_client() - response = client.get(f'/api/users/{user_1.username}/picture') - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'not found' in data['status'] - assert 'No picture.' in data['message'] - - -def test_user_picture_no_user(app, user_1): - client = app.test_client() - response = client.get('/api/users/not_existing/picture') - data = json.loads(response.data.decode()) - - assert response.status_code == 404 - assert 'fail' in data['status'] - assert 'User does not exist.' in data['message'] - - -def test_it_adds_admin_rights_to_a_user(app, user_1_admin, user_2): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/users/toto', - content_type='application/json', - data=json.dumps(dict(admin=True)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 1 - - user = data['data']['users'][0] - assert user['email'] == 'toto@toto.com' - assert user['admin'] is True - - -def test_it_removes_admin_rights_to_a_user(app, user_1_admin, user_2): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/users/toto', - content_type='application/json', - data=json.dumps(dict(admin=False)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 200 - assert 'success' in data['status'] - assert len(data['data']['users']) == 1 - - user = data['data']['users'][0] - assert user['email'] == 'toto@toto.com' - assert user['admin'] is False - - -def test_it_returns_error_if_payload_for_admin_rights_is_empty( - app, user_1_admin, user_2 -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/users/toto', - content_type='application/json', - data=json.dumps(dict()), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 400 - assert 'error' in data['status'] - assert 'Invalid payload.' in data['message'] - - -def test_it_returns_error_if_payload_for_admin_rights_is_invalid( - app, user_1_admin, user_2 -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.patch( - '/api/users/toto', - content_type='application/json', - data=json.dumps(dict(admin="")), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 500 - assert 'error' in data['status'] - assert ( - 'Error. Please try again or contact the administrator.' - in data['message'] - ) - - -def test_it_returns_error_if_user_can_not_change_admin_rights( - app, user_1, user_2 -): - 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.patch( - '/api/users/toto', - content_type='application/json', - data=json.dumps(dict(admin=True)), - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - data = json.loads(response.data.decode()) - - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_user_can_delete_its_own_account(app, 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.delete( - '/api/users/test', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - assert response.status_code == 204 - - -def test_user_with_activity_can_delete_its_own_account( - app, user_1, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/activities', - data=dict( - file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), - data='{"sport_id": 1}', - ), - headers=dict( - content_type='multipart/form-data', - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.delete( - '/api/users/test', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - assert response.status_code == 204 - - -def test_user_with_picture_can_delete_its_own_account( - app, user_1, sport_1_cycling, gpx_file -): - 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', - ) - client.post( - '/api/auth/picture', - data=dict(file=(BytesIO(b'avatar'), 'avatar.png')), - headers=dict( - content_type='multipart/form-data', - authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'], - ), - ) - response = client.delete( - '/api/users/test', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - assert response.status_code == 204 - - -def test_user_can_not_delete_another_user_account(app, user_1, user_2): - 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.delete( - '/api/users/toto', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 403 - assert 'error' in data['status'] - assert 'You do not have permissions.' in data['message'] - - -def test_it_returns_error_when_deleting_non_existing_user(app, 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.delete( - '/api/users/not_existing', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 404 - assert 'not found' in data['status'] - assert 'User does not exist.' in data['message'] - - -def test_admin_can_delete_another_user_account(app, user_1_admin, user_2): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.delete( - '/api/users/toto', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - assert response.status_code == 204 - - -def test_admin_can_delete_its_own_account(app, user_1_admin, user_2_admin): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.delete( - '/api/users/admin', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - assert response.status_code == 204 - - -def test_admin_can_not_delete_its_own_account_if_no_other_admin( - app, user_1_admin, user_2 -): - client = app.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - response = client.delete( - '/api/users/admin', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - - data = json.loads(response.data.decode()) - assert response.status_code == 403 - assert 'error' in data['status'] - assert ( - 'You can not delete your account, no other user has admin rights.' - in data['message'] - ) - - -def test_it_enables_registration_on_user_delete( - app_no_config, app_config, user_1_admin, user_2, user_3 -): - app_config.max_users = 3 - client = app_no_config.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - client.delete( - '/api/users/toto', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='justatest', - email='test@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - assert response.status_code == 201 - - -def test_it_does_not_enable_registration_on_user_delete( - app_no_config, app_config, user_1_admin, user_2, user_3 -): - app_config.max_users = 2 - client = app_no_config.test_client() - resp_login = client.post( - '/api/auth/login', - data=json.dumps(dict(email='admin@example.com', password='12345678')), - content_type='application/json', - ) - client.delete( - '/api/users/toto', - headers=dict( - Authorization='Bearer ' - + json.loads(resp_login.data.decode())['auth_token'] - ), - ) - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='justatest', - email='test@test.com', - password='12345678', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - assert response.status_code == 403 - data = json.loads(response.data.decode()) - assert data['status'] == 'error' - assert data['message'] == 'Error. Registration is disabled.' + +class TestGetUser: + def test_it_gets_single_user_without_activities(self, app, user_1, user_2): + 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( + f'/api/users/{user_2.username}', + content_type='application/json', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert data['status'] == 'success' + assert len(data['data']['users']) == 1 + user = data['data']['users'][0] + assert user['username'] == 'toto' + assert user['email'] == 'toto@toto.com' + assert user['created_at'] + assert not user['admin'] + assert user['first_name'] is None + assert user['last_name'] is None + assert user['birth_date'] is None + assert user['bio'] is None + assert user['location'] is None + assert user['timezone'] is None + assert user['weekm'] is False + assert user['language'] is None + assert user['nb_activities'] == 0 + assert user['nb_sports'] == 0 + assert user['sports_list'] == [] + assert user['total_distance'] == 0 + assert user['total_duration'] == '0:00:00' + + def test_it_gets_single_user_with_activities( + self, + 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( + f'/api/users/{user_1.username}', + content_type='application/json', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert data['status'] == 'success' + assert len(data['data']['users']) == 1 + user = data['data']['users'][0] + assert user['username'] == 'test' + assert user['email'] == 'test@test.com' + assert user['created_at'] + assert not user['admin'] + assert user['first_name'] is None + assert user['last_name'] is None + assert user['birth_date'] is None + assert user['bio'] is None + assert user['location'] is None + assert user['timezone'] is None + assert user['weekm'] is False + assert user['language'] is None + assert user['nb_activities'] == 2 + assert user['nb_sports'] == 2 + assert user['sports_list'] == [1, 2] + assert user['total_distance'] == 22 + assert user['total_duration'] == '2:40:00' + + def test_it_returns_error_if_user_does_not_exist(self, app, 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/users/not_existing', + content_type='application/json', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + data = json.loads(response.data.decode()) + + assert response.status_code == 404 + assert 'fail' in data['status'] + assert 'User does not exist.' in data['message'] + + +class TestGetUsers: + def test_it_get_users_list(self, app, user_1, user_2, user_3): + 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/users', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'created_at' in data['data']['users'][0] + assert 'created_at' in data['data']['users'][1] + assert 'created_at' in data['data']['users'][2] + assert 'test' in data['data']['users'][0]['username'] + assert 'toto' in data['data']['users'][1]['username'] + assert 'sam' in data['data']['users'][2]['username'] + assert 'test@test.com' in data['data']['users'][0]['email'] + assert 'toto@toto.com' in data['data']['users'][1]['email'] + assert 'sam@test.com' in data['data']['users'][2]['email'] + assert data['data']['users'][0]['timezone'] is None + assert data['data']['users'][0]['weekm'] is False + assert data['data']['users'][0]['language'] is None + assert data['data']['users'][0]['nb_activities'] == 0 + assert data['data']['users'][0]['nb_sports'] == 0 + assert data['data']['users'][0]['sports_list'] == [] + assert data['data']['users'][0]['total_distance'] == 0 + assert data['data']['users'][0]['total_duration'] == '0:00:00' + assert data['data']['users'][1]['timezone'] is None + assert data['data']['users'][1]['weekm'] is False + assert data['data']['users'][1]['language'] is None + assert data['data']['users'][1]['nb_activities'] == 0 + assert data['data']['users'][1]['nb_sports'] == 0 + assert data['data']['users'][1]['sports_list'] == [] + assert data['data']['users'][1]['total_distance'] == 0 + assert data['data']['users'][1]['total_duration'] == '0:00:00' + assert data['data']['users'][2]['timezone'] is None + assert data['data']['users'][2]['weekm'] is True + assert data['data']['users'][2]['language'] is None + assert data['data']['users'][2]['nb_activities'] == 0 + assert data['data']['users'][2]['nb_sports'] == 0 + assert data['data']['users'][2]['sports_list'] == [] + assert data['data']['users'][2]['total_distance'] == 0 + assert data['data']['users'][2]['total_duration'] == '0:00:00' + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_with_activities( + self, + app, + user_1, + user_2, + user_3, + sport_1_cycling, + activity_cycling_user_1, + sport_2_running, + activity_running_user_1, + activity_cycling_user_2, + ): + 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/users', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'created_at' in data['data']['users'][0] + assert 'created_at' in data['data']['users'][1] + assert 'created_at' in data['data']['users'][2] + assert 'test' in data['data']['users'][0]['username'] + assert 'toto' in data['data']['users'][1]['username'] + assert 'sam' in data['data']['users'][2]['username'] + assert 'test@test.com' in data['data']['users'][0]['email'] + assert 'toto@toto.com' in data['data']['users'][1]['email'] + assert 'sam@test.com' in data['data']['users'][2]['email'] + assert data['data']['users'][0]['timezone'] is None + assert data['data']['users'][0]['weekm'] is False + assert data['data']['users'][0]['nb_activities'] == 2 + assert data['data']['users'][0]['nb_sports'] == 2 + assert data['data']['users'][0]['sports_list'] == [1, 2] + assert data['data']['users'][0]['total_distance'] == 22.0 + assert data['data']['users'][0]['total_duration'] == '2:40:00' + assert data['data']['users'][1]['timezone'] is None + assert data['data']['users'][1]['weekm'] is False + assert data['data']['users'][1]['nb_activities'] == 1 + assert data['data']['users'][1]['nb_sports'] == 1 + assert data['data']['users'][1]['sports_list'] == [1] + assert data['data']['users'][1]['total_distance'] == 15 + assert data['data']['users'][1]['total_duration'] == '1:00:00' + assert data['data']['users'][2]['timezone'] is None + assert data['data']['users'][2]['weekm'] is True + assert data['data']['users'][2]['nb_activities'] == 0 + assert data['data']['users'][2]['nb_sports'] == 0 + assert data['data']['users'][2]['sports_list'] == [] + assert data['data']['users'][2]['total_distance'] == 0 + assert data['data']['users'][2]['total_duration'] == '0:00:00' + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + @patch('fittrackee_api.users.users.USER_PER_PAGE', 2) + def test_it_gets_first_page_on_users_list( + self, app, user_1, user_2, user_3, + ): + 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/users?page=1', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 2 + assert data['pagination'] == { + 'has_next': True, + 'has_prev': False, + 'page': 1, + 'pages': 2, + 'total': 3, + } + + @patch('fittrackee_api.users.users.USER_PER_PAGE', 2) + def test_it_gets_next_page_on_users_list( + self, app, user_1, user_2, user_3, + ): + 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/users?page=2', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 1 + assert data['pagination'] == { + 'has_next': False, + 'has_prev': True, + 'page': 2, + 'pages': 2, + 'total': 3, + } + + def test_it_gets_empty_next_page_on_users_list( + self, app, user_1, user_2, user_3, + ): + 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/users?page=2', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 0 + assert data['pagination'] == { + 'has_next': False, + 'has_prev': True, + 'page': 2, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_user_list_with_2_per_page( + self, app, user_1, user_2, user_3, + ): + 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/users?per_page=2', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 2 + assert data['pagination'] == { + 'has_next': True, + 'has_prev': False, + 'page': 1, + 'pages': 2, + 'total': 3, + } + + def test_it_gets_next_page_on_user_list_with_2_per_page( + self, app, user_1, user_2, user_3, + ): + 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/users?page=2&per_page=2', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 1 + assert data['pagination'] == { + 'has_next': False, + 'has_prev': True, + 'page': 2, + 'pages': 2, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_username( + self, app, user_1, user_2, user_3 + ): + 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/users?order_by=username', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'sam' in data['data']['users'][0]['username'] + assert 'test' in data['data']['users'][1]['username'] + assert 'toto' in data['data']['users'][2]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_username_ascending( + self, app, user_1, user_2, user_3 + ): + 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/users?order_by=username&order=asc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'sam' in data['data']['users'][0]['username'] + assert 'test' in data['data']['users'][1]['username'] + assert 'toto' in data['data']['users'][2]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_username_descending( + self, app, user_1, user_2, user_3 + ): + 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/users?order_by=username&order=desc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'toto' in data['data']['users'][0]['username'] + assert 'test' in data['data']['users'][1]['username'] + assert 'sam' in data['data']['users'][2]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_creation_date( + self, app, user_2, user_3, user_1_admin + ): + user_2.created_at = datetime.utcnow() - timedelta(days=1) + user_3.created_at = datetime.utcnow() - timedelta(hours=1) + user_1_admin.created_at = datetime.utcnow() + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.get( + '/api/users?order_by=created_at', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'toto' in data['data']['users'][0]['username'] + assert 'sam' in data['data']['users'][1]['username'] + assert 'admin' in data['data']['users'][2]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_creation_date_ascending( + self, app, user_2, user_3, user_1_admin + ): + user_2.created_at = datetime.utcnow() - timedelta(days=1) + user_3.created_at = datetime.utcnow() - timedelta(hours=1) + user_1_admin.created_at = datetime.utcnow() + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.get( + '/api/users?order_by=created_at&order=asc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'toto' in data['data']['users'][0]['username'] + assert 'sam' in data['data']['users'][1]['username'] + assert 'admin' in data['data']['users'][2]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_creation_date_descending( + self, app, user_2, user_3, user_1_admin + ): + user_2.created_at = datetime.utcnow() - timedelta(days=1) + user_3.created_at = datetime.utcnow() - timedelta(hours=1) + user_1_admin.created_at = datetime.utcnow() + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.get( + '/api/users?order_by=created_at&order=desc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'admin' in data['data']['users'][0]['username'] + assert 'sam' in data['data']['users'][1]['username'] + assert 'toto' in data['data']['users'][2]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_admin_rights( + self, app, user_2, user_1_admin, user_3 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.get( + '/api/users?order_by=admin', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'toto' in data['data']['users'][0]['username'] + assert 'sam' in data['data']['users'][1]['username'] + assert 'admin' in data['data']['users'][2]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_admin_rights_ascending( + self, app, user_2, user_1_admin, user_3 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.get( + '/api/users?order_by=admin&order=asc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'toto' in data['data']['users'][0]['username'] + assert 'sam' in data['data']['users'][1]['username'] + assert 'admin' in data['data']['users'][2]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_admin_rights_descending( + self, app, user_2, user_3, user_1_admin + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.get( + '/api/users?order_by=admin&order=desc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'admin' in data['data']['users'][0]['username'] + assert 'toto' in data['data']['users'][1]['username'] + assert 'sam' in data['data']['users'][2]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_activities_count( + self, + app, + user_1, + user_2, + user_3, + sport_1_cycling, + activity_cycling_user_2, + ): + 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/users?order_by=activities_count', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'test' in data['data']['users'][0]['username'] + assert 0 == data['data']['users'][0]['nb_activities'] + assert 'sam' in data['data']['users'][1]['username'] + assert 0 == data['data']['users'][1]['nb_activities'] + assert 'toto' in data['data']['users'][2]['username'] + assert 1 == data['data']['users'][2]['nb_activities'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_activities_count_ascending( + self, + app, + user_1, + user_2, + user_3, + sport_1_cycling, + activity_cycling_user_2, + ): + 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/users?order_by=activities_count&order=asc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'test' in data['data']['users'][0]['username'] + assert 0 == data['data']['users'][0]['nb_activities'] + assert 'sam' in data['data']['users'][1]['username'] + assert 0 == data['data']['users'][1]['nb_activities'] + assert 'toto' in data['data']['users'][2]['username'] + assert 1 == data['data']['users'][2]['nb_activities'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_ordered_by_activities_count_descending( + self, + app, + user_1, + user_2, + user_3, + sport_1_cycling, + activity_cycling_user_2, + ): + 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/users?order_by=activities_count&order=desc', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 3 + assert 'toto' in data['data']['users'][0]['username'] + assert 1 == data['data']['users'][0]['nb_activities'] + assert 'test' in data['data']['users'][1]['username'] + assert 0 == data['data']['users'][1]['nb_activities'] + assert 'sam' in data['data']['users'][2]['username'] + assert 0 == data['data']['users'][2]['nb_activities'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 3, + } + + def test_it_gets_users_list_filtering_on_username( + self, app, user_1, user_2, user_3 + ): + 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/users?q=toto', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 1 + assert 'toto' in data['data']['users'][0]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 1, + 'total': 1, + } + + def test_it_returns_empty_users_list_filtering_on_username( + self, app, user_1, user_2, user_3 + ): + 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/users?q=not_existing', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 0 + assert data['pagination'] == { + 'has_next': False, + 'has_prev': False, + 'page': 1, + 'pages': 0, + 'total': 0, + } + + def test_it_users_list_with_complex_query( + self, app, user_1, user_2, user_3 + ): + 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/users?order_by=username&order=desc&page=2&per_page=2', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 1 + assert 'sam' in data['data']['users'][0]['username'] + assert data['pagination'] == { + 'has_next': False, + 'has_prev': True, + 'page': 2, + 'pages': 2, + 'total': 3, + } + + +class TestGetUserPicture: + def test_it_return_error_if_user_has_no_picture(self, app, user_1): + client = app.test_client() + + response = client.get(f'/api/users/{user_1.username}/picture') + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert 'No picture.' in data['message'] + + def test_it_returns_error_if_user_does_not_exist(self, app, user_1): + client = app.test_client() + + response = client.get('/api/users/not_existing/picture') + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'fail' in data['status'] + assert 'User does not exist.' in data['message'] + + +class TestUpdateUser: + def test_it_adds_admin_rights_to_a_user(self, app, user_1_admin, user_2): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.patch( + '/api/users/toto', + content_type='application/json', + data=json.dumps(dict(admin=True)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 1 + user = data['data']['users'][0] + assert user['email'] == 'toto@toto.com' + assert user['admin'] is True + + def test_it_removes_admin_rights_to_a_user( + self, app, user_1_admin, user_2 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.patch( + '/api/users/toto', + content_type='application/json', + data=json.dumps(dict(admin=False)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['users']) == 1 + + user = data['data']['users'][0] + assert user['email'] == 'toto@toto.com' + assert user['admin'] is False + + def test_it_returns_error_if_payload_for_admin_rights_is_empty( + self, app, user_1_admin, user_2 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.patch( + '/api/users/toto', + content_type='application/json', + data=json.dumps(dict()), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 400 + assert 'error' in data['status'] + assert 'Invalid payload.' in data['message'] + + def test_it_returns_error_if_payload_for_admin_rights_is_invalid( + self, app, user_1_admin, user_2 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.patch( + '/api/users/toto', + content_type='application/json', + data=json.dumps(dict(admin="")), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 500 + assert 'error' in data['status'] + assert ( + 'Error. Please try again or contact the administrator.' + in data['message'] + ) + + def test_it_returns_error_if_user_can_not_change_admin_rights( + self, app, user_1, user_2 + ): + 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.patch( + '/api/users/toto', + content_type='application/json', + data=json.dumps(dict(admin=True)), + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 403 + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] + + +class TestDeleteUser: + def test_user_can_delete_its_own_account(self, app, 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.delete( + '/api/users/test', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + assert response.status_code == 204 + + def test_user_with_activity_can_delete_its_own_account( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}', + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + response = client.delete( + '/api/users/test', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + assert response.status_code == 204 + + def test_user_with_picture_can_delete_its_own_account( + self, app, user_1, sport_1_cycling, gpx_file + ): + 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', + ) + client.post( + '/api/auth/picture', + data=dict(file=(BytesIO(b'avatar'), 'avatar.png')), + headers=dict( + content_type='multipart/form-data', + authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'], + ), + ) + + response = client.delete( + '/api/users/test', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + assert response.status_code == 204 + + def test_user_can_not_delete_another_user_account( + self, app, user_1, user_2 + ): + 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.delete( + '/api/users/toto', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 403 + assert 'error' in data['status'] + assert 'You do not have permissions.' in data['message'] + + def test_it_returns_error_when_deleting_non_existing_user( + self, app, 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.delete( + '/api/users/not_existing', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 404 + assert 'not found' in data['status'] + assert 'User does not exist.' in data['message'] + + def test_admin_can_delete_another_user_account( + self, app, user_1_admin, user_2 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.delete( + '/api/users/toto', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + assert response.status_code == 204 + + def test_admin_can_delete_its_own_account( + self, app, user_1_admin, user_2_admin + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + response = client.delete( + '/api/users/admin', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + assert response.status_code == 204 + + def test_admin_can_not_delete_its_own_account_if_no_other_admin( + self, app, user_1_admin, user_2 + ): + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + response = client.delete( + '/api/users/admin', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + + data = json.loads(response.data.decode()) + assert response.status_code == 403 + assert 'error' in data['status'] + assert ( + 'You can not delete your account, no other user has admin rights.' + in data['message'] + ) + + def test_it_enables_registration_on_user_delete( + self, app_no_config, app_config, user_1_admin, user_2, user_3 + ): + app_config.max_users = 3 + client = app_no_config.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + client.delete( + '/api/users/toto', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='justatest', + email='test@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + assert response.status_code == 201 + + def test_it_does_not_enable_registration_on_user_delete( + self, app_no_config, app_config, user_1_admin, user_2, user_3 + ): + app_config.max_users = 2 + client = app_no_config.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps( + dict(email='admin@example.com', password='12345678') + ), + content_type='application/json', + ) + + client.delete( + '/api/users/toto', + headers=dict( + Authorization='Bearer ' + + json.loads(resp_login.data.decode())['auth_token'] + ), + ) + response = client.post( + '/api/auth/register', + data=json.dumps( + dict( + username='justatest', + email='test@test.com', + password='12345678', + password_conf='12345678', + ) + ), + content_type='application/json', + ) + + assert response.status_code == 403 + data = json.loads(response.data.decode()) + assert data['status'] == 'error' + assert data['message'] == 'Error. Registration is disabled.' diff --git a/fittrackee_api/fittrackee_api/tests/test_users_model.py b/fittrackee_api/fittrackee_api/tests/test_users_model.py index 5cd37a73..85c0cb52 100644 --- a/fittrackee_api/fittrackee_api/tests/test_users_model.py +++ b/fittrackee_api/fittrackee_api/tests/test_users_model.py @@ -1,20 +1,33 @@ -def test_user_model(app, user_1): - assert '' == str(user_1) +from fittrackee_api.users.models import User - serialized_user = user_1.serialize() - assert 'test' == serialized_user['username'] - assert 'created_at' in serialized_user - assert serialized_user['admin'] is False - assert serialized_user['first_name'] is None - assert serialized_user['last_name'] is None - assert serialized_user['bio'] is None - assert serialized_user['location'] is None - assert serialized_user['birth_date'] is None - assert serialized_user['picture'] is False - assert serialized_user['timezone'] is None - assert serialized_user['weekm'] is False - assert serialized_user['language'] is None - 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' + +class TestUserModel: + def test_user_model(self, app, user_1): + assert '' == str(user_1) + + serialized_user = user_1.serialize() + assert 'test' == serialized_user['username'] + assert 'created_at' in serialized_user + assert serialized_user['admin'] is False + assert serialized_user['first_name'] is None + assert serialized_user['last_name'] is None + assert serialized_user['bio'] is None + assert serialized_user['location'] is None + assert serialized_user['birth_date'] is None + assert serialized_user['picture'] is False + assert serialized_user['timezone'] is None + assert serialized_user['weekm'] is False + assert serialized_user['language'] is None + 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' + + def test_encode_auth_token(self, app, user_1): + auth_token = user_1.encode_auth_token(user_1.id) + assert isinstance(auth_token, bytes) + + def test_decode_auth_token(self, app, user_1): + auth_token = user_1.encode_auth_token(user_1.id) + assert isinstance(auth_token, bytes) + assert User.decode_auth_token(auth_token) == user_1.id