mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 13:19:21 +00:00
Add convert method for ListUsersByMetadata request
This commit is contained in:
@@ -49,6 +49,17 @@ func TimestampMethodPbToQuery(method filter.TimestampFilterMethod) query.Timesta
|
||||
}
|
||||
}
|
||||
|
||||
func ByteMethodPbToQuery(method filter.ByteFilterMethod) query.BytesComparison {
|
||||
switch method {
|
||||
case filter.ByteFilterMethod_BYTE_FILTER_METHOD_EQUALS:
|
||||
return query.BytesEquals
|
||||
case filter.ByteFilterMethod_BYTE_FILTER_METHOD_NOT_EQUALS:
|
||||
return query.BytesNotEquals
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
func PaginationPbToQuery(defaults systemdefaults.SystemDefaults, query *filter.PaginationRequest) (offset, limit uint64, asc bool, err error) {
|
||||
limit = defaults.DefaultQueryLimit
|
||||
if query == nil {
|
||||
|
164
internal/api/grpc/filter/v2/converter_test.go
Normal file
164
internal/api/grpc/filter/v2/converter_test.go
Normal file
@@ -0,0 +1,164 @@
|
||||
package filter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/filter/v2"
|
||||
)
|
||||
|
||||
func TestTextMethodPbToQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tt := []struct {
|
||||
name string
|
||||
input filter.TextFilterMethod
|
||||
output query.TextComparison
|
||||
}{
|
||||
{"Equals", filter.TextFilterMethod_TEXT_FILTER_METHOD_EQUALS, query.TextEquals},
|
||||
{"EqualsIgnoreCase", filter.TextFilterMethod_TEXT_FILTER_METHOD_EQUALS_IGNORE_CASE, query.TextEqualsIgnoreCase},
|
||||
{"StartsWith", filter.TextFilterMethod_TEXT_FILTER_METHOD_STARTS_WITH, query.TextStartsWith},
|
||||
{"StartsWithIgnoreCase", filter.TextFilterMethod_TEXT_FILTER_METHOD_STARTS_WITH_IGNORE_CASE, query.TextStartsWithIgnoreCase},
|
||||
{"Contains", filter.TextFilterMethod_TEXT_FILTER_METHOD_CONTAINS, query.TextContains},
|
||||
{"ContainsIgnoreCase", filter.TextFilterMethod_TEXT_FILTER_METHOD_CONTAINS_IGNORE_CASE, query.TextContainsIgnoreCase},
|
||||
{"EndsWith", filter.TextFilterMethod_TEXT_FILTER_METHOD_ENDS_WITH, query.TextEndsWith},
|
||||
{"EndsWithIgnoreCase", filter.TextFilterMethod_TEXT_FILTER_METHOD_ENDS_WITH_IGNORE_CASE, query.TextEndsWithIgnoreCase},
|
||||
{"Unknown", filter.TextFilterMethod(999), -1},
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := TextMethodPbToQuery(tc.input)
|
||||
|
||||
assert.Equal(t, tc.output, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimestampMethodPbToQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tt := []struct {
|
||||
name string
|
||||
input filter.TimestampFilterMethod
|
||||
output query.TimestampComparison
|
||||
}{
|
||||
{"Equals", filter.TimestampFilterMethod_TIMESTAMP_FILTER_METHOD_EQUALS, query.TimestampEquals},
|
||||
{"Before", filter.TimestampFilterMethod_TIMESTAMP_FILTER_METHOD_BEFORE, query.TimestampLess},
|
||||
{"After", filter.TimestampFilterMethod_TIMESTAMP_FILTER_METHOD_AFTER, query.TimestampGreater},
|
||||
{"BeforeOrEquals", filter.TimestampFilterMethod_TIMESTAMP_FILTER_METHOD_BEFORE_OR_EQUALS, query.TimestampLessOrEquals},
|
||||
{"AfterOrEquals", filter.TimestampFilterMethod_TIMESTAMP_FILTER_METHOD_AFTER_OR_EQUALS, query.TimestampGreaterOrEquals},
|
||||
{"Unknown", filter.TimestampFilterMethod(999), -1},
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := TimestampMethodPbToQuery(tc.input)
|
||||
|
||||
assert.Equal(t, tc.output, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestByteMethodPbToQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tt := []struct {
|
||||
name string
|
||||
input filter.ByteFilterMethod
|
||||
output query.BytesComparison
|
||||
}{
|
||||
{"Equals", filter.ByteFilterMethod_BYTE_FILTER_METHOD_EQUALS, query.BytesEquals},
|
||||
{"NotEquals", filter.ByteFilterMethod_BYTE_FILTER_METHOD_NOT_EQUALS, query.BytesNotEquals},
|
||||
{"Unknown", filter.ByteFilterMethod(999), -1},
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := ByteMethodPbToQuery(tc.input)
|
||||
|
||||
assert.Equal(t, tc.output, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPaginationPbToQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defaults := systemdefaults.SystemDefaults{
|
||||
DefaultQueryLimit: 10,
|
||||
MaxQueryLimit: 100,
|
||||
}
|
||||
tt := []struct {
|
||||
name string
|
||||
query *filter.PaginationRequest
|
||||
wantOff uint64
|
||||
wantLim uint64
|
||||
wantAsc bool
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "nil query",
|
||||
query: nil,
|
||||
wantOff: 0,
|
||||
wantLim: 10,
|
||||
wantAsc: false,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "limit not set",
|
||||
query: &filter.PaginationRequest{Offset: 5, Limit: 0, Asc: true},
|
||||
wantOff: 5,
|
||||
wantLim: 10,
|
||||
wantAsc: true,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "limit set below max",
|
||||
query: &filter.PaginationRequest{Offset: 2, Limit: 50, Asc: false},
|
||||
wantOff: 2,
|
||||
wantLim: 50,
|
||||
wantAsc: false,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "limit exceeds max",
|
||||
query: &filter.PaginationRequest{Offset: 1, Limit: 101, Asc: true},
|
||||
wantOff: 0,
|
||||
wantLim: 0,
|
||||
wantAsc: false,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
off, lim, asc, err := PaginationPbToQuery(defaults, tc.query)
|
||||
|
||||
require.Equal(t, tc.wantErr, err != nil)
|
||||
|
||||
assert.Equal(t, tc.wantOff, off)
|
||||
assert.Equal(t, tc.wantLim, lim)
|
||||
assert.Equal(t, tc.wantAsc, asc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryToPaginationPb(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
req := query.SearchRequest{Limit: 20}
|
||||
resp := query.SearchResponse{Count: 123}
|
||||
got := QueryToPaginationPb(req, resp)
|
||||
|
||||
assert.Equal(t, req.Limit, got.AppliedLimit)
|
||||
assert.Equal(t, resp.Count, got.TotalResult)
|
||||
}
|
115
internal/api/grpc/user/v2beta/convert/metadata.go
Normal file
115
internal/api/grpc/user/v2beta/convert/metadata.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"github.com/zitadel/zitadel/internal/api/grpc/filter/v2"
|
||||
"github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
metadata "github.com/zitadel/zitadel/pkg/grpc/metadata/v2"
|
||||
user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta"
|
||||
)
|
||||
|
||||
func ListUsersByMetadataRequestToModel(req *user.ListUsersByMetadataRequest, sysDefaults systemdefaults.SystemDefaults) (*query.UserSearchQueries, error) {
|
||||
offset, limit, asc, err := filter.PaginationPbToQuery(sysDefaults, req.GetPagination())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
queries, err := usersByMetadataQueries(req.GetFilters(), 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &query.UserSearchQueries{
|
||||
SearchRequest: query.SearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
Asc: asc,
|
||||
SortingColumn: usersByMetadataSorting(req.GetSortingColumn()),
|
||||
},
|
||||
Queries: queries,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func usersByMetadataSorting(sortingColumn user.UsersByMetadataSorting) query.Column {
|
||||
switch sortingColumn {
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_DISPLAY_NAME:
|
||||
return query.HumanDisplayNameCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_EMAIL:
|
||||
return query.HumanEmailCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_FIRST_NAME:
|
||||
return query.HumanFirstNameCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_LAST_NAME:
|
||||
return query.HumanLastNameCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_METADATA_KEY:
|
||||
return query.UserMetadataKeyCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_METADATA_VALUE:
|
||||
return query.UserMetadataValueCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_NICK_NAME:
|
||||
return query.HumanNickNameCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_STATE:
|
||||
return query.UserStateCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_TYPE:
|
||||
return query.UserTypeCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_USER_NAME:
|
||||
return query.UserUsernameCol
|
||||
case user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_USER_ID, user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_UNSPECIFIED:
|
||||
fallthrough
|
||||
default:
|
||||
return query.UserIDCol
|
||||
}
|
||||
}
|
||||
|
||||
func usersByMetadataQueries(queries []*metadata.UserByMetadataSearchFilter, nesting uint) ([]query.SearchQuery, error) {
|
||||
toReturn := make([]query.SearchQuery, len(queries))
|
||||
|
||||
for i, query := range queries {
|
||||
res, err := userByMetadataQuery(query, nesting)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
toReturn[i] = res
|
||||
}
|
||||
|
||||
return toReturn, nil
|
||||
}
|
||||
|
||||
func userByMetadataQuery(q *metadata.UserByMetadataSearchFilter, nesting uint) (query.SearchQuery, error) {
|
||||
if nesting > 20 {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "CONV-Jhaltm", "Errors.Query.TooManyNestingLevels")
|
||||
}
|
||||
|
||||
switch t := q.GetFilter().(type) {
|
||||
|
||||
case *metadata.UserByMetadataSearchFilter_KeyFilter:
|
||||
return query.NewUserMetadataKeySearchQuery(t.KeyFilter.GetKey(), filter.TextMethodPbToQuery(t.KeyFilter.GetMethod()))
|
||||
|
||||
case *metadata.UserByMetadataSearchFilter_ValueFilter:
|
||||
return query.NewUserMetadataValueSearchQuery(t.ValueFilter.GetValue(), filter.ByteMethodPbToQuery(t.ValueFilter.GetMethod()))
|
||||
|
||||
case *metadata.UserByMetadataSearchFilter_AndFilter:
|
||||
mappedQueries, err := usersByMetadataQueries(t.AndFilter.GetQueries(), nesting+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return query.NewUserMetadataAndSearchQuery(mappedQueries)
|
||||
|
||||
case *metadata.UserByMetadataSearchFilter_OrFilter:
|
||||
mappedQueries, err := usersByMetadataQueries(t.OrFilter.GetQueries(), nesting+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return query.NewUserMetadataOrSearchQuery(mappedQueries)
|
||||
|
||||
case *metadata.UserByMetadataSearchFilter_NotFilter:
|
||||
mappedQuery, err := userByMetadataQuery(t.NotFilter.GetQuery(), nesting+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return query.NewUserMetadataNotSearchQuery(mappedQuery)
|
||||
|
||||
default:
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "CONV-GG1Jnh", "List.Query.Invalid")
|
||||
}
|
||||
}
|
273
internal/api/grpc/user/v2beta/convert/metadata_test.go
Normal file
273
internal/api/grpc/user/v2beta/convert/metadata_test.go
Normal file
@@ -0,0 +1,273 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
filter "github.com/zitadel/zitadel/pkg/grpc/filter/v2"
|
||||
metadata "github.com/zitadel/zitadel/pkg/grpc/metadata/v2"
|
||||
user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta"
|
||||
)
|
||||
|
||||
func Test_usersByMetadataSorting(t *testing.T) {
|
||||
t.Parallel()
|
||||
tt := []struct {
|
||||
name string
|
||||
input user.UsersByMetadataSorting
|
||||
expected query.Column
|
||||
}{
|
||||
{"DisplayName", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_DISPLAY_NAME, query.HumanDisplayNameCol},
|
||||
{"Email", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_EMAIL, query.HumanEmailCol},
|
||||
{"FirstName", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_FIRST_NAME, query.HumanFirstNameCol},
|
||||
{"LastName", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_LAST_NAME, query.HumanLastNameCol},
|
||||
{"MetadataKey", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_METADATA_KEY, query.UserMetadataKeyCol},
|
||||
{"MetadataValue", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_METADATA_VALUE, query.UserMetadataValueCol},
|
||||
{"NickName", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_NICK_NAME, query.HumanNickNameCol},
|
||||
{"State", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_STATE, query.UserStateCol},
|
||||
{"Type", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_TYPE, query.UserTypeCol},
|
||||
{"UserName", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_USER_NAME, query.UserUsernameCol},
|
||||
{"UserID", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_USER_ID, query.UserIDCol},
|
||||
{"Unspecified", user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_UNSPECIFIED, query.UserIDCol},
|
||||
{"Default", user.UsersByMetadataSorting(999), query.UserIDCol},
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := usersByMetadataSorting(tc.input)
|
||||
assert.Equal(t, tc.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_userByMetadataQuery(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tt := []struct {
|
||||
name string
|
||||
input *metadata.UserByMetadataSearchFilter
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "KeyFilter",
|
||||
input: &metadata.UserByMetadataSearchFilter{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_KeyFilter{
|
||||
KeyFilter: &metadata.MetadataKeyFilter{
|
||||
Key: "foo",
|
||||
Method: filter.TextFilterMethod_TEXT_FILTER_METHOD_EQUALS,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "ValueFilter",
|
||||
input: &metadata.UserByMetadataSearchFilter{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_ValueFilter{
|
||||
ValueFilter: &metadata.MetadataValueFilter{
|
||||
Value: []byte("bar"),
|
||||
Method: filter.ByteFilterMethod_BYTE_FILTER_METHOD_EQUALS,
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "AndFilter",
|
||||
input: &metadata.UserByMetadataSearchFilter{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_AndFilter{
|
||||
AndFilter: &metadata.MetadataAndFilter{
|
||||
Queries: []*metadata.UserByMetadataSearchFilter{
|
||||
{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_KeyFilter{
|
||||
KeyFilter: &metadata.MetadataKeyFilter{
|
||||
Key: "foo",
|
||||
Method: filter.TextFilterMethod_TEXT_FILTER_METHOD_EQUALS,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "OrFilter",
|
||||
input: &metadata.UserByMetadataSearchFilter{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_OrFilter{
|
||||
OrFilter: &metadata.MetadataOrFilter{
|
||||
Queries: []*metadata.UserByMetadataSearchFilter{
|
||||
{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_ValueFilter{
|
||||
ValueFilter: &metadata.MetadataValueFilter{
|
||||
Value: []byte("baz"),
|
||||
Method: filter.ByteFilterMethod_BYTE_FILTER_METHOD_EQUALS,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "NotFilter",
|
||||
input: &metadata.UserByMetadataSearchFilter{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_NotFilter{
|
||||
NotFilter: &metadata.MetadataNotFilter{
|
||||
Query: &metadata.UserByMetadataSearchFilter{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_KeyFilter{
|
||||
KeyFilter: &metadata.MetadataKeyFilter{
|
||||
Key: "not",
|
||||
Method: filter.TextFilterMethod_TEXT_FILTER_METHOD_EQUALS,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "TooManyNestingLevels",
|
||||
input: &metadata.UserByMetadataSearchFilter{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_AndFilter{
|
||||
AndFilter: &metadata.MetadataAndFilter{
|
||||
Queries: []*metadata.UserByMetadataSearchFilter{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "InvalidFilter",
|
||||
input: &metadata.UserByMetadataSearchFilter{},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
nesting := uint(0)
|
||||
if tc.name == "TooManyNestingLevels" {
|
||||
nesting = 21
|
||||
}
|
||||
got, err := userByMetadataQuery(tc.input, nesting)
|
||||
if tc.wantErr {
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, got)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_usersByMetadataQueries(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
queries, err := usersByMetadataQueries([]*metadata.UserByMetadataSearchFilter{}, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, queries, 0)
|
||||
})
|
||||
|
||||
t.Run("single valid", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
queries, err := usersByMetadataQueries([]*metadata.UserByMetadataSearchFilter{
|
||||
{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_KeyFilter{
|
||||
KeyFilter: &metadata.MetadataKeyFilter{
|
||||
Key: "foo",
|
||||
Method: filter.TextFilterMethod_TEXT_FILTER_METHOD_EQUALS,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, queries, 1)
|
||||
})
|
||||
|
||||
t.Run("invalid filter", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
queries, err := usersByMetadataQueries([]*metadata.UserByMetadataSearchFilter{
|
||||
{},
|
||||
}, 0)
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, queries)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ListUsersByMetadataRequestToModel(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
sysDefaults := systemdefaults.SystemDefaults{
|
||||
MaxQueryLimit: 100,
|
||||
}
|
||||
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
req := &user.ListUsersByMetadataRequest{
|
||||
Pagination: &filter.PaginationRequest{
|
||||
Limit: 10,
|
||||
Offset: 5,
|
||||
Asc: true,
|
||||
},
|
||||
SortingColumn: user.UsersByMetadataSorting_USERS_BY_METADATA_SORT_BY_EMAIL,
|
||||
Filters: []*metadata.UserByMetadataSearchFilter{
|
||||
{
|
||||
Filter: &metadata.UserByMetadataSearchFilter_KeyFilter{
|
||||
KeyFilter: &metadata.MetadataKeyFilter{
|
||||
Key: "foo",
|
||||
Method: filter.TextFilterMethod_TEXT_FILTER_METHOD_EQUALS,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
model, err := ListUsersByMetadataRequestToModel(req, sysDefaults)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, model)
|
||||
assert.EqualValues(t, 5, model.Offset)
|
||||
assert.EqualValues(t, 10, model.Limit)
|
||||
assert.True(t, model.Asc)
|
||||
assert.Equal(t, query.HumanEmailCol, model.SortingColumn)
|
||||
assert.Len(t, model.Queries, 1)
|
||||
})
|
||||
|
||||
t.Run("invalid pagination", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
req := &user.ListUsersByMetadataRequest{
|
||||
Pagination: &filter.PaginationRequest{
|
||||
|
||||
Limit: 200,
|
||||
},
|
||||
Filters: []*metadata.UserByMetadataSearchFilter{},
|
||||
}
|
||||
model, err := ListUsersByMetadataRequestToModel(req, sysDefaults)
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, model)
|
||||
})
|
||||
|
||||
t.Run("invalid filter", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
req := &user.ListUsersByMetadataRequest{
|
||||
Pagination: &filter.PaginationRequest{
|
||||
Limit: 1,
|
||||
},
|
||||
Filters: []*metadata.UserByMetadataSearchFilter{
|
||||
{},
|
||||
},
|
||||
}
|
||||
model, err := ListUsersByMetadataRequestToModel(req, sysDefaults)
|
||||
require.Error(t, err)
|
||||
assert.Nil(t, model)
|
||||
})
|
||||
}
|
@@ -233,6 +233,22 @@ func NewUserMetadataKeySearchQuery(value string, comparison TextComparison) (Sea
|
||||
return NewTextQuery(UserMetadataKeyCol, value, comparison)
|
||||
}
|
||||
|
||||
func NewUserMetadataValueSearchQuery(value []byte, comparison BytesComparison) (SearchQuery, error) {
|
||||
return NewBytesQuery(UserMetadataValueCol, value, comparison)
|
||||
}
|
||||
|
||||
func NewUserMetadataAndSearchQuery(values []SearchQuery) (SearchQuery, error) {
|
||||
return NewAndQuery(values...)
|
||||
}
|
||||
|
||||
func NewUserMetadataOrSearchQuery(values []SearchQuery) (SearchQuery, error) {
|
||||
return NewOrQuery(values...)
|
||||
}
|
||||
|
||||
func NewUserMetadataNotSearchQuery(value SearchQuery) (SearchQuery, error) {
|
||||
return NewNotQuery(value)
|
||||
}
|
||||
|
||||
func NewUserMetadataExistsQuery(key string, value []byte, keyComparison TextComparison, valueComparison BytesComparison) (SearchQuery, error) {
|
||||
// linking queries for the subselect
|
||||
instanceQuery, err := NewColumnComparisonQuery(UserMetadataInstanceIDCol, UserInstanceIDCol, ColumnEquals)
|
||||
|
Reference in New Issue
Block a user