164 lines
4.9 KiB
Python
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
|