feat(clientcache): add test for sort options and search functions

llb-desktop-client-sort-backup
Sepehr 4 months ago
parent f4fee7fd2f
commit 077d6ffa44

@ -126,4 +126,65 @@ func Test_GetOpts(t *testing.T) {
testOpts.withUseNonPagedListing = true
assert.Equal(t, opts, testOpts)
})
t.Run("WithSort-default-sortby-ignored", func(t *testing.T) {
opts, err := getOpts(WithSort(SortByDefault, Ascending, []SortBy{SortByName}))
require.NoError(t, err)
testOpts := getDefaultOptions()
assert.Equal(t, opts, testOpts)
})
t.Run("WithSort-empty-sortby-ignored", func(t *testing.T) {
opts, err := getOpts(WithSort("", Ascending, []SortBy{SortByName}))
require.NoError(t, err)
testOpts := getDefaultOptions()
assert.Equal(t, opts, testOpts)
})
t.Run("WithSort-valid-name-ascending", func(t *testing.T) {
opts, err := getOpts(WithSort(SortByName, Ascending, []SortBy{SortByName, SortByCreatedAt}))
require.NoError(t, err)
testOpts := getDefaultOptions()
testOpts.withSortBy = SortByName
testOpts.withSortDirection = Ascending
assert.Equal(t, opts, testOpts)
})
t.Run("WithSort-valid-created_at-descending", func(t *testing.T) {
opts, err := getOpts(WithSort(SortByCreatedAt, Descending, []SortBy{SortByCreatedAt}))
require.NoError(t, err)
testOpts := getDefaultOptions()
testOpts.withSortBy = SortByCreatedAt
testOpts.withSortDirection = Descending
assert.Equal(t, opts, testOpts)
})
t.Run("WithSort-column-not-in-sortable-list", func(t *testing.T) {
_, err := getOpts(WithSort(SortByName, Ascending, []SortBy{SortByCreatedAt}))
require.Error(t, err)
assert.ErrorContains(t, err, "not allowed for this resource type")
})
t.Run("WithSort-empty-sortable-columns", func(t *testing.T) {
_, err := getOpts(WithSort(SortByName, Ascending, []SortBy{}))
require.Error(t, err)
assert.ErrorContains(t, err, "not allowed for this resource type")
})
t.Run("WithSort-nil-sortable-columns", func(t *testing.T) {
_, err := getOpts(WithSort(SortByName, Ascending, nil))
require.Error(t, err)
assert.ErrorContains(t, err, "not allowed for this resource type")
})
t.Run("WithSort-unsafe-chars-semicolon", func(t *testing.T) {
_, err := getOpts(WithSort(SortBy("name; DROP TABLE"), Ascending, []SortBy{SortBy("name; DROP TABLE")}))
require.Error(t, err)
assert.ErrorContains(t, err, "contains unsafe characters")
})
t.Run("WithSort-unsafe-chars-quote", func(t *testing.T) {
_, err := getOpts(WithSort(SortBy("name'--"), Ascending, []SortBy{SortBy("name'--")}))
require.Error(t, err)
assert.ErrorContains(t, err, "contains unsafe characters")
})
t.Run("WithSort-default-direction", func(t *testing.T) {
opts, err := getOpts(WithSort(SortByName, SortDirectionDefault, []SortBy{SortByName}))
require.NoError(t, err)
testOpts := getDefaultOptions()
testOpts.withSortBy = SortByName
testOpts.withSortDirection = SortDirectionDefault
assert.Equal(t, opts, testOpts)
})
}

@ -442,3 +442,166 @@ func TestSearch(t *testing.T) {
assert.Equal(t, &SearchResult{Targets: []*targets.Target{}}, got)
})
}
func TestSortByValid(t *testing.T) {
cases := []struct {
sortBy SortBy
valid bool
}{
{SortByDefault, true},
{SortBy(""), true},
{SortByName, true},
{SortByCreatedAt, true},
{SortBy("unknown"), false},
{SortBy("id"), false},
{SortBy("invalid_column"), false},
{SortBy("name; DROP TABLE"), false},
{SortBy("name'--"), false},
{SortBy("name\"--"), false},
{SortBy("name\\x00"), false},
{SortBy("name,other"), false},
{SortBy("name ("), false},
{SortBy("name)"), false},
{SortBy("name\t"), false},
{SortBy("name\n"), false},
{SortBy("name\r"), false},
{SortBy("name "), false},
}
for _, tc := range cases {
t.Run(string(tc.sortBy), func(t *testing.T) {
assert.Equal(t, tc.valid, tc.sortBy.Valid())
})
}
}
func TestSortDirectionValid(t *testing.T) {
cases := []struct {
direction SortDirection
valid bool
}{
{SortDirectionDefault, true},
{SortDirection(""), true},
{Ascending, true},
{Descending, true},
{SortDirection("ASC"), false},
{SortDirection("DESC"), false},
{SortDirection("invalid"), false},
}
for _, tc := range cases {
t.Run(string(tc.direction), func(t *testing.T) {
assert.Equal(t, tc.valid, tc.direction.Valid())
})
}
}
func TestSearch_Sorting(t *testing.T) {
ctx := context.Background()
s, err := cachedb.Open(ctx)
require.NoError(t, err)
at := &AuthToken{
Id: "at_sort",
UserId: "u_sort",
}
{
u := &user{Id: at.UserId, Address: "address"}
rw := db.New(s)
require.NoError(t, rw.Create(ctx, u))
require.NoError(t, rw.Create(ctx, at))
targets := []*Target{
{FkUserId: u.Id, Id: "t_1", Name: "alpha", Type: "tcp", Item: `{"id": "t_1", "name": "alpha", "type": "tcp"}`},
{FkUserId: u.Id, Id: "t_2", Name: "charlie", Type: "tcp", Item: `{"id": "t_2", "name": "charlie", "type": "tcp"}`},
{FkUserId: u.Id, Id: "t_3", Name: "bravo", Type: "tcp", Item: `{"id": "t_3", "name": "bravo", "type": "tcp"}`},
}
require.NoError(t, rw.CreateItems(ctx, targets))
sessions := []*Session{
{FkUserId: u.Id, Id: "s_1", Endpoint: "one", Type: "tcp", UserId: "u123", Item: `{"id": "s_1", "endpoint": "one", "type": "tcp", "user_id": "u123"}`},
{FkUserId: u.Id, Id: "s_2", Endpoint: "two", Type: "ssh", UserId: "u321", Item: `{"id": "s_2", "endpoint": "two", "type": "ssh", "user_id": "u321"}`},
}
require.NoError(t, rw.CreateItems(ctx, sessions))
aliases := []*ResolvableAlias{
{FkUserId: u.Id, Id: "alt_1", Value: "one", Type: "target", Item: `{"id": "alt_1", "value": "one", "type": "target"}`},
}
require.NoError(t, rw.CreateItems(ctx, aliases))
}
r, err := NewRepository(ctx, s, &sync.Map{},
mapBasedAuthTokenKeyringLookup(nil),
sliceBasedAuthTokenBoundaryReader(nil))
require.NoError(t, err)
ss, err := NewSearchService(ctx, r)
require.NoError(t, err)
t.Run("no sort specified returns results", func(t *testing.T) {
got, err := ss.Search(ctx, SearchParams{
Resource: Targets,
AuthTokenId: at.Id,
})
require.NoError(t, err)
require.Len(t, got.Targets, 3)
})
t.Run("invalid sort by value", func(t *testing.T) {
got, err := ss.Search(ctx, SearchParams{
Resource: Targets,
AuthTokenId: at.Id,
SortBy: SortBy("invalid_column"),
})
assert.Error(t, err)
assert.ErrorContains(t, err, "invalid sort by value")
assert.Nil(t, got)
})
t.Run("invalid sort direction value", func(t *testing.T) {
got, err := ss.Search(ctx, SearchParams{
Resource: Targets,
AuthTokenId: at.Id,
SortBy: SortByName,
SortDirection: SortDirection("invalid"),
})
assert.Error(t, err)
assert.ErrorContains(t, err, "invalid sort direction value")
assert.Nil(t, got)
})
t.Run("sort column not allowed for resolvable aliases", func(t *testing.T) {
got, err := ss.Search(ctx, SearchParams{
Resource: ResolvableAliases,
AuthTokenId: at.Id,
SortBy: SortByName,
SortDirection: Ascending,
})
assert.Error(t, err)
assert.ErrorContains(t, err, "not allowed for this resource type")
assert.Nil(t, got)
})
t.Run("sessions reject name sort", func(t *testing.T) {
got, err := ss.Search(ctx, SearchParams{
Resource: Sessions,
AuthTokenId: at.Id,
SortBy: SortByName,
SortDirection: Ascending,
})
assert.Error(t, err)
assert.ErrorContains(t, err, "not allowed for this resource type")
assert.Nil(t, got)
})
t.Run("sessions accept created_at sort", func(t *testing.T) {
got, err := ss.Search(ctx, SearchParams{
Resource: Sessions,
AuthTokenId: at.Id,
SortBy: SortByCreatedAt,
SortDirection: Descending,
})
require.NoError(t, err)
require.Len(t, got.Sessions, 2)
})
}

Loading…
Cancel
Save