FitTrackee/fittrackee/tests/users/test_users_api.py

1750 lines
57 KiB
Python
Raw Normal View History

2017-12-16 21:00:46 +01:00
import json
from datetime import datetime, timedelta
from io import BytesIO
from unittest.mock import MagicMock, patch
2017-12-16 21:00:46 +01:00
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, UserDataExport, UserSportPreference
from fittrackee.utils import get_readable_duration
from fittrackee.workouts.models import Sport, Workout
2021-01-02 19:28:03 +01:00
from ..mixins import ApiTestCaseMixin
from ..utils import jsonify_dict
2020-05-10 15:55:56 +02:00
2021-02-20 23:20:20 +01:00
class TestGetUser(ApiTestCaseMixin):
def test_it_returns_error_if_user_has_no_admin_rights(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1: User, user_2: 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(
f'/api/users/{user_2.username}',
content_type='application/json',
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)
def test_user_can_access_his_profile(
self, app: Flask, user_1: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
response = client.get(
f'/api/users/{user_1.username}',
content_type='application/json',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert data['status'] == 'success'
assert len(data['data']['users']) == 1
user = data['data']['users'][0]
assert user['username'] == user_1.username
2022-03-19 22:02:06 +01:00
def test_it_gets_inactive_user(
self, app: Flask, user_1_admin: User, inactive_user: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.get(
f'/api/users/{inactive_user.username}',
content_type='application/json',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
data = json.loads(response.data.decode())
assert response.status_code == 200
assert data['status'] == 'success'
assert len(data['data']['users']) == 1
user = data['data']['users'][0]
assert user == jsonify_dict(inactive_user.serialize(user_1_admin))
2022-03-19 22:02:06 +01:00
def test_it_gets_single_user_without_workouts(
self, app: Flask, user_1_admin: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.get(
f'/api/users/{user_2.username}',
content_type='application/json',
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 data['status'] == 'success'
assert len(data['data']['users']) == 1
user = data['data']['users'][0]
assert user == jsonify_dict(user_2.serialize(user_1_admin))
2020-05-10 15:55:56 +02:00
def test_it_gets_single_user_with_workouts(
2020-05-10 15:55:56 +02:00
self,
2021-01-02 19:28:03 +01:00
app: Flask,
user_1: User,
user_2_admin: User,
2021-01-02 19:28:03 +01:00
sport_1_cycling: Sport,
sport_2_running: Sport,
workout_cycling_user_1: Workout,
workout_running_user_1: Workout,
2021-01-02 19:28:03 +01:00
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_2_admin.email
)
2020-05-10 15:55:56 +02:00
response = client.get(
f'/api/users/{user_1.username}',
content_type='application/json',
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 data['status'] == 'success'
assert len(data['data']['users']) == 1
user = data['data']['users'][0]
assert user == jsonify_dict(user_1.serialize(user_2_admin))
2020-05-10 15:55:56 +02:00
2021-01-02 19:28:03 +01:00
def test_it_returns_error_if_user_does_not_exist(
self, app: Flask, user_1_admin: User
2021-01-02 19:28:03 +01:00
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
2021-02-20 23:20:20 +01:00
2020-05-10 15:55:56 +02:00
response = client.get(
'/api/users/not_existing',
content_type='application/json',
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_404_with_entity(response, 'user')
2020-05-10 15:55:56 +02:00
2022-06-15 19:16:14 +02:00
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', True),
('users:write', False),
('workouts:read', False),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1_admin: User,
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.get(
'/api/users/not_existing',
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 TestGetUsers(ApiTestCaseMixin):
def test_it_returns_error_if_user_has_no_admin_rights(
self, app: Flask, user_1: User, user_2: User
2021-01-02 19:28:03 +01:00
) -> 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/users',
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)
2022-03-19 22:02:06 +01:00
def test_it_get_users_list_regardless_their_account_status(
self, app: Flask, user_1_admin: User, inactive_user: User, user_3: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.get(
'/api/users',
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']['users']) == 3
assert data['data']['users'][0] == jsonify_dict(
user_1_admin.serialize(user_1_admin)
)
assert data['data']['users'][1] == jsonify_dict(
inactive_user.serialize(user_1_admin)
)
assert data['data']['users'][2] == jsonify_dict(
user_3.serialize(user_1_admin)
2020-05-10 15:55:56 +02:00
)
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
@patch('fittrackee.users.users.USER_PER_PAGE', 2)
2020-05-10 15:55:56 +02:00
def test_it_gets_first_page_on_users_list(
2020-09-16 11:09:32 +02:00
self,
2021-01-02 19:28:03 +01:00
app: Flask,
user_1_admin: User,
2021-01-02 19:28:03 +01:00
user_2: User,
user_3: User,
) -> None:
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/users?page=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']['users']) == 2
assert data['pagination'] == {
'has_next': True,
'has_prev': False,
'page': 1,
'pages': 2,
'total': 3,
}
@patch('fittrackee.users.users.USER_PER_PAGE', 2)
2020-05-10 15:55:56 +02:00
def test_it_gets_next_page_on_users_list(
2020-09-16 11:09:32 +02:00
self,
2021-01-02 19:28:03 +01:00
app: Flask,
user_1_admin: User,
2021-01-02 19:28:03 +01:00
user_2: User,
user_3: User,
) -> None:
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/users?page=2',
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']['users']) == 1
assert data['pagination'] == {
'has_next': False,
'has_prev': True,
'page': 2,
'pages': 2,
'total': 3,
}
def test_it_gets_empty_next_page_on_users_list(
2020-09-16 11:09:32 +02:00
self,
2021-01-02 19:28:03 +01:00
app: Flask,
user_1_admin: User,
2021-01-02 19:28:03 +01:00
user_2: User,
user_3: User,
) -> None:
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/users?page=2',
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']['users']) == 0
assert data['pagination'] == {
'has_next': False,
'has_prev': True,
'page': 2,
'pages': 1,
'total': 3,
}
def test_it_gets_user_list_with_2_per_page(
2020-09-16 11:09:32 +02:00
self,
2021-01-02 19:28:03 +01:00
app: Flask,
user_1_admin: User,
2021-01-02 19:28:03 +01:00
user_2: User,
user_3: User,
) -> None:
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/users?per_page=2',
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']['users']) == 2
assert data['pagination'] == {
'has_next': True,
'has_prev': False,
'page': 1,
'pages': 2,
'total': 3,
}
def test_it_gets_next_page_on_user_list_with_2_per_page(
2020-09-16 11:09:32 +02:00
self,
2021-01-02 19:28:03 +01:00
app: Flask,
user_1_admin: User,
2021-01-02 19:28:03 +01:00
user_2: User,
user_3: User,
) -> None:
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/users?page=2&per_page=2',
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']['users']) == 1
assert data['pagination'] == {
'has_next': False,
'has_prev': True,
'page': 2,
'pages': 2,
'total': 3,
}
def test_it_gets_users_list_ordered_by_username(
self, app: Flask, user_1_admin: User, user_2: User, user_3: User
2021-01-02 19:28:03 +01:00
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
2021-02-20 23:20:20 +01:00
2020-05-10 15:55:56 +02:00
response = client.get(
'/api/users?order_by=username',
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']['users']) == 3
assert 'admin' in data['data']['users'][0]['username']
assert 'sam' in data['data']['users'][1]['username']
2020-05-10 15:55:56 +02:00
assert 'toto' in data['data']['users'][2]['username']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_username_ascending(
self, app: Flask, user_1_admin: User, user_2: User, user_3: User
2021-01-02 19:28:03 +01:00
) -> None:
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/users?order_by=username&order=asc',
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']['users']) == 3
assert 'admin' in data['data']['users'][0]['username']
assert 'sam' in data['data']['users'][1]['username']
2020-05-10 15:55:56 +02:00
assert 'toto' in data['data']['users'][2]['username']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_username_descending(
self, app: Flask, user_1_admin: User, user_2: User, user_3: User
2021-01-02 19:28:03 +01:00
) -> None:
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/users?order_by=username&order=desc',
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']['users']) == 3
assert 'toto' in data['data']['users'][0]['username']
assert 'sam' in data['data']['users'][1]['username']
assert 'admin' in data['data']['users'][2]['username']
2020-05-10 15:55:56 +02:00
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_creation_date(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_2: User, user_3: User, user_1_admin: User
) -> None:
2020-05-10 15:55:56 +02:00
user_2.created_at = datetime.utcnow() - timedelta(days=1)
user_3.created_at = datetime.utcnow() - timedelta(hours=1)
user_1_admin.created_at = datetime.utcnow()
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/users?order_by=created_at',
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']['users']) == 3
assert 'toto' in data['data']['users'][0]['username']
assert 'sam' in data['data']['users'][1]['username']
assert 'admin' in data['data']['users'][2]['username']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_creation_date_ascending(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_2: User, user_3: User, user_1_admin: User
) -> None:
2020-05-10 15:55:56 +02:00
user_2.created_at = datetime.utcnow() - timedelta(days=1)
user_3.created_at = datetime.utcnow() - timedelta(hours=1)
user_1_admin.created_at = datetime.utcnow()
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/users?order_by=created_at&order=asc',
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']['users']) == 3
assert 'toto' in data['data']['users'][0]['username']
assert 'sam' in data['data']['users'][1]['username']
assert 'admin' in data['data']['users'][2]['username']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_creation_date_descending(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_2: User, user_3: User, user_1_admin: User
) -> None:
2020-05-10 15:55:56 +02:00
user_2.created_at = datetime.utcnow() - timedelta(days=1)
user_3.created_at = datetime.utcnow() - timedelta(hours=1)
user_1_admin.created_at = datetime.utcnow()
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/users?order_by=created_at&order=desc',
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']['users']) == 3
assert 'admin' in data['data']['users'][0]['username']
assert 'sam' in data['data']['users'][1]['username']
assert 'toto' in data['data']['users'][2]['username']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_admin_rights(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_2: User, user_1_admin: User, user_3: 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.get(
'/api/users?order_by=admin',
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']['users']) == 3
assert 'toto' in data['data']['users'][0]['username']
assert 'sam' in data['data']['users'][1]['username']
assert 'admin' in data['data']['users'][2]['username']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_admin_rights_ascending(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_2: User, user_1_admin: User, user_3: 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.get(
'/api/users?order_by=admin&order=asc',
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']['users']) == 3
assert 'toto' in data['data']['users'][0]['username']
assert 'sam' in data['data']['users'][1]['username']
assert 'admin' in data['data']['users'][2]['username']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_admin_rights_descending(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_2: User, user_3: User, 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.get(
'/api/users?order_by=admin&order=desc',
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']['users']) == 3
assert 'admin' in data['data']['users'][0]['username']
assert 'toto' in data['data']['users'][1]['username']
assert 'sam' in data['data']['users'][2]['username']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_workouts_count(
2020-05-10 15:55:56 +02:00
self,
2021-01-02 19:28:03 +01:00
app: Flask,
user_1_admin: User,
2021-01-02 19:28:03 +01:00
user_2: User,
user_3: User,
sport_1_cycling: Sport,
workout_cycling_user_2: Workout,
2021-01-02 19:28:03 +01:00
) -> None:
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/users?order_by=workouts_count',
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']['users']) == 3
assert 'admin' in data['data']['users'][0]['username']
assert 0 == data['data']['users'][0]['nb_workouts']
2020-05-10 15:55:56 +02:00
assert 'sam' in data['data']['users'][1]['username']
assert 0 == data['data']['users'][1]['nb_workouts']
2020-05-10 15:55:56 +02:00
assert 'toto' in data['data']['users'][2]['username']
assert 1 == data['data']['users'][2]['nb_workouts']
2020-05-10 15:55:56 +02:00
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_workouts_count_ascending(
2020-05-10 15:55:56 +02:00
self,
2021-01-02 19:28:03 +01:00
app: Flask,
user_1_admin: User,
2021-01-02 19:28:03 +01:00
user_2: User,
user_3: User,
sport_1_cycling: Sport,
workout_cycling_user_2: Workout,
2021-01-02 19:28:03 +01:00
) -> None:
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/users?order_by=workouts_count&order=asc',
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']['users']) == 3
assert 'admin' in data['data']['users'][0]['username']
assert 0 == data['data']['users'][0]['nb_workouts']
2020-05-10 15:55:56 +02:00
assert 'sam' in data['data']['users'][1]['username']
assert 0 == data['data']['users'][1]['nb_workouts']
2020-05-10 15:55:56 +02:00
assert 'toto' in data['data']['users'][2]['username']
assert 1 == data['data']['users'][2]['nb_workouts']
2020-05-10 15:55:56 +02:00
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_ordered_by_account_status(
self,
app: Flask,
user_1_admin: User,
inactive_user: User,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.get(
'/api/users?order_by=is_active',
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']['users']) == 2
assert data['data']['users'][0]['username'] == inactive_user.username
assert not data['data']['users'][0]['is_active']
assert data['data']['users'][1]['username'] == user_1_admin.username
assert data['data']['users'][1]['is_active']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 2,
}
def test_it_gets_users_list_ordered_by_account_status_ascending(
self,
app: Flask,
user_1_admin: User,
inactive_user: User,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.get(
'/api/users?order_by=is_active&order=asc',
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']['users']) == 2
assert data['data']['users'][0]['username'] == inactive_user.username
assert not data['data']['users'][0]['is_active']
assert data['data']['users'][1]['username'] == user_1_admin.username
assert data['data']['users'][1]['is_active']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 2,
}
def test_it_gets_users_list_ordered_by_account_status_descending(
self,
app: Flask,
user_1_admin: User,
inactive_user: User,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.get(
'/api/users?order_by=is_active&order=desc',
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']['users']) == 2
assert data['data']['users'][0]['username'] == user_1_admin.username
assert data['data']['users'][0]['is_active']
assert data['data']['users'][1]['username'] == inactive_user.username
assert not data['data']['users'][1]['is_active']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 2,
}
def test_it_gets_users_list_ordered_by_workouts_count_descending(
2020-05-10 15:55:56 +02:00
self,
2021-01-02 19:28:03 +01:00
app: Flask,
user_1_admin: User,
2021-01-02 19:28:03 +01:00
user_2: User,
user_3: User,
sport_1_cycling: Sport,
workout_cycling_user_2: Workout,
2021-01-02 19:28:03 +01:00
) -> None:
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/users?order_by=workouts_count&order=desc',
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']['users']) == 3
assert 'toto' in data['data']['users'][0]['username']
assert 1 == data['data']['users'][0]['nb_workouts']
assert 'admin' in data['data']['users'][1]['username']
assert 0 == data['data']['users'][1]['nb_workouts']
2020-05-10 15:55:56 +02:00
assert 'sam' in data['data']['users'][2]['username']
assert 0 == data['data']['users'][2]['nb_workouts']
2020-05-10 15:55:56 +02:00
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 3,
}
def test_it_gets_users_list_filtering_on_username(
self, app: Flask, user_1_admin: User, user_2: User, user_3: User
2021-01-02 19:28:03 +01:00
) -> None:
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/users?q=toto',
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']['users']) == 1
assert 'toto' in data['data']['users'][0]['username']
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 1,
'total': 1,
}
def test_it_returns_username_matching_query(
self, app: Flask, user_1_admin: User, user_2: User, user_3: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.get(
'/api/users?q=oto',
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']['users']) == 1
assert 'toto' in data['data']['users'][0]['username']
def test_it_filtering_on_username_is_case_insensitive(
self, app: Flask, user_1_admin: User, user_2: User, user_3: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.get(
'/api/users?q=TOTO',
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']['users']) == 1
assert 'toto' in data['data']['users'][0]['username']
2020-05-10 15:55:56 +02:00
def test_it_returns_empty_users_list_filtering_on_username(
self, app: Flask, user_1_admin: User, user_2: User, user_3: User
2021-01-02 19:28:03 +01:00
) -> None:
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/users?q=not_existing',
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']['users']) == 0
assert data['pagination'] == {
'has_next': False,
'has_prev': False,
'page': 1,
'pages': 0,
'total': 0,
}
def test_it_users_list_with_complex_query(
self, app: Flask, user_1_admin: User, user_2: User, user_3: User
2021-01-02 19:28:03 +01:00
) -> None:
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/users?order_by=username&order=desc&page=2&per_page=2',
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']['users']) == 1
assert 'admin' in data['data']['users'][0]['username']
2020-05-10 15:55:56 +02:00
assert data['pagination'] == {
'has_next': False,
'has_prev': True,
'page': 2,
'pages': 2,
'total': 3,
}
2022-06-15 19:16:14 +02:00
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', True),
('users:write', False),
('workouts:read', False),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1_admin: User,
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.get(
'/api/users',
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
class TestGetUserPicture(ApiTestCaseMixin):
2021-01-02 19:28:03 +01:00
def test_it_return_error_if_user_has_no_picture(
self, app: Flask, user_1: User
) -> None:
2020-05-10 15:55:56 +02:00
client = app.test_client()
response = client.get(f'/api/users/{user_1.username}/picture')
self.assert_404_with_message(response, 'No picture.')
2020-05-10 15:55:56 +02:00
2021-01-02 19:28:03 +01:00
def test_it_returns_error_if_user_does_not_exist(
self, app: Flask, user_1: User
) -> None:
2020-05-10 15:55:56 +02:00
client = app.test_client()
response = client.get('/api/users/not_existing/picture')
self.assert_404_with_entity(response, 'user')
2020-05-10 15:55:56 +02:00
2021-02-20 23:20:20 +01:00
class TestUpdateUser(ApiTestCaseMixin):
def test_it_returns_error_if_payload_is_empty(
self, app: Flask, user_1_admin: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict()),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
self.assert_400(response)
def test_it_returns_error_if_payload_for_admin_rights_is_invalid(
self, app: Flask, user_1_admin: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(admin="")),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 500
data = json.loads(response.data.decode())
assert 'error' in data['status']
assert (
'error, please try again or contact the administrator'
in data['message']
)
def test_it_returns_error_if_user_can_not_change_admin_rights(
self, app: Flask, user_1: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(admin=True)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
self.assert_403(response)
2021-01-02 19:28:03 +01:00
def test_it_adds_admin_rights_to_a_user(
self, app: Flask, user_1_admin: User, user_2: 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(
f'/api/users/{user_2.username}',
2020-05-10 15:55:56 +02:00
content_type='application/json',
data=json.dumps(dict(admin=True)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 200
data = json.loads(response.data.decode())
2020-05-10 15:55:56 +02:00
assert 'success' in data['status']
assert len(data['data']['users']) == 1
user = data['data']['users'][0]
assert user['email'] == 'toto@toto.com'
assert user['admin'] is True
def test_it_removes_admin_rights_to_a_user(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1_admin: User, user_2: 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(
f'/api/users/{user_2.username}',
2020-05-10 15:55:56 +02:00
content_type='application/json',
data=json.dumps(dict(admin=False)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 200
data = json.loads(response.data.decode())
2020-05-10 15:55:56 +02:00
assert 'success' in data['status']
assert len(data['data']['users']) == 1
user = data['data']['users'][0]
assert user['email'] == 'toto@toto.com'
assert user['admin'] is False
def test_it_does_not_send_email_when_only_admin_rights_update(
self,
app: Flask,
user_1_admin: User,
user_2: User,
user_password_change_email_mock: MagicMock,
user_reset_password_email: MagicMock,
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(
f'/api/users/{user_2.username}',
2020-05-10 15:55:56 +02:00
content_type='application/json',
data=json.dumps(dict(admin=True)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 200
user_password_change_email_mock.send.assert_not_called()
user_reset_password_email.send.assert_not_called()
2020-05-10 15:55:56 +02:00
def test_it_resets_user_password(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1_admin: User, user_2: 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
)
user_2_password = user_2.password
2020-05-10 15:55:56 +02:00
response = client.patch(
f'/api/users/{user_2.username}',
2020-05-10 15:55:56 +02:00
content_type='application/json',
data=json.dumps(dict(reset_password=True)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 200
assert user_2.password != user_2_password
2020-05-10 15:55:56 +02:00
def test_it_calls_password_change_email_when_password_reset_is_successful(
self,
app: Flask,
user_1_admin: User,
user_2: User,
user_password_change_email_mock: MagicMock,
2021-01-02 19:28:03 +01:00
) -> None:
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(
f'/api/users/{user_2.username}',
2020-05-10 15:55:56 +02:00
content_type='application/json',
data=json.dumps(dict(reset_password=True)),
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 200
user_password_change_email_mock.send.assert_called_once_with(
{
'language': 'en',
'email': user_2.email,
},
{
'username': user_2.username,
'fittrackee_url': 'http://0.0.0.0:5000',
},
)
def test_it_does_not_call_password_change_email_when_email_sending_is_disabled( # noqa
self,
app_wo_email_activation: Flask,
user_1_admin: User,
user_2: User,
user_password_change_email_mock: MagicMock,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app_wo_email_activation, user_1_admin.email
)
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(reset_password=True)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 200
user_password_change_email_mock.send.assert_not_called()
def test_it_calls_reset_password_email_when_password_reset_is_successful(
self,
app: Flask,
user_1_admin: User,
user_2: User,
user_reset_password_email: MagicMock,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
with patch(
'fittrackee.users.users.User.encode_password_reset_token',
return_value='xxx',
):
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(reset_password=True)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 200
user_reset_password_email.send.assert_called_once_with(
{
'language': 'en',
'email': user_2.email,
},
{
'expiration_delay': get_readable_duration(
app.config['PASSWORD_TOKEN_EXPIRATION_SECONDS'],
'en',
),
'username': user_2.username,
'password_reset_url': (
'http://0.0.0.0:5000/password-reset?token=xxx'
),
'fittrackee_url': 'http://0.0.0.0:5000',
},
)
2020-05-10 15:55:56 +02:00
def test_it_does_not_call_reset_password_email_when_email_sending_is_disabled( # noqa
self,
app_wo_email_activation: Flask,
user_1_admin: User,
user_2: User,
user_reset_password_email: MagicMock,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app_wo_email_activation, user_1_admin.email
)
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(reset_password=True)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 200
user_reset_password_email.send.assert_not_called()
def test_it_returns_error_when_updating_email_with_invalid_address(
self, app: Flask, user_1_admin: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(new_email=self.random_string())),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
self.assert_400(response, 'valid email must be provided')
def test_it_returns_error_when_new_email_is_same_as_current_email(
self, app: Flask, user_1_admin: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(new_email=user_2.email)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
self.assert_400(
response, 'new email must be different than curent email'
)
def test_it_does_not_send_email_when_error_on_updating_email(
self,
app: Flask,
user_1_admin: User,
user_2: User,
user_email_updated_to_new_address_mock: MagicMock,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(new_email=self.random_string())),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
user_email_updated_to_new_address_mock.send.assert_not_called()
def test_it_updates_user_email_to_confirm_when_email_sending_is_enabled(
self, app: Flask, user_1_admin: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
new_email = 'new.' + user_2.email
user_2_email = user_2.email
user_2_confirmation_token = user_2.confirmation_token
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(new_email=new_email)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 200
assert user_2.email == user_2_email
assert user_2.email_to_confirm == new_email
assert user_2.confirmation_token != user_2_confirmation_token
def test_it_updates_user_email_when_email_sending_is_disabled(
self, app_wo_email_activation: Flask, user_1_admin: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app_wo_email_activation, user_1_admin.email
)
new_email = 'new.' + user_2.email
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(new_email=new_email)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 200
assert user_2.email == new_email
assert user_2.email_to_confirm is None
assert user_2.confirmation_token is None
def test_it_calls_email_updated_to_new_address_when_password_reset_is_successful( # noqa
self,
app: Flask,
user_1_admin: User,
user_2: User,
user_email_updated_to_new_address_mock: MagicMock,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
new_email = 'new.' + user_2.email
expected_token = self.random_string()
with patch('secrets.token_urlsafe', return_value=expected_token):
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(new_email=new_email)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 200
user_email_updated_to_new_address_mock.send.assert_called_once_with(
{
'language': 'en',
'email': new_email,
},
{
'username': user_2.username,
'fittrackee_url': 'http://0.0.0.0:5000',
'email_confirmation_url': (
f'http://0.0.0.0:5000/email-update?token={expected_token}'
),
},
)
def test_it_does_not_call_email_updated_to_new_address_when_email_sending_is_disabled( # noqa
self,
app_wo_email_activation: Flask,
user_1_admin: User,
user_2: User,
user_email_updated_to_new_address_mock: MagicMock,
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app_wo_email_activation, user_1_admin.email
)
new_email = 'new.' + user_2.email
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(new_email=new_email)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 200
user_email_updated_to_new_address_mock.send.assert_not_called()
def test_it_activates_user_account(
self, app: Flask, user_1_admin: User, inactive_user: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.patch(
f'/api/users/{inactive_user.username}',
content_type='application/json',
data=json.dumps(dict(activate=True)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 200
data = json.loads(response.data.decode())
assert 'success' in data['status']
assert len(data['data']['users']) == 1
user = data['data']['users'][0]
assert user['email'] == inactive_user.email
assert user['is_active'] is True
assert inactive_user.confirmation_token is None
def test_it_can_only_activate_user_account(
self, app: Flask, user_1_admin: User, user_2: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1_admin.email
)
response = client.patch(
f'/api/users/{user_2.username}',
content_type='application/json',
data=json.dumps(dict(activate=False)),
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 200
data = json.loads(response.data.decode())
assert 'success' in data['status']
assert len(data['data']['users']) == 1
user = data['data']['users'][0]
assert user['email'] == user_2.email
assert user['is_active'] is True
assert user_2.confirmation_token is None
2022-06-15 19:16:14 +02:00
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', True),
('workouts:read', False),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1_admin: User,
user_2: User,
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/users/{user_2.username}',
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 TestDeleteUser(ApiTestCaseMixin):
2021-01-02 19:28:03 +01:00
def test_user_can_delete_its_own_account(
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.delete(
'/api/users/test',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 204
def test_user_with_workout_can_delete_its_own_account(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
2020-05-10 15:55:56 +02:00
client.post(
'/api/workouts',
2020-05-10 15:55:56 +02:00
data=dict(
file=(BytesIO(str.encode(gpx_file)), 'example.gpx'),
data='{"sport_id": 1}',
),
headers=dict(
content_type='multipart/form-data',
2021-02-20 23:20:20 +01:00
Authorization=f'Bearer {auth_token}',
2020-05-10 15:55:56 +02:00
),
)
response = client.delete(
'/api/users/test',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 204
def test_user_with_preferences_can_delete_its_own_account(
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.delete(
'/api/users/test',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 204
2020-05-10 15:55:56 +02:00
def test_user_with_picture_can_delete_its_own_account(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
2020-05-10 15:55:56 +02:00
client.post(
'/api/auth/picture',
data=dict(file=(BytesIO(b'avatar'), 'avatar.png')),
headers=dict(
content_type='multipart/form-data',
2021-02-20 23:20:20 +01:00
Authorization=f'Bearer {auth_token}',
2020-05-10 15:55:56 +02:00
),
)
response = client.delete(
'/api/users/test',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 204
def test_user_with_export_request_can_delete_its_own_account(
self, app: Flask, user_1: User, sport_1_cycling: Sport, gpx_file: str
) -> None:
db.session.add(UserDataExport(user_1.id))
db.session.commit()
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
client.post(
'/api/auth/picture',
data=dict(file=(BytesIO(b'avatar'), 'avatar.png')),
headers=dict(
content_type='multipart/form-data',
Authorization=f'Bearer {auth_token}',
),
)
response = client.delete(
'/api/users/test',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 204
2020-05-10 15:55:56 +02:00
def test_user_can_not_delete_another_user_account(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1: User, user_2: 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.delete(
'/api/users/toto',
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
def test_it_returns_error_when_deleting_non_existing_user(
2021-01-02 19:28:03 +01:00
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.delete(
'/api/users/not_existing',
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_404_with_entity(response, 'user')
2020-05-10 15:55:56 +02:00
def test_admin_can_delete_another_user_account(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1_admin: User, user_2: 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.delete(
'/api/users/toto',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 204
def test_admin_can_delete_its_own_account(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1_admin: User, user_2_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.delete(
'/api/users/admin',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
assert response.status_code == 204
def test_admin_can_not_delete_its_own_account_if_no_other_admin(
2021-01-02 19:28:03 +01:00
self, app: Flask, user_1_admin: User, user_2: 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.delete(
'/api/users/admin',
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,
'you can not delete your account, no other user has admin rights',
2020-05-10 15:55:56 +02:00
)
2023-02-25 14:06:49 +01:00
def test_it_enables_registration_after_user_delete_when_users_count_is_below_limit( # noqa
2021-01-02 19:28:03 +01:00
self,
2021-02-20 23:20:20 +01:00
app_with_3_users_max: Flask,
2021-01-02 19:28:03 +01:00
user_1_admin: User,
user_2: User,
user_3: User,
) -> None:
2021-02-20 23:20:20 +01:00
client, auth_token = self.get_test_client_and_auth_token(
app_with_3_users_max, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
client.delete(
'/api/users/toto',
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
2020-05-10 15:55:56 +02:00
response = client.post(
'/api/auth/register',
data=json.dumps(
dict(
2022-03-19 22:02:06 +01:00
username=self.random_string(),
email=self.random_email(),
password=self.random_string(),
2023-02-25 14:06:49 +01:00
accepted_policy=True,
2020-05-10 15:55:56 +02:00
)
),
content_type='application/json',
)
2022-03-19 22:02:06 +01:00
assert response.status_code == 200
2020-05-10 15:55:56 +02:00
2023-02-25 14:06:49 +01:00
def test_it_does_not_enable_registration_on_user_delete_when_users_count_is_not_below_limit( # noqa
2021-01-02 19:28:03 +01:00
self,
2021-02-20 23:20:20 +01:00
app_with_3_users_max: Flask,
2021-01-02 19:28:03 +01:00
user_1_admin: User,
user_2: User,
user_3: User,
2021-02-20 23:20:20 +01:00
user_1_paris: User,
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_with_3_users_max, user_1_admin.email
2020-05-10 15:55:56 +02:00
)
client.delete(
'/api/users/toto',
2021-02-20 23:20:20 +01:00
headers=dict(Authorization=f'Bearer {auth_token}'),
2020-05-10 15:55:56 +02:00
)
response = client.post(
'/api/auth/register',
data=json.dumps(
dict(
username='justatest',
email='test@test.com',
password='12345678',
password_conf='12345678',
2023-02-25 14:06:49 +01:00
accepted_policy=True,
2020-05-10 15:55:56 +02:00
)
),
content_type='application/json',
)
self.assert_403(response, 'error, registration is disabled')
2022-06-15 19:16:14 +02:00
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', True),
('workouts:read', False),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1_admin: User,
user_2: User,
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.delete(
f'/api/users/{user_2.username}',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)