package main import ( "net/http" "net/http/httptest" "testing" ) func TestLoginValid(t *testing.T) { app := testApp(t) admin := testAdminUser(t, app) mux := testMux(app) req := testRequest("POST", "/api/login", map[string]string{ "email": admin.Email, "password": "admin123", }) w := httptest.NewRecorder() mux.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("status = %d, want 200\nbody: %s", w.Code, w.Body.String()) } result := parseJSON(t, w) if result["token"] == nil || result["token"] == "" { t.Error("missing token in response") } user, ok := result["user"].(map[string]any) if !ok || user["email"] != "oberon@athens.example" { t.Errorf("user = %v", result["user"]) } } func TestLoginWrongPassword(t *testing.T) { app := testApp(t) testAdminUser(t, app) mux := testMux(app) req := testRequest("POST", "/api/login", map[string]string{ "email": "oberon@athens.example", "password": "wrong", }) w := httptest.NewRecorder() mux.ServeHTTP(w, req) if w.Code != http.StatusUnauthorized { t.Errorf("status = %d, want 401", w.Code) } } func TestLoginNonexistentUser(t *testing.T) { app := testApp(t) mux := testMux(app) req := testRequest("POST", "/api/login", map[string]string{ "email": "nobody@test.com", "password": "test", }) w := httptest.NewRecorder() mux.ServeHTTP(w, req) if w.Code != http.StatusUnauthorized { t.Errorf("status = %d, want 401", w.Code) } } func TestAuthMiddlewareNoToken(t *testing.T) { app := testApp(t) mux := testMux(app) req := testRequest("GET", "/api/me", nil) w := httptest.NewRecorder() mux.ServeHTTP(w, req) if w.Code != http.StatusUnauthorized { t.Errorf("status = %d, want 401", w.Code) } } func TestAuthMiddlewareInvalidToken(t *testing.T) { app := testApp(t) mux := testMux(app) req := testAuthRequest("GET", "/api/me", nil, "bad-token") w := httptest.NewRecorder() mux.ServeHTTP(w, req) if w.Code != http.StatusUnauthorized { t.Errorf("status = %d, want 401", w.Code) } } func TestAuthMiddlewareRoleEnforcement(t *testing.T) { app := testApp(t) mux := testMux(app) gate := testUserWithRoles(t, app, "Starveling", []string{"gatekeeper"}, []int{}) token := testToken(t, app, gate) req := testAuthRequest("GET", "/api/users", nil, token) w := httptest.NewRecorder() mux.ServeHTTP(w, req) if w.Code != http.StatusForbidden { t.Errorf("status = %d, want 403", w.Code) } } func TestMeEndpoint(t *testing.T) { app := testApp(t) admin := testAdminUser(t, app) token := testToken(t, app, admin) mux := testMux(app) req := testAuthRequest("GET", "/api/me", nil, token) w := httptest.NewRecorder() mux.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("status = %d", w.Code) } result := parseJSON(t, w) if result["email"] != "oberon@athens.example" { t.Errorf("email = %v", result["email"]) } }