FitTrackee/fittrackee/tests/workouts/test_sports_api.py

534 lines
17 KiB
Python
Raw Normal View History

2018-05-01 17:12:51 +02:00
import json
2022-06-15 19:16:14 +02:00
import pytest
2021-01-20 16:47:00 +01:00
from flask import Flask
from fittrackee import db
from fittrackee.users.models import User, UserSportPreference
from fittrackee.workouts.models import Sport, Workout
2021-01-02 19:28:03 +01:00
from ..mixins import ApiTestCaseMixin
2023-05-21 16:13:14 +02:00
from ..utils import OAUTH_SCOPES, jsonify_dict
2018-05-01 17:12:51 +02:00
2021-02-20 23:20:20 +01:00
class TestGetSports(ApiTestCaseMixin):
2022-03-19 22:02:06 +01:00
def test_it_returns_error_if_user_is_not_authenticated(
self,
app: Flask,
) -> None:
client = app.test_client()
response = client.get('/api/sports')
self.assert_401(response)
2020-05-10 15:55:56 +02:00
def test_it_gets_all_sports(
2021-01-02 19:28:03 +01:00
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
sport_2_running: Sport,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
2020-05-10 15:55:56 +02:00
response = client.get(
'/api/sports',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 2
assert data['data']['sports'][0] == jsonify_dict(
sport_1_cycling.serialize()
)
assert data['data']['sports'][1] == jsonify_dict(
sport_2_running.serialize()
)
2020-05-10 15:55:56 +02:00
def test_it_gets_all_sports_with_inactive_one(
2021-01-02 19:28:03 +01:00
self,
app: Flask,
user_1: User,
sport_1_cycling_inactive: Sport,
sport_2_running: Sport,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
2020-05-10 15:55:56 +02:00
response = client.get(
'/api/sports',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 2
assert data['data']['sports'][0] == jsonify_dict(
sport_1_cycling_inactive.serialize()
)
assert data['data']['sports'][1] == jsonify_dict(
sport_2_running.serialize()
2020-05-10 15:55:56 +02:00
)
def test_it_gets_all_sports_with_admin_rights(
2021-01-02 19:28:03 +01:00
self,
app: Flask,
user_1_admin: User,
sport_1_cycling_inactive: Sport,
sport_2_running: Sport,
) -> None:
2021-02-20 23:20:20 +01:00
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
response = client.get(
'/api/sports',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 2
assert data['data']['sports'][0] == jsonify_dict(
sport_1_cycling_inactive.serialize(is_admin=True)
2020-05-10 15:55:56 +02:00
)
assert data['data']['sports'][1] == jsonify_dict(
sport_2_running.serialize(is_admin=True)
2020-05-10 15:55:56 +02:00
)
def test_it_gets_sports_with_auth_user_preferences(
self,
app: Flask,
user_1_admin: User,
sport_1_cycling: Sport,
sport_2_running: Sport,
user_admin_sport_1_preference: UserSportPreference,
) -> None:
user_admin_sport_1_preference.color = '#000000'
user_admin_sport_1_preference.stopped_speed_threshold = 0.5
user_admin_sport_1_preference.is_active = False
db.session.commit()
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.get(
'/api/sports',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 2
assert data['data']['sports'][0] == jsonify_dict(
sport_1_cycling.serialize(
is_admin=True,
sport_preferences=user_admin_sport_1_preference.serialize(),
)
)
assert data['data']['sports'][1] == jsonify_dict(
sport_2_running.serialize(is_admin=True)
)
2022-06-15 19:16:14 +02:00
@pytest.mark.parametrize(
'client_scope, can_access',
2023-05-21 16:13:14 +02:00
{**OAUTH_SCOPES, 'workouts:read': True}.items(),
2022-06-15 19:16:14 +02:00
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
2022-06-19 20:04:42 +02:00
) = self.create_oauth2_client_and_issue_token(
2022-06-15 19:16:14 +02:00
app, user_1, scope=client_scope
)
response = client.get(
'/api/sports',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
2020-05-10 15:55:56 +02:00
2021-02-20 23:20:20 +01:00
class TestGetSport(ApiTestCaseMixin):
2021-01-02 19:28:03 +01:00
def test_it_gets_a_sport(
self, app: Flask, user_1: User, sport_1_cycling: Sport
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
2020-05-10 15:55:56 +02:00
response = client.get(
'/api/sports/1',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0] == jsonify_dict(
sport_1_cycling.serialize()
)
2020-05-10 15:55:56 +02:00
def test_it_gets_a_sport_with_preferences(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
user_sport_1_preference: UserSportPreference,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
response = client.get(
'/api/sports/1',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0] == jsonify_dict(
sport_1_cycling.serialize(
sport_preferences=user_sport_1_preference.serialize()
)
)
2021-01-02 19:28:03 +01:00
def test_it_returns_404_if_sport_does_not_exist(
self, app: Flask, user_1: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
2020-05-10 15:55:56 +02:00
response = client.get(
'/api/sports/1',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = self.assert_404(response)
2020-05-10 15:55:56 +02:00
assert len(data['data']['sports']) == 0
def test_it_gets_a_inactive_sport(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1: User, sport_1_cycling_inactive: Sport
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
2021-02-20 23:20:20 +01:00
2020-05-10 15:55:56 +02:00
response = client.get(
'/api/sports/1',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
2021-02-20 23:20:20 +01:00
data = json.loads(response.data.decode())
2020-05-10 15:55:56 +02:00
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0] == jsonify_dict(
sport_1_cycling_inactive.serialize()
2020-05-10 15:55:56 +02:00
)
def test_it_get_an_inactive_sport_with_admin_rights(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1_admin: User, sport_1_cycling_inactive: Sport
) -> None:
2021-02-20 23:20:20 +01:00
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
2021-02-20 23:20:20 +01:00
2020-05-10 15:55:56 +02:00
response = client.get(
'/api/sports/1',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
2021-02-20 23:20:20 +01:00
data = json.loads(response.data.decode())
2020-05-10 15:55:56 +02:00
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0] == jsonify_dict(
sport_1_cycling_inactive.serialize(is_admin=True)
2020-05-10 15:55:56 +02:00
)
2022-06-15 19:16:14 +02:00
@pytest.mark.parametrize(
'client_scope, can_access',
2023-05-21 16:13:14 +02:00
{**OAUTH_SCOPES, 'workouts:read': True}.items(),
2022-06-15 19:16:14 +02:00
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
2022-06-19 20:04:42 +02:00
) = self.create_oauth2_client_and_issue_token(
2022-06-15 19:16:14 +02:00
app, user_1, scope=client_scope
)
response = client.get(
f'/api/sports/{sport_1_cycling.id}',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
2020-05-10 15:55:56 +02:00
2021-02-20 23:20:20 +01:00
class TestUpdateSport(ApiTestCaseMixin):
2021-01-02 19:28:03 +01:00
def test_it_disables_a_sport(
self, app: Flask, user_1_admin: User, sport_1_cycling: Sport
) -> None:
2021-02-20 23:20:20 +01:00
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
response = client.patch(
'/api/sports/1',
content_type='application/json',
data=json.dumps(dict(is_active=False)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0]['is_active'] is False
assert data['data']['sports'][0]['is_active_for_user'] is False
assert data['data']['sports'][0]['has_workouts'] is False
2020-05-10 15:55:56 +02:00
2021-01-02 19:28:03 +01:00
def test_it_enables_a_sport(
self, app: Flask, user_1_admin: User, sport_1_cycling: Sport
) -> None:
2020-05-10 15:55:56 +02:00
sport_1_cycling.is_active = False
2021-02-20 23:20:20 +01:00
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
response = client.patch(
'/api/sports/1',
content_type='application/json',
data=json.dumps(dict(is_active=True)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0]['is_active'] is True
assert data['data']['sports'][0]['is_active_for_user'] is True
assert data['data']['sports'][0]['has_workouts'] is False
2020-05-10 15:55:56 +02:00
def test_it_disables_a_sport_with_workouts(
2021-01-02 19:28:03 +01:00
self,
app: Flask,
user_1_admin: User,
sport_1_cycling: Sport,
workout_cycling_user_1: Workout,
2021-01-02 19:28:03 +01:00
) -> None:
2021-02-20 23:20:20 +01:00
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
response = client.patch(
'/api/sports/1',
content_type='application/json',
data=json.dumps(dict(is_active=False)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0]['is_active'] is False
assert data['data']['sports'][0]['is_active_for_user'] is False
assert data['data']['sports'][0]['has_workouts'] is True
2020-05-10 15:55:56 +02:00
def test_it_enables_a_sport_with_workouts(
2021-01-02 19:28:03 +01:00
self,
app: Flask,
user_1_admin: User,
sport_1_cycling: Sport,
workout_cycling_user_1: Workout,
2021-01-02 19:28:03 +01:00
) -> None:
2020-05-10 15:55:56 +02:00
sport_1_cycling.is_active = False
2021-02-20 23:20:20 +01:00
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
response = client.patch(
'/api/sports/1',
content_type='application/json',
data=json.dumps(dict(is_active=True)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0]['is_active'] is True
assert data['data']['sports'][0]['is_active_for_user'] is True
assert data['data']['sports'][0]['has_workouts'] is True
2020-05-10 15:55:56 +02:00
def test_it_disables_a_sport_with_preferences(
self,
app: Flask,
user_1_admin: User,
sport_1_cycling: Sport,
user_admin_sport_1_preference: UserSportPreference,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.patch(
'/api/sports/1',
content_type='application/json',
data=json.dumps(dict(is_active=False)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0]['is_active'] is False
assert data['data']['sports'][0]['is_active_for_user'] is False
assert data['data']['sports'][0]['has_workouts'] is False
def test_it_enables_a_sport_with_preferences(
self,
app: Flask,
user_1_admin: User,
sport_1_cycling: Sport,
user_admin_sport_1_preference: UserSportPreference,
) -> None:
sport_1_cycling.is_active = False
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.patch(
'/api/sports/1',
content_type='application/json',
data=json.dumps(dict(is_active=True)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert 'success' in data['status']
assert len(data['data']['sports']) == 1
assert data['data']['sports'][0]['is_active'] is True
assert data['data']['sports'][0]['is_active_for_user'] is True
assert data['data']['sports'][0]['has_workouts'] is False
2020-05-10 15:55:56 +02:00
def test_returns_error_if_user_has_no_admin_rights(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1: User, sport_1_cycling: Sport
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
2021-02-20 23:20:20 +01:00
2020-05-10 15:55:56 +02:00
response = client.patch(
'/api/sports/1',
content_type='application/json',
data=json.dumps(dict(is_active=False)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
self.assert_403(response)
2020-05-10 15:55:56 +02:00
2021-01-02 19:28:03 +01:00
def test_returns_error_if_payload_is_invalid(
self, app: Flask, user_1_admin: User
) -> None:
2021-02-20 23:20:20 +01:00
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
response = client.patch(
'/api/sports/1',
content_type='application/json',
data=json.dumps(dict()),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
self.assert_400(response)
2020-05-10 15:55:56 +02:00
2021-01-02 19:28:03 +01:00
def test_it_returns_error_if_sport_does_not_exist(
self, app: Flask, user_1_admin: User
) -> None:
2021-02-20 23:20:20 +01:00
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
2021-02-20 23:20:20 +01:00
2020-05-10 15:55:56 +02:00
response = client.patch(
'/api/sports/1',
content_type='application/json',
data=json.dumps(dict(is_active=False)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
data = self.assert_404(response)
2020-05-10 15:55:56 +02:00
assert len(data['data']['sports']) == 0
2022-06-15 19:16:14 +02:00
@pytest.mark.parametrize(
'client_scope, can_access',
2023-05-21 16:13:14 +02:00
{**OAUTH_SCOPES, 'workouts:write': True}.items(),
2022-06-15 19:16:14 +02:00
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1_admin: User,
user_2: User,
sport_1_cycling: Sport,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
2022-06-19 20:04:42 +02:00
) = self.create_oauth2_client_and_issue_token(
2022-06-15 19:16:14 +02:00
app, user_1_admin, scope=client_scope
)
response = client.patch(
f'/api/sports/{sport_1_cycling.id}',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)