From 58b69878c4069befbf0ad1ff7dfd582d0f60409f Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 9 May 2018 18:54:30 +0200 Subject: [PATCH] API: delete an activity --- mpwo_api/mpwo_api/activities/activities.py | 44 +++++- mpwo_api/mpwo_api/activities/sports.py | 3 +- mpwo_api/mpwo_api/tests/test_activities.py | 147 ++++++++++++++++++++- mpwo_api/mpwo_api/tests/utils.py | 5 + 4 files changed, 194 insertions(+), 5 deletions(-) diff --git a/mpwo_api/mpwo_api/activities/activities.py b/mpwo_api/mpwo_api/activities/activities.py index b8ca95fa..77240fca 100644 --- a/mpwo_api/mpwo_api/activities/activities.py +++ b/mpwo_api/mpwo_api/activities/activities.py @@ -1,4 +1,5 @@ import json +import os from flask import Blueprint, jsonify, request from mpwo_api import appLog, db @@ -57,8 +58,7 @@ def get_activity(auth_user_id, activity_id): @activities_blueprint.route( - '/activities//gpx', - methods=['GET'] + '/activities//gpx', methods=['GET'] ) @authenticate def get_activity_gpx(auth_user_id, activity_id): @@ -196,3 +196,43 @@ def post_activity_no_gpx(auth_user_id): 'message': 'Error during activity save.' } return jsonify(response_object), 500 + + +@activities_blueprint.route( + '/activities/', methods=['DELETE'] +) +@authenticate +def delete_activity(auth_user_id, activity_id): + """Delete an activity""" + try: + activity = Activity.query.filter_by(id=activity_id).first() + if activity: + gpx_filepath = activity.gpx + db.session.delete(activity) + db.session.commit() + + if gpx_filepath: + os.remove(gpx_filepath) + + response_object = { + 'status': 'no content' + } + code = 204 + else: + response_object = { + 'status': 'not found', + 'data': { + 'activities': [] + } + } + code = 404 + except (exc.IntegrityError, exc.OperationalError, ValueError, OSError) \ + as e: + db.session.rollback() + appLog.error(e) + response_object = { + 'status': 'error', + 'message': 'Error. Please try again or contact the administrator.' + } + code = 500 + return jsonify(response_object), code diff --git a/mpwo_api/mpwo_api/activities/sports.py b/mpwo_api/mpwo_api/activities/sports.py index a254bb8a..bb531d39 100644 --- a/mpwo_api/mpwo_api/activities/sports.py +++ b/mpwo_api/mpwo_api/activities/sports.py @@ -140,7 +140,6 @@ def update_sport(auth_user_id, sport_id): @authenticate_as_admin def delete_sport(auth_user_id, sport_id): """Delete a sport""" - sports_list = [] try: sport = Sport.query.filter_by(id=sport_id).first() if sport: @@ -154,7 +153,7 @@ def delete_sport(auth_user_id, sport_id): response_object = { 'status': 'not found', 'data': { - 'sports': sports_list + 'sports': [] } } code = 404 diff --git a/mpwo_api/mpwo_api/tests/test_activities.py b/mpwo_api/mpwo_api/tests/test_activities.py index e883bd75..1e7be969 100644 --- a/mpwo_api/mpwo_api/tests/test_activities.py +++ b/mpwo_api/mpwo_api/tests/test_activities.py @@ -1,8 +1,11 @@ import datetime import json +import os from io import BytesIO -from mpwo_api.tests.utils import add_activity, add_sport, add_user +from mpwo_api.tests.utils import ( + add_activity, add_sport, add_user, get_gpx_filepath +) from mpwo_api.tests.utils_gpx import gpx_file @@ -473,3 +476,145 @@ def test_get_an_activity_with_gpx(app): assert data['data']['activities'][0]['moving'] == '0:04:10' assert data['data']['activities'][0]['pauses'] is None assert data['data']['activities'][0]['with_gpx'] is True + + +def test_delete_an_activity_with_gpx(app): + add_user('test', 'test@test.com', '12345678') + add_sport('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', + 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 + + +def test_delete_an_activity_wo_gpx(app): + add_user('test', 'test@test.com', '12345678') + add_sport('cycling') + add_activity( + 1, + 1, + datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'), + datetime.timedelta(seconds=1024)) + + client = 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_no_activityy(app): + add_user('test', 'test@test.com', '12345678') + + client = 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): + add_user('test', 'test@test.com', '12345678') + add_sport('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', + 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) + 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'] diff --git a/mpwo_api/mpwo_api/tests/utils.py b/mpwo_api/mpwo_api/tests/utils.py index 574c055b..c9670ad8 100644 --- a/mpwo_api/mpwo_api/tests/utils.py +++ b/mpwo_api/mpwo_api/tests/utils.py @@ -52,3 +52,8 @@ def add_activity(user_id, sport_id, activity_date, duration): db.session.add(activity) db.session.commit() return activity + + +def get_gpx_filepath(activity_id): + activity = Activity.query.filter_by(id=activity_id).first() + return activity.gpx