Skip to content

Commit fcac7e6

Browse files
committed
Add tests for activity signup and unregistration functionality
1 parent 1c66265 commit fcac7e6

3 files changed

Lines changed: 152 additions & 1 deletion

File tree

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
fastapi
22
uvicorn
33
httpx
4-
watchfiles
4+
watchfiles
5+
pytest

tests/__init__.py

Whitespace-only changes.

tests/test_app.py

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import copy
2+
import pytest
3+
from fastapi.testclient import TestClient
4+
from src.app import app, activities
5+
6+
@pytest.fixture(autouse=True)
7+
def reset_activities():
8+
"""Reset activities to original state before each test."""
9+
original = copy.deepcopy(activities)
10+
yield
11+
activities.clear()
12+
activities.update(original)
13+
14+
15+
client = TestClient(app)
16+
17+
18+
# ── GET / ────────────────────────────────────────────────────────────────
19+
20+
def test_root_redirect():
21+
# Arrange
22+
url = "/"
23+
24+
# Act
25+
response = client.get(url, follow_redirects=False)
26+
27+
# Assert
28+
assert response.status_code == 307
29+
assert response.headers["location"] == "/static/index.html"
30+
31+
32+
# ── GET /activities ──────────────────────────────────────────────────────
33+
34+
def test_get_activities_returns_all():
35+
# Arrange
36+
expected_keys = {"description", "schedule", "max_participants", "participants"}
37+
38+
# Act
39+
response = client.get("/activities")
40+
41+
# Assert
42+
assert response.status_code == 200
43+
data = response.json()
44+
assert isinstance(data, dict)
45+
assert len(data) == len(activities)
46+
for name, details in data.items():
47+
assert expected_keys == set(details.keys())
48+
assert isinstance(details["participants"], list)
49+
50+
51+
# ── POST /activities/{name}/signup ───────────────────────────────────────
52+
53+
def test_signup_success():
54+
# Arrange
55+
activity_name = "Chess Club"
56+
email = "newstudent@mergington.edu"
57+
58+
# Act
59+
response = client.post(
60+
f"/activities/{activity_name}/signup",
61+
params={"email": email},
62+
)
63+
64+
# Assert
65+
assert response.status_code == 200
66+
assert email in activities[activity_name]["participants"]
67+
assert response.json()["message"] == f"Signed up {email} for {activity_name}"
68+
69+
70+
def test_signup_duplicate():
71+
# Arrange
72+
activity_name = "Chess Club"
73+
email = "michael@mergington.edu" # already in participants
74+
75+
# Act
76+
response = client.post(
77+
f"/activities/{activity_name}/signup",
78+
params={"email": email},
79+
)
80+
81+
# Assert
82+
assert response.status_code == 400
83+
assert response.json()["detail"] == "Already signed up"
84+
85+
86+
def test_signup_unknown_activity():
87+
# Arrange
88+
activity_name = "Nonexistent Club"
89+
email = "student@mergington.edu"
90+
91+
# Act
92+
response = client.post(
93+
f"/activities/{activity_name}/signup",
94+
params={"email": email},
95+
)
96+
97+
# Assert
98+
assert response.status_code == 404
99+
assert response.json()["detail"] == "Activity not found"
100+
101+
102+
# ── DELETE /activities/{name}/signup ─────────────────────────────────────
103+
104+
def test_unregister_success():
105+
# Arrange
106+
activity_name = "Chess Club"
107+
email = "michael@mergington.edu" # existing participant
108+
109+
# Act
110+
response = client.delete(
111+
f"/activities/{activity_name}/signup",
112+
params={"email": email},
113+
)
114+
115+
# Assert
116+
assert response.status_code == 200
117+
assert email not in activities[activity_name]["participants"]
118+
assert response.json()["message"] == f"Unregistered {email} from {activity_name}"
119+
120+
121+
def test_unregister_not_signed_up():
122+
# Arrange
123+
activity_name = "Chess Club"
124+
email = "unknown@mergington.edu"
125+
126+
# Act
127+
response = client.delete(
128+
f"/activities/{activity_name}/signup",
129+
params={"email": email},
130+
)
131+
132+
# Assert
133+
assert response.status_code == 400
134+
assert response.json()["detail"] == "Student not signed up for this activity"
135+
136+
137+
def test_unregister_unknown_activity():
138+
# Arrange
139+
activity_name = "Nonexistent Club"
140+
email = "student@mergington.edu"
141+
142+
# Act
143+
response = client.delete(
144+
f"/activities/{activity_name}/signup",
145+
params={"email": email},
146+
)
147+
148+
# Assert
149+
assert response.status_code == 404
150+
assert response.json()["detail"] == "Activity not found"

0 commit comments

Comments
 (0)