FitTrackee/fittrackee/tests/oauth2/test_oauth2_routes.py

164 lines
4.9 KiB
Python

import json
from typing import List, Union
from unittest.mock import patch
import pytest
from flask import Flask
from fittrackee.oauth2.models import OAuth2Client
from fittrackee.users.models import User
from ..mixins import ApiTestCaseMixin
from ..utils import random_domain, random_string
TEST_METADATA = {
'client_name': random_string(),
'client_uri': random_domain(),
'redirect_uris': [random_domain()],
'scope': 'read write',
}
class TestOAuthClientCreation(ApiTestCaseMixin):
route = '/api/oauth/apps'
def test_it_returns_error_when_no_user_authenticated(
self, app: Flask, user_1: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
response = client.post(
self.route,
data=json.dumps(TEST_METADATA),
content_type='application/json',
)
self.assert_401(response)
def test_it_returns_error_when_no_metadata_provided(
self, app: Flask, user_1: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
response = client.post(
self.route,
data=json.dumps(dict()),
content_type='application/json',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
self.assert_400(
response, error_message='OAuth client metadata missing'
)
@pytest.mark.parametrize(
'missing_key',
[
'client_name',
'client_uri',
'redirect_uris',
'scope',
],
)
def test_it_returns_error_when_metadata_key_is_missing(
self, app: Flask, user_1: User, missing_key: str
) -> None:
metadata = TEST_METADATA.copy()
del metadata[missing_key]
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
response = client.post(
self.route,
data=json.dumps(metadata),
content_type='application/json',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
self.assert_400(
response,
error_message=f'OAuth client metadata missing keys: {missing_key}',
)
def test_it_creates_oauth_client(self, app: Flask, user_1: User) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
response = client.post(
self.route,
data=json.dumps(TEST_METADATA),
content_type='application/json',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
assert response.status_code == 201
oauth_client = OAuth2Client.query.first()
assert oauth_client is not None
def test_it_returns_serialized_oauth_client(
self, app: Flask, user_1: User
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
client_id = self.random_string()
client_secret = self.random_string()
with patch(
'fittrackee.oauth2.client.gen_salt',
side_effect=[client_id, client_secret],
):
response = client.post(
self.route,
data=json.dumps(TEST_METADATA),
content_type='application/json',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
data = json.loads(response.data.decode())
assert data['data']['client']['client_id'] == client_id
assert data['data']['client']['client_secret'] == client_secret
assert data['data']['client']['name'] == TEST_METADATA['client_name']
assert (
data['data']['client']['redirect_uris']
== TEST_METADATA['redirect_uris']
)
assert data['data']['client']['website'] == TEST_METADATA['client_uri']
@pytest.mark.parametrize(
'input_key,expected_value',
[
('grant_types', ['authorization_code']),
('response_types', ['code']),
('token_endpoint_auth_method', 'client_secret_post'),
],
)
def test_it_always_create_oauth_client_with_authorization_grant(
self,
app: Flask,
user_1: User,
input_key: str,
expected_value: Union[List, str],
) -> None:
client, auth_token = self.get_test_client_and_auth_token(
app, user_1.email
)
client.post(
self.route,
data=json.dumps(
{**TEST_METADATA, input_key: self.random_string()}
),
content_type='application/json',
headers=dict(Authorization=f'Bearer {auth_token}'),
)
oauth_client = OAuth2Client.query.first()
assert getattr(oauth_client, input_key) == expected_value