Add sort query parameter to GET /emojis (#8121)

Этот коммит содержится в:
Joram Wilander
2018-01-19 09:37:59 -05:00
коммит произвёл Harrison Healey
родитель 9d6a9ff4be
Коммит a844577535
10 изменённых файлов: 68 добавлений и 23 удалений

Просмотреть файл

@@ -31,7 +31,7 @@ func getEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
listEmoji, err := c.App.GetEmojiList(0, 100000) listEmoji, err := c.App.GetEmojiList(0, 100000, "")
if err != nil { if err != nil {
c.Err = err c.Err = err
return return

Просмотреть файл

@@ -75,7 +75,13 @@ func getEmojiList(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
listEmoji, err := c.App.GetEmojiList(c.Params.Page, c.Params.PerPage) sort := r.URL.Query().Get("sort")
if sort != "" && sort != model.EMOJI_SORT_BY_NAME {
c.SetInvalidUrlParam("sort")
return
}
listEmoji, err := c.App.GetEmojiList(c.Params.Page, c.Params.PerPage, sort)
if err != nil { if err != nil {
c.Err = err c.Err = err
return return

Просмотреть файл

@@ -209,6 +209,13 @@ func TestGetEmojiList(t *testing.T) {
if len(listEmoji) != 1 { if len(listEmoji) != 1 {
t.Fatal("should only return 1") t.Fatal("should only return 1")
} }
listEmoji, resp = Client.GetSortedEmojiList(0, 100, model.EMOJI_SORT_BY_NAME)
CheckNoError(t, resp)
if len(listEmoji) == 0 {
t.Fatal("should return more than 0")
}
} }
func TestDeleteEmoji(t *testing.T) { func TestDeleteEmoji(t *testing.T) {

Просмотреть файл

@@ -66,8 +66,8 @@ func (a *App) CreateEmoji(sessionUserId string, emoji *model.Emoji, multiPartIma
} }
} }
func (a *App) GetEmojiList(page, perPage int) ([]*model.Emoji, *model.AppError) { func (a *App) GetEmojiList(page, perPage int, sort string) ([]*model.Emoji, *model.AppError) {
if result := <-a.Srv.Store.Emoji().GetList(page*perPage, perPage); result.Err != nil { if result := <-a.Srv.Store.Emoji().GetList(page*perPage, perPage, sort); result.Err != nil {
return nil, result.Err return nil, result.Err
} else { } else {
return result.Data.([]*model.Emoji), nil return result.Data.([]*model.Emoji), nil

Просмотреть файл

@@ -3023,6 +3023,18 @@ func (c *Client4) GetEmojiList(page, perPage int) ([]*Emoji, *Response) {
} }
} }
// GetSortedEmojiList returns a page of custom emoji on the system sorted based on the sort
// parameter, blank for no sorting and "name" to sort by emoji names.
func (c *Client4) GetSortedEmojiList(page, perPage int, sort string) ([]*Emoji, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v&sort=%v", page, perPage, sort)
if r, err := c.DoApiGet(c.GetEmojisRoute()+query, ""); err != nil {
return nil, BuildErrorResponse(r, err)
} else {
defer closeBody(r)
return EmojiListFromJson(r.Body), BuildResponse(r)
}
}
// DeleteEmoji delete an custom emoji on the provided emoji id string. // DeleteEmoji delete an custom emoji on the provided emoji id string.
func (c *Client4) DeleteEmoji(emojiId string) (bool, *Response) { func (c *Client4) DeleteEmoji(emojiId string) (bool, *Response) {
if r, err := c.DoApiDelete(c.GetEmojiRoute(emojiId)); err != nil { if r, err := c.DoApiDelete(c.GetEmojiRoute(emojiId)); err != nil {

Просмотреть файл

@@ -11,6 +11,7 @@ import (
const ( const (
EMOJI_NAME_MAX_LENGTH = 64 EMOJI_NAME_MAX_LENGTH = 64
EMOJI_SORT_BY_NAME = "name"
) )
type Emoji struct { type Emoji struct {

Просмотреть файл

@@ -123,18 +123,19 @@ func (es SqlEmojiStore) GetByName(name string) store.StoreChannel {
}) })
} }
func (es SqlEmojiStore) GetList(offset, limit int) store.StoreChannel { func (es SqlEmojiStore) GetList(offset, limit int, sort string) store.StoreChannel {
return store.Do(func(result *store.StoreResult) { return store.Do(func(result *store.StoreResult) {
var emoji []*model.Emoji var emoji []*model.Emoji
if _, err := es.GetReplica().Select(&emoji, query := "SELECT * FROM Emoji WHERE DeleteAt = 0"
`SELECT
* if sort == model.EMOJI_SORT_BY_NAME {
FROM query += " ORDER BY Name"
Emoji }
WHERE
DeleteAt = 0 query += " LIMIT :Limit OFFSET :Offset"
LIMIT :Limit OFFSET :Offset`, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil {
if _, err := es.GetReplica().Select(&emoji, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil {
result.Err = model.NewAppError("SqlEmojiStore.GetList", "store.sql_emoji.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) result.Err = model.NewAppError("SqlEmojiStore.GetList", "store.sql_emoji.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
} else { } else {
result.Data = emoji result.Data = emoji

Просмотреть файл

@@ -391,7 +391,7 @@ type EmojiStore interface {
Save(emoji *model.Emoji) StoreChannel Save(emoji *model.Emoji) StoreChannel
Get(id string, allowFromCache bool) StoreChannel Get(id string, allowFromCache bool) StoreChannel
GetByName(name string) StoreChannel GetByName(name string) StoreChannel
GetList(offset, limit int) StoreChannel GetList(offset, limit int, sort string) StoreChannel
Delete(id string, time int64) StoreChannel Delete(id string, time int64) StoreChannel
} }

Просмотреть файл

@@ -9,6 +9,8 @@ import (
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store" "github.com/mattermost/mattermost-server/store"
"github.com/stretchr/testify/assert"
) )
func TestEmojiStore(t *testing.T, ss store.Store) { func TestEmojiStore(t *testing.T, ss store.Store) {
@@ -133,15 +135,15 @@ func testEmojiGetList(t *testing.T, ss store.Store) {
emojis := []model.Emoji{ emojis := []model.Emoji{
{ {
CreatorId: model.NewId(), CreatorId: model.NewId(),
Name: model.NewId(), Name: "00000000000000000000000000a" + model.NewId(),
}, },
{ {
CreatorId: model.NewId(), CreatorId: model.NewId(),
Name: model.NewId(), Name: "00000000000000000000000000b" + model.NewId(),
}, },
{ {
CreatorId: model.NewId(), CreatorId: model.NewId(),
Name: model.NewId(), Name: "00000000000000000000000000c" + model.NewId(),
}, },
} }
@@ -154,7 +156,7 @@ func testEmojiGetList(t *testing.T, ss store.Store) {
} }
}() }()
if result := <-ss.Emoji().GetList(0, 100); result.Err != nil { if result := <-ss.Emoji().GetList(0, 100, ""); result.Err != nil {
t.Fatal(result.Err) t.Fatal(result.Err)
} else { } else {
for _, emoji := range emojis { for _, emoji := range emojis {
@@ -172,4 +174,20 @@ func testEmojiGetList(t *testing.T, ss store.Store) {
} }
} }
} }
result := <-ss.Emoji().GetList(0, 3, model.EMOJI_SORT_BY_NAME)
assert.Nil(t, result.Err)
remojis := result.Data.([]*model.Emoji)
assert.Equal(t, 3, len(remojis))
assert.Equal(t, emojis[0].Name, remojis[0].Name)
assert.Equal(t, emojis[1].Name, remojis[1].Name)
assert.Equal(t, emojis[2].Name, remojis[2].Name)
result = <-ss.Emoji().GetList(1, 2, model.EMOJI_SORT_BY_NAME)
assert.Nil(t, result.Err)
remojis = result.Data.([]*model.Emoji)
assert.Equal(t, 2, len(remojis))
assert.Equal(t, emojis[1].Name, remojis[0].Name)
assert.Equal(t, emojis[2].Name, remojis[1].Name)
} }

Просмотреть файл

@@ -61,13 +61,13 @@ func (_m *EmojiStore) GetByName(name string) store.StoreChannel {
return r0 return r0
} }
// GetList provides a mock function with given fields: offset, limit // GetList provides a mock function with given fields: offset, limit, sort
func (_m *EmojiStore) GetList(offset int, limit int) store.StoreChannel { func (_m *EmojiStore) GetList(offset int, limit int, sort string) store.StoreChannel {
ret := _m.Called(offset, limit) ret := _m.Called(offset, limit, sort)
var r0 store.StoreChannel var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(int, int) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(int, int, string) store.StoreChannel); ok {
r0 = rf(offset, limit) r0 = rf(offset, limit, sort)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).(store.StoreChannel)