Rewrites the internal/api comment blocks to rule 32: task, milestone and rule ids gone, the stories behind them restated as the constraint they left, stale references corrected (the stream secret is wired from config, the timezone handler already refreshes the scheduler, the Android app is the native client, the design docs cited are not in the repo). Also rewraps comment lines over 80 columns left by the earlier batches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
90 lines
2.6 KiB
Go
90 lines
2.6 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
|
)
|
|
|
|
func TestHandleGetMe_ReturnsAuthenticatedUser(t *testing.T) {
|
|
h, pool := testHandlers(t)
|
|
user := seedUser(t, pool, "alice", "hunter2", true)
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/me", nil)
|
|
req = withUser(req, user)
|
|
w := httptest.NewRecorder()
|
|
h.handleGetMe(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d body = %s", w.Code, w.Body.String())
|
|
}
|
|
var got meProfileResp
|
|
if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
|
|
t.Fatalf("decode: %v", err)
|
|
}
|
|
if got.Username != "test-alice" || !got.IsAdmin {
|
|
t.Errorf("user = %+v, want test-alice/admin", got)
|
|
}
|
|
if got.DisplayName != nil {
|
|
t.Errorf("DisplayName = %v, want nil for a user with no profile set", *got.DisplayName)
|
|
}
|
|
if got.Email != nil {
|
|
t.Errorf("Email = %v, want nil for a user with no profile set", *got.Email)
|
|
}
|
|
}
|
|
|
|
// A user whose profile fields ARE set must see them in the /api/me
|
|
// response: a Settings → Profile form seeded without them would, on save,
|
|
// clear the stored values through PUT /api/me/profile's "empty string
|
|
// clears to NULL".
|
|
func TestHandleGetMe_IncludesDisplayNameAndEmail(t *testing.T) {
|
|
h, pool := testHandlers(t)
|
|
user := seedUser(t, pool, "alice", "hunter2", false)
|
|
|
|
displayName := "Alice Liddell"
|
|
email := "alice@example.com"
|
|
updated, err := dbq.New(pool).UpdateUserProfile(context.Background(), dbq.UpdateUserProfileParams{
|
|
ID: user.ID,
|
|
DisplayName: &displayName,
|
|
Email: &email,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("UpdateUserProfile: %v", err)
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/me", nil)
|
|
req = withUser(req, updated)
|
|
w := httptest.NewRecorder()
|
|
h.handleGetMe(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d body = %s", w.Code, w.Body.String())
|
|
}
|
|
var got meProfileResp
|
|
if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
|
|
t.Fatalf("decode: %v", err)
|
|
}
|
|
if got.DisplayName == nil || *got.DisplayName != displayName {
|
|
t.Errorf("DisplayName = %v, want %q", got.DisplayName, displayName)
|
|
}
|
|
if got.Email == nil || *got.Email != email {
|
|
t.Errorf("Email = %v, want %q", got.Email, email)
|
|
}
|
|
}
|
|
|
|
func TestHandleGetMe_MissingContextReturns500(t *testing.T) {
|
|
h, _ := testHandlers(t)
|
|
req := httptest.NewRequest(http.MethodGet, "/api/me", nil)
|
|
w := httptest.NewRecorder()
|
|
h.handleGetMe(w, req)
|
|
|
|
if w.Code != http.StatusInternalServerError {
|
|
t.Errorf("status = %d, want 500 (context should be populated by RequireUser)", w.Code)
|
|
}
|
|
_ = dbq.User{} // keep the import used
|
|
}
|