API: add notes to activities - #10

This commit is contained in:
Sam 2018-06-13 18:17:28 +02:00
parent 0729f3d074
commit 47fc2ab830
6 changed files with 214 additions and 1 deletions

View File

@ -123,6 +123,7 @@ class Activity(db.Model):
map_id = db.Column(db.String(50), nullable=True)
weather_start = db.Column(JSON, nullable=True)
weather_end = db.Column(JSON, nullable=True)
notes = db.Column(db.String(500), nullable=True)
segments = db.relationship('ActivitySegment',
lazy=True,
cascade='all, delete',
@ -238,7 +239,8 @@ class Activity(db.Model):
"records": [record.serialize() for record in self.records],
"map": self.map_id if self.map else None,
"weather_start": self.weather_start,
"weather_end": self.weather_end
"weather_end": self.weather_end,
"notes": self.notes
}
@classmethod

View File

@ -73,6 +73,7 @@ def create_activity(
distance=distance,
duration=duration
)
new_activity.notes = activity_data.get('notes')
if title is not None and title != '':
new_activity.title = title
@ -116,6 +117,8 @@ def edit_activity(activity, activity_data, auth_user_id):
activity.sport_id = activity_data.get('sport_id')
if activity_data.get('title'):
activity.title = activity_data.get('title')
if activity_data.get('notes'):
activity.notes = activity_data.get('notes')
if not activity.gpx:
if activity_data.get('activity_date'):
activity_date = datetime.strptime(

View File

@ -23,6 +23,9 @@ def assert_activity_data_with_gpx(data):
assert data['data']['activities'][0]['pauses'] is None
assert data['data']['activities'][0]['with_gpx'] is True
assert data['data']['activities'][0]['map'] is not None
assert data['data']['activities'][0]['weather_start'] is None
assert data['data']['activities'][0]['weather_end'] is None
assert data['data']['activities'][0]['notes'] is None
assert len(data['data']['activities'][0]['segments']) == 1
segment = data['data']['activities'][0]['segments'][0]
@ -81,6 +84,9 @@ def assert_activity_data_wo_gpx(data):
assert data['data']['activities'][0]['pauses'] is None
assert data['data']['activities'][0]['with_gpx'] is False
assert data['data']['activities'][0]['map'] is None
assert data['data']['activities'][0]['weather_start'] is None
assert data['data']['activities'][0]['weather_end'] is None
assert data['data']['activities'][0]['notes'] is None
assert len(data['data']['activities'][0]['segments']) == 0
@ -305,6 +311,48 @@ def test_add_an_activity_with_gpx_without_name(
assert_activity_data_with_gpx(data)
def test_get_an_activity_with_gpx_notes(
app, user_1, sport_1_cycling, gpx_file
):
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, "notes": "test activity"}'
),
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 'just an activity' == data['data']['activities'][0]['title']
assert 'test activity' == data['data']['activities'][0]['notes']
def test_add_an_activity_with_gpx_invalid_file(
app, user_1, sport_1_cycling, gpx_file_wo_track
):
@ -570,6 +618,48 @@ def test_get_an_activity_wo_gpx(app, user_1, sport_1_cycling):
assert_activity_data_wo_gpx(data)
def test_get_an_activity_wo_gpx_notes(app, user_1, sport_1_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,
notes="new test with notes"
)),
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 'new test with notes' == data['data']['activities'][0]['notes']
def test_get_an_activity_wo_gpx_with_timezone(app, user_1, sport_1_cycling):
user_1.timezone = 'Europe/Paris'
client = app.test_client()

View File

@ -89,6 +89,26 @@ def test_edit_an_activity_with_gpx(
assert data['data']['activities'][0]['title'] == 'Activity test'
assert_activity_data_with_gpx(data)
response = client.patch(
'/api/activities/1',
content_type='application/json',
data=json.dumps(dict(
notes="test notes"
)),
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 data['data']['activities'][0]['title'] == 'Activity test'
assert data['data']['activities'][0]['notes'] == 'test notes'
def test_edit_an_activity_with_gpx_partial(
app, user_1, sport_1_cycling, sport_2_running, gpx_file
@ -276,6 +296,10 @@ def test_edit_an_activity_wo_gpx(
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
assert data['data']['activities'][0]['map'] is None
assert data['data']['activities'][0]['weather_start'] is None
assert data['data']['activities'][0]['weather_end'] is None
assert data['data']['activities'][0]['notes'] is None
records = data['data']['activities'][0]['records']
assert len(records) == 4
@ -337,6 +361,71 @@ def test_edit_an_activity_wo_gpx(
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
assert data['data']['activities'][0]['map'] is None
assert data['data']['activities'][0]['weather_start'] is None
assert data['data']['activities'][0]['weather_end'] is None
assert data['data']['activities'][0]['notes'] is None
records = data['data']['activities'][0]['records']
assert len(records) == 4
assert records[0]['sport_id'] == 2
assert records[0]['activity_id'] == 1
assert records[0]['record_type'] == 'MS'
assert records[0]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT'
assert records[0]['value'] == 8.0
assert records[1]['sport_id'] == 2
assert records[1]['activity_id'] == 1
assert records[1]['record_type'] == 'LD'
assert records[1]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT'
assert records[1]['value'] == '1:00:00'
assert records[2]['sport_id'] == 2
assert records[2]['activity_id'] == 1
assert records[2]['record_type'] == 'FD'
assert records[2]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT'
assert records[2]['value'] == 8.0
assert records[3]['sport_id'] == 2
assert records[3]['activity_id'] == 1
assert records[3]['record_type'] == 'AS'
assert records[3]['activity_date'] == 'Tue, 15 May 2018 15:05:00 GMT'
assert records[3]['value'] == 8.0
response = client.patch(
'/api/activities/1',
content_type='application/json',
data=json.dumps(dict(
notes='test notes'
)),
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 15:05:00 GMT' # noqa
assert data['data']['activities'][0]['user_id'] == 1
assert data['data']['activities'][0]['sport_id'] == 2
assert data['data']['activities'][0]['duration'] == '1:00:00'
assert data['data']['activities'][0]['title'] == 'Activity test'
assert data['data']['activities'][0]['ascent'] is None
assert data['data']['activities'][0]['ave_speed'] == 8.0
assert data['data']['activities'][0]['descent'] is None
assert data['data']['activities'][0]['distance'] == 8.0
assert data['data']['activities'][0]['max_alt'] is None
assert data['data']['activities'][0]['max_speed'] == 8.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
assert data['data']['activities'][0]['map'] is None
assert data['data']['activities'][0]['weather_start'] is None
assert data['data']['activities'][0]['weather_end'] is None
assert data['data']['activities'][0]['notes'] == 'test notes'
records = data['data']['activities'][0]['records']
assert len(records) == 4

View File

@ -40,6 +40,7 @@ def test_add_activity(
assert serialized_activity['map'] is None
assert serialized_activity['weather_start'] is None
assert serialized_activity['weather_end'] is None
assert serialized_activity['notes'] is None
def test_add_segment(

View File

@ -0,0 +1,28 @@
"""empty message
Revision ID: 096dd0b43beb
Revises: 71093ac9ca44
Create Date: 2018-06-13 17:56:20.359884
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '096dd0b43beb'
down_revision = '71093ac9ca44'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('activities', sa.Column('notes', sa.String(length=500), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('activities', 'notes')
# ### end Alembic commands ###