API & Client: now activity w/ gpx can be modified
+ fix (source and tests)
This commit is contained in:
parent
288528716c
commit
74dcdc6840
@ -8,7 +8,7 @@ from sqlalchemy import exc
|
||||
from ..users.utils import authenticate, verify_extension
|
||||
from .models import Activity, Sport
|
||||
from .utils import (
|
||||
create_activity, edit_activity_wo_gpx, get_file_path, get_gpx_info,
|
||||
create_activity, edit_activity, get_file_path, get_gpx_info,
|
||||
get_new_file_path
|
||||
)
|
||||
|
||||
@ -225,10 +225,7 @@ def post_activity_no_gpx(auth_user_id):
|
||||
def update_activity(auth_user_id, activity_id):
|
||||
"""Update an activity"""
|
||||
activity_data = request.get_json()
|
||||
if not activity_data or activity_data.get('sport_id') is None \
|
||||
or activity_data.get('duration') is None \
|
||||
or activity_data.get('distance') is None \
|
||||
or activity_data.get('activity_date') is None:
|
||||
if not activity_data:
|
||||
response_object = {
|
||||
'status': 'error',
|
||||
'message': 'Invalid payload.'
|
||||
@ -238,16 +235,7 @@ def update_activity(auth_user_id, activity_id):
|
||||
try:
|
||||
activity = Activity.query.filter_by(id=activity_id).first()
|
||||
if activity:
|
||||
if activity.gpx:
|
||||
response_object = {
|
||||
'status': 'error',
|
||||
'message': 'You can not modify an activity with gpx file. '
|
||||
'Please delete and re-import the gpx file.'
|
||||
}
|
||||
code = 500
|
||||
return jsonify(response_object), code
|
||||
|
||||
activity = edit_activity_wo_gpx(activity, activity_data)
|
||||
activity = edit_activity(activity, activity_data)
|
||||
db.session.commit()
|
||||
response_object = {
|
||||
'status': 'success',
|
||||
|
@ -60,10 +60,11 @@ class Activity(db.Model):
|
||||
return str(self.sports.label) + \
|
||||
" - " + self.activity_date.strftime('%Y-%m-%d')
|
||||
|
||||
def __init__(self, user_id, sport_id, activity_date, duration):
|
||||
def __init__(self, user_id, sport_id, activity_date, distance, duration):
|
||||
self.user_id = user_id
|
||||
self.sport_id = sport_id
|
||||
self.activity_date = activity_date
|
||||
self.distance = distance
|
||||
self.duration = duration
|
||||
|
||||
def serialize(self):
|
||||
|
@ -16,11 +16,14 @@ def create_activity(
|
||||
activity_data.get('activity_date'), '%Y-%m-%d %H:%M')
|
||||
duration = timedelta(seconds=gpx_data['duration']) if gpx_data \
|
||||
else timedelta(seconds=activity_data.get('duration'))
|
||||
distance = gpx_data['distance'] if gpx_data \
|
||||
else activity_data.get('distance')
|
||||
|
||||
new_activity = Activity(
|
||||
user_id=auth_user_id,
|
||||
sport_id=activity_data.get('sport_id'),
|
||||
activity_date=activity_date,
|
||||
distance=distance,
|
||||
duration=duration
|
||||
)
|
||||
|
||||
@ -28,7 +31,6 @@ def create_activity(
|
||||
new_activity.gpx = gpx_data['filename']
|
||||
new_activity.pauses = timedelta(seconds=gpx_data['stop_time'])
|
||||
new_activity.moving = timedelta(seconds=gpx_data['moving_time'])
|
||||
new_activity.distance = gpx_data['distance']
|
||||
new_activity.min_alt = gpx_data['elevation_min']
|
||||
new_activity.max_alt = gpx_data['elevation_max']
|
||||
new_activity.descent = gpx_data['downhill']
|
||||
@ -37,19 +39,22 @@ def create_activity(
|
||||
new_activity.ave_speed = gpx_data['average_speed']
|
||||
else:
|
||||
new_activity.moving = duration
|
||||
new_activity.distance = activity_data.get('distance')
|
||||
new_activity.ave_speed = new_activity.distance / (
|
||||
duration.seconds / 3600)
|
||||
new_activity.max_speed = new_activity.ave_speed
|
||||
return new_activity
|
||||
|
||||
|
||||
def edit_activity_wo_gpx(activity, activity_data):
|
||||
def edit_activity(activity, activity_data):
|
||||
activity.sport_id = activity_data.get('sport_id')
|
||||
if not activity.gpx:
|
||||
if activity_data.get('activity_date'):
|
||||
activity.activity_date = datetime.strptime(
|
||||
activity_data.get('activity_date'), '%Y-%m-%d %H:%M')
|
||||
activity.duration = timedelta(seconds=activity_data.get('duration'))
|
||||
if activity_data.get('duration'):
|
||||
activity.duration = timedelta(seconds=activity_data.get('duration')) # noqa
|
||||
activity.moving = activity.duration
|
||||
if activity_data.get('distance'):
|
||||
activity.distance = activity_data.get('distance')
|
||||
activity.ave_speed = activity.distance / (
|
||||
activity.duration.seconds / 3600)
|
||||
@ -121,7 +126,7 @@ def get_file_path(auth_user_id, activity_file):
|
||||
def get_new_file_path(auth_user_id, activity_date, activity_file, sport):
|
||||
old_filename = secure_filename(activity_file.filename)
|
||||
extension = '.{}'.format(old_filename.rsplit('.', 1)[1].lower())
|
||||
fi, new_filename = tempfile.mkstemp(
|
||||
_, new_filename = tempfile.mkstemp(
|
||||
prefix='{}_{}_'.format(activity_date, sport),
|
||||
suffix=extension
|
||||
)
|
||||
@ -129,5 +134,5 @@ def get_new_file_path(auth_user_id, activity_date, activity_file, sport):
|
||||
current_app.config['UPLOAD_FOLDER'], 'activities', str(auth_user_id))
|
||||
if not os.path.exists(dir_path):
|
||||
os.makedirs(dir_path)
|
||||
file_path = os.path.join(dir_path, new_filename.replace('/tmp/', ''))
|
||||
file_path = os.path.join(dir_path, new_filename.replace('/tmp/', '')) # noqa
|
||||
return file_path
|
||||
|
@ -1,977 +0,0 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
from io import BytesIO
|
||||
|
||||
from mpwo_api.tests.utils import (
|
||||
add_activity, add_sport, add_user, get_gpx_filepath
|
||||
)
|
||||
from mpwo_api.tests.utils_gpx import gpx_file
|
||||
|
||||
|
||||
def test_get_all_activities_for_authenticated_user(app):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_user('toto', 'toto@toto.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_sport('running')
|
||||
add_activity(
|
||||
1,
|
||||
2,
|
||||
datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=1024))
|
||||
add_activity(
|
||||
2,
|
||||
1,
|
||||
datetime.datetime.strptime('23/01/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=3600))
|
||||
add_activity(
|
||||
1,
|
||||
1,
|
||||
datetime.datetime.strptime('01/04/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=6000))
|
||||
|
||||
client = 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'] # noqa
|
||||
assert 1 == data['data']['activities'][0]['user_id']
|
||||
assert 1 == data['data']['activities'][0]['sport_id']
|
||||
assert '1:40:00' == data['data']['activities'][0]['duration']
|
||||
assert data['data']['activities'][0]['with_gpx'] is False
|
||||
|
||||
assert 'creation_date' in data['data']['activities'][1]
|
||||
assert 'Mon, 01 Jan 2018 00:00:00 GMT' == data['data']['activities'][1]['activity_date'] # noqa
|
||||
assert 1 == data['data']['activities'][1]['user_id']
|
||||
assert 2 == data['data']['activities'][1]['sport_id']
|
||||
assert '0:17:04' == data['data']['activities'][1]['duration']
|
||||
assert data['data']['activities'][1]['with_gpx'] is False
|
||||
|
||||
|
||||
def test_get_activities_for_authenticated_user_no_activity(app):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_user('toto', 'toto@toto.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_sport('running')
|
||||
add_activity(
|
||||
1,
|
||||
2,
|
||||
datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=1024))
|
||||
add_activity(
|
||||
1,
|
||||
1,
|
||||
datetime.datetime.strptime('01/04/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=6000))
|
||||
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(
|
||||
email='toto@toto.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']) == 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 == 403
|
||||
assert 'error' in data['status']
|
||||
assert 'Provide a valid auth token.' in data['message']
|
||||
|
||||
|
||||
def test_get_activities_pagination(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))
|
||||
add_activity(
|
||||
1,
|
||||
1,
|
||||
datetime.datetime.strptime('01/04/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=6000))
|
||||
add_activity(
|
||||
1,
|
||||
1,
|
||||
datetime.datetime.strptime('20/03/2017', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=1024))
|
||||
add_activity(
|
||||
1,
|
||||
1,
|
||||
datetime.datetime.strptime('09/05/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=3000))
|
||||
add_activity(
|
||||
1,
|
||||
1,
|
||||
datetime.datetime.strptime('01/06/2017', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=3456))
|
||||
add_activity(
|
||||
1,
|
||||
1,
|
||||
datetime.datetime.strptime('23/02/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=600))
|
||||
add_activity(
|
||||
1,
|
||||
1,
|
||||
datetime.datetime.strptime('23/02/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=1000))
|
||||
|
||||
client = 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'] # noqa
|
||||
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'] # noqa
|
||||
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'] # noqa
|
||||
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'] # noqa
|
||||
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'] # noqa
|
||||
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'] # noqa
|
||||
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_add_an_activity_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'
|
||||
)
|
||||
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 'creation_date' in data['data']['activities'][0]
|
||||
assert 'Tue, 13 Mar 2018 12:44:45 GMT' == data['data']['activities'][0]['activity_date'] # noqa
|
||||
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 data['data']['activities'][0]['ascent'] == 0.4
|
||||
assert data['data']['activities'][0]['ave_speed'] == 4.6
|
||||
assert data['data']['activities'][0]['descent'] == 23.4
|
||||
assert data['data']['activities'][0]['distance'] == 0.32
|
||||
assert data['data']['activities'][0]['max_alt'] == 998.0
|
||||
assert data['data']['activities'][0]['max_speed'] == 5.09
|
||||
assert data['data']['activities'][0]['min_alt'] == 975.0
|
||||
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_add_an_activity_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'
|
||||
)
|
||||
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):
|
||||
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'
|
||||
)
|
||||
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_no_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'
|
||||
)
|
||||
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):
|
||||
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'
|
||||
)
|
||||
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 'creation_date' in data['data']['activities'][0]
|
||||
assert data['data']['activities'][0]['activity_date'] == 'Tue, 15 May 2018 14:05:00 GMT' # noqa
|
||||
assert data['data']['activities'][0]['user_id'] == 1
|
||||
assert data['data']['activities'][0]['sport_id'] == 1
|
||||
assert data['data']['activities'][0]['duration'] == '1:00:00'
|
||||
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
|
||||
|
||||
|
||||
def test_add_an_activity_no_gpx_invalid_payload(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'
|
||||
)
|
||||
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):
|
||||
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'
|
||||
)
|
||||
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_get_an_activity_without_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.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'] # noqa
|
||||
assert 1 == data['data']['activities'][0]['user_id']
|
||||
assert 1 == data['data']['activities'][0]['sport_id']
|
||||
assert '0:17:04' == data['data']['activities'][0]['duration']
|
||||
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
|
||||
|
||||
|
||||
def test_get_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.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 'Tue, 13 Mar 2018 12:44:45 GMT' == data['data']['activities'][0]['activity_date'] # noqa
|
||||
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 data['data']['activities'][0]['ascent'] == 0.4
|
||||
assert data['data']['activities'][0]['ave_speed'] == 4.6
|
||||
assert data['data']['activities'][0]['descent'] == 23.4
|
||||
assert data['data']['activities'][0]['distance'] == 0.32
|
||||
assert data['data']['activities'][0]['max_alt'] == 998.0
|
||||
assert data['data']['activities'][0]['max_speed'] == 5.09
|
||||
assert data['data']['activities'][0]['min_alt'] == 975.0
|
||||
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_edit_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.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 == 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 14:05:00 GMT' # noqa
|
||||
assert data['data']['activities'][0]['user_id'] == 1
|
||||
assert data['data']['activities'][0]['sport_id'] == 1
|
||||
assert data['data']['activities'][0]['duration'] == '1:00:00'
|
||||
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
|
||||
|
||||
|
||||
def test_edit_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.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 == 500
|
||||
assert 'error' in data['status']
|
||||
assert ('You can not modify an activity with gpx file. '
|
||||
'Please delete and re-import the gpx file.') in data['message']
|
||||
|
||||
|
||||
def test_edit_an_activity_wo_gpx_invalid_payload(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.patch(
|
||||
'/api/activities/1',
|
||||
content_type='application/json',
|
||||
data=json.dumps(dict(
|
||||
sport_id=1,
|
||||
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 == 400
|
||||
assert 'error' in data['status']
|
||||
assert 'Invalid payload.' in data['message']
|
||||
|
||||
|
||||
def test_edit_an_activity_wo_gpx_incorrect_data(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.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):
|
||||
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'
|
||||
)
|
||||
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_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']
|
260
mpwo_api/mpwo_api/tests/test_activities_0_get.py
Normal file
260
mpwo_api/mpwo_api/tests/test_activities_0_get.py
Normal file
@ -0,0 +1,260 @@
|
||||
import datetime
|
||||
import json
|
||||
|
||||
from mpwo_api.tests.utils import add_activity, add_sport, add_user
|
||||
|
||||
|
||||
def test_get_all_activities_for_authenticated_user(app):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_user('toto', 'toto@toto.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_sport('running')
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=2,
|
||||
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=1024)
|
||||
)
|
||||
add_activity(
|
||||
user_id=2,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('23/01/2018', '%d/%m/%Y'),
|
||||
distance=15,
|
||||
duration=datetime.timedelta(seconds=3600),
|
||||
)
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/04/2018', '%d/%m/%Y'),
|
||||
distance=12,
|
||||
duration=datetime.timedelta(seconds=6000)
|
||||
)
|
||||
|
||||
client = 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'] # noqa
|
||||
assert 1 == data['data']['activities'][0]['user_id']
|
||||
assert 1 == 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'] # noqa
|
||||
assert 1 == data['data']['activities'][1]['user_id']
|
||||
assert 2 == 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):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_user('toto', 'toto@toto.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_sport('running')
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=2,
|
||||
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=1024)
|
||||
)
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/04/2018', '%d/%m/%Y'),
|
||||
distance=12,
|
||||
duration=datetime.timedelta(seconds=6000)
|
||||
)
|
||||
|
||||
client = app.test_client()
|
||||
resp_login = client.post(
|
||||
'/api/auth/login',
|
||||
data=json.dumps(dict(
|
||||
email='toto@toto.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']) == 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 == 403
|
||||
assert 'error' in data['status']
|
||||
assert 'Provide a valid auth token.' in data['message']
|
||||
|
||||
|
||||
def test_get_activities_pagination(app):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=1024)
|
||||
)
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/04/2018', '%d/%m/%Y'),
|
||||
distance=8,
|
||||
duration=datetime.timedelta(seconds=6000)
|
||||
)
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('20/03/2017', '%d/%m/%Y'),
|
||||
distance=5,
|
||||
duration=datetime.timedelta(seconds=1024)
|
||||
)
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('09/05/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=3000)
|
||||
)
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/06/2017', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=3456)
|
||||
)
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('23/02/2018', '%d/%m/%Y'),
|
||||
distance=1,
|
||||
duration=datetime.timedelta(seconds=600)
|
||||
)
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('23/02/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=1000)
|
||||
)
|
||||
|
||||
client = 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'] # noqa
|
||||
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'] # noqa
|
||||
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'] # noqa
|
||||
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'] # noqa
|
||||
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'] # noqa
|
||||
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'] # noqa
|
||||
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
|
419
mpwo_api/mpwo_api/tests/test_activities_1_post.py
Normal file
419
mpwo_api/mpwo_api/tests/test_activities_1_post.py
Normal file
@ -0,0 +1,419 @@
|
||||
import json
|
||||
from io import BytesIO
|
||||
|
||||
from mpwo_api.tests.utils import add_sport, add_user
|
||||
from mpwo_api.tests.utils_gpx import gpx_file
|
||||
|
||||
|
||||
def test_add_an_activity_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'
|
||||
)
|
||||
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 'creation_date' in data['data']['activities'][0]
|
||||
assert 'Tue, 13 Mar 2018 12:44:45 GMT' == data['data']['activities'][0]['activity_date'] # noqa
|
||||
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 data['data']['activities'][0]['ascent'] == 0.4
|
||||
assert data['data']['activities'][0]['ave_speed'] == 4.6
|
||||
assert data['data']['activities'][0]['descent'] == 23.4
|
||||
assert data['data']['activities'][0]['distance'] == 0.32
|
||||
assert data['data']['activities'][0]['max_alt'] == 998.0
|
||||
assert data['data']['activities'][0]['max_speed'] == 5.09
|
||||
assert data['data']['activities'][0]['min_alt'] == 975.0
|
||||
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_get_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.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 'Tue, 13 Mar 2018 12:44:45 GMT' == data['data']['activities'][0]['activity_date'] # noqa
|
||||
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 data['data']['activities'][0]['ascent'] == 0.4
|
||||
assert data['data']['activities'][0]['ave_speed'] == 4.6
|
||||
assert data['data']['activities'][0]['descent'] == 23.4
|
||||
assert data['data']['activities'][0]['distance'] == 0.32
|
||||
assert data['data']['activities'][0]['max_alt'] == 998.0
|
||||
assert data['data']['activities'][0]['max_speed'] == 5.09
|
||||
assert data['data']['activities'][0]['min_alt'] == 975.0
|
||||
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_add_an_activity_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'
|
||||
)
|
||||
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):
|
||||
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'
|
||||
)
|
||||
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):
|
||||
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'
|
||||
)
|
||||
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'] == \
|
||||
'Error during activity file save.'
|
||||
|
||||
|
||||
def test_add_an_activity_gpx_no_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'
|
||||
)
|
||||
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):
|
||||
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'
|
||||
)
|
||||
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 'creation_date' in data['data']['activities'][0]
|
||||
assert data['data']['activities'][0]['activity_date'] == 'Tue, 15 May 2018 14:05:00 GMT' # noqa
|
||||
assert data['data']['activities'][0]['user_id'] == 1
|
||||
assert data['data']['activities'][0]['sport_id'] == 1
|
||||
assert data['data']['activities'][0]['duration'] == '1:00:00'
|
||||
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
|
||||
|
||||
|
||||
def test_get_an_activity_wo_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/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 'creation_date' in data['data']['activities'][0]
|
||||
assert data['data']['activities'][0]['activity_date'] == 'Tue, 15 May 2018 14:05:00 GMT' # noqa
|
||||
assert data['data']['activities'][0]['user_id'] == 1
|
||||
assert data['data']['activities'][0]['sport_id'] == 1
|
||||
assert data['data']['activities'][0]['duration'] == '1:00:00'
|
||||
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
|
||||
|
||||
|
||||
def test_add_an_activity_no_gpx_invalid_payload(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'
|
||||
)
|
||||
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):
|
||||
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'
|
||||
)
|
||||
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']
|
392
mpwo_api/mpwo_api/tests/test_activities_2_patch.py
Normal file
392
mpwo_api/mpwo_api/tests/test_activities_2_patch.py
Normal file
@ -0,0 +1,392 @@
|
||||
import datetime
|
||||
import json
|
||||
from io import BytesIO
|
||||
|
||||
from mpwo_api.tests.utils import add_activity, add_sport, add_user
|
||||
from mpwo_api.tests.utils_gpx import gpx_file
|
||||
|
||||
|
||||
def test_edit_an_activity_with_gpx(app):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_sport('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',
|
||||
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 'creation_date' in data['data']['activities'][0]
|
||||
assert 'Tue, 13 Mar 2018 12:44:45 GMT' == data['data']['activities'][0]['activity_date'] # noqa
|
||||
assert 1 == data['data']['activities'][0]['user_id']
|
||||
assert 2 == data['data']['activities'][0]['sport_id']
|
||||
assert '0:04:10' == data['data']['activities'][0]['duration']
|
||||
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
|
||||
assert data['data']['activities'][0]['distance'] == 0.32
|
||||
assert data['data']['activities'][0]['max_alt'] == 998.0
|
||||
assert data['data']['activities'][0]['max_speed'] == 5.09
|
||||
assert data['data']['activities'][0]['min_alt'] == 975.0
|
||||
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_edit_an_activity_with_gpx_invalid_payload(app):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_sport('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',
|
||||
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):
|
||||
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.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):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=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.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 == 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 14:05:00 GMT' # noqa
|
||||
assert data['data']['activities'][0]['user_id'] == 1
|
||||
assert data['data']['activities'][0]['sport_id'] == 1
|
||||
assert data['data']['activities'][0]['duration'] == '1:00:00'
|
||||
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
|
||||
|
||||
|
||||
def test_edit_an_activity_wo_gpx_partial(app):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=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.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, 01 Jan 2018 00:00:00 GMT' # noqa
|
||||
assert data['data']['activities'][0]['user_id'] == 1
|
||||
assert data['data']['activities'][0]['sport_id'] == 1
|
||||
assert data['data']['activities'][0]['duration'] == '0:17:04'
|
||||
assert data['data']['activities'][0]['ascent'] is None
|
||||
assert data['data']['activities'][0]['ave_speed'] == 35.16
|
||||
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'] == 35.16
|
||||
assert data['data']['activities'][0]['min_alt'] is None
|
||||
assert data['data']['activities'][0]['moving'] is None # no calculate
|
||||
assert data['data']['activities'][0]['pauses'] is None
|
||||
assert data['data']['activities'][0]['with_gpx'] is False
|
||||
|
||||
|
||||
def test_edit_an_activity_wo_gpx_invalid_payload(app):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=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.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):
|
||||
add_user('test', 'test@test.com', '12345678')
|
||||
add_sport('cycling')
|
||||
add_activity(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=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.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):
|
||||
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'
|
||||
)
|
||||
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
|
153
mpwo_api/mpwo_api/tests/test_activities_3_delete.py
Normal file
153
mpwo_api/mpwo_api/tests/test_activities_3_delete.py
Normal file
@ -0,0 +1,153 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
from io import BytesIO
|
||||
|
||||
from mpwo_api.tests.utils import (
|
||||
add_activity, add_sport, add_user, get_gpx_filepath
|
||||
)
|
||||
from mpwo_api.tests.utils_gpx import gpx_file
|
||||
|
||||
|
||||
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(
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=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']
|
@ -256,10 +256,11 @@ def test_delete_a_sport_with_an_activity(app):
|
||||
add_admin()
|
||||
add_sport('cycling')
|
||||
add_activity(
|
||||
1,
|
||||
1,
|
||||
datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
datetime.timedelta(seconds=1024)
|
||||
user_id=1,
|
||||
sport_id=1,
|
||||
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||
distance=10,
|
||||
duration=datetime.timedelta(seconds=1024)
|
||||
)
|
||||
|
||||
client = app.test_client()
|
||||
|
@ -43,11 +43,12 @@ def add_sport(label):
|
||||
return sport
|
||||
|
||||
|
||||
def add_activity(user_id, sport_id, activity_date, duration):
|
||||
def add_activity(user_id, sport_id, activity_date, distance, duration):
|
||||
activity = Activity(
|
||||
user_id=user_id,
|
||||
sport_id=sport_id,
|
||||
activity_date=activity_date,
|
||||
distance=distance,
|
||||
duration=duration)
|
||||
db.session.add(activity)
|
||||
db.session.commit()
|
||||
|
@ -1,3 +1,5 @@
|
||||
import shutil
|
||||
|
||||
from mpwo_api import create_app, db
|
||||
from mpwo_api.activities.models import Sport
|
||||
from mpwo_api.users.models import User
|
||||
@ -12,6 +14,8 @@ def drop_db():
|
||||
db.drop_all()
|
||||
db.session.commit()
|
||||
print('Database dropped.')
|
||||
shutil.rmtree(app.config['UPLOAD_FOLDER'], ignore_errors=True)
|
||||
print('Uploaded files deleted.')
|
||||
|
||||
|
||||
@app.cli.command()
|
||||
|
@ -46,13 +46,9 @@ export default class ActivityAddEdit extends React.Component {
|
||||
<div className="card-body">
|
||||
{activity ? (
|
||||
activity.with_gpx ? (
|
||||
'You can\'t modify this activity.' +
|
||||
' Please delete and re-import gpx file.'
|
||||
<FormWithGpx activity={activity} sports={sports} />
|
||||
) : (
|
||||
<FormWithoutGpx
|
||||
activity={activity}
|
||||
sports={sports}
|
||||
/>
|
||||
<FormWithoutGpx activity={activity} sports={sports} />
|
||||
)
|
||||
) : (
|
||||
<div>
|
||||
|
@ -54,14 +54,12 @@ class ActivityDisplay extends React.Component {
|
||||
{sports.filter(sport => sport.id === activity.sport_id)
|
||||
.map(sport => sport.label)} -{' '}
|
||||
{activity.activity_date}{' '}
|
||||
{!activity.with_gpx && (
|
||||
<Link
|
||||
className="unlink"
|
||||
to={`/activities/${activity.id}/edit`}
|
||||
>
|
||||
<i className="fa fa-edit custom-fa" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
<i
|
||||
className="fa fa-trash custom-fa"
|
||||
aria-hidden="true"
|
||||
|
@ -1,12 +1,13 @@
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { addActivity } from '../../../actions/activities'
|
||||
import { addActivity, editActivity } from '../../../actions/activities'
|
||||
import { history } from '../../../index'
|
||||
|
||||
|
||||
function FormWithGpx (props) {
|
||||
const { onAddSport, sports } = props
|
||||
const { activity, onAddActivity, onEditActivity, sports } = props
|
||||
const sportId = activity ? activity.sport_id : ''
|
||||
return (
|
||||
<form
|
||||
encType="multipart/form-data"
|
||||
@ -18,6 +19,7 @@ function FormWithGpx (props) {
|
||||
Sport:
|
||||
<select
|
||||
className="form-control input-lg"
|
||||
defaultValue={sportId}
|
||||
name="sport"
|
||||
required
|
||||
>
|
||||
@ -30,6 +32,7 @@ function FormWithGpx (props) {
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
{!activity && (
|
||||
<div className="form-group">
|
||||
<label>
|
||||
GPX file:
|
||||
@ -42,10 +45,15 @@ function FormWithGpx (props) {
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
type="submit"
|
||||
className="btn btn-primary btn-lg btn-block"
|
||||
onClick={event => onAddSport(event)}
|
||||
onClick={
|
||||
event => activity
|
||||
? onEditActivity(event, activity)
|
||||
: onAddActivity(event)
|
||||
}
|
||||
value="Submit"
|
||||
/>
|
||||
<input
|
||||
@ -61,13 +69,19 @@ function FormWithGpx (props) {
|
||||
export default connect(
|
||||
() => ({ }),
|
||||
dispatch => ({
|
||||
onAddSport: event => {
|
||||
onAddActivity: e => {
|
||||
const form = new FormData()
|
||||
form.append('file', event.target.form.gpxFile.files[0])
|
||||
form.append('file', e.target.form.gpxFile.files[0])
|
||||
form.append(
|
||||
'data', `{"sport_id": ${event.target.form.sport.value}}`
|
||||
'data', `{"sport_id": ${e.target.form.sport.value}}`
|
||||
)
|
||||
dispatch(addActivity(form))
|
||||
},
|
||||
onEditActivity: (e, activity) => {
|
||||
dispatch(editActivity({
|
||||
id: activity.id,
|
||||
sport_id: +e.target.form.sport.value
|
||||
}))
|
||||
},
|
||||
})
|
||||
)(FormWithGpx)
|
||||
|
Loading…
Reference in New Issue
Block a user