Full Mattermost server source with integrated Community Enterprise features. Includes vendor directory for offline/air-gapped builds. Structure: - enterprise-impl/: Enterprise feature implementations - enterprise-community/: Init files that register implementations - enterprise/: Bridge imports (community_imports.go) - vendor/: All dependencies for offline builds Build (online): go build ./cmd/mattermost Build (offline/air-gapped): go build -mod=vendor ./cmd/mattermost 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
629 lines
20 KiB
Go
629 lines
20 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package api4
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"math/rand"
|
|
"net/http"
|
|
"sort"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
)
|
|
|
|
var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
|
func setupForSharedChannels(tb testing.TB) *TestHelper {
|
|
th := SetupConfig(tb, func(cfg *model.Config) {
|
|
*cfg.ConnectedWorkspacesSettings.EnableRemoteClusterService = true
|
|
*cfg.ConnectedWorkspacesSettings.EnableSharedChannels = true
|
|
})
|
|
|
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
|
*cfg.ServiceSettings.SiteURL = fmt.Sprintf("http://localhost:%d", th.Server.ListenAddr.Port)
|
|
})
|
|
|
|
return th
|
|
}
|
|
|
|
func TestGetAllSharedChannels(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := setupForSharedChannels(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
const pages = 3
|
|
const pageSize = 7
|
|
|
|
savedIds := make([]string, 0, pages*pageSize)
|
|
|
|
// make some shared channels
|
|
for i := range pages * pageSize {
|
|
channel := th.CreateChannelWithClientAndTeam(th.Client, model.ChannelTypeOpen, th.BasicTeam.Id)
|
|
sc := &model.SharedChannel{
|
|
ChannelId: channel.Id,
|
|
TeamId: channel.TeamId,
|
|
Home: randomBool(),
|
|
ShareName: fmt.Sprintf("test_share_%d", i),
|
|
CreatorId: th.BasicChannel.CreatorId,
|
|
RemoteId: model.NewId(),
|
|
}
|
|
|
|
_, err := th.App.ShareChannel(th.Context, sc)
|
|
require.NoError(t, err)
|
|
savedIds = append(savedIds, channel.Id)
|
|
}
|
|
sort.Strings(savedIds)
|
|
|
|
t.Run("get shared channels paginated", func(t *testing.T) {
|
|
channelIds := make([]string, 0, 21)
|
|
for i := range pages {
|
|
channels, _, err := th.Client.GetAllSharedChannels(context.Background(), th.BasicTeam.Id, i, pageSize)
|
|
require.NoError(t, err)
|
|
channelIds = append(channelIds, getIds(channels)...)
|
|
}
|
|
sort.Strings(channelIds)
|
|
|
|
// ids lists should now match
|
|
assert.Equal(t, savedIds, channelIds, "id lists should match")
|
|
})
|
|
|
|
t.Run("get shared channels for invalid team", func(t *testing.T) {
|
|
_, _, err := th.Client.GetAllSharedChannels(context.Background(), model.NewId(), 0, 100)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("get shared channels, user not member of team", func(t *testing.T) {
|
|
team := &model.Team{
|
|
DisplayName: "tteam",
|
|
Name: GenerateTestTeamName(),
|
|
Type: model.TeamOpen,
|
|
}
|
|
team, _, err := th.SystemAdminClient.CreateTeam(context.Background(), team)
|
|
require.NoError(t, err)
|
|
|
|
_, _, err = th.Client.GetAllSharedChannels(context.Background(), team.Id, 0, 100)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func getIds(channels []*model.SharedChannel) []string {
|
|
ids := make([]string, 0, len(channels))
|
|
for _, c := range channels {
|
|
ids = append(ids, c.ChannelId)
|
|
}
|
|
return ids
|
|
}
|
|
|
|
func randomBool() bool {
|
|
return rnd.Intn(2) != 0
|
|
}
|
|
|
|
func TestGetRemoteClusterById(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := setupForSharedChannels(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
// for this test we need a user that belongs to a channel that
|
|
// is shared with the requested remote id.
|
|
|
|
// create a remote cluster
|
|
rc := &model.RemoteCluster{
|
|
RemoteId: model.NewId(),
|
|
Name: "Test1",
|
|
SiteURL: model.NewId(),
|
|
CreatorId: model.NewId(),
|
|
}
|
|
rc, appErr := th.App.AddRemoteCluster(rc)
|
|
require.Nil(t, appErr)
|
|
|
|
// create a shared channel
|
|
sc := &model.SharedChannel{
|
|
ChannelId: th.BasicChannel.Id,
|
|
TeamId: th.BasicChannel.TeamId,
|
|
Home: false,
|
|
ShareName: "test_share",
|
|
CreatorId: th.BasicChannel.CreatorId,
|
|
RemoteId: rc.RemoteId,
|
|
}
|
|
sc, err := th.App.ShareChannel(th.Context, sc)
|
|
require.NoError(t, err)
|
|
|
|
// create a shared channel remote to connect them
|
|
scr := &model.SharedChannelRemote{
|
|
Id: model.NewId(),
|
|
ChannelId: sc.ChannelId,
|
|
CreatorId: sc.CreatorId,
|
|
IsInviteAccepted: true,
|
|
IsInviteConfirmed: true,
|
|
RemoteId: sc.RemoteId,
|
|
}
|
|
_, err = th.App.SaveSharedChannelRemote(scr)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("valid remote, user is member", func(t *testing.T) {
|
|
rcInfo, _, err := th.Client.GetRemoteClusterInfo(context.Background(), rc.RemoteId)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, rc.Name, rcInfo.Name)
|
|
})
|
|
|
|
t.Run("invalid remote", func(t *testing.T) {
|
|
_, resp, err := th.Client.GetRemoteClusterInfo(context.Background(), model.NewId())
|
|
require.Error(t, err)
|
|
CheckNotFoundStatus(t, resp)
|
|
})
|
|
}
|
|
|
|
func TestCreateDirectChannelWithRemoteUser(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
t.Run("should not create a local DM channel that is shared", func(t *testing.T) {
|
|
th := setupForSharedChannels(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
defer func() {
|
|
_, err := client.Logout(context.Background())
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
localUser := th.BasicUser
|
|
remoteUser := th.CreateUser()
|
|
remoteUser.RemoteId = model.NewPointer(model.NewId())
|
|
remoteUser, appErr := th.App.UpdateUser(th.Context, remoteUser, false)
|
|
require.Nil(t, appErr)
|
|
|
|
dm, _, err := client.CreateDirectChannel(context.Background(), localUser.Id, remoteUser.Id)
|
|
require.Error(t, err)
|
|
require.Nil(t, dm)
|
|
})
|
|
|
|
t.Run("creates a local DM channel that is shared", func(t *testing.T) {
|
|
t.Skip("Remote DMs are currently disabled")
|
|
|
|
th := setupForSharedChannels(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
defer func() {
|
|
_, err := client.Logout(context.Background())
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
localUser := th.BasicUser
|
|
remoteUser := th.CreateUser()
|
|
remoteUser.RemoteId = model.NewPointer(model.NewId())
|
|
remoteUser, appErr := th.App.UpdateUser(th.Context, remoteUser, false)
|
|
require.Nil(t, appErr)
|
|
|
|
dm, _, err := client.CreateDirectChannel(context.Background(), localUser.Id, remoteUser.Id)
|
|
require.NoError(t, err)
|
|
|
|
channelName := model.GetDMNameFromIds(localUser.Id, remoteUser.Id)
|
|
require.Equal(t, channelName, dm.Name, "dm name didn't match")
|
|
assert.True(t, dm.IsShared())
|
|
})
|
|
|
|
t.Run("sends a shared channel invitation to the remote", func(t *testing.T) {
|
|
t.Skip("Remote DMs are currently disabled")
|
|
|
|
th := setupForSharedChannels(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
defer func() {
|
|
_, err := client.Logout(context.Background())
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
localUser := th.BasicUser
|
|
remoteUser := th.CreateUser()
|
|
|
|
rc := &model.RemoteCluster{
|
|
Name: "test",
|
|
Token: model.NewId(),
|
|
CreatorId: localUser.Id,
|
|
}
|
|
rc, appErr := th.App.AddRemoteCluster(rc)
|
|
require.Nil(t, appErr)
|
|
|
|
remoteUser.RemoteId = model.NewPointer(rc.RemoteId)
|
|
remoteUser, appErr = th.App.UpdateUser(th.Context, remoteUser, false)
|
|
require.Nil(t, appErr)
|
|
|
|
dm, _, err := client.CreateDirectChannel(context.Background(), localUser.Id, remoteUser.Id)
|
|
require.NoError(t, err)
|
|
|
|
channelName := model.GetDMNameFromIds(localUser.Id, remoteUser.Id)
|
|
require.Equal(t, channelName, dm.Name, "dm name didn't match")
|
|
require.True(t, dm.IsShared())
|
|
})
|
|
|
|
t.Run("does not send a shared channel invitation to the remote when creator is remote", func(t *testing.T) {
|
|
t.Skip("Remote DMs are currently disabled")
|
|
|
|
th := setupForSharedChannels(t).InitBasic()
|
|
defer th.TearDown()
|
|
client := th.Client
|
|
defer func() {
|
|
_, err := client.Logout(context.Background())
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
localUser := th.BasicUser
|
|
remoteUser := th.CreateUser()
|
|
|
|
rc := &model.RemoteCluster{
|
|
Name: "test",
|
|
Token: model.NewId(),
|
|
CreatorId: localUser.Id,
|
|
}
|
|
rc, appErr := th.App.AddRemoteCluster(rc)
|
|
require.Nil(t, appErr)
|
|
|
|
remoteUser.RemoteId = model.NewPointer(rc.RemoteId)
|
|
remoteUser, appErr = th.App.UpdateUser(th.Context, remoteUser, false)
|
|
require.Nil(t, appErr)
|
|
|
|
dm, _, err := client.CreateDirectChannel(context.Background(), remoteUser.Id, localUser.Id)
|
|
require.NoError(t, err)
|
|
|
|
channelName := model.GetDMNameFromIds(localUser.Id, remoteUser.Id)
|
|
require.Equal(t, channelName, dm.Name, "dm name didn't match")
|
|
require.True(t, dm.IsShared())
|
|
})
|
|
}
|
|
|
|
func TestGetSharedChannelRemotesByRemoteCluster(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
t.Run("Should not work if the remote cluster service is not enabled", func(t *testing.T) {
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
resp, err := th.SystemAdminClient.DeleteRemoteCluster(context.Background(), model.NewId())
|
|
CheckNotImplementedStatus(t, resp)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
th := setupForSharedChannels(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
newRC1 := &model.RemoteCluster{Name: "rc1", SiteURL: "http://example1.com", CreatorId: th.SystemAdminUser.Id}
|
|
newRC2 := &model.RemoteCluster{Name: "rc2", SiteURL: "http://example2.com", CreatorId: th.SystemAdminUser.Id}
|
|
|
|
rc1, appErr := th.App.AddRemoteCluster(newRC1)
|
|
require.Nil(t, appErr)
|
|
rc2, appErr := th.App.AddRemoteCluster(newRC2)
|
|
require.Nil(t, appErr)
|
|
|
|
c1 := th.CreateChannelWithClientAndTeam(th.Client, model.ChannelTypeOpen, th.BasicTeam.Id)
|
|
sc1 := &model.SharedChannel{
|
|
ChannelId: c1.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
ShareName: "shared_1",
|
|
ShareDisplayName: "Shared Channel 1", // for sorting purposes
|
|
CreatorId: th.BasicUser.Id,
|
|
RemoteId: rc1.RemoteId,
|
|
Home: true,
|
|
}
|
|
_, err := th.App.ShareChannel(th.Context, sc1)
|
|
require.NoError(t, err)
|
|
|
|
c2 := th.CreateChannelWithClientAndTeam(th.Client, model.ChannelTypeOpen, th.BasicTeam.Id)
|
|
sc2 := &model.SharedChannel{
|
|
ChannelId: c2.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
ShareName: "shared_2",
|
|
ShareDisplayName: "Shared Channel 2",
|
|
CreatorId: th.BasicUser.Id,
|
|
RemoteId: rc1.RemoteId,
|
|
Home: false,
|
|
}
|
|
|
|
_, err = th.App.ShareChannel(th.Context, sc2)
|
|
require.NoError(t, err)
|
|
|
|
c3 := th.CreateChannelWithClientAndTeam(th.Client, model.ChannelTypeOpen, th.BasicTeam.Id)
|
|
sc3 := &model.SharedChannel{
|
|
ChannelId: c3.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
ShareName: "shared_3",
|
|
CreatorId: th.BasicUser.Id,
|
|
RemoteId: rc2.RemoteId,
|
|
}
|
|
_, err = th.App.ShareChannel(th.Context, sc3)
|
|
require.NoError(t, err)
|
|
|
|
c4 := th.CreateChannelWithClientAndTeam(th.Client, model.ChannelTypeOpen, th.BasicTeam.Id)
|
|
sc4 := &model.SharedChannel{
|
|
ChannelId: c4.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
ShareName: "shared_4",
|
|
ShareDisplayName: "Shared Channel 4",
|
|
CreatorId: th.BasicUser.Id,
|
|
RemoteId: rc1.RemoteId,
|
|
Home: false,
|
|
}
|
|
|
|
_, err = th.App.ShareChannel(th.Context, sc4)
|
|
require.NoError(t, err)
|
|
|
|
c5 := th.CreateChannelWithClientAndTeam(th.Client, model.ChannelTypeOpen, th.BasicTeam.Id)
|
|
sc5 := &model.SharedChannel{
|
|
ChannelId: c5.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
ShareName: "shared_5",
|
|
ShareDisplayName: "Shared Channel 5",
|
|
CreatorId: th.BasicUser.Id,
|
|
RemoteId: rc1.RemoteId,
|
|
Home: false,
|
|
}
|
|
|
|
_, err = th.App.ShareChannel(th.Context, sc5)
|
|
require.NoError(t, err)
|
|
|
|
// for the pagination test, we need to get the channelId of the
|
|
// second SharedChannelRemote that belongs to RC1, sorted by ID,
|
|
// so we accumulate those SharedChannelRemotes on creation and
|
|
// later sort them to be able to get the right one for the test
|
|
// result
|
|
sharedChannelRemotesFromRC1 := []*model.SharedChannelRemote{}
|
|
|
|
// create the shared channel remotes
|
|
for _, sc := range []*model.SharedChannel{sc1, sc2, sc3, sc4, sc5} {
|
|
scr := &model.SharedChannelRemote{
|
|
Id: model.NewId(),
|
|
ChannelId: sc.ChannelId,
|
|
CreatorId: sc.CreatorId,
|
|
IsInviteAccepted: true,
|
|
IsInviteConfirmed: true,
|
|
RemoteId: sc.RemoteId,
|
|
}
|
|
// scr for c5 is not confirmed yet
|
|
if sc.ChannelId == sc5.ChannelId {
|
|
scr.IsInviteConfirmed = false
|
|
}
|
|
_, err = th.App.SaveSharedChannelRemote(scr)
|
|
require.NoError(t, err)
|
|
|
|
if scr.RemoteId == rc1.RemoteId {
|
|
sharedChannelRemotesFromRC1 = append(sharedChannelRemotesFromRC1, scr)
|
|
}
|
|
}
|
|
|
|
// we delete the shared channel remote for sc4
|
|
scr4, err := th.App.GetSharedChannelRemoteByIds(sc4.ChannelId, sc4.RemoteId)
|
|
require.NoError(t, err)
|
|
|
|
deleted, err := th.App.DeleteSharedChannelRemote(scr4.Id)
|
|
require.NoError(t, err)
|
|
require.True(t, deleted)
|
|
|
|
sort.Slice(sharedChannelRemotesFromRC1, func(i, j int) bool {
|
|
return sharedChannelRemotesFromRC1[i].Id < sharedChannelRemotesFromRC1[j].Id
|
|
})
|
|
|
|
t.Run("should return the expected shared channels", func(t *testing.T) {
|
|
testCases := []struct {
|
|
Name string
|
|
Client *model.Client4
|
|
RemoteId string
|
|
Filter model.SharedChannelRemoteFilterOpts
|
|
Page int
|
|
PerPage int
|
|
ExpectedStatusCode int
|
|
ExpectedError bool
|
|
ExpectedIds []string
|
|
}{
|
|
{
|
|
Name: "should not work if the user doesn't have the right permissions",
|
|
Client: th.Client,
|
|
RemoteId: rc1.RemoteId,
|
|
Page: 0,
|
|
PerPage: 100,
|
|
ExpectedStatusCode: http.StatusForbidden,
|
|
ExpectedError: true,
|
|
},
|
|
{
|
|
Name: "should not work if the remote cluster is nonexistent",
|
|
Client: th.SystemAdminClient,
|
|
RemoteId: model.NewId(),
|
|
Page: 0,
|
|
PerPage: 100,
|
|
ExpectedStatusCode: http.StatusNotFound,
|
|
ExpectedError: true,
|
|
},
|
|
{
|
|
Name: "should return the complete list of shared channel remotes for a remote cluster",
|
|
Client: th.SystemAdminClient,
|
|
RemoteId: rc1.RemoteId,
|
|
Page: 0,
|
|
PerPage: 100,
|
|
ExpectedStatusCode: http.StatusOK,
|
|
ExpectedError: false,
|
|
ExpectedIds: []string{sc1.ChannelId, sc2.ChannelId},
|
|
},
|
|
{
|
|
Name: "should return the complete list of shared channel remotes for a remote cluster, including deleted",
|
|
Client: th.SystemAdminClient,
|
|
RemoteId: rc1.RemoteId,
|
|
Filter: model.SharedChannelRemoteFilterOpts{IncludeDeleted: true},
|
|
Page: 0,
|
|
PerPage: 100,
|
|
ExpectedStatusCode: http.StatusOK,
|
|
ExpectedError: false,
|
|
ExpectedIds: []string{sc1.ChannelId, sc2.ChannelId, sc4.ChannelId},
|
|
},
|
|
{
|
|
Name: "should return only the shared channel remotes homed localy",
|
|
Client: th.SystemAdminClient,
|
|
RemoteId: rc1.RemoteId,
|
|
Filter: model.SharedChannelRemoteFilterOpts{ExcludeRemote: true},
|
|
Page: 0,
|
|
PerPage: 100,
|
|
ExpectedStatusCode: http.StatusOK,
|
|
ExpectedError: false,
|
|
ExpectedIds: []string{sc1.ChannelId},
|
|
},
|
|
{
|
|
Name: "should return only the shared channel remotes homed remotely",
|
|
Client: th.SystemAdminClient,
|
|
RemoteId: rc1.RemoteId,
|
|
Filter: model.SharedChannelRemoteFilterOpts{ExcludeHome: true},
|
|
Page: 0,
|
|
PerPage: 100,
|
|
ExpectedStatusCode: http.StatusOK,
|
|
ExpectedError: false,
|
|
ExpectedIds: []string{sc2.ChannelId},
|
|
},
|
|
{
|
|
Name: "should return the complete list of shared channel remotes for a remote cluster including unconfirmed",
|
|
Client: th.SystemAdminClient,
|
|
RemoteId: rc1.RemoteId,
|
|
Filter: model.SharedChannelRemoteFilterOpts{IncludeUnconfirmed: true},
|
|
Page: 0,
|
|
PerPage: 100,
|
|
ExpectedStatusCode: http.StatusOK,
|
|
ExpectedError: false,
|
|
ExpectedIds: []string{sc1.ChannelId, sc2.ChannelId, sc5.ChannelId},
|
|
},
|
|
{
|
|
Name: "should return only the unconfirmed shared channel remotes for a remote cluster",
|
|
Client: th.SystemAdminClient,
|
|
RemoteId: rc1.RemoteId,
|
|
Filter: model.SharedChannelRemoteFilterOpts{ExcludeConfirmed: true},
|
|
Page: 0,
|
|
PerPage: 100,
|
|
ExpectedStatusCode: http.StatusOK,
|
|
ExpectedError: false,
|
|
ExpectedIds: []string{sc5.ChannelId},
|
|
},
|
|
{
|
|
Name: "should correctly paginate the results",
|
|
Client: th.SystemAdminClient,
|
|
RemoteId: rc1.RemoteId,
|
|
Filter: model.SharedChannelRemoteFilterOpts{IncludeDeleted: true, IncludeUnconfirmed: true},
|
|
Page: 1,
|
|
PerPage: 1,
|
|
ExpectedStatusCode: http.StatusOK,
|
|
ExpectedError: false,
|
|
ExpectedIds: []string{sharedChannelRemotesFromRC1[1].ChannelId},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
scrs, resp, err := tc.Client.GetSharedChannelRemotesByRemoteCluster(context.Background(), tc.RemoteId, tc.Filter, tc.Page, tc.PerPage)
|
|
checkHTTPStatus(t, resp, tc.ExpectedStatusCode)
|
|
if tc.ExpectedError {
|
|
require.Error(t, err)
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
require.Len(t, scrs, len(tc.ExpectedIds))
|
|
|
|
foundIds := []string{}
|
|
for _, scr := range scrs {
|
|
require.Equal(t, tc.RemoteId, scr.RemoteId)
|
|
foundIds = append(foundIds, scr.ChannelId)
|
|
}
|
|
require.ElementsMatch(t, tc.ExpectedIds, foundIds)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestInviteRemoteClusterToChannel(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
t.Run("Should not work if the remote cluster service is not enabled", func(t *testing.T) {
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
resp, err := th.SystemAdminClient.InviteRemoteClusterToChannel(context.Background(), model.NewId(), model.NewId())
|
|
CheckNotImplementedStatus(t, resp)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
th := setupForSharedChannels(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
newRC := &model.RemoteCluster{Name: "rc", SiteURL: "http://example.com", CreatorId: th.SystemAdminUser.Id}
|
|
|
|
rc, appErr := th.App.AddRemoteCluster(newRC)
|
|
require.Nil(t, appErr)
|
|
|
|
t.Run("Should not work if the user doesn't have the right permissions", func(t *testing.T) {
|
|
resp, err := th.Client.InviteRemoteClusterToChannel(context.Background(), model.NewId(), model.NewId())
|
|
CheckForbiddenStatus(t, resp)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("should not work if the remote cluster is nonexistent", func(t *testing.T) {
|
|
resp, err := th.SystemAdminClient.InviteRemoteClusterToChannel(context.Background(), model.NewId(), model.NewId())
|
|
CheckBadRequestStatus(t, resp)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("should not work if the channel is nonexistent", func(t *testing.T) {
|
|
resp, err := th.SystemAdminClient.InviteRemoteClusterToChannel(context.Background(), rc.RemoteId, model.NewId())
|
|
CheckBadRequestStatus(t, resp)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("should correctly invite the remote cluster to the channel", func(t *testing.T) {
|
|
t.Skip("Requires server2server communication: ToBeImplemented")
|
|
})
|
|
|
|
t.Run("should do nothing but return 204 if the remote cluster is already invited to the channel", func(t *testing.T) {
|
|
t.Skip("Requires server2server communication: ToBeImplemented")
|
|
})
|
|
}
|
|
|
|
func TestUninviteRemoteClusterToChannel(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
t.Run("Should not work if the remote cluster service is not enabled", func(t *testing.T) {
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
resp, err := th.SystemAdminClient.UninviteRemoteClusterToChannel(context.Background(), model.NewId(), model.NewId())
|
|
CheckNotImplementedStatus(t, resp)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
th := setupForSharedChannels(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
newRC := &model.RemoteCluster{Name: "rc", SiteURL: "http://example.com", CreatorId: th.SystemAdminUser.Id}
|
|
|
|
rc, appErr := th.App.AddRemoteCluster(newRC)
|
|
require.Nil(t, appErr)
|
|
|
|
t.Run("Should not work if the user doesn't have the right permissions", func(t *testing.T) {
|
|
resp, err := th.Client.UninviteRemoteClusterToChannel(context.Background(), model.NewId(), model.NewId())
|
|
CheckForbiddenStatus(t, resp)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("should not work if the remote cluster is nonexistent", func(t *testing.T) {
|
|
resp, err := th.SystemAdminClient.UninviteRemoteClusterToChannel(context.Background(), model.NewId(), model.NewId())
|
|
CheckBadRequestStatus(t, resp)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("should not work if the channel is nonexistent", func(t *testing.T) {
|
|
resp, err := th.SystemAdminClient.UninviteRemoteClusterToChannel(context.Background(), rc.RemoteId, model.NewId())
|
|
CheckBadRequestStatus(t, resp)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("should correctly uninvite the remote cluster to the channel", func(t *testing.T) {
|
|
t.Skip("Requires server2server communication: ToBeImplemented")
|
|
})
|
|
|
|
t.Run("should do nothing but return 204 if the remote cluster is not sharing the channel", func(t *testing.T) {
|
|
t.Skip("Requires server2server communication: ToBeImplemented")
|
|
})
|
|
}
|