diff --git a/README.md b/README.md index a969989b..970cfe3b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Flask Version](https://img.shields.io/badge/flask-1.0-brightgreen.svg)](http://flask.pocoo.org/) [![React Version](https://img.shields.io/badge/react-16.3-brightgreen.svg)](https://reactjs.org/) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/45d64b31e37e4890a239b8298e66a011)](https://www.codacy.com/app/SamR1/mpwo?utm_source=github.com&utm_medium=referral&utm_content=SamR1/mpwo&utm_campaign=badger) -[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/45d64b31e37e4890a239b8298e66a011)](https://www.codacy.com/app/SamR1/mpwo?utm_source=github.com&utm_medium=referral&utm_content=SamR1/mpwo&utm_campaign=Badge_Coverage)1 +[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/45d64b31e37e4890a239b8298e66a011)](https://www.codacy.com/app/SamR1/mpwo?utm_source=github.com&utm_medium=referral&utm_content=SamR1/mpwo&utm_campaign=Badge_Coverage)1 [![Build Status](https://travis-ci.org/SamR1/mpwo.svg?branch=master)](https://travis-ci.org/SamR1/mpwo) Self hosted workout/activity tracker written with Flask and React (_work in progress_). diff --git a/mpwo_api/mpwo_api/activities/activities.py b/mpwo_api/mpwo_api/activities/activities.py index c22a707f..2e40021c 100644 --- a/mpwo_api/mpwo_api/activities/activities.py +++ b/mpwo_api/mpwo_api/activities/activities.py @@ -122,7 +122,7 @@ def get_activity_gpx(auth_user_id, activity_id): @activities_blueprint.route('/activities', methods=['POST']) @authenticate def post_activity(auth_user_id): - """Post an activity""" + """Post an activity (with gpx file)""" response_object = verify_extension('activity', request) if response_object['status'] != 'success': return jsonify(response_object), 400 @@ -142,6 +142,13 @@ def post_activity(auth_user_id): activity_file.save(file_path) gpx_data = get_gpx_info(file_path) + if gpx_data is None: + response_object = { + 'status': 'error', + 'message': 'Error during gpx file parsing.' + } + return jsonify(response_object), 500 + sport = Sport.query.filter_by(id=activity_data.get('sport_id')).first() new_filepath = get_new_file_path( auth_user_id=auth_user_id, diff --git a/mpwo_api/mpwo_api/activities/utils.py b/mpwo_api/mpwo_api/activities/utils.py index 984c5c4d..f9a06de1 100644 --- a/mpwo_api/mpwo_api/activities/utils.py +++ b/mpwo_api/mpwo_api/activities/utils.py @@ -116,7 +116,8 @@ def get_gpx_info(gpx_file): gpx_data = { 'name': gpx.tracks[0].name, - 'segments': []} + 'segments': [] + } max_speed = 0 start = 0 diff --git a/mpwo_api/mpwo_api/tests/test_activities_api_1_post.py b/mpwo_api/mpwo_api/tests/test_activities_api_1_post.py index 4fb69a3c..2e8e6e1f 100644 --- a/mpwo_api/mpwo_api/tests/test_activities_api_1_post.py +++ b/mpwo_api/mpwo_api/tests/test_activities_api_1_post.py @@ -8,7 +8,6 @@ def assert_activity_data_with_gpx(data): assert 1 == data['data']['activities'][0]['user_id'] assert 1 == data['data']['activities'][0]['sport_id'] assert '0:04:10' == data['data']['activities'][0]['duration'] - assert 'just an activity' == data['data']['activities'][0]['title'] assert data['data']['activities'][0]['ascent'] == 0.4 assert data['data']['activities'][0]['ave_speed'] == 4.6 assert data['data']['activities'][0]['descent'] == 23.4 @@ -66,11 +65,13 @@ def test_add_an_activity_gpx(app, user_1, sport_1_cycling, gpx_file): 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_get_an_activity_with_gpx(app, user_1, sport_1_cycling, gpx_file): +def test_add_an_activity_with_gpx(app, user_1, sport_1_cycling, gpx_file): client = app.test_client() resp_login = client.post( '/api/auth/login', @@ -106,10 +107,78 @@ def test_get_an_activity_with_gpx(app, user_1, sport_1_cycling, gpx_file): 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_activity_data_with_gpx(data) -def test_add_an_activity_gpx_invalid_file( +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'] # noqa + assert_activity_data_with_gpx(data) + + +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_gpx_invalid_extension( app, user_1, sport_1_cycling, gpx_file ): client = app.test_client()