-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_quotes_api.py
More file actions
248 lines (183 loc) · 9.5 KB
/
test_quotes_api.py
File metadata and controls
248 lines (183 loc) · 9.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
import requests
import pytest
class APIClient:
def __init__(self):
self.base_url = "http://127.0.0.1:6543"
self.session = requests.Session()
# POST /reset
def reset_api_state(self):
# Make a POST request to the /reset endpoint with an empty JSON object
response = self.session.post(f"{self.base_url}/reset", json={})
# Store JSON data
response_data = response.json()
# Verify API status
assert response_data.get("ok") is True, "Failed to reset API state"
# GET /quotes
def get_quotes(self):
# Retrieve list of quote objects
response = self.session.get(f"{self.base_url}/quotes")
# Store JSON data
response_data = response.json()
# Verify quotes retrieval
assert response_data.get("ok") is True, "Failed to retrieve quotes"
# Store data from dictionary
response_data = response_data.get("data")
# Check for sorted by ID
assert all(response_data[i]['id'] < response_data[i + 1]['id'] for i in range(len(response_data) - 1)), "Quotes are not sorted by ID"
# Check for duplicates
assert len(response_data) == len(set(quote["id"] for quote in response_data)), "Duplicate IDs found"
# Display quotes
print(f"\n\nQuotes in JSON format from GET /quotes:\n\n {response_data}")
return response_data
# POST /quotes
def add_quote(self, text):
# Check for STRING INPUT else return error 400
assert isinstance(text, str), "400 Bad Request - Invalid text format"
# Check for EMPTY FIELD else return error 400
assert len(text) > 0, "400 Bad Request - Text cannot be empty"
# Make a GET request to retrieve current list of quotes
previous_get_response = self.session.get(f"{self.base_url}/quotes")
# Store JSON data
previous_get_response_data = previous_get_response.json()
# Verify OLD quotes were retrieved
assert previous_get_response_data.get("ok") is True, "Failed to retrieve quote"
# Store OLD quotes' IDs
previous_ids_list = [item["id"] for item in previous_get_response_data.get("data")]
# Make a POST request to add a new quote
post_response = self.session.post(f"{self.base_url}/quotes", json={"text": text})
# Store JSON data
post_response_data = post_response.json()
# Verify NEW quote addition
assert post_response_data.get("ok") is True, "Failed to add quote"
# Retrieve UPDATED list of quotes
new_get_response = self.session.get(f"{self.base_url}/quotes")
# Store JSON data
new_get_response_data = new_get_response.json()
# Verify NEW UPDATED quotes retrieved
assert new_get_response_data.get("ok") is True, "Failed request. Possible max capacity reached."
# Store NEW last quote's id
new_id = max([item["id"] for item in new_get_response_data.get("data")]) # Only works if the new id = new id - 1 (e.g. 9 is the previous ID, and 10 is the new last ID)
# Store NEW last quote's text
new_text = next(item["text"] for item in new_get_response_data.get("data") if item["id"] == new_id)
# Verify new quote contains a new ID
assert new_id not in list(set(previous_ids_list)), "New quote does not have a new ID"
# Verify new quote contains the new input text corresponding to its new assigned ID
assert new_text == text, f"Text mismatch: {new_text} != {text}"
return new_get_response_data
# GET /quotes/<id>
def get_quote_by_id(self, quote_id):
# Make a GET request to fetch a specific quote by ID
quote_response = self.session.get(f"{self.base_url}/quotes/{quote_id}")
# Store JSON data
quote_response_data = quote_response.json()
# Verify quote retrieval
assert quote_response_data.get("ok") is True, f"404 Not Found - Quote with ID {quote_id} not found"
# Store text requested by ID
quote_by_id = quote_response_data.get("data").get("text")
# Make a GET request to fetch all quotes
all_response = self.session.get(f"{self.base_url}/quotes")
# Store JSON
all_response_data = all_response.json()
# Store text by ID from dictionary of all quotes (response_data)
quote_from_all = next(quote["text"] for quote in all_response_data["data"] if quote["id"] == quote_id)
# Verify text of quote by ID matches quote from GET /quotes
assert quote_by_id == quote_from_all, "Text retrieved by ID does not match text in API list"
# Store quote
quote_object = quote_response_data.get("data")
# Display object [id, text]
print(f"\nRequested quote: {quote_object}\n")
return quote_object
# DELETE /quotes/<id>
def delete_quote_by_id(self, quote_id):
# Make a DELETE request to remove a specific quote
response = self.session.delete(f"{self.base_url}/quotes/{quote_id}")
# Store JSON
response_data = response.json()
# Verify quote deletion
assert response_data.get("ok") is True, f"404 Not Found - Quote with ID {quote_id} not found"
# Store data
deleted_quote = response_data.get("data")
# Print retrieved data from API (data should be None/Null)
print(f"\nDeleted quote '{quote_id}' data: {deleted_quote}\n")
# Decorator allowing pytest to identify a fixture
@pytest.fixture
def api_client():
# Create an instance of APIClient for each test
client = APIClient()
# Reset the API state before each test
client.reset_api_state()
# Return the client object
return client
# ALL TESTS ARE BELOW
def test_get_quotes(api_client):
print("Beginning of 1st set of tests: Retrieved data should be sorted by id & without duplicates for at least 12 quotes.")
print("\n\nBEFORE POSTING NEW QUOTES")
api_client.get_quotes()
api_client.add_quote("Mambo number 4")
api_client.add_quote("Mambo number 5")
api_client.add_quote("Mambo number 6")
api_client.add_quote("Mambo number 7")
api_client.add_quote("Mambo number 8")
api_client.add_quote("Mambo number 9")
api_client.add_quote("Mambo number 10") # AssertionError
api_client.add_quote("Mambo number 11") # AssertionError
api_client.add_quote("Mambo number 12") # AssertionError
print("\n\nAFTER POSTING NEW QUOTES")
api_client.get_quotes()
print("\n\nEnd of 1st set of tests.")
def test_add_quote(api_client):
print("Beginning of 2nd set of tests: User can add a new code with personalized text. Added quote should be a non-empty string.\n"
"Response data should contain a new ID with its corresponding text. Verify that API can store at least 20 quotes.")
api_client.get_quotes()
print("\n\nBEFORE POSTING NEW QUOTES")
api_client.add_quote("Mambo number 4")
api_client.add_quote("Mambo number 5")
api_client.add_quote("Mambo number 6")
api_client.add_quote("Mambo number 7")
api_client.add_quote("Mambo number 8")
api_client.add_quote("Mambo number 9")
api_client.add_quote("Mambo number 10")
api_client.add_quote("Mambo number 11")
api_client.add_quote("Mambo number 12")
api_client.add_quote("Mambo number 13")
api_client.add_quote("Mambo number 14")
api_client.add_quote("Mambo number 15")
api_client.add_quote("Mambo number 16")
api_client.add_quote("Mambo number 17")
api_client.add_quote("Mambo number 18")
api_client.add_quote("Mambo number 19") # AssertionError
api_client.add_quote("Mambo number 20") # AssertionError
api_client.add_quote(123) # AssertionError
api_client.add_quote("") # AssertionError
print("\n\nAFTER POSTING NEW QUOTES")
api_client.get_quotes()
print("\n\nEnd of 2nd set of tests.")
def test_get_quote_by_id(api_client):
print("Beginning of 3rd set of tests: All quotes are retrievable individually based on their ID, and the text matches.")
print("\n\nBEFORE POSTING NEW QUOTES")
api_client.get_quotes()
api_client.add_quote("Mambo number 4")
api_client.add_quote("Mambo number 5")
api_client.add_quote("Mambo number 6")
api_client.add_quote("Mambo number 7")
api_client.add_quote("Mambo number 8")
api_client.add_quote("Mambo number 9")
api_client.add_quote("Mambo number 10")
api_client.get_quote_by_id(5)
api_client.get_quote_by_id(10)
api_client.get_quote_by_id(11) # AssertionError
print("\nAFTER POSTING NEW QUOTES")
api_client.get_quotes()
print("\n\nEnd of 3rd set of tests.")
def test_delete_quote_by_id(api_client):
print("Beginning of 4th set of tests: Removing quotes should succeed and subsequent attempts reply with code 404. No longer shows up in GET /quotes after deletion.")
print("\n\nBEFORE POSTING NEW QUOTES")
api_client.get_quotes()
api_client.add_quote("Mambo number 4")
api_client.add_quote("Mambo number 5")
api_client.delete_quote_by_id(2)
api_client.delete_quote_by_id(4)
api_client.delete_quote_by_id(4) # AssertionError
print("\nAFTER POSTING NEW QUOTES & DELETION")
api_client.get_quotes()
print("\n\nEnd of 4th set of tests.")