mirror of
https://github.com/hanzoai/team.git
synced 2026-09-30 01:57:35 +00:00
* [MM-69691] Fix /secure-connection status table sorting and header Sort deleted connections to the bottom (active first, ordered by CreateAt within each group) and remove the spurious empty cell from the Markdown table header separator so it has 9 cells matching the header and data rows. Co-authored-by: mattermost-code <[email protected]> * [MM-69691] Add test for /secure-connection status output Verifies deleted connections sort to the bottom (active first, ordered by CreateAt within each group) and that the Markdown table header separator has exactly nine cells matching the columns. Co-authored-by: mattermost-code <[email protected]> * [MM-69691] Strengthen /secure-connection status test assertions Assert the separator row equals the exact nine-cell string and has nine alignment cells, verify data rows have nine cells, and cover CreateAt ordering (overriding alphabetical) plus stable ordering for equal CreateAt within a group. Co-authored-by: mattermost-code <[email protected]> * [MM-69691] Use strings.SplitSeq in status test to satisfy linter Co-authored-by: mattermost-code <[email protected]> * [MM-69691] Retrigger CI after buildenv artifact infra failure Co-authored-by: mattermost-code <[email protected]> * [MM-69691] Retrigger Enterprise CI after npm ECONNRESET flake Co-authored-by: mattermost-code <[email protected]> * Add missing return in doStatus error path Address review feedback from @wiggin77: the error branch in doStatus built an error response but discarded it, so execution fell through to the empty-list check on a nil list. Return the response instead. --------- Co-authored-by: mattermost-code <[email protected]> Co-authored-by: Hanzo Dev <[email protected]>
107 lines
3.9 KiB
Go
107 lines
3.9 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package slashcommands
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
)
|
|
|
|
func TestRemoteProviderDoStatus(t *testing.T) {
|
|
th := setupForSharedChannels(t).initBasic(t)
|
|
th.addPermissionToRole(t, model.PermissionManageSecureConnections.Id, th.BasicUser.Roles)
|
|
|
|
// seedRemote creates a remote cluster. When deleted is true it is soft-deleted
|
|
// after creation so it carries a non-zero DeleteAt, mirroring a removed connection.
|
|
seedRemote := func(t *testing.T, displayName string, createAt int64, deleted bool) {
|
|
t.Helper()
|
|
rc, appErr := th.App.AddRemoteCluster(&model.RemoteCluster{
|
|
RemoteId: model.NewId(),
|
|
Name: "remote-" + model.NewId(),
|
|
DisplayName: displayName,
|
|
SiteURL: "https://" + model.NewId() + ".example.com",
|
|
Token: model.NewId(),
|
|
CreateAt: createAt,
|
|
CreatorId: th.BasicUser.Id,
|
|
})
|
|
require.Nil(t, appErr)
|
|
|
|
if deleted {
|
|
_, appErr = th.App.DeleteRemoteCluster(rc.RemoteId)
|
|
require.Nil(t, appErr)
|
|
}
|
|
}
|
|
|
|
// The store returns rows ordered by DisplayName (see sqlRemoteClusterStore.GetAll),
|
|
// so without the fix the rows come back interleaved: AAA, BBB, CCC, DDD.
|
|
//
|
|
// CreateAt values are chosen so the fix's behavior is unambiguous:
|
|
// - Active group: CCC (100) must sort before AAA (300), proving the CreateAt
|
|
// ordering overrides the store's alphabetical order.
|
|
// - Deleted group: BBB and DDD share a CreateAt, so the stable sort must
|
|
// preserve their store order (BBB before DDD).
|
|
// Expected final order: CCC, AAA, BBB, DDD.
|
|
seedRemote(t, "AAA Active", 300, false)
|
|
seedRemote(t, "BBB Deleted", 200, true)
|
|
seedRemote(t, "CCC Active", 100, false)
|
|
seedRemote(t, "DDD Deleted", 200, true)
|
|
|
|
args := &model.CommandArgs{
|
|
T: func(s string, args ...any) string { return s },
|
|
UserId: th.BasicUser.Id,
|
|
TeamId: th.BasicTeam.Id,
|
|
ChannelId: th.BasicChannel.Id,
|
|
Command: "/secure-connection status",
|
|
}
|
|
|
|
resp := (&RemoteProvider{}).DoCommand(th.App, th.Context, args, "")
|
|
require.NotNil(t, resp)
|
|
output := resp.Text
|
|
|
|
// separatorLine returns the Markdown table separator row (the line made up of
|
|
// alignment cells) from the command output.
|
|
separatorLine := func() string {
|
|
for line := range strings.SplitSeq(output, "\n") {
|
|
if strings.HasPrefix(strings.TrimSpace(line), "| :----") {
|
|
return line
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
t.Run("header separator has exactly nine cells matching the columns", func(t *testing.T) {
|
|
sep := separatorLine()
|
|
require.NotEmpty(t, sep, "expected a Markdown separator row in the output")
|
|
require.Equal(t, "| :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- |", sep,
|
|
"separator row must have exactly nine cells to match the nine-column header and data rows")
|
|
require.Equal(t, 9, strings.Count(sep, ":----"), "separator must contain exactly nine alignment cells")
|
|
})
|
|
|
|
t.Run("data rows have nine cells matching the header", func(t *testing.T) {
|
|
for line := range strings.SplitSeq(output, "\n") {
|
|
if strings.Contains(line, "AAA Active") {
|
|
// A row with 9 cells is delimited by 10 pipe characters.
|
|
require.Equal(t, 10, strings.Count(line, "|"), "each data row must have nine cells")
|
|
return
|
|
}
|
|
}
|
|
require.Fail(t, "expected to find the AAA Active data row in the output")
|
|
})
|
|
|
|
t.Run("active connections sort before deleted ones, by CreateAt then stably", func(t *testing.T) {
|
|
rowOrder := []string{"CCC Active", "AAA Active", "BBB Deleted", "DDD Deleted"}
|
|
lastIdx := -1
|
|
for _, name := range rowOrder {
|
|
idx := strings.Index(output, name)
|
|
require.GreaterOrEqual(t, idx, 0, "expected %q to appear in the status output", name)
|
|
require.Greater(t, idx, lastIdx, "expected %q to appear after the previous row", name)
|
|
lastIdx = idx
|
|
}
|
|
})
|
|
}
|