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 ..users.utils import authenticate, verify_extension
|
||||||
from .models import Activity, Sport
|
from .models import Activity, Sport
|
||||||
from .utils import (
|
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
|
get_new_file_path
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -225,10 +225,7 @@ def post_activity_no_gpx(auth_user_id):
|
|||||||
def update_activity(auth_user_id, activity_id):
|
def update_activity(auth_user_id, activity_id):
|
||||||
"""Update an activity"""
|
"""Update an activity"""
|
||||||
activity_data = request.get_json()
|
activity_data = request.get_json()
|
||||||
if not activity_data or activity_data.get('sport_id') is None \
|
if not activity_data:
|
||||||
or activity_data.get('duration') is None \
|
|
||||||
or activity_data.get('distance') is None \
|
|
||||||
or activity_data.get('activity_date') is None:
|
|
||||||
response_object = {
|
response_object = {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'message': 'Invalid payload.'
|
'message': 'Invalid payload.'
|
||||||
@ -238,16 +235,7 @@ def update_activity(auth_user_id, activity_id):
|
|||||||
try:
|
try:
|
||||||
activity = Activity.query.filter_by(id=activity_id).first()
|
activity = Activity.query.filter_by(id=activity_id).first()
|
||||||
if activity:
|
if activity:
|
||||||
if activity.gpx:
|
activity = edit_activity(activity, activity_data)
|
||||||
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)
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
response_object = {
|
response_object = {
|
||||||
'status': 'success',
|
'status': 'success',
|
||||||
|
@ -60,10 +60,11 @@ class Activity(db.Model):
|
|||||||
return str(self.sports.label) + \
|
return str(self.sports.label) + \
|
||||||
" - " + self.activity_date.strftime('%Y-%m-%d')
|
" - " + 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.user_id = user_id
|
||||||
self.sport_id = sport_id
|
self.sport_id = sport_id
|
||||||
self.activity_date = activity_date
|
self.activity_date = activity_date
|
||||||
|
self.distance = distance
|
||||||
self.duration = duration
|
self.duration = duration
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
|
@ -16,11 +16,14 @@ def create_activity(
|
|||||||
activity_data.get('activity_date'), '%Y-%m-%d %H:%M')
|
activity_data.get('activity_date'), '%Y-%m-%d %H:%M')
|
||||||
duration = timedelta(seconds=gpx_data['duration']) if gpx_data \
|
duration = timedelta(seconds=gpx_data['duration']) if gpx_data \
|
||||||
else timedelta(seconds=activity_data.get('duration'))
|
else timedelta(seconds=activity_data.get('duration'))
|
||||||
|
distance = gpx_data['distance'] if gpx_data \
|
||||||
|
else activity_data.get('distance')
|
||||||
|
|
||||||
new_activity = Activity(
|
new_activity = Activity(
|
||||||
user_id=auth_user_id,
|
user_id=auth_user_id,
|
||||||
sport_id=activity_data.get('sport_id'),
|
sport_id=activity_data.get('sport_id'),
|
||||||
activity_date=activity_date,
|
activity_date=activity_date,
|
||||||
|
distance=distance,
|
||||||
duration=duration
|
duration=duration
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,7 +31,6 @@ def create_activity(
|
|||||||
new_activity.gpx = gpx_data['filename']
|
new_activity.gpx = gpx_data['filename']
|
||||||
new_activity.pauses = timedelta(seconds=gpx_data['stop_time'])
|
new_activity.pauses = timedelta(seconds=gpx_data['stop_time'])
|
||||||
new_activity.moving = timedelta(seconds=gpx_data['moving_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.min_alt = gpx_data['elevation_min']
|
||||||
new_activity.max_alt = gpx_data['elevation_max']
|
new_activity.max_alt = gpx_data['elevation_max']
|
||||||
new_activity.descent = gpx_data['downhill']
|
new_activity.descent = gpx_data['downhill']
|
||||||
@ -37,19 +39,22 @@ def create_activity(
|
|||||||
new_activity.ave_speed = gpx_data['average_speed']
|
new_activity.ave_speed = gpx_data['average_speed']
|
||||||
else:
|
else:
|
||||||
new_activity.moving = duration
|
new_activity.moving = duration
|
||||||
new_activity.distance = activity_data.get('distance')
|
|
||||||
new_activity.ave_speed = new_activity.distance / (
|
new_activity.ave_speed = new_activity.distance / (
|
||||||
duration.seconds / 3600)
|
duration.seconds / 3600)
|
||||||
new_activity.max_speed = new_activity.ave_speed
|
new_activity.max_speed = new_activity.ave_speed
|
||||||
return new_activity
|
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')
|
activity.sport_id = activity_data.get('sport_id')
|
||||||
|
if not activity.gpx:
|
||||||
|
if activity_data.get('activity_date'):
|
||||||
activity.activity_date = datetime.strptime(
|
activity.activity_date = datetime.strptime(
|
||||||
activity_data.get('activity_date'), '%Y-%m-%d %H:%M')
|
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
|
activity.moving = activity.duration
|
||||||
|
if activity_data.get('distance'):
|
||||||
activity.distance = activity_data.get('distance')
|
activity.distance = activity_data.get('distance')
|
||||||
activity.ave_speed = activity.distance / (
|
activity.ave_speed = activity.distance / (
|
||||||
activity.duration.seconds / 3600)
|
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):
|
def get_new_file_path(auth_user_id, activity_date, activity_file, sport):
|
||||||
old_filename = secure_filename(activity_file.filename)
|
old_filename = secure_filename(activity_file.filename)
|
||||||
extension = '.{}'.format(old_filename.rsplit('.', 1)[1].lower())
|
extension = '.{}'.format(old_filename.rsplit('.', 1)[1].lower())
|
||||||
fi, new_filename = tempfile.mkstemp(
|
_, new_filename = tempfile.mkstemp(
|
||||||
prefix='{}_{}_'.format(activity_date, sport),
|
prefix='{}_{}_'.format(activity_date, sport),
|
||||||
suffix=extension
|
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))
|
current_app.config['UPLOAD_FOLDER'], 'activities', str(auth_user_id))
|
||||||
if not os.path.exists(dir_path):
|
if not os.path.exists(dir_path):
|
||||||
os.makedirs(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
|
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_admin()
|
||||||
add_sport('cycling')
|
add_sport('cycling')
|
||||||
add_activity(
|
add_activity(
|
||||||
1,
|
user_id=1,
|
||||||
1,
|
sport_id=1,
|
||||||
datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'),
|
||||||
datetime.timedelta(seconds=1024)
|
distance=10,
|
||||||
|
duration=datetime.timedelta(seconds=1024)
|
||||||
)
|
)
|
||||||
|
|
||||||
client = app.test_client()
|
client = app.test_client()
|
||||||
|
@ -43,11 +43,12 @@ def add_sport(label):
|
|||||||
return sport
|
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(
|
activity = Activity(
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
sport_id=sport_id,
|
sport_id=sport_id,
|
||||||
activity_date=activity_date,
|
activity_date=activity_date,
|
||||||
|
distance=distance,
|
||||||
duration=duration)
|
duration=duration)
|
||||||
db.session.add(activity)
|
db.session.add(activity)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import shutil
|
||||||
|
|
||||||
from mpwo_api import create_app, db
|
from mpwo_api import create_app, db
|
||||||
from mpwo_api.activities.models import Sport
|
from mpwo_api.activities.models import Sport
|
||||||
from mpwo_api.users.models import User
|
from mpwo_api.users.models import User
|
||||||
@ -12,6 +14,8 @@ def drop_db():
|
|||||||
db.drop_all()
|
db.drop_all()
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
print('Database dropped.')
|
print('Database dropped.')
|
||||||
|
shutil.rmtree(app.config['UPLOAD_FOLDER'], ignore_errors=True)
|
||||||
|
print('Uploaded files deleted.')
|
||||||
|
|
||||||
|
|
||||||
@app.cli.command()
|
@app.cli.command()
|
||||||
|
@ -46,13 +46,9 @@ export default class ActivityAddEdit extends React.Component {
|
|||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
{activity ? (
|
{activity ? (
|
||||||
activity.with_gpx ? (
|
activity.with_gpx ? (
|
||||||
'You can\'t modify this activity.' +
|
<FormWithGpx activity={activity} sports={sports} />
|
||||||
' Please delete and re-import gpx file.'
|
|
||||||
) : (
|
) : (
|
||||||
<FormWithoutGpx
|
<FormWithoutGpx activity={activity} sports={sports} />
|
||||||
activity={activity}
|
|
||||||
sports={sports}
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
|
@ -54,14 +54,12 @@ class ActivityDisplay extends React.Component {
|
|||||||
{sports.filter(sport => sport.id === activity.sport_id)
|
{sports.filter(sport => sport.id === activity.sport_id)
|
||||||
.map(sport => sport.label)} -{' '}
|
.map(sport => sport.label)} -{' '}
|
||||||
{activity.activity_date}{' '}
|
{activity.activity_date}{' '}
|
||||||
{!activity.with_gpx && (
|
|
||||||
<Link
|
<Link
|
||||||
className="unlink"
|
className="unlink"
|
||||||
to={`/activities/${activity.id}/edit`}
|
to={`/activities/${activity.id}/edit`}
|
||||||
>
|
>
|
||||||
<i className="fa fa-edit custom-fa" aria-hidden="true" />
|
<i className="fa fa-edit custom-fa" aria-hidden="true" />
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
|
||||||
<i
|
<i
|
||||||
className="fa fa-trash custom-fa"
|
className="fa fa-trash custom-fa"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
import { addActivity } from '../../../actions/activities'
|
import { addActivity, editActivity } from '../../../actions/activities'
|
||||||
import { history } from '../../../index'
|
import { history } from '../../../index'
|
||||||
|
|
||||||
|
|
||||||
function FormWithGpx (props) {
|
function FormWithGpx (props) {
|
||||||
const { onAddSport, sports } = props
|
const { activity, onAddActivity, onEditActivity, sports } = props
|
||||||
|
const sportId = activity ? activity.sport_id : ''
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
encType="multipart/form-data"
|
encType="multipart/form-data"
|
||||||
@ -18,6 +19,7 @@ function FormWithGpx (props) {
|
|||||||
Sport:
|
Sport:
|
||||||
<select
|
<select
|
||||||
className="form-control input-lg"
|
className="form-control input-lg"
|
||||||
|
defaultValue={sportId}
|
||||||
name="sport"
|
name="sport"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
@ -30,6 +32,7 @@ function FormWithGpx (props) {
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
{!activity && (
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>
|
<label>
|
||||||
GPX file:
|
GPX file:
|
||||||
@ -42,10 +45,15 @@ function FormWithGpx (props) {
|
|||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
<input
|
<input
|
||||||
type="submit"
|
type="submit"
|
||||||
className="btn btn-primary btn-lg btn-block"
|
className="btn btn-primary btn-lg btn-block"
|
||||||
onClick={event => onAddSport(event)}
|
onClick={
|
||||||
|
event => activity
|
||||||
|
? onEditActivity(event, activity)
|
||||||
|
: onAddActivity(event)
|
||||||
|
}
|
||||||
value="Submit"
|
value="Submit"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
@ -61,13 +69,19 @@ function FormWithGpx (props) {
|
|||||||
export default connect(
|
export default connect(
|
||||||
() => ({ }),
|
() => ({ }),
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
onAddSport: event => {
|
onAddActivity: e => {
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
form.append('file', event.target.form.gpxFile.files[0])
|
form.append('file', e.target.form.gpxFile.files[0])
|
||||||
form.append(
|
form.append(
|
||||||
'data', `{"sport_id": ${event.target.form.sport.value}}`
|
'data', `{"sport_id": ${e.target.form.sport.value}}`
|
||||||
)
|
)
|
||||||
dispatch(addActivity(form))
|
dispatch(addActivity(form))
|
||||||
},
|
},
|
||||||
|
onEditActivity: (e, activity) => {
|
||||||
|
dispatch(editActivity({
|
||||||
|
id: activity.id,
|
||||||
|
sport_id: +e.target.form.sport.value
|
||||||
|
}))
|
||||||
|
},
|
||||||
})
|
})
|
||||||
)(FormWithGpx)
|
)(FormWithGpx)
|
||||||
|
Loading…
Reference in New Issue
Block a user