API - add preference for imperial units conversion

This commit is contained in:
Sam 2021-11-13 19:46:12 +01:00
parent d60bf52505
commit bb2c149caa
11 changed files with 75 additions and 2 deletions

View File

@ -319,6 +319,7 @@
<span class="nt">&quot;created_at&quot;</span><span class="p">:</span> <span class="s2">&quot;Sun, 14 Jul 2019 14:09:58 GMT&quot;</span><span class="p">,</span>
<span class="nt">&quot;email&quot;</span><span class="p">:</span> <span class="s2">&quot;sam@example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;first_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;imperial_units&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nt">&quot;language&quot;</span><span class="p">:</span> <span class="s2">&quot;en&quot;</span><span class="p">,</span>
<span class="nt">&quot;last_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;location&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
@ -419,6 +420,7 @@
<span class="nt">&quot;created_at&quot;</span><span class="p">:</span> <span class="s2">&quot;Sun, 14 Jul 2019 14:09:58 GMT&quot;</span><span class="p">,</span>
<span class="nt">&quot;email&quot;</span><span class="p">:</span> <span class="s2">&quot;sam@example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;first_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;imperial_units&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nt">&quot;language&quot;</span><span class="p">:</span> <span class="s2">&quot;en&quot;</span><span class="p">,</span>
<span class="nt">&quot;last_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;location&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
@ -537,6 +539,7 @@
<span class="nt">&quot;created_at&quot;</span><span class="p">:</span> <span class="s2">&quot;Sun, 14 Jul 2019 14:09:58 GMT&quot;</span><span class="p">,</span>
<span class="nt">&quot;email&quot;</span><span class="p">:</span> <span class="s2">&quot;sam@example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;first_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;imperial_units&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nt">&quot;language&quot;</span><span class="p">:</span> <span class="s2">&quot;en&quot;</span><span class="p">,</span>
<span class="nt">&quot;last_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;location&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>

View File

@ -160,6 +160,7 @@
<span class="nt">&quot;created_at&quot;</span><span class="p">:</span> <span class="s2">&quot;Sun, 14 Jul 2019 14:09:58 GMT&quot;</span><span class="p">,</span>
<span class="nt">&quot;email&quot;</span><span class="p">:</span> <span class="s2">&quot;admin@example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;first_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;imperial_units&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nt">&quot;language&quot;</span><span class="p">:</span> <span class="s2">&quot;en&quot;</span><span class="p">,</span>
<span class="nt">&quot;last_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;location&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
@ -297,6 +298,7 @@
<span class="nt">&quot;created_at&quot;</span><span class="p">:</span> <span class="s2">&quot;Sun, 14 Jul 2019 14:09:58 GMT&quot;</span><span class="p">,</span>
<span class="nt">&quot;email&quot;</span><span class="p">:</span> <span class="s2">&quot;admin@example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;first_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;imperial_units&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nt">&quot;language&quot;</span><span class="p">:</span> <span class="s2">&quot;en&quot;</span><span class="p">,</span>
<span class="nt">&quot;last_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;location&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
@ -442,6 +444,7 @@
<span class="nt">&quot;created_at&quot;</span><span class="p">:</span> <span class="s2">&quot;Sun, 14 Jul 2019 14:09:58 GMT&quot;</span><span class="p">,</span>
<span class="nt">&quot;email&quot;</span><span class="p">:</span> <span class="s2">&quot;admin@example.com&quot;</span><span class="p">,</span>
<span class="nt">&quot;first_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;imperial_units&quot;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
<span class="nt">&quot;language&quot;</span><span class="p">:</span> <span class="s2">&quot;en&quot;</span><span class="p">,</span>
<span class="nt">&quot;last_name&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nt">&quot;location&quot;</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span>

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
from typing import Dict
from flask import current_app
from sqlalchemy import exc
from sqlalchemy.engine.base import Connection
from sqlalchemy.event import listens_for
from sqlalchemy.ext.declarative import DeclarativeMeta
@ -25,7 +26,15 @@ class AppConfig(BaseModel):
@property
def is_registration_enabled(self) -> bool:
nb_users = User.query.count()
try:
nb_users = User.query.count()
except exc.ProgrammingError as e:
# workaround for user model related migrations
if 'psycopg2.errors.UndefinedColumn' in str(e):
result = db.engine.execute("SELECT COUNT(*) FROM users;")
nb_users = result.fetchone()[0]
else:
raise e
return self.max_users == 0 or nb_users < self.max_users
@property

View File

@ -0,0 +1,31 @@
"""add imperial units preferences
Revision ID: 07188ca7620a
Revises: 080acc8ee956
Create Date: 2021-11-13 19:11:17.753567
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '07188ca7620a'
down_revision = '080acc8ee956'
branch_labels = None
depends_on = None
def upgrade():
op.add_column(
'users',
sa.Column('imperial_units', sa.Boolean(), nullable=True),
)
op.execute("UPDATE users SET imperial_units = false")
op.alter_column('users', 'imperial_units', nullable=False)
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('users', 'imperial_units')
# ### end Alembic commands ###

View File

@ -487,6 +487,7 @@ class TestUserProfile(ApiTestCaseMixin):
assert not data['data']['admin']
assert data['data']['timezone'] is None
assert data['data']['weekm'] is False
assert data['data']['imperial_units'] is False
assert data['data']['language'] is None
assert data['data']['nb_sports'] == 0
assert data['data']['nb_workouts'] == 0
@ -517,6 +518,7 @@ class TestUserProfile(ApiTestCaseMixin):
assert data['data']['last_name'] == 'Doe'
assert data['data']['birth_date']
assert data['data']['bio'] == 'just a random guy'
assert data['data']['imperial_units'] is False
assert data['data']['location'] == 'somewhere'
assert data['data']['timezone'] == 'America/New_York'
assert data['data']['weekm'] is False
@ -553,6 +555,7 @@ class TestUserProfile(ApiTestCaseMixin):
assert data['data']['created_at']
assert not data['data']['admin']
assert data['data']['timezone'] is None
assert data['data']['imperial_units'] is False
assert data['data']['nb_sports'] == 2
assert data['data']['nb_workouts'] == 2
assert len(data['data']['records']) == 6
@ -605,6 +608,7 @@ class TestUserProfileUpdate(ApiTestCaseMixin):
assert data['data']['last_name'] == 'Doe'
assert data['data']['birth_date']
assert data['data']['bio'] == 'Nothing to tell'
assert data['data']['imperial_units'] is False
assert data['data']['location'] == 'Somewhere'
assert data['data']['timezone'] is None
assert data['data']['weekm'] is False
@ -648,6 +652,7 @@ class TestUserProfileUpdate(ApiTestCaseMixin):
assert data['data']['last_name'] == 'Doe'
assert data['data']['birth_date']
assert data['data']['bio'] == 'Nothing to tell'
assert data['data']['imperial_units'] is False
assert data['data']['location'] == 'Somewhere'
assert data['data']['timezone'] is None
assert data['data']['weekm'] is False
@ -767,6 +772,7 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin):
timezone='America/New_York',
weekm=True,
language='fr',
imperial_units=True,
)
),
headers=dict(Authorization=f'Bearer {auth_token}'),
@ -784,6 +790,7 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin):
assert data['data']['last_name'] is None
assert data['data']['birth_date'] is None
assert data['data']['bio'] is None
assert data['data']['imperial_units']
assert data['data']['location'] is None
assert data['data']['timezone'] == 'America/New_York'
assert data['data']['weekm'] is True

View File

@ -36,6 +36,7 @@ class TestGetUser(ApiTestCaseMixin):
assert user['last_name'] is None
assert user['birth_date'] is None
assert user['bio'] is None
assert user['imperial_units'] is False
assert user['location'] is None
assert user['timezone'] is None
assert user['weekm'] is False
@ -77,6 +78,7 @@ class TestGetUser(ApiTestCaseMixin):
assert user['last_name'] is None
assert user['birth_date'] is None
assert user['bio'] is None
assert user['imperial_units'] is False
assert user['location'] is None
assert user['timezone'] is None
assert user['weekm'] is False
@ -129,6 +131,7 @@ class TestGetUsers(ApiTestCaseMixin):
assert 'test@test.com' in data['data']['users'][0]['email']
assert 'toto@toto.com' in data['data']['users'][1]['email']
assert 'sam@test.com' in data['data']['users'][2]['email']
assert data['data']['users'][0]['imperial_units'] is False
assert data['data']['users'][0]['timezone'] is None
assert data['data']['users'][0]['weekm'] is False
assert data['data']['users'][0]['language'] is None
@ -138,6 +141,7 @@ class TestGetUsers(ApiTestCaseMixin):
assert data['data']['users'][0]['sports_list'] == []
assert data['data']['users'][0]['total_distance'] == 0
assert data['data']['users'][0]['total_duration'] == '0:00:00'
assert data['data']['users'][1]['imperial_units'] is False
assert data['data']['users'][1]['timezone'] is None
assert data['data']['users'][1]['weekm'] is False
assert data['data']['users'][1]['language'] is None
@ -147,6 +151,7 @@ class TestGetUsers(ApiTestCaseMixin):
assert data['data']['users'][1]['sports_list'] == []
assert data['data']['users'][1]['total_distance'] == 0
assert data['data']['users'][1]['total_duration'] == '0:00:00'
assert data['data']['users'][2]['imperial_units'] is False
assert data['data']['users'][2]['timezone'] is None
assert data['data']['users'][2]['weekm'] is True
assert data['data']['users'][2]['language'] is None
@ -196,6 +201,7 @@ class TestGetUsers(ApiTestCaseMixin):
assert 'test@test.com' in data['data']['users'][0]['email']
assert 'toto@toto.com' in data['data']['users'][1]['email']
assert 'sam@test.com' in data['data']['users'][2]['email']
assert data['data']['users'][0]['imperial_units'] is False
assert data['data']['users'][0]['timezone'] is None
assert data['data']['users'][0]['weekm'] is False
assert data['data']['users'][0]['nb_sports'] == 2
@ -204,6 +210,7 @@ class TestGetUsers(ApiTestCaseMixin):
assert data['data']['users'][0]['sports_list'] == [1, 2]
assert data['data']['users'][0]['total_distance'] == 22.0
assert data['data']['users'][0]['total_duration'] == '2:40:00'
assert data['data']['users'][1]['imperial_units'] is False
assert data['data']['users'][1]['timezone'] is None
assert data['data']['users'][1]['weekm'] is False
assert data['data']['users'][1]['nb_sports'] == 1
@ -212,6 +219,7 @@ class TestGetUsers(ApiTestCaseMixin):
assert data['data']['users'][1]['sports_list'] == [1]
assert data['data']['users'][1]['total_distance'] == 15
assert data['data']['users'][1]['total_duration'] == '1:00:00'
assert data['data']['users'][2]['imperial_units'] is False
assert data['data']['users'][2]['timezone'] is None
assert data['data']['users'][2]['weekm'] is True
assert data['data']['users'][2]['nb_sports'] == 0

View File

@ -14,6 +14,7 @@ class TestUserModel:
assert serialized_user['admin'] is False
assert serialized_user['first_name'] is None
assert serialized_user['last_name'] is None
assert serialized_user['imperial_units'] is False
assert serialized_user['bio'] is None
assert serialized_user['location'] is None
assert serialized_user['birth_date'] is None

View File

@ -313,6 +313,7 @@ def get_authenticated_user_profile(
"created_at": "Sun, 14 Jul 2019 14:09:58 GMT",
"email": "sam@example.com",
"first_name": null,
"imperial_units": false,
"language": "en",
"last_name": null,
"location": null,
@ -412,6 +413,7 @@ def edit_user(auth_user_id: int) -> Union[Dict, HttpResponse]:
"created_at": "Sun, 14 Jul 2019 14:09:58 GMT",
"email": "sam@example.com",
"first_name": null,
"imperial_units": false,
"language": "en",
"last_name": null,
"location": null,
@ -574,6 +576,7 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]:
"created_at": "Sun, 14 Jul 2019 14:09:58 GMT",
"email": "sam@example.com",
"first_name": null,
"imperial_units": false,
"language": "en",
"last_name": null,
"location": null,
@ -653,6 +656,7 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]:
# get post data
post_data = request.get_json()
user_mandatory_data = {
'imperial_units',
'language',
'timezone',
'weekm',
@ -660,12 +664,14 @@ def edit_user_preferences(auth_user_id: int) -> Union[Dict, HttpResponse]:
if not post_data or not post_data.keys() >= user_mandatory_data:
return InvalidPayloadErrorResponse()
imperial_units = post_data.get('imperial_units')
language = post_data.get('language')
timezone = post_data.get('timezone')
weekm = post_data.get('weekm')
try:
user = User.query.filter_by(id=auth_user_id).first()
user.imperial_units = imperial_units
user.language = language
user.timezone = timezone
user.weekm = weekm

View File

@ -40,6 +40,7 @@ class User(BaseModel):
'Record', lazy=True, backref=db.backref('user', lazy='joined')
)
language = db.Column(db.String(50), nullable=True)
imperial_units = db.Column(db.Boolean, default=False, nullable=False)
def __repr__(self) -> str:
return f'<User {self.username!r}>'
@ -142,6 +143,7 @@ class User(BaseModel):
],
'total_distance': float(total[0]),
'total_duration': str(total[1]),
'imperial_units': self.imperial_units,
}

View File

@ -64,6 +64,7 @@ def get_users(auth_user_id: int) -> Dict:
"created_at": "Sun, 14 Jul 2019 14:09:58 GMT",
"email": "admin@example.com",
"first_name": null,
"imperial_units": false,
"language": "en",
"last_name": null,
"location": null,
@ -246,6 +247,7 @@ def get_single_user(
"created_at": "Sun, 14 Jul 2019 14:09:58 GMT",
"email": "admin@example.com",
"first_name": null,
"imperial_units": false,
"language": "en",
"last_name": null,
"location": null,
@ -400,6 +402,7 @@ def update_user(
"created_at": "Sun, 14 Jul 2019 14:09:58 GMT",
"email": "admin@example.com",
"first_name": null,
"imperial_units": false,
"language": "en",
"last_name": null,
"location": null,