Skip to content
Merged
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
6 changes: 6 additions & 0 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ def signup_for_activity(activity_name: str, email: str):
if activity_name not in activities:
raise HTTPException(status_code=404, detail="Activity not found")

# Normalize email to prevent case/whitespace bypass
email = email.strip().lower()

# Get the specific activity
activity = activities[activity_name]

Expand All @@ -114,6 +117,9 @@ def unregister_from_activity(activity_name: str, email: str):
if activity_name not in activities:
raise HTTPException(status_code=404, detail="Activity not found")

# Normalize email to prevent case/whitespace bypass
email = email.strip().lower()

# Get the specific activity
activity = activities[activity_name]

Expand Down
7 changes: 6 additions & 1 deletion src/static/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,12 @@ document.addEventListener("DOMContentLoaded", () => {
});

activitiesList.addEventListener("click", async (event) => {
const removeButton = event.target.closest(".participant-remove-btn");
const target = event.target;
if (!(target instanceof Element)) {
return;
}

const removeButton = target.closest(".participant-remove-btn");
if (!removeButton) {
return;
}
Expand Down
39 changes: 39 additions & 0 deletions tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,45 @@ def test_signup_duplicate_returns_bad_request(client):
assert "detail" in body


def test_signup_normalizes_email_case(client):
activity_name = "Chess Club"
email_upper = "New.Student@Mergington.EDU"
email_normalized = email_upper.strip().lower()
endpoint = f"/activities/{quote(activity_name, safe='')}/signup"

response = client.post(endpoint, params={"email": email_upper})

body = response.json()
assert response.status_code == 200
assert email_normalized in activities[activity_name]["participants"]


def test_signup_duplicate_case_insensitive_returns_bad_request(client):
activity_name = "Chess Club"
email_upper = "Michael@Mergington.EDU"
endpoint = f"/activities/{quote(activity_name, safe='')}/signup"

response = client.post(endpoint, params={"email": email_upper})

body = response.json()
assert response.status_code == 400
assert "detail" in body


def test_unregister_normalizes_email_case(client):
activity_name = "Chess Club"
email_upper = "Michael@Mergington.EDU"
endpoint = (
f"/activities/{quote(activity_name, safe='')}/participants/{quote(email_upper, safe='')}"
)

response = client.delete(endpoint)

body = response.json()
assert response.status_code == 200
assert "michael@mergington.edu" not in activities[activity_name]["participants"]


def test_unregister_removes_participant(client):
activity_name = "Chess Club"
email = "michael@mergington.edu"
Expand Down