API: add notes to activities - #10
This commit is contained in:
parent
0729f3d074
commit
47fc2ab830
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
28
fittrackee_api/migrations/versions/096dd0b43beb_.py
Normal file
28
fittrackee_api/migrations/versions/096dd0b43beb_.py
Normal 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 ###
|
Loading…
Reference in New Issue
Block a user