MM-24692: Add a since parameter to getGroups api (#14444)
* add a since parameter to getGroups api * update for lint error * when using since, return deleted groups as well. * update flaky test, groups have same create time Co-authored-by: mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
1031e27fd8
Коммит
80c846412d
@@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/v5/audit"
|
"github.com/mattermost/mattermost-server/v5/audit"
|
||||||
@@ -730,6 +731,16 @@ func getGroups(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
opts.NotAssociatedToChannel = channelID
|
opts.NotAssociatedToChannel = channelID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sinceString := r.URL.Query().Get("since")
|
||||||
|
if len(sinceString) > 0 {
|
||||||
|
since, parseError := strconv.ParseInt(sinceString, 10, 64)
|
||||||
|
if parseError != nil {
|
||||||
|
c.SetInvalidParam("since")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
opts.Since = since
|
||||||
|
}
|
||||||
|
|
||||||
groups, err := c.App.GetGroups(c.Params.Page, c.Params.PerPage, opts)
|
groups, err := c.App.GetGroups(c.Params.Page, c.Params.PerPage, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
|
|||||||
@@ -851,6 +851,8 @@ func TestGetGroups(t *testing.T) {
|
|||||||
th := Setup(t).InitBasic()
|
th := Setup(t).InitBasic()
|
||||||
defer th.TearDown()
|
defer th.TearDown()
|
||||||
|
|
||||||
|
// make sure "createdDate" for next group is after one created in InitBasic()
|
||||||
|
time.Sleep(2 * time.Millisecond)
|
||||||
id := model.NewId()
|
id := model.NewId()
|
||||||
group, err := th.App.CreateGroup(&model.Group{
|
group, err := th.App.CreateGroup(&model.Group{
|
||||||
DisplayName: "dn-foo_" + id,
|
DisplayName: "dn-foo_" + id,
|
||||||
@@ -860,6 +862,7 @@ func TestGetGroups(t *testing.T) {
|
|||||||
RemoteId: model.NewId(),
|
RemoteId: model.NewId(),
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
start := group.UpdateAt - 1
|
||||||
|
|
||||||
opts := model.GroupSearchOpts{
|
opts := model.GroupSearchOpts{
|
||||||
PageOpts: &model.PageOpts{
|
PageOpts: &model.PageOpts{
|
||||||
@@ -911,6 +914,36 @@ func TestGetGroups(t *testing.T) {
|
|||||||
|
|
||||||
_, response = th.Client.GetGroups(opts)
|
_, response = th.Client.GetGroups(opts)
|
||||||
assert.Nil(t, response.Error)
|
assert.Nil(t, response.Error)
|
||||||
|
|
||||||
|
// test "since", should only return group created in this test, not th.Group
|
||||||
|
opts.Since = start
|
||||||
|
groups, response = th.Client.GetGroups(opts)
|
||||||
|
assert.Nil(t, response.Error)
|
||||||
|
assert.Len(t, groups, 1)
|
||||||
|
// test correct group returned
|
||||||
|
assert.Equal(t, groups[0].Id, group.Id)
|
||||||
|
|
||||||
|
// delete group, should still return
|
||||||
|
th.App.DeleteGroup(group.Id)
|
||||||
|
groups, response = th.Client.GetGroups(opts)
|
||||||
|
assert.Nil(t, response.Error)
|
||||||
|
assert.Len(t, groups, 1)
|
||||||
|
assert.Equal(t, groups[0].Id, group.Id)
|
||||||
|
|
||||||
|
// test with current since value, return none
|
||||||
|
opts.Since = model.GetMillis()
|
||||||
|
groups, response = th.Client.GetGroups(opts)
|
||||||
|
assert.Nil(t, response.Error)
|
||||||
|
assert.Empty(t, groups)
|
||||||
|
|
||||||
|
// make sure delete group is not returned without Since
|
||||||
|
opts.Since = 0
|
||||||
|
groups, response = th.Client.GetGroups(opts)
|
||||||
|
assert.Nil(t, response.Error)
|
||||||
|
//'Normal getGroups should not return delete groups
|
||||||
|
assert.Len(t, groups, 1)
|
||||||
|
// make sure it returned th.Group,not group
|
||||||
|
assert.Equal(t, groups[0].Id, th.Group.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetGroupsByUserId(t *testing.T) {
|
func TestGetGroupsByUserId(t *testing.T) {
|
||||||
|
|||||||
@@ -3781,6 +3781,9 @@ func (c *Client4) GetGroups(opts GroupSearchOpts) ([]*Group, *Response) {
|
|||||||
opts.FilterAllowReference,
|
opts.FilterAllowReference,
|
||||||
opts.Q,
|
opts.Q,
|
||||||
)
|
)
|
||||||
|
if opts.Since > 0 {
|
||||||
|
path = fmt.Sprintf("%s&since=%v", path, opts.Since)
|
||||||
|
}
|
||||||
if opts.PageOpts != nil {
|
if opts.PageOpts != nil {
|
||||||
path = fmt.Sprintf("%s&page=%v&per_page=%v", path, opts.PageOpts.Page, opts.PageOpts.PerPage)
|
path = fmt.Sprintf("%s&page=%v&per_page=%v", path, opts.PageOpts.Page, opts.PageOpts.PerPage)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ type GroupSearchOpts struct {
|
|||||||
IncludeMemberCount bool
|
IncludeMemberCount bool
|
||||||
FilterAllowReference bool
|
FilterAllowReference bool
|
||||||
PageOpts *PageOpts
|
PageOpts *PageOpts
|
||||||
|
Since int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type PageOpts struct {
|
type PageOpts struct {
|
||||||
|
|||||||
@@ -1144,9 +1144,16 @@ func (s *SqlGroupStore) GetGroups(page, perPage int, opts model.GroupSearchOpts)
|
|||||||
|
|
||||||
groupsQuery = groupsQuery.
|
groupsQuery = groupsQuery.
|
||||||
From("UserGroups g").
|
From("UserGroups g").
|
||||||
Where("g.DeleteAt = 0").
|
|
||||||
OrderBy("g.DisplayName")
|
OrderBy("g.DisplayName")
|
||||||
|
|
||||||
|
if opts.Since > 0 {
|
||||||
|
groupsQuery = groupsQuery.Where(sq.Gt{
|
||||||
|
"g.UpdateAt": opts.Since,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
groupsQuery = groupsQuery.Where("g.DeleteAt = 0")
|
||||||
|
}
|
||||||
|
|
||||||
if perPage != 0 {
|
if perPage != 0 {
|
||||||
groupsQuery = groupsQuery.
|
groupsQuery = groupsQuery.
|
||||||
Limit(uint64(perPage)).
|
Limit(uint64(perPage)).
|
||||||
|
|||||||
@@ -3010,6 +3010,8 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
|||||||
team1, err := ss.Team().Save(team1)
|
team1, err := ss.Team().Save(team1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
startCreateTime := team1.UpdateAt - 1
|
||||||
|
|
||||||
// Create Channel1
|
// Create Channel1
|
||||||
channel1 := &model.Channel{
|
channel1 := &model.Channel{
|
||||||
TeamId: model.NewId(),
|
TeamId: model.NewId(),
|
||||||
@@ -3148,10 +3150,12 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
user2.DeleteAt = 1
|
user2.DeleteAt = 1
|
||||||
ss.User().Update(user2, true)
|
u2Update, _ := ss.User().Update(user2, true)
|
||||||
|
|
||||||
group2NameSubstring := "group-2"
|
group2NameSubstring := "group-2"
|
||||||
|
|
||||||
|
endCreateTime := u2Update.New.UpdateAt + 1
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
Name string
|
Name string
|
||||||
Page int
|
Page int
|
||||||
@@ -3309,6 +3313,32 @@ func testGetGroups(t *testing.T, ss store.Store) {
|
|||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "Use Since return all",
|
||||||
|
Opts: model.GroupSearchOpts{FilterAllowReference: true, Since: startCreateTime},
|
||||||
|
Page: 0,
|
||||||
|
PerPage: 100,
|
||||||
|
Resultf: func(groups []*model.Group) bool {
|
||||||
|
if len(groups) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, g := range groups {
|
||||||
|
if g.DeleteAt != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Use Since return none",
|
||||||
|
Opts: model.GroupSearchOpts{FilterAllowReference: true, Since: endCreateTime},
|
||||||
|
Page: 0,
|
||||||
|
PerPage: 100,
|
||||||
|
Resultf: func(groups []*model.Group) bool {
|
||||||
|
return len(groups) == 0
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user