API: add an activity w/o gpx file
This commit is contained in:
parent
4d36a047d9
commit
9b1335233d
@ -1,6 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from datetime import timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from flask import Blueprint, current_app, jsonify, request
|
from flask import Blueprint, current_app, jsonify, request
|
||||||
from mpwo_api import appLog, db
|
from mpwo_api import appLog, db
|
||||||
@ -185,3 +185,52 @@ def post_activity(auth_user_id):
|
|||||||
'message': 'Error during activity save.'
|
'message': 'Error during activity save.'
|
||||||
}
|
}
|
||||||
return jsonify(response_object), 500
|
return jsonify(response_object), 500
|
||||||
|
|
||||||
|
|
||||||
|
@activities_blueprint.route('/activities/no_gpx', methods=['POST'])
|
||||||
|
@authenticate
|
||||||
|
def post_activity_no_gpx(auth_user_id):
|
||||||
|
"""Post an activity without gpx file"""
|
||||||
|
activity_data = request.get_json()
|
||||||
|
if not activity_data or activity_data.get('sport_id') is None \
|
||||||
|
or activity_data.get('duration') is None \
|
||||||
|
or activity_data.get('distance') is None \
|
||||||
|
or activity_data.get('activity_date') is None:
|
||||||
|
response_object = {
|
||||||
|
'status': 'error',
|
||||||
|
'message': 'Invalid payload.'
|
||||||
|
}
|
||||||
|
return jsonify(response_object), 400
|
||||||
|
|
||||||
|
try:
|
||||||
|
new_activity = Activity(
|
||||||
|
user_id=auth_user_id,
|
||||||
|
sport_id=activity_data.get('sport_id'),
|
||||||
|
activity_date=datetime.strptime(
|
||||||
|
activity_data.get('activity_date'), '%d/%m/%Y'),
|
||||||
|
duration=timedelta(seconds=activity_data.get('duration'))
|
||||||
|
)
|
||||||
|
new_activity.moving = new_activity.duration
|
||||||
|
new_activity.distance = activity_data.get('distance')
|
||||||
|
new_activity.ave_speed = new_activity.distance / (
|
||||||
|
new_activity.duration.seconds / 3600)
|
||||||
|
new_activity.max_speed = new_activity.ave_speed
|
||||||
|
db.session.add(new_activity)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
response_object = {
|
||||||
|
'status': 'created',
|
||||||
|
'data': {
|
||||||
|
'activities': [new_activity.serialize()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jsonify(response_object), 201
|
||||||
|
|
||||||
|
except (exc.IntegrityError, ValueError) as e:
|
||||||
|
db.session.rollback()
|
||||||
|
appLog.error(e)
|
||||||
|
response_object = {
|
||||||
|
'status': 'fail',
|
||||||
|
'message': 'Error during activity save.'
|
||||||
|
}
|
||||||
|
return jsonify(response_object), 500
|
||||||
|
@ -41,13 +41,13 @@ class Activity(db.Model):
|
|||||||
duration = db.Column(db.Interval, nullable=False)
|
duration = db.Column(db.Interval, nullable=False)
|
||||||
pauses = db.Column(db.Interval, nullable=True)
|
pauses = db.Column(db.Interval, nullable=True)
|
||||||
moving = db.Column(db.Interval, nullable=True)
|
moving = db.Column(db.Interval, nullable=True)
|
||||||
distance = db.Column(db.Numeric(5, 2), nullable=True)
|
distance = db.Column(db.Numeric(5, 2), nullable=True) # kilometers
|
||||||
min_alt = db.Column(db.Numeric(5, 2), nullable=True)
|
min_alt = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
||||||
max_alt = db.Column(db.Numeric(5, 2), nullable=True)
|
max_alt = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
||||||
descent = db.Column(db.Numeric(5, 2), nullable=True)
|
descent = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
||||||
ascent = db.Column(db.Numeric(5, 2), nullable=True)
|
ascent = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
||||||
max_speed = db.Column(db.Numeric(5, 2), nullable=True)
|
max_speed = db.Column(db.Numeric(5, 2), nullable=True) # km/h
|
||||||
ave_speed = db.Column(db.Numeric(5, 2), nullable=True)
|
ave_speed = db.Column(db.Numeric(5, 2), nullable=True) # km/h
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.sports.label) + \
|
return str(self.sports.label) + \
|
||||||
|
@ -103,7 +103,7 @@ def test_get_activities_for_authenticated_user_no_activity(app):
|
|||||||
assert len(data['data']['activities']) == 0
|
assert len(data['data']['activities']) == 0
|
||||||
|
|
||||||
|
|
||||||
def test_add_an_activity(app):
|
def test_add_an_activity_gpx(app):
|
||||||
add_user('test', 'test@test.com', '12345678')
|
add_user('test', 'test@test.com', '12345678')
|
||||||
add_sport('cycling')
|
add_sport('cycling')
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ def test_add_an_activity(app):
|
|||||||
assert 'created' in data['status']
|
assert 'created' in data['status']
|
||||||
|
|
||||||
|
|
||||||
def test_add_an_activity_invalid_file(app):
|
def test_add_an_activity_gpx_invalid_file(app):
|
||||||
add_user('test', 'test@test.com', '12345678')
|
add_user('test', 'test@test.com', '12345678')
|
||||||
add_sport('cycling')
|
add_sport('cycling')
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ def test_add_an_activity_invalid_file(app):
|
|||||||
assert data['message'] == 'File extension not allowed.'
|
assert data['message'] == 'File extension not allowed.'
|
||||||
|
|
||||||
|
|
||||||
def test_add_an_activity_no_sport_id(app):
|
def test_add_an_activity_gpx_no_sport_id(app):
|
||||||
add_user('test', 'test@test.com', '12345678')
|
add_user('test', 'test@test.com', '12345678')
|
||||||
add_sport('cycling')
|
add_sport('cycling')
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ def test_add_an_activity_no_sport_id(app):
|
|||||||
assert data['message'] == 'Invalid payload.'
|
assert data['message'] == 'Invalid payload.'
|
||||||
|
|
||||||
|
|
||||||
def test_add_an_activity_no_file(app):
|
def test_add_an_activity_gpx_no_file(app):
|
||||||
add_user('test', 'test@test.com', '12345678')
|
add_user('test', 'test@test.com', '12345678')
|
||||||
add_sport('cycling')
|
add_sport('cycling')
|
||||||
|
|
||||||
@ -233,6 +233,124 @@ def test_add_an_activity_no_file(app):
|
|||||||
assert data['message'] == 'No file part.'
|
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='15/05/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 == 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 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'] == '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
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
def test_get_an_activity_without_gpx(app):
|
||||||
add_user('test', 'test@test.com', '12345678')
|
add_user('test', 'test@test.com', '12345678')
|
||||||
add_sport('cycling')
|
add_sport('cycling')
|
||||||
|
Loading…
Reference in New Issue
Block a user