Skip to content

Commit 6204734

Browse files
author
Gaurav Singh
committed
- Abstracted API methods into a people_client which makes use of a custom request wrapper instead of directly depending on requests
Note: This change breaks few tests.
1 parent e8c0016 commit 6204734

File tree

10 files changed

+111
-54
lines changed

10 files changed

+111
-54
lines changed

clients/__init__.py

Whitespace-only changes.

clients/people/__init__.py

Whitespace-only changes.

clients/people/people_client.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from json import dumps
2+
from uuid import uuid4
3+
4+
import requests
5+
from assertpy import assert_that
6+
7+
from config import BASE_URI
8+
from utils.request import get, post
9+
10+
11+
class PeopleClient:
12+
def __init__(self):
13+
self.base_url = BASE_URI
14+
15+
def create_person(self, body=None):
16+
last_name, response = self.create_person_with_unique_last_name(body)
17+
assert_that(response.status_code, description='Person not created').is_equal_to(requests.codes.no_content)
18+
return last_name, response
19+
20+
def read_one_person_by_id(self, person_id):
21+
pass
22+
23+
def read_all_persons(self):
24+
return get(self.base_url)
25+
26+
def update_person(self):
27+
pass
28+
29+
def delete_person(self, person_id):
30+
delete_url = f'{BASE_URI}/{person_id}'
31+
32+
33+
def create_person_with_unique_last_name(self, body=None):
34+
if body is None:
35+
last_name = f'User {str(uuid4())}'
36+
payload = dumps({
37+
'fname': 'New',
38+
'lname': last_name
39+
})
40+
else:
41+
last_name = body['lname']
42+
payload = dumps(body)
43+
44+
headers = {
45+
'Content-Type': 'application/json',
46+
'Accept': 'application/json'
47+
}
48+
49+
response = post(self.base_url, payload, headers)
50+
return last_name, response

endpoints/__init__.py

Whitespace-only changes.

tests/assertions/__init__.py

Whitespace-only changes.

tests/helpers/__init__.py

Whitespace-only changes.

tests/helpers/people_helpers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def search_created_user_in(peoples, last_name):
2+
return [person for person in peoples if person['lname'] == last_name]

tests/people_test.py

Lines changed: 16 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,41 @@
11
import random
2-
from json import dumps, loads
3-
from uuid import uuid4
2+
from json import loads
43

54
import pytest
65
import requests
76
from assertpy.assertpy import assert_that
87
from jsonpath_ng import parse
98

9+
from clients.people.people_client import PeopleClient
1010
from config import BASE_URI
11+
from tests.helpers.people_helpers import search_created_user_in
1112
from utils.file_reader import read_file
1213

14+
client = PeopleClient()
15+
1316

1417
def test_read_all_has_kent():
15-
# We use requests.get() with url to make a get request
16-
response = requests.get(BASE_URI)
17-
# response from requests has many useful properties
18-
# we can assert on the response status code
19-
assert_that(response.status_code).is_equal_to(requests.codes.ok)
20-
# We can get python dict as response by using .json() method
21-
response_content = response.json()
18+
response = client.read_all_persons()
2219

23-
# Use assertpy's fluent assertions to extract all fnames and then see the result is non empty and has
24-
# Kent in it.
25-
assert_that(response_content).extracting('fname').is_not_empty().contains('Kent')
20+
assert_that(response.status_code).is_equal_to(requests.codes.ok)
21+
assert_that(response.as_dict).extracting('fname').is_not_empty().contains('Kent')
2622

2723

2824
def test_new_person_can_be_added():
29-
unique_last_name = create_person_with_unique_last_name()
25+
last_name, response = client.create_person()
26+
peoples = client.read_all_persons().as_dict
3027

31-
# After user is created, we read all the users and then use filter expression to find if the
32-
# created user is present in the response list
33-
peoples = requests.get(BASE_URI).json()
34-
is_new_user_created = search_created_user_in(peoples, unique_last_name)
28+
is_new_user_created = search_created_user_in(peoples, last_name)
3529
assert_that(is_new_user_created).is_not_empty()
3630

3731

3832
def test_created_person_can_be_deleted():
39-
persons_last_name = create_person_with_unique_last_name()
33+
persons_last_name = client.create_person()
4034

41-
peoples = requests.get(BASE_URI).json()
42-
newly_created_user = search_created_user_in(peoples, persons_last_name)[0]
35+
peoples = client.read_all_persons().as_dict
36+
new_person_id = search_created_user_in(peoples, persons_last_name)[0]['person_id']
4337

44-
delete_url = f'{BASE_URI}/{newly_created_user["person_id"]}'
45-
response = requests.delete(delete_url)
38+
response = client.delete_person(new_person_id)
4639
assert_that(response.status_code).is_equal_to(requests.codes.ok)
4740

4841

@@ -58,7 +51,7 @@ def create_data():
5851

5952

6053
def test_person_can_be_added_with_a_json_template(create_data):
61-
create_person_with_unique_last_name(create_data)
54+
client.create_person(create_data)
6255

6356
response = requests.get(BASE_URI)
6457
peoples = loads(response.text)
@@ -72,33 +65,3 @@ def test_person_can_be_added_with_a_json_template(create_data):
7265

7366
expected_last_name = create_data['lname']
7467
assert_that(result).contains(expected_last_name)
75-
76-
77-
def create_person_with_unique_last_name(body=None):
78-
if body is None:
79-
# Ensure a user with a unique last name is created everytime the test runs
80-
# Note: json.dumps() is used to convert python dict to json string
81-
unique_last_name = f'User {str(uuid4())}'
82-
payload = dumps({
83-
'fname': 'New',
84-
'lname': unique_last_name
85-
})
86-
else:
87-
unique_last_name = body['lname']
88-
payload = dumps(body)
89-
90-
# Setting default headers to show that the client accepts json
91-
# And will send json in the headers
92-
headers = {
93-
'Content-Type': 'application/json',
94-
'Accept': 'application/json'
95-
}
96-
97-
# We use requests.post method with keyword params to make the request more readable
98-
response = requests.post(url=BASE_URI, data=payload, headers=headers)
99-
assert_that(response.status_code, description='Person not created').is_equal_to(requests.codes.no_content)
100-
return unique_last_name
101-
102-
103-
def search_created_user_in(peoples, last_name):
104-
return [person for person in peoples if person['lname'] == last_name]

utils/file_reader.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import json
22
from pathlib import Path
33

4-
BASE_PATH = Path.cwd().joinpath('..', 'tests', 'data')
4+
BASE_PATH = Path.cwd().joinpath('tests', 'data')
55

66

77
def read_file(file_name):

utils/request.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from dataclasses import dataclass
2+
3+
import requests
4+
5+
6+
@dataclass
7+
class Response:
8+
status_code: int
9+
text: str
10+
as_dict: object
11+
headers: dict
12+
13+
14+
def __get_responses(response):
15+
status_code = response.status_code
16+
text = response.text
17+
18+
try:
19+
as_dict = response.json()
20+
except Exception:
21+
as_dict = {}
22+
23+
headers = response.headers
24+
25+
return Response(
26+
status_code, text, as_dict, headers
27+
)
28+
29+
30+
def get(url):
31+
response = requests.get(url)
32+
return __get_responses(response)
33+
34+
35+
def post(url, payload, headers):
36+
response = requests.post(url, data=payload, headers=headers)
37+
return __get_responses(response)
38+
39+
40+
def delete(url):
41+
response = requests.delete(url)
42+
return __get_responses(response)

0 commit comments

Comments
 (0)