package user import ( "net/http" "strconv" "testing" "git.golem15.com/golem15/sm-user-plugin/models" ) // TestAdminUsersGroupFilterValue (D-23): the groups filter takes a group id. // A value that is not one matches nobody (or is refused with 422 by the // framework); it must not reach the database as it is, where a non-numeric // text fails the whole list with a 500. func TestAdminUsersGroupFilterValue(t *testing.T) { env := newAdminEnv(t) token := env.admin(t, permAccessUsers) marker := "gfilter" + adminStamp() group := env.seedGroup(t, "Filter "+marker, "") member := env.seedUser(t, marker, nil) other := env.seedUser(t, marker, nil) env.join(t, member, group) gid := strconv.FormatUint(uint64(group.ID), 10) if page := env.users(t, token, "search="+marker+"&filter[groups]="+gid); page.Total != 1 || !page.has(member.ID) || page.has(other.ID) { t.Fatalf("group filter = %s", page.Raw) } for _, value := range []string{"abc", "1%20OR%201=1", "-1", "0", "1.5", "99999999999999999999", gid + "x"} { rec := env.call(t, http.MethodGet, adminAPI(adminUsersPath)+"?search="+marker+"&filter[groups]="+value, token, nil) // The framework refuses a value it cannot read as a scope argument // with 422; whatever it lets through must list nobody. if rec.Code == http.StatusUnprocessableEntity { continue } if rec.Code != http.StatusOK { t.Fatalf("filter[groups]=%s answers %d: %s", value, rec.Code, rec.Body.String()) } var rows []map[string]any adminInto(t, rec, &rows) if len(rows) != 0 { t.Fatalf("filter[groups]=%s lists %d users, want none", value, len(rows)) } } // The list without the filter is unaffected. if page := env.users(t, token, "search="+marker); page.Total != 2 { t.Fatalf("unfiltered list = %s", page.Raw) } _ = models.FilterByGroup }