mirror of
https://github.com/absmach/magistrala.git
synced 2026-06-23 04:10:28 +00:00
NOISSUE - Allow sorting (#3052)
Signed-off-by: Musilah <nataleigh.nk@gmail.com>
This commit is contained in:
@@ -284,6 +284,15 @@ func decodePageMeta(r *http.Request) (groups.PageMeta, error) {
|
||||
return groups.PageMeta{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
|
||||
order, err := apiutil.ReadStringQuery(r, api.OrderKey, api.DefOrder)
|
||||
if err != nil {
|
||||
return groups.PageMeta{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
dir, err := apiutil.ReadStringQuery(r, api.DirKey, api.DescDir)
|
||||
if err != nil {
|
||||
return groups.PageMeta{}, errors.Wrap(apiutil.ErrValidation, err)
|
||||
}
|
||||
|
||||
ret := groups.PageMeta{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
@@ -297,6 +306,8 @@ func decodePageMeta(r *http.Request) (groups.PageMeta, error) {
|
||||
AccessType: accessType,
|
||||
RootGroup: rootGroup,
|
||||
OnlyTotal: ot,
|
||||
Order: order,
|
||||
Dir: dir,
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ func TestDecodeListGroupsRequest(t *testing.T) {
|
||||
PageMeta: groups.PageMeta{
|
||||
Limit: 10,
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
@@ -54,6 +56,8 @@ func TestDecodeListGroupsRequest(t *testing.T) {
|
||||
"test": "test",
|
||||
},
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
@@ -166,13 +170,15 @@ func TestDecodeListChildrenRequest(t *testing.T) {
|
||||
PageMeta: groups.PageMeta{
|
||||
Limit: 10,
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
desc: "valid request with all parameters",
|
||||
url: "http://localhost:8080?status=enabled&offset=10&limit=10&name=random&metadata={\"test\":\"test\"}&level=2&parent_id=random&tree=true&dir=-1&member_kind=random&permission=random&list_perms=true",
|
||||
url: "http://localhost:8080?status=enabled&offset=10&limit=10&name=random&metadata={\"test\":\"test\"}&level=2&parent_id=random&tree=true&dir=desc&member_kind=random&permission=random&list_perms=true",
|
||||
header: map[string][]string{
|
||||
"Authorization": {"Bearer 123"},
|
||||
},
|
||||
@@ -188,6 +194,8 @@ func TestDecodeListChildrenRequest(t *testing.T) {
|
||||
"test": "test",
|
||||
},
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
@@ -227,6 +235,8 @@ func TestDecodePageMeta(t *testing.T) {
|
||||
resp: groups.PageMeta{
|
||||
Limit: 10,
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
@@ -242,6 +252,8 @@ func TestDecodePageMeta(t *testing.T) {
|
||||
"test": "test",
|
||||
},
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
|
||||
@@ -2034,6 +2034,8 @@ func TestListChildrenGroupsEndpoint(t *testing.T) {
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
svcRes: groups.Page{
|
||||
PageMeta: groups.PageMeta{
|
||||
@@ -2056,6 +2058,8 @@ func TestListChildrenGroupsEndpoint(t *testing.T) {
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
authnErr: svcerr.ErrAuthentication,
|
||||
status: http.StatusUnauthorized,
|
||||
@@ -2072,6 +2076,8 @@ func TestListChildrenGroupsEndpoint(t *testing.T) {
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
status: http.StatusUnauthorized,
|
||||
err: apiutil.ErrBearerToken,
|
||||
@@ -2094,6 +2100,8 @@ func TestListChildrenGroupsEndpoint(t *testing.T) {
|
||||
Limit: 1,
|
||||
Offset: 0,
|
||||
Actions: []string{},
|
||||
Dir: "desc",
|
||||
Order: "updated_at",
|
||||
},
|
||||
svcRes: groups.Page{},
|
||||
svcErr: svcerr.ErrAuthorization,
|
||||
|
||||
@@ -66,6 +66,17 @@ func (req listGroupsReq) validate() error {
|
||||
if req.userID != "" && req.groupID != "" {
|
||||
return apiutil.ErrMultipleEntitiesFilter
|
||||
}
|
||||
|
||||
switch req.Order {
|
||||
case "", api.NameOrder, api.CreatedAtOrder, api.UpdatedAtOrder:
|
||||
default:
|
||||
return apiutil.ErrInvalidOrder
|
||||
}
|
||||
|
||||
if req.Dir != "" && (req.Dir != api.DescDir && req.Dir != api.AscDir) {
|
||||
return apiutil.ErrInvalidDirection
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ type PageMeta struct {
|
||||
OnlyTotal bool `json:"only_total"`
|
||||
Name string `json:"name,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Dir string `json:"dir,omitempty"`
|
||||
Order string `json:"order,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
DomainID string `json:"domain_id,omitempty"`
|
||||
Tag string `json:"tag,omitempty"`
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
api "github.com/absmach/supermq/api/http"
|
||||
groups "github.com/absmach/supermq/groups"
|
||||
"github.com/absmach/supermq/internal/nullable"
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
@@ -408,11 +409,19 @@ func (repo groupRepository) RetrieveByIDAndUser(ctx context.Context, domainID, u
|
||||
}
|
||||
|
||||
func (repo groupRepository) RetrieveAll(ctx context.Context, pm groups.PageMeta) (groups.Page, error) {
|
||||
var q string
|
||||
query := buildQuery(pm)
|
||||
|
||||
q = fmt.Sprintf(`SELECT DISTINCT g.id, g.domain_id, tags, COALESCE(g.parent_id, '') AS parent_id, g.name, g.description,
|
||||
g.metadata, g.created_at, g.updated_at, g.updated_by, g.status FROM groups g %s ORDER BY g.created_at LIMIT :limit OFFSET :offset;`, query)
|
||||
orderClause := ""
|
||||
switch pm.Order {
|
||||
case "name", "created_at", "updated_at":
|
||||
orderClause = fmt.Sprintf("ORDER BY g.%s", pm.Order)
|
||||
if pm.Dir == api.AscDir || pm.Dir == api.DescDir {
|
||||
orderClause = fmt.Sprintf("%s %s", orderClause, pm.Dir)
|
||||
}
|
||||
}
|
||||
|
||||
q := fmt.Sprintf(`SELECT DISTINCT g.id, g.domain_id, tags, COALESCE(g.parent_id, '') AS parent_id, g.name, g.description,
|
||||
g.metadata, g.created_at, g.updated_at, g.updated_by, g.status FROM groups g %s %s LIMIT :limit OFFSET :offset;`, query, orderClause)
|
||||
|
||||
dbPageMeta, err := toDBGroupPageMeta(pm)
|
||||
if err != nil {
|
||||
|
||||
@@ -707,6 +707,8 @@ func TestRetrieveAll(t *testing.T) {
|
||||
PageMeta: groups.PageMeta{
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
Order: "created_at",
|
||||
Dir: "asc",
|
||||
},
|
||||
},
|
||||
response: groups.Page{
|
||||
@@ -725,6 +727,8 @@ func TestRetrieveAll(t *testing.T) {
|
||||
PageMeta: groups.PageMeta{
|
||||
Offset: 10,
|
||||
Limit: 10,
|
||||
Order: "created_at",
|
||||
Dir: "asc",
|
||||
},
|
||||
},
|
||||
response: groups.Page{
|
||||
@@ -743,6 +747,9 @@ func TestRetrieveAll(t *testing.T) {
|
||||
PageMeta: groups.PageMeta{
|
||||
Offset: 0,
|
||||
Limit: 50,
|
||||
|
||||
Order: "created_at",
|
||||
Dir: "asc",
|
||||
},
|
||||
},
|
||||
response: groups.Page{
|
||||
@@ -761,6 +768,8 @@ func TestRetrieveAll(t *testing.T) {
|
||||
PageMeta: groups.PageMeta{
|
||||
Offset: 50,
|
||||
Limit: 50,
|
||||
Order: "created_at",
|
||||
Dir: "asc",
|
||||
},
|
||||
},
|
||||
response: groups.Page{
|
||||
@@ -779,6 +788,8 @@ func TestRetrieveAll(t *testing.T) {
|
||||
PageMeta: groups.PageMeta{
|
||||
Offset: 1000,
|
||||
Limit: 50,
|
||||
Order: "created_at",
|
||||
Dir: "asc",
|
||||
},
|
||||
},
|
||||
response: groups.Page{
|
||||
@@ -797,6 +808,8 @@ func TestRetrieveAll(t *testing.T) {
|
||||
PageMeta: groups.PageMeta{
|
||||
Offset: 170,
|
||||
Limit: 50,
|
||||
Order: "created_at",
|
||||
Dir: "asc",
|
||||
},
|
||||
},
|
||||
response: groups.Page{
|
||||
|
||||
Reference in New Issue
Block a user