auth0mock / build (push) Skipped
auth0mock / build (pull_request) Successful in 1m41s
GET /api/v2/users with q=email:"..." answers like Auth0's user search: the email matches in any letter case, unlike users-by-email, and the answer has the include_totals shape the Go SDK asks for by default. Any other query is refused with 400 rather than answered wrong. Goodfeed's backend checks whether an address is taken with this search before it lets a user change their email.
67 lines
2.2 KiB
Go
67 lines
2.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log/slog"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"testing"
|
|
|
|
"git.unbound.se/unboundsoftware/auth0mock/store"
|
|
)
|
|
|
|
func searchUsers(t *testing.T, h *ManagementHandler, q string) (int, []UserResponse) {
|
|
t.Helper()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v2/users?search_engine=v3&include_totals=true&q="+url.QueryEscape(q), nil)
|
|
rec := httptest.NewRecorder()
|
|
h.SearchUsers(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
return rec.Code, nil
|
|
}
|
|
var body struct {
|
|
Total int `json:"total"`
|
|
Users []UserResponse `json:"users"`
|
|
}
|
|
if err := json.NewDecoder(rec.Body).Decode(&body); err != nil {
|
|
t.Fatalf("decode: %v", err)
|
|
}
|
|
if body.Total != len(body.Users) {
|
|
t.Fatalf("total %d, users %d", body.Total, len(body.Users))
|
|
}
|
|
return rec.Code, body.Users
|
|
}
|
|
|
|
// The search matches email in any letter case, as Auth0's does: a backend that
|
|
// checks whether an address is taken must find it however it was typed.
|
|
func TestSearchUsersMatchesEmailInAnyCase(t *testing.T) {
|
|
users := store.NewUserStore()
|
|
users.Create("anna@kpmg.se", &store.User{GivenName: "Anna"})
|
|
users.Create("bob@acme.se", &store.User{GivenName: "Bob"})
|
|
h := NewManagementHandler(users, slog.New(slog.DiscardHandler))
|
|
|
|
for _, q := range []string{`email:"anna@kpmg.se"`, `email:"ANNA@KPMG.SE"`, `email:"Anna@Kpmg.se"`} {
|
|
code, found := searchUsers(t, h, q)
|
|
if code != http.StatusOK || len(found) != 1 || found[0].UserID != "auth0|anna@kpmg.se" {
|
|
t.Fatalf("%s: code %d, found %+v", q, code, found)
|
|
}
|
|
}
|
|
|
|
if _, found := searchUsers(t, h, `email:"nobody@acme.se"`); len(found) != 0 {
|
|
t.Fatalf("an unknown address found %+v", found)
|
|
}
|
|
// A quoted * is part of the address, not a wildcard.
|
|
if _, found := searchUsers(t, h, `email:"*@kpmg.se"`); len(found) != 0 {
|
|
t.Fatalf("a quoted * matched %+v", found)
|
|
}
|
|
}
|
|
|
|
func TestSearchUsersRefusesOtherQueries(t *testing.T) {
|
|
h := NewManagementHandler(store.NewUserStore(), slog.New(slog.DiscardHandler))
|
|
for _, q := range []string{"", "name:anna", `email:"a@b.se" OR name:x`} {
|
|
if code, _ := searchUsers(t, h, q); code != http.StatusBadRequest {
|
|
t.Fatalf("%q: code %d, want 400", q, code)
|
|
}
|
|
}
|
|
}
|