mirror of
https://github.com/mattermost/mattermost.git
synced 2026-02-03 20:40:00 -05:00
On page load, we load ALL channels and channel members from all teams. But then, on team_switch, we would again load channels and channel members from that team. This was redundant and mainly kept because previously the websocket events were considered unreliable. Now with reliable websockets, and client-side pings, we can detect broken connections faster and recover without loss. Additionally, the getAllChannelMembers call would page through all responses on the client side. This was inefficient and incur extra latency. To optimize for this, we introduce server-side streaming of the full response if page is set to -1. This optimizes the intial response as well. https://mattermost.atlassian.net/browse/MM-56906 ```release-note Optimize team switch operation by removing calls to get channels and channel members. ``` Co-authored-by: Mattermost Build <build@mattermost.com>
502 lines
10 KiB
Go
502 lines
10 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
package web
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"testing"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
)
|
|
|
|
func TestParamsFromRequest(t *testing.T) {
|
|
testCases := []struct {
|
|
Description string
|
|
URL *url.URL
|
|
Vars map[string]string
|
|
Params *Params
|
|
}{
|
|
{
|
|
"empty params",
|
|
mustURL("/"),
|
|
nil,
|
|
&Params{
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"query params",
|
|
mustURL("/page?" +
|
|
"channel_id=abc123&" +
|
|
"filename=file.ext&" +
|
|
"page=42&" +
|
|
"time_range=then-till-now&" +
|
|
"permanent=1&" +
|
|
"logs_per_page=5&" +
|
|
"limit_after=6&" +
|
|
"limit_before=7&" +
|
|
"q=picard&" +
|
|
"is_linked=t&" +
|
|
"is_configured=TRUE&" +
|
|
"not_associated_to_team=this_team&" +
|
|
"not_associated_to_channel=this_channel&" +
|
|
"filter_allow_reference=true&" +
|
|
"filter_parent_team_permitted=True&" +
|
|
"paginate=T&" +
|
|
"include_member_count=1&" +
|
|
"not_associated_to_group=test&" +
|
|
"exclude_default_channels=1&" +
|
|
"group_ids=hello,world&" +
|
|
"include_total_count=T&" +
|
|
"include_deleted=True&" +
|
|
"exclude_policy_constrained=TRUE&" +
|
|
"filter_has_member=xyz"),
|
|
nil,
|
|
&Params{
|
|
ChannelId: "abc123",
|
|
Filename: "file.ext",
|
|
Page: 42,
|
|
TimeRange: "then-till-now",
|
|
PerPage: PerPageDefault,
|
|
Permanent: true,
|
|
LogsPerPage: 5,
|
|
LimitAfter: 6,
|
|
LimitBefore: 7,
|
|
Q: "picard",
|
|
IsLinked: boolPtr(true),
|
|
IsConfigured: boolPtr(true),
|
|
NotAssociatedToTeam: "this_team",
|
|
NotAssociatedToChannel: "this_channel",
|
|
FilterAllowReference: true,
|
|
FilterParentTeamPermitted: true,
|
|
Paginate: boolPtr(true),
|
|
IncludeMemberCount: true,
|
|
NotAssociatedToGroup: "test",
|
|
ExcludeDefaultChannels: true,
|
|
GroupIDs: "hello,world",
|
|
IncludeTotalCount: true,
|
|
IncludeDeleted: true,
|
|
ExcludePolicyConstrained: true,
|
|
FilterHasMember: "xyz",
|
|
},
|
|
},
|
|
{
|
|
"page invalid",
|
|
mustURL("?page=hello"),
|
|
nil,
|
|
&Params{
|
|
Page: PageDefault,
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"page negative",
|
|
mustURL("?page=-1"),
|
|
nil,
|
|
&Params{
|
|
Page: PageDefault,
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"per page valid",
|
|
mustURL("?per_page=123"),
|
|
nil,
|
|
&Params{
|
|
PerPage: 123,
|
|
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"per page too small",
|
|
mustURL("?per_page=-100"),
|
|
nil,
|
|
&Params{
|
|
PerPage: PerPageDefault,
|
|
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"per page too big",
|
|
mustURL("?per_page=100000"),
|
|
nil,
|
|
&Params{
|
|
PerPage: PerPageMaximum,
|
|
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"logs per page valid",
|
|
mustURL("?logs_per_page=512"),
|
|
nil,
|
|
&Params{
|
|
LogsPerPage: 512,
|
|
|
|
PerPage: PerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"logs per page invalid",
|
|
mustURL("?logs_per_page=logs"),
|
|
nil,
|
|
&Params{
|
|
LogsPerPage: LogsPerPageDefault,
|
|
|
|
PerPage: PerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"logs per page too small",
|
|
mustURL("?logs_per_page=-512"),
|
|
nil,
|
|
&Params{
|
|
LogsPerPage: LogsPerPageDefault,
|
|
|
|
PerPage: PerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"logs per page too big",
|
|
mustURL("?logs_per_page=99999999"),
|
|
nil,
|
|
&Params{
|
|
LogsPerPage: LogsPerPageMaximum,
|
|
|
|
PerPage: PerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"limit before valid",
|
|
mustURL("?limit_before=100"),
|
|
nil,
|
|
&Params{
|
|
LimitBefore: 100,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"limit before invalid",
|
|
mustURL("?limit_before=limit"),
|
|
nil,
|
|
&Params{
|
|
LimitBefore: LimitDefault,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"limit before too small",
|
|
mustURL("?limit_before=-100"),
|
|
nil,
|
|
&Params{
|
|
LimitBefore: LimitDefault,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"limit before too big",
|
|
mustURL("?limit_before=99999"),
|
|
nil,
|
|
&Params{
|
|
LimitBefore: LimitMaximum,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"limit after valid",
|
|
mustURL("?limit_after=100"),
|
|
nil,
|
|
&Params{
|
|
LimitAfter: 100,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"limit after invalid",
|
|
mustURL("?limit_after=limit"),
|
|
nil,
|
|
&Params{
|
|
LimitAfter: LimitDefault,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"limit after too small",
|
|
mustURL("?limit_aftere=-100"),
|
|
nil,
|
|
&Params{
|
|
LimitAfter: LimitDefault,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"limit after too big",
|
|
mustURL("?limit_after=99999"),
|
|
nil,
|
|
&Params{
|
|
LimitAfter: LimitMaximum,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"group source custom",
|
|
mustURL("?group_source=custom"),
|
|
nil,
|
|
&Params{
|
|
GroupSource: model.GroupSourceCustom,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"group source LDAP",
|
|
mustURL("?group_source=ldap"),
|
|
nil,
|
|
&Params{
|
|
GroupSource: model.GroupSourceLdap,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"group source other",
|
|
mustURL("?group_source=aabbcc"),
|
|
nil,
|
|
&Params{
|
|
GroupSource: model.GroupSourceLdap,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"group source empty",
|
|
mustURL("?group_souce="),
|
|
nil,
|
|
&Params{
|
|
GroupSource: "",
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"timestamp valid",
|
|
mustURL("/"),
|
|
map[string]string{
|
|
"timestamp": "1234567",
|
|
},
|
|
&Params{
|
|
Timestamp: 1234567,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"timestamp valid",
|
|
mustURL("/"),
|
|
map[string]string{
|
|
"timestamp": "yes",
|
|
},
|
|
&Params{
|
|
Timestamp: 0,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"timestamp too small",
|
|
mustURL("/"),
|
|
map[string]string{
|
|
"timestamp": "-1234567",
|
|
},
|
|
&Params{
|
|
Timestamp: 0,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"syncable type teams",
|
|
mustURL("/"),
|
|
map[string]string{
|
|
"syncable_type": "teams",
|
|
},
|
|
&Params{
|
|
SyncableType: model.GroupSyncableTypeTeam,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"syncable type channels",
|
|
mustURL("/"),
|
|
map[string]string{
|
|
"syncable_type": "channels",
|
|
},
|
|
&Params{
|
|
SyncableType: model.GroupSyncableTypeChannel,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"syncable type other",
|
|
mustURL("/"),
|
|
map[string]string{
|
|
"syncable_type": "unknownvalue",
|
|
},
|
|
&Params{
|
|
SyncableType: "",
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
LimitAfter: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"include channel bookmarks",
|
|
mustURL("/?include_bookmarks=true"),
|
|
nil,
|
|
&Params{
|
|
BookmarksSince: 0,
|
|
|
|
LimitAfter: LimitDefault,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"include channel bookmarks with negative bookmark since",
|
|
mustURL("/?include_bookmarks=true&bookmarks_since=-1"),
|
|
nil,
|
|
&Params{
|
|
BookmarksSince: 0,
|
|
|
|
LimitAfter: LimitDefault,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
{
|
|
"include channel bookmarks with bookmark since",
|
|
mustURL("/?include_bookmarks=true&bookmarks_since=123456789"),
|
|
nil,
|
|
&Params{
|
|
BookmarksSince: 123456789,
|
|
|
|
LimitAfter: LimitDefault,
|
|
|
|
PerPage: PerPageDefault,
|
|
LogsPerPage: LogsPerPageDefault,
|
|
LimitBefore: LimitDefault,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, testCase := range testCases {
|
|
t.Run(testCase.Description, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
r := &http.Request{URL: testCase.URL}
|
|
r = mux.SetURLVars(r, testCase.Vars)
|
|
params := ParamsFromRequest(r)
|
|
require.Equal(t, testCase.Params, params)
|
|
})
|
|
}
|
|
}
|
|
|
|
func mustURL(u string) *url.URL {
|
|
parsed, err := url.Parse(u)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return parsed
|
|
}
|
|
|
|
func boolPtr(b bool) *bool {
|
|
return &b
|
|
}
|