Skip to content
Open
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
39 changes: 39 additions & 0 deletions internal/api/user_handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,45 @@ func TestAdminListUsers_SnakeCaseShape(t *testing.T) {
}
}

func TestAdminListUsers_SearchMatchesUserID(t *testing.T) {
ts := testutil.NewTestServer(t)
ctx := context.Background()
now := time.Now().UTC()

u := &storage.User{
ID: "usr_agent_owner_123",
Email: "agent-owner@example.com",
HashType: "argon2id",
Metadata: "{}",
CreatedAt: now.Format(time.RFC3339),
UpdatedAt: now.Format(time.RFC3339),
}
if err := ts.Store.CreateUser(ctx, u); err != nil {
t.Fatal(err)
}

resp := ts.GetWithAdminKey("/api/v1/users?search=usr_agent_owner_123")
if resp.StatusCode != http.StatusOK {
t.Fatalf("expected 200, got %d", resp.StatusCode)
}

var body struct {
Users []struct {
ID string `json:"id"`
Email string `json:"email"`
} `json:"users"`
Total int `json:"total"`
}
ts.DecodeJSON(resp, &body)

if body.Total != 1 {
t.Fatalf("total: got %d, want 1", body.Total)
}
if len(body.Users) != 1 || body.Users[0].ID != "usr_agent_owner_123" {
t.Fatalf("users: got %+v, want usr_agent_owner_123", body.Users)
}
}

// TestAdminGetUser_SnakeCaseShape verifies the single-user endpoint also
// emits snake_case keys.
func TestAdminGetUser_SnakeCaseShape(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions internal/storage/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ func userListConditions(opts ListUsersOpts) ([]string, []interface{}) {
args = append(args, opts.RoleID)
}
if opts.Search != "" {
conditions = append(conditions, `(email LIKE ? OR name LIKE ?)`)
conditions = append(conditions, `(id LIKE ? OR email LIKE ? OR name LIKE ?)`)
search := "%" + opts.Search + "%"
args = append(args, search, search)
args = append(args, search, search, search)
}
if opts.MFAEnabled != nil {
conditions = append(conditions, `mfa_enabled = ?`)
Expand Down
2 changes: 1 addition & 1 deletion internal/storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ type DayCount struct {
type ListUsersOpts struct {
Limit int
Offset int
Search string // optional email/name search
Search string // optional id/email/name search
MFAEnabled *bool // filter by mfa_enabled
EmailVerified *bool // filter by email_verified
RoleID string // filter by role assignment
Expand Down