API - add route to accept privacy policy
This commit is contained in:
parent
1c1d2a77b7
commit
8a3f9a5d59
@ -1,7 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Optional
|
from typing import Optional, Union
|
||||||
from unittest.mock import MagicMock, Mock, patch
|
from unittest.mock import MagicMock, Mock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -2749,3 +2749,76 @@ class TestUserLogout(ApiTestCaseMixin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.assert_invalid_token(response)
|
self.assert_invalid_token(response)
|
||||||
|
|
||||||
|
|
||||||
|
class TestUserPrivacyPolicyUpdate(ApiTestCaseMixin):
|
||||||
|
def test_it_returns_error_if_user_is_not_authenticated(
|
||||||
|
self, app: Flask, user_1: User
|
||||||
|
) -> None:
|
||||||
|
client = app.test_client()
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
'/api/auth/profile/edit/preferences',
|
||||||
|
content_type='application/json',
|
||||||
|
data=json.dumps(dict(accepted_policy=True)),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assert_401(response)
|
||||||
|
|
||||||
|
def test_it_returns_error_if_accepted_policy_is_missing(
|
||||||
|
self, app: Flask, user_1: User
|
||||||
|
) -> None:
|
||||||
|
client, auth_token = self.get_test_client_and_auth_token(
|
||||||
|
app, user_1.email
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
'/api/auth/account/privacy-policy',
|
||||||
|
content_type='application/json',
|
||||||
|
data=json.dumps(dict()),
|
||||||
|
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assert_400(response)
|
||||||
|
|
||||||
|
def test_it_updates_accepted_policy(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
user_1: User,
|
||||||
|
) -> None:
|
||||||
|
client, auth_token = self.get_test_client_and_auth_token(
|
||||||
|
app, user_1.email
|
||||||
|
)
|
||||||
|
accepted_policy_date = datetime.utcnow()
|
||||||
|
|
||||||
|
with patch('fittrackee.users.auth.datetime.datetime') as datetime_mock:
|
||||||
|
datetime_mock.utcnow = Mock(return_value=accepted_policy_date)
|
||||||
|
response = client.post(
|
||||||
|
'/api/auth/account/privacy-policy',
|
||||||
|
content_type='application/json',
|
||||||
|
data=json.dumps(dict(accepted_policy=True)),
|
||||||
|
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert user_1.accepted_policy_date == accepted_policy_date
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('input_accepted_policy', [False, '', None, 'foo'])
|
||||||
|
def test_it_return_error_if_user_has_not_accepted_policy(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
user_1: User,
|
||||||
|
input_accepted_policy: Union[str, bool, None],
|
||||||
|
) -> None:
|
||||||
|
client, auth_token = self.get_test_client_and_auth_token(
|
||||||
|
app, user_1.email
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
'/api/auth/account/privacy-policy',
|
||||||
|
content_type='application/json',
|
||||||
|
data=json.dumps(dict(accepted_policy=input_accepted_policy)),
|
||||||
|
headers=dict(Authorization=f'Bearer {auth_token}'),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
@ -883,6 +883,7 @@ def edit_user_preferences(auth_user: User) -> Union[Dict, HttpResponse]:
|
|||||||
:<json string language: language preferences
|
:<json string language: language preferences
|
||||||
:<json string timezone: user time zone
|
:<json string timezone: user time zone
|
||||||
:<json boolean weekm: does week start on Monday?
|
:<json boolean weekm: does week start on Monday?
|
||||||
|
:<json boolean weekm: does week start on Monday?
|
||||||
|
|
||||||
:reqheader Authorization: OAuth 2.0 Bearer Token
|
:reqheader Authorization: OAuth 2.0 Bearer Token
|
||||||
|
|
||||||
@ -1631,3 +1632,55 @@ def logout_user(auth_user: User) -> Union[Tuple[Dict, int], HttpResponse]:
|
|||||||
'status': 'success',
|
'status': 'success',
|
||||||
'message': 'successfully logged out',
|
'message': 'successfully logged out',
|
||||||
}, 200
|
}, 200
|
||||||
|
|
||||||
|
|
||||||
|
@auth_blueprint.route('/auth/account/privacy-policy', methods=['POST'])
|
||||||
|
@require_auth()
|
||||||
|
def accept_privacy_policy(auth_user: User) -> Union[Dict, HttpResponse]:
|
||||||
|
"""
|
||||||
|
The authenticated user accepts the privacy policy.
|
||||||
|
|
||||||
|
**Example request**:
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
POST /auth/account/privacy-policy HTTP/1.1
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
**Example response**:
|
||||||
|
|
||||||
|
.. sourcecode:: http
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"status": "success"
|
||||||
|
}
|
||||||
|
|
||||||
|
:<json boolean accepted_policy: true if user accepted privacy policy
|
||||||
|
|
||||||
|
:reqheader Authorization: OAuth 2.0 Bearer Token
|
||||||
|
|
||||||
|
:statuscode 200: success
|
||||||
|
:statuscode 400:
|
||||||
|
- invalid payload
|
||||||
|
:statuscode 401:
|
||||||
|
- provide a valid auth token
|
||||||
|
- signature expired, please log in again
|
||||||
|
- invalid token, please log in again
|
||||||
|
:statuscode 500: internal server error
|
||||||
|
"""
|
||||||
|
post_data = request.get_json()
|
||||||
|
if not post_data or not post_data.get('accepted_policy'):
|
||||||
|
return InvalidPayloadErrorResponse()
|
||||||
|
|
||||||
|
try:
|
||||||
|
if post_data.get('accepted_policy') is True:
|
||||||
|
auth_user.accepted_policy_date = datetime.datetime.utcnow()
|
||||||
|
db.session.commit()
|
||||||
|
return {"status": "success"}
|
||||||
|
else:
|
||||||
|
return InvalidPayloadErrorResponse()
|
||||||
|
except (exc.IntegrityError, exc.OperationalError, ValueError) as e:
|
||||||
|
return handle_error_and_return_response(e, db=db)
|
||||||
|
Loading…
Reference in New Issue
Block a user