package server import ( "encoding/json" "net/http" "net/http/httptest" "testing" "git.wntrmute.dev/kyle/mcr/internal/auth" ) type fakeLoginClient struct { token string expiresIn int err error } func (f *fakeLoginClient) Login(_, _ string) (string, int, error) { return f.token, f.expiresIn, f.err } func TestTokenHandlerSuccess(t *testing.T) { t.Helper() lc := &fakeLoginClient{token: "tok-xyz", expiresIn: 7200} handler := TokenHandler(lc) req := httptest.NewRequest(http.MethodGet, "/v2/token", nil) req.SetBasicAuth("alice", "secret") rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("status: got %d, want %d", rec.Code, http.StatusOK) } var resp tokenResponse if err := json.NewDecoder(rec.Body).Decode(&resp); err != nil { t.Fatalf("decode response: %v", err) } if resp.Token != "tok-xyz" { t.Fatalf("token: got %q, want %q", resp.Token, "tok-xyz") } if resp.ExpiresIn != 7200 { t.Fatalf("expires_in: got %d, want %d", resp.ExpiresIn, 7200) } if resp.IssuedAt == "" { t.Fatal("issued_at: expected non-empty RFC 3339 timestamp") } } func TestTokenHandlerInvalidCreds(t *testing.T) { t.Helper() lc := &fakeLoginClient{err: auth.ErrUnauthorized} handler := TokenHandler(lc) req := httptest.NewRequest(http.MethodGet, "/v2/token", nil) req.SetBasicAuth("alice", "wrong") rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusUnauthorized { t.Fatalf("status: got %d, want %d", rec.Code, http.StatusUnauthorized) } var ociErr ociErrorResponse if err := json.NewDecoder(rec.Body).Decode(&ociErr); err != nil { t.Fatalf("decode OCI error: %v", err) } if len(ociErr.Errors) != 1 || ociErr.Errors[0].Code != "UNAUTHORIZED" { t.Fatalf("OCI error: got %+v, want UNAUTHORIZED", ociErr.Errors) } } func TestTokenHandlerMissingAuth(t *testing.T) { t.Helper() lc := &fakeLoginClient{token: "should-not-matter"} handler := TokenHandler(lc) req := httptest.NewRequest(http.MethodGet, "/v2/token", nil) // No Authorization header. rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusUnauthorized { t.Fatalf("status: got %d, want %d", rec.Code, http.StatusUnauthorized) } var ociErr ociErrorResponse if err := json.NewDecoder(rec.Body).Decode(&ociErr); err != nil { t.Fatalf("decode OCI error: %v", err) } if len(ociErr.Errors) != 1 || ociErr.Errors[0].Code != "UNAUTHORIZED" { t.Fatalf("OCI error: got %+v, want UNAUTHORIZED", ociErr.Errors) } }