The HTTP 401 status code means a request does not include valid authentication credentials. It differs from 403 Forbidden: 403 means the credentials are valid, but access is not allowed. section 12.4
Testing an unauthenticated request
A test sends an unauthenticated GET request to /courses/{course_id}/lessons/{lesson_id}. The correct expectation is 401. If the API returns 403 instead, the test has exposed an authentication-response problem and potentially a security flaw. section 12.4
Use these checks when testing authentication failures:
- Send the request without credentials and assert a 401 response. section 12.4
- Use pytest to automate the check and reveal unauthorized access to protected content. section 12.4
Listing 12.2 Running a broken authentication test
# file: ch12/tests.py
from sqlalchemy import select
from starlette_testclient import TestClient
from db_session import session_maker
from models import Course
from server import server
client = TestClient(server) #1
def test_broken_authentication():
with session_maker() as session: #2
course = session.scalar(select(Course)) #3
lessons = course.lessons
response = client.get(
f"/courses/{course.id}/lessons/{lessons[0].id}"
) #4
assert response.status_code == 403 #5
Inspect the focused test structure: create a test client, obtain resource identifiers, send an unauthenticated request, and verify the response status. section 12.4

