API includes sort_order, and WebSocket includes data (#19157)
* API includes sort_order, and WebSocket includes data * Adds sort_order API test * MM-40470: Tests that new WS payload is sent after categories are updated via API. * Update api4/channel_category_test.go Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com> Co-authored-by: Martin Kraft <martin@upspin.org> Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
Этот коммит содержится в:
@@ -4,7 +4,9 @@
|
|||||||
package api4
|
package api4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@@ -71,6 +73,82 @@ func TestCreateCategoryForTeamForUser(t *testing.T) {
|
|||||||
assert.NotContains(t, received.Channels, channel.Id)
|
assert.NotContains(t, received.Channels, channel.Id)
|
||||||
assert.Equal(t, []string{th.BasicChannel.Id}, received.Channels)
|
assert.Equal(t, []string{th.BasicChannel.Id}, received.Channels)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("should return expected sort order value", func(t *testing.T) {
|
||||||
|
user, client := setupUserForSubtest(t, th)
|
||||||
|
|
||||||
|
customCategory, _, err := client.CreateSidebarCategoryForTeamForUser(user.Id, th.BasicTeam.Id, &model.SidebarCategoryWithChannels{
|
||||||
|
SidebarCategory: model.SidebarCategory{
|
||||||
|
UserId: user.Id,
|
||||||
|
TeamId: th.BasicTeam.Id,
|
||||||
|
DisplayName: "custom123",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Initial new category sort order is 10 (first)
|
||||||
|
require.Equal(t, int64(10), customCategory.SortOrder)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("should publish expected WS payload", func(t *testing.T) {
|
||||||
|
userWSClient, err := th.CreateWebSocketClient()
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer userWSClient.Close()
|
||||||
|
userWSClient.Listen()
|
||||||
|
|
||||||
|
category := &model.SidebarCategoryWithChannels{
|
||||||
|
SidebarCategory: model.SidebarCategory{
|
||||||
|
UserId: th.BasicUser.Id,
|
||||||
|
TeamId: th.BasicTeam.Id,
|
||||||
|
DisplayName: "test",
|
||||||
|
},
|
||||||
|
Channels: []string{th.BasicChannel.Id, "notachannel", th.BasicChannel2.Id},
|
||||||
|
}
|
||||||
|
|
||||||
|
received, _, err := th.Client.CreateSidebarCategoryForTeamForUser(th.BasicUser.Id, th.BasicTeam.Id, category)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
testCategories := []*model.SidebarCategoryWithChannels{
|
||||||
|
{
|
||||||
|
SidebarCategory: model.SidebarCategory{
|
||||||
|
Id: received.Id,
|
||||||
|
UserId: th.BasicUser.Id,
|
||||||
|
TeamId: th.BasicTeam.Id,
|
||||||
|
Sorting: model.SidebarCategorySortRecent,
|
||||||
|
Muted: true,
|
||||||
|
},
|
||||||
|
Channels: []string{th.BasicChannel.Id},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
testCategories, _, err = th.Client.UpdateSidebarCategoriesForTeamForUser(th.BasicUser.Id, th.BasicTeam.Id, testCategories)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
b, err := json.Marshal(testCategories)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := string(b)
|
||||||
|
|
||||||
|
var caught bool
|
||||||
|
func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case ev := <-userWSClient.EventChannel:
|
||||||
|
if ev.EventType() == model.WebsocketEventSidebarCategoryUpdated {
|
||||||
|
caught = true
|
||||||
|
data := ev.GetData()
|
||||||
|
|
||||||
|
updatedCategoriesData, ok := data["updatedCategories"]
|
||||||
|
require.True(t, ok)
|
||||||
|
require.EqualValues(t, expected, updatedCategoriesData)
|
||||||
|
}
|
||||||
|
case <-time.After(1 * time.Second):
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
require.Truef(t, caught, "User should have received %s event", model.WebsocketEventSidebarCategoryUpdated)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateCategoryForTeamForUser(t *testing.T) {
|
func TestUpdateCategoryForTeamForUser(t *testing.T) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@@ -119,6 +120,14 @@ func (a *App) UpdateSidebarCategories(userID, teamID string, categories []*model
|
|||||||
}
|
}
|
||||||
|
|
||||||
message := model.NewWebSocketEvent(model.WebsocketEventSidebarCategoryUpdated, teamID, "", userID, nil)
|
message := model.NewWebSocketEvent(model.WebsocketEventSidebarCategoryUpdated, teamID, "", userID, nil)
|
||||||
|
|
||||||
|
updatedCategoriesJSON, jsonErr := json.Marshal(updatedCategories)
|
||||||
|
if jsonErr != nil {
|
||||||
|
mlog.Warn("Failed to encode original categories to JSON", mlog.Err(jsonErr))
|
||||||
|
}
|
||||||
|
|
||||||
|
message.Add("updatedCategories", string(updatedCategoriesJSON))
|
||||||
|
|
||||||
a.Publish(message)
|
a.Publish(message)
|
||||||
|
|
||||||
a.muteChannelsForUpdatedCategories(userID, updatedCategories, originalCategories)
|
a.muteChannelsForUpdatedCategories(userID, updatedCategories, originalCategories)
|
||||||
|
|||||||
@@ -37,12 +37,11 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// SidebarCategory represents the corresponding DB table
|
// SidebarCategory represents the corresponding DB table
|
||||||
// SortOrder is never returned to the user and only used for queries
|
|
||||||
type SidebarCategory struct {
|
type SidebarCategory struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
UserId string `json:"user_id"`
|
UserId string `json:"user_id"`
|
||||||
TeamId string `json:"team_id"`
|
TeamId string `json:"team_id"`
|
||||||
SortOrder int64 `json:"-"`
|
SortOrder int64 `json:"sort_order"`
|
||||||
Sorting SidebarCategorySorting `json:"sorting"`
|
Sorting SidebarCategorySorting `json:"sorting"`
|
||||||
Type SidebarCategoryType `json:"type"`
|
Type SidebarCategoryType `json:"type"`
|
||||||
DisplayName string `json:"display_name"`
|
DisplayName string `json:"display_name"`
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user