Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions schema_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import jsonschema

#created this file to place helper functions for cleaner code

#helper function to validate pet schemas
def validate_schema(instance, schema):
try:
jsonschema.validate(instance=instance, schema=schema)
except jsonschema.ValidationError as e:
path = ".".join(str(p) for p in e.path)
raise AssertionError(
f"Schema validation error at '{path}': {e.message}"
) from e

#helper function to safely verify json
def safe_json(response):
if not response.content:
return None

try:
return response.json()
except ValueError:
return None
28 changes: 27 additions & 1 deletion schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
"id": {
"type": "integer"
},
#switched name type to string from integer to fix test 1 in test_pet.py
"name": {
"type": "integer"
"type": "string"
},
"type": {
"type": "string",
Expand All @@ -18,3 +19,28 @@
},
}
}

#defined new order schemas for use in test_store
order = {
"type": "object",
"required": ["pet_id"],
"properties": {
"id": {
"type": "string"
},
"pet_id": {
"type": "integer"
}
}
}


order_update = {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["available", "sold", "pending"]
}
}
}
52 changes: 47 additions & 5 deletions test_pet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import schemas
import api_helpers
from hamcrest import assert_that, contains_string, is_
#added imports for helper functions in a new helper file
import schema_helpers
from schema_helpers import safe_json

'''
TODO: Finish this test by...
Expand All @@ -26,21 +29,60 @@ def test_pet_schema():
3) Validate the 'status' property in the response is equal to the expected status
4) Validate the schema for each object in the response
'''
@pytest.mark.parametrize("status", [("available")])
#updated parameters to include all status params - added pending, sold
@pytest.mark.parametrize("status", ["available", "pending", "sold"])
def test_find_by_status_200(status):
test_endpoint = "/pets/findByStatus"
params = {
"status": status
}

response = api_helpers.get_api_data(test_endpoint, params)
# TODO...

#validate appropriate response code
assert response.status_code == 200

response_json = response.json()

#response should be a list
assert isinstance(response_json, list)

for pet in response_json:
#validate the status property
assert pet["status"] == status

#validating schema for each object
schema_helpers.validate_schema(
instance=pet,
schema=schemas.pet
)


'''
TODO: Finish this test by...
1) Testing and validating the appropriate 404 response for /pets/{pet_id}
2) Parameterizing the test for any edge cases
'''
def test_get_by_id_404():
# TODO...
pass
#parameterizing the edge cases
@pytest.mark.parametrize(
"pet_id, expected_status",
[
(0, 200), # API treats 0 as valid
(-1, 404), # invalid ID, no body
(999999999, 404), # non-existent
("invalid", 404), # invalid type
]
)
def test_get_by_id_404(pet_id, expected_status):
response = api_helpers.get_api_data(f"/pets/{pet_id}")

#validate response code
assert response.status_code == expected_status

#safely validate error body if present
if expected_status == 404:
body = safe_json(response)

#API may or may not return a body, valid either way
if body is not None:
assert "message" in body
79 changes: 73 additions & 6 deletions test_store.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
from jsonschema import validate
import pytest
import schemas
import api_helpers
from hamcrest import assert_that, contains_string, is_
import requests
import random
import schema_helpers
from schemas import pet, order, order_update # assumes your schemas.py has order and order_update
import schema_helpers
from schema_helpers import safe_json
import string

BASE_URL = "http://127.0.0.1:5000/" # Replace with your API base URL

'''
TODO: Finish this test by...
Expand All @@ -12,5 +17,67 @@
3) Validate the response codes and values
4) Validate the response message "Order and pet status updated successfully"
'''
def test_patch_order_by_id():
pass

@pytest.fixture
def create_random_order():
#create a random pet
pet_id = random.randint(1000, 99999)
pet_name = "pet_" + "".join(random.choices(string.ascii_lowercase + string.digits, k=6))
pet_data = {
"id": pet_id,
"name": pet_name,
"type": "cat",
"status": "available"
}

resp_pet = requests.post(f"{BASE_URL}/pets", json=pet_data)
assert resp_pet.status_code in (200, 201), f"Pet creation failed: {resp_pet.content}"

#create a random order for this pet
order_id = "order_" + "".join(random.choices(string.digits, k=5))
order_data = {
"id": order_id,
"pet_id": pet_id
}

resp_order = requests.post(f"{BASE_URL}/store/order", json=order_data)
assert resp_order.status_code in (200, 201), f"Order creation failed: {resp_order.content}"

#validate order schema
order_schema = {
"type": "object",
"required": ["pet_id"],
"properties": {
"id": {"type": "string"},
"pet_id": {"type": "integer"}
}
}
schema_helpers.validate_schema(resp_order.json(), order_schema)

yield order_id, pet_id

#delete the order and pet
requests.delete(f"{BASE_URL}/store/order/{order_id}")
requests.delete(f"{BASE_URL}/pets/{pet_id}")


def test_patch_order_to_available(create_random_order):

order_id, pet_id = create_random_order
patch_data = {"status": "available"}

#send PATCH request
#NOTE: this line quietly fails, unsure of cause
resp = requests.patch(f"{BASE_URL}/store/order/{order_id}", json=patch_data)
assert resp.status_code == 200, f"PATCH failed: {resp.content}"

resp_json = resp.json()

#validate message
assert resp_json.get("message") == "Order and pet status updated successfully"

#validate schema
schema_helpers.validate_schema(resp_json, order_update)

#validate updated status
assert resp_json.get("status") == "available"