This article discusses extending a testing suite to verify the retrieval of individual posts, including unauthorized access and handling non-existent posts.
In this article, we extend our testing suite by verifying the retrieval of individual posts. We start by ensuring that unauthorized users are prevented from accessing posts and then validate both valid and invalid post retrieval scenarios using an authorized client.–––––––
First, we verify that an unauthorized user cannot retrieve all posts. The following code snippet demonstrates this test:
Copy
Ask AI
def test_unauthorized_user_get_all_posts(client, test_posts): res = client.get("/posts/") assert res.status_code == 401
Next, we ensure that an unauthorized user cannot access a single post. We use the ID of the first post in our test data. Depending on your data structure, the ID may be accessed as a dictionary key or as an object attribute. Here, we assume it is provided by the SQLAlchemy model as an attribute:
Copy
Ask AI
def test_unauthorized_user_get_one_post(client, test_posts): res = client.get(f"/posts/{test_posts[0].id}") assert res.status_code == 401
It is essential to confirm that the service returns a 404 error when a request is made for a post which does not exist. In the example below, we simulate a request for a post with an ID that is very unlikely to exist (e.g., 88888):
Copy
Ask AI
def test_get_one_post_not_exist(authorized_client, test_posts): res = authorized_client.get(f"/posts/88888") assert res.status_code == 404
When running these tests, you might encounter warnings similar to the following. These warnings do not affect the test outcomes.
Copy
Ask AI
venv\lib\site-packages\aiofiles\os.py:10: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead-- Docs: https://docs.pytest.org/en/stable/warnings.html
Finally, we test the retrieval of a valid post with an authorized client. The test includes printing the returned JSON response (useful for debugging) and then validating the response against our Pydantic schema. Note that the JSON response contains a “Post” property nested within the returned data; thus, the details are accessed from this nested object.
Copy
Ask AI
def test_get_one_post(authorized_client, test_posts): res = authorized_client.get(f"/posts/{test_posts[0].id}") # Optional: Print the JSON response for debugging purposes. # print(res.json()) post = schemas.PostOut(**res.json()) # Confirm that the retrieved post's ID and content match the expected test post. assert post.Post.id == test_posts[0].id assert post.Post.content == test_posts[0].content
For your reference, the Pydantic schema for a post is defined as follows:
Copy
Ask AI
class Post(PostBase): id: int created_at: datetime owner_id: int owner: UserOut class Config: orm_mode = True
This configuration ensures that the data returned by SQLAlchemy is compatible with our schema, which is why we access the nested “Post” property in our validation assertions.–––––––
When you run the tests with pytest, you will see an output similar to this:
Copy
Ask AI
venv\lib\site-packages\aiofiles\os.py:10: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead-- Docs: https://docs.pytest.org/en/stable/warnings.html...5 passed, 5 warnings in 1.65s
This output confirms that the tests for unauthorized access, handling non-existent posts, and retrieving a valid post are functioning as expected.–––––––
In the next article, we will explore testing the creation of a post.