Skip to content

Commit 5203ff9

Browse files
Angeluz-07magallegos1996scastillo-jp
authored
230 users endpoint (#233)
* feat: WIP users endpoint #230 * feat: WIP users endpoint role field #230 * feat: WIP users endpoint unit tests #230 * feat: users endpoint test expected response props and http status code #230 * fix: remove library Co-authored-by: magallegos1996 <[email protected]> Co-authored-by: Sandro Castillo <[email protected]>
1 parent 5a27fe4 commit 5203ff9

File tree

4 files changed

+106
-3
lines changed

4 files changed

+106
-3
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from unittest.mock import Mock
2+
from flask import json
3+
from flask.testing import FlaskClient
4+
from flask_restplus._http import HTTPStatus
5+
from utils.azure_users import AzureConnection
6+
7+
8+
def test_users_response_contains_expected_props(
9+
client: FlaskClient,
10+
valid_header: dict,
11+
):
12+
13+
AzureConnection.users = Mock(
14+
return_value=[{'name': 'dummy', 'email': 'dummy', 'role': 'dummy'}]
15+
)
16+
17+
response = client.get(
18+
'/users',
19+
headers=valid_header,
20+
)
21+
22+
assert HTTPStatus.OK == response.status_code
23+
assert 'name' in json.loads(response.data)[0]
24+
assert 'email' in json.loads(response.data)[0]
25+
assert 'role' in json.loads(response.data)[0]

time_tracker_api/api.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ def init_app(app: Flask):
118118

119119
api.add_namespace(technologies_namespace.ns)
120120

121+
from time_tracker_api.users import users_namespace
122+
123+
api.add_namespace(users_namespace.ns)
124+
121125

122126
"""
123127
Error handlers
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from faker import Faker
2+
from flask_restplus import fields, Resource
3+
from flask_restplus._http import HTTPStatus
4+
5+
from time_tracker_api.api import common_fields, api
6+
7+
faker = Faker()
8+
9+
ns = api.namespace('users', description='Namespace of the API for users')
10+
11+
# User Model
12+
13+
user_response_fields = ns.model(
14+
'User',
15+
{
16+
'name': fields.String(
17+
title='Name',
18+
max_length=50,
19+
description='Name of the user',
20+
example=faker.word(['Marcelo', 'Sandro']),
21+
),
22+
'email': fields.String(
23+
title="User's Email",
24+
max_length=50,
25+
description='Email of the user that belongs to the tenant',
26+
example=faker.email(),
27+
),
28+
'role': fields.String(
29+
title="User's Role",
30+
max_length=50,
31+
description='Role assigned to the user by the tenant',
32+
example=faker.word(['admin']),
33+
),
34+
},
35+
)
36+
37+
user_response_fields.update(common_fields)
38+
39+
40+
@ns.route('')
41+
class Users(Resource):
42+
@ns.doc('list_users')
43+
@ns.marshal_list_with(user_response_fields)
44+
def get(self):
45+
"""List all users"""
46+
from utils.azure_users import AzureConnection
47+
48+
azure_connection = AzureConnection()
49+
return azure_connection.users()
50+
51+
52+
@ns.route('/<string:id>')
53+
@ns.response(HTTPStatus.NOT_FOUND, 'User not found')
54+
@ns.response(HTTPStatus.UNPROCESSABLE_ENTITY, 'The id has an invalid format')
55+
@ns.param('id', 'The user identifier')
56+
class User(Resource):
57+
@ns.doc('get_user')
58+
@ns.marshal_with(user_response_fields)
59+
def get(self, id):
60+
"""Get an user"""
61+
return {}

utils/azure_users.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ def __call__(self, r):
3737

3838

3939
class AzureUser:
40-
def __init__(self, id, name, email):
40+
def __init__(self, id, name, email, role):
4141
self.id = id
4242
self.name = name
4343
self.email = email
44+
self.role = role
4445

4546

4647
class AzureConnection:
@@ -66,12 +67,24 @@ def get_token(self):
6667
def users(self) -> List[AzureUser]:
6768
def to_azure_user(item) -> AzureUser:
6869
there_is_email = len(item['otherMails']) > 0
70+
there_is_role = (
71+
'extension_1d76efa96f604499acc0c0ee116a1453_role' in item
72+
)
73+
6974
id = item['objectId']
7075
name = item['displayName']
7176
email = item['otherMails'][0] if there_is_email else ''
72-
return AzureUser(id, name, email)
77+
role = (
78+
item['extension_1d76efa96f604499acc0c0ee116a1453_role']
79+
if there_is_role
80+
else None
81+
)
82+
return AzureUser(id, name, email, role)
7383

74-
endpoint = f"{self.config.ENDPOINT}/users?api-version=1.6&$select=displayName,otherMails,objectId"
84+
endpoint = "{endpoint}/users?api-version=1.6&$select=displayName,otherMails,objectId,{role_field}".format(
85+
endpoint=self.config.ENDPOINT,
86+
role_field='extension_1d76efa96f604499acc0c0ee116a1453_role',
87+
)
7588
response = requests.get(endpoint, auth=BearerAuth(self.access_token))
7689

7790
assert 200 == response.status_code

0 commit comments

Comments
 (0)