Turnpike/handle_volunteers_test.go

140 lines
4.2 KiB
Go

package main
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestConfirmVolunteer(t *testing.T) {
app := testApp(t)
mux := testMux(app)
admin := testAdminUser(t, app)
tok := testToken(t, app, admin)
dept, _ := app.createDepartment(Department{Name: "Gate"})
deptID := dept.ID
p, _ := app.createParticipant(Participant{PreferredName: "Titania", Email: "titania@test.com", EmailConfirmed: true})
v, _ := app.createVolunteer(Volunteer{ParticipantID: p.ID, DepartmentID: &deptID})
w := httptest.NewRecorder()
mux.ServeHTTP(w, testAuthRequest("POST", "/api/volunteers/"+itoa(v.ID)+"/confirm", nil, tok))
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
}
result := parseJSON(t, w)
vol := result["confirmed"]
if vol != true {
t.Error("expected confirmed=true in response")
}
got, _ := app.getVolunteer(v.ID)
if got == nil || !got.Confirmed {
t.Error("volunteer should be confirmed in DB")
}
if got.ConfirmedAt == nil {
t.Error("confirmed_at should be set")
}
}
func TestConfirmVolunteerIdempotent(t *testing.T) {
app := testApp(t)
mux := testMux(app)
admin := testAdminUser(t, app)
tok := testToken(t, app, admin)
p, _ := app.createParticipant(Participant{PreferredName: "Puck", Email: "puck@test.com", EmailConfirmed: true})
v, _ := app.createVolunteer(Volunteer{ParticipantID: p.ID})
// Confirm twice — second should be a no-op, not an error.
w := httptest.NewRecorder()
mux.ServeHTTP(w, testAuthRequest("POST", "/api/volunteers/"+itoa(v.ID)+"/confirm", nil, tok))
if w.Code != 200 {
t.Fatalf("first confirm: %d", w.Code)
}
w = httptest.NewRecorder()
mux.ServeHTTP(w, testAuthRequest("POST", "/api/volunteers/"+itoa(v.ID)+"/confirm", nil, tok))
if w.Code != 200 {
t.Fatalf("second confirm: %d", w.Code)
}
}
func TestConfirmVolunteerRequiresRole(t *testing.T) {
app := testApp(t)
mux := testMux(app)
// Ticketing role should NOT be able to confirm volunteers.
ticketing := testUserWithRole(t, app, "ticket_lead", "ticketing", nil)
tok := testToken(t, app, ticketing)
p, _ := app.createParticipant(Participant{PreferredName: "Helena", EmailConfirmed: true})
v, _ := app.createVolunteer(Volunteer{ParticipantID: p.ID})
w := httptest.NewRecorder()
mux.ServeHTTP(w, testAuthRequest("POST", "/api/volunteers/"+itoa(v.ID)+"/confirm", nil, tok))
if w.Code != http.StatusForbidden {
t.Errorf("expected 403 for ticketing role, got %d", w.Code)
}
}
func TestUpdateVolunteerDepartment(t *testing.T) {
app := testApp(t)
mux := testMux(app)
admin := testAdminUser(t, app)
tok := testToken(t, app, admin)
dept, _ := app.createDepartment(Department{Name: "Gate"})
p, _ := app.createParticipant(Participant{PreferredName: "Hermia"})
v, _ := app.createVolunteer(Volunteer{ParticipantID: p.ID})
// Assign department via update.
w := httptest.NewRecorder()
mux.ServeHTTP(w, testAuthRequest("PUT", "/api/volunteers/"+itoa(v.ID), map[string]any{
"department_id": dept.ID,
}, tok))
if w.Code != 200 {
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
}
got, _ := app.getVolunteer(v.ID)
if got.DepartmentID == nil || *got.DepartmentID != dept.ID {
t.Errorf("department_id = %v, want %d", got.DepartmentID, dept.ID)
}
}
func TestUpdateVolunteerCoLeadAutoConfirms(t *testing.T) {
app := testApp(t)
mux := testMux(app)
admin := testAdminUser(t, app)
tok := testToken(t, app, admin)
dept, _ := app.createDepartment(Department{Name: "Build"})
deptID := dept.ID
p, _ := app.createParticipant(Participant{PreferredName: "Lysander", Email: "lys@test.com", EmailConfirmed: true})
v, _ := app.createVolunteer(Volunteer{ParticipantID: p.ID, DepartmentID: &deptID})
// Verify not confirmed before update.
got, _ := app.getVolunteer(v.ID)
if got.Confirmed {
t.Fatal("should not be confirmed before update")
}
// Update is_lead=true should auto-confirm.
w := httptest.NewRecorder()
mux.ServeHTTP(w, testAuthRequest("PUT", "/api/volunteers/"+itoa(v.ID), map[string]any{
"department_id": deptID, "is_lead": true,
}, tok))
if w.Code != 200 {
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
}
got, _ = app.getVolunteer(v.ID)
if !got.IsLead {
t.Error("expected is_lead=true")
}
if !got.Confirmed {
t.Error("co-lead should be auto-confirmed")
}
}