mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Merge branch 'master' into mark-as-unread
This commit is contained in:
@@ -30,7 +30,7 @@ jobs:
|
||||
|
||||
if [ $CURL_FAILED -eq 1 ]
|
||||
then
|
||||
npm ci && cd node_modules/mattermost-redux && npm install && npm run build && cd ../.. && make build
|
||||
npm ci && make build
|
||||
fi
|
||||
- persist_to_workspace:
|
||||
root: /go/src/github.com/mattermost
|
||||
@@ -232,7 +232,7 @@ jobs:
|
||||
--env MM_ELASTICSEARCHSETTINGS_CONNECTIONURL=http://elasticsearch:9200 \
|
||||
-v ~/go/src:/go/src \
|
||||
-w /go/src/github.com/mattermost/mattermost-server \
|
||||
mattermost/mattermost-build-server:feb-28-2019 \
|
||||
mattermost/mattermost-build-server:oct-18-2019 \
|
||||
bash -c 'ulimit -n 8096; make ARGS="version" run-cli && make MM_SQLSETTINGS_DATASOURCE="mmuser:mostest@tcp(mysql:3306)/latest?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s" ARGS="version" run-cli'
|
||||
|
||||
echo "Ignoring known MySQL mismatch: ChannelMembers.SchemeGuest"
|
||||
|
||||
32
.golangci.yml
Normal file
32
.golangci.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
run:
|
||||
timeout: 5m
|
||||
modules-download-mode: vendor
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
gofmt:
|
||||
simplify: true
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- deadcode
|
||||
- gofmt
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- structcheck
|
||||
- unconvert
|
||||
- unused
|
||||
- varcheck
|
||||
# TODO: enable this later
|
||||
# - errcheck
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- linters:
|
||||
# ignore unused warnings from enterprise code
|
||||
# add more as required.
|
||||
- unused
|
||||
text: "RedisSupplier|LocalCacheSupplier|Enterprise"
|
||||
13
Makefile
13
Makefile
@@ -173,6 +173,18 @@ gofmt: ## Runs gofmt against all packages.
|
||||
done
|
||||
@echo "gofmt success"; \
|
||||
|
||||
golangci-lint:
|
||||
# https://stackoverflow.com/a/677212/1027058 (check if a command exists or not)
|
||||
# https://github.com/golangci/golangci-lint#binary-release
|
||||
# It is recommended to NOT use go get, but instead use a binary release pinned to a version.
|
||||
@if ! [ -x "$$(command -v golangci-lint)" ]; then \
|
||||
echo "golangci-lint is not installed. Please run: curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(GOPATH)/bin v1.21.0"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
|
||||
@echo Running golangci-lint
|
||||
$(GOPATH)/bin/golangci-lint run
|
||||
|
||||
megacheck: ## Run megacheck on codebasis
|
||||
env GO111MODULE=off go get -u honnef.co/go/tools/cmd/megacheck
|
||||
$(GOPATH)/bin/megacheck $(TE_PACKAGES)
|
||||
@@ -219,6 +231,7 @@ check-licenses: ## Checks license status.
|
||||
check-prereqs: ## Checks prerequisite software status.
|
||||
./scripts/prereq-check.sh
|
||||
|
||||
# TODO: remove govet and gofmt checks once golangci-lint is being enforced.
|
||||
check-style: govet gofmt check-licenses ## Runs govet and gofmt against all packages.
|
||||
|
||||
test-te-race: ## Checks for race conditions in the team edition.
|
||||
|
||||
@@ -9,8 +9,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -26,6 +24,7 @@ import (
|
||||
|
||||
s3 "github.com/minio/minio-go/v6"
|
||||
"github.com/minio/minio-go/v6/pkg/credentials"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type TestHelper struct {
|
||||
@@ -560,57 +559,34 @@ func GenerateTestId() string {
|
||||
func CheckUserSanitization(t *testing.T, user *model.User) {
|
||||
t.Helper()
|
||||
|
||||
if user.Password != "" {
|
||||
t.Fatal("password wasn't blank")
|
||||
}
|
||||
|
||||
if user.AuthData != nil && *user.AuthData != "" {
|
||||
t.Fatal("auth data wasn't blank")
|
||||
}
|
||||
|
||||
if user.MfaSecret != "" {
|
||||
t.Fatal("mfa secret wasn't blank")
|
||||
}
|
||||
require.Equal(t, "", user.Password, "password wasn't blank")
|
||||
require.Empty(t, user.AuthData, "auth data wasn't blank")
|
||||
require.Equal(t, "", user.MfaSecret, "mfa secret wasn't blank")
|
||||
}
|
||||
|
||||
func CheckEtag(t *testing.T, data interface{}, resp *model.Response) {
|
||||
t.Helper()
|
||||
|
||||
if !reflect.ValueOf(data).IsNil() {
|
||||
t.Fatal("etag data was not nil")
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusNotModified {
|
||||
t.Log("actual: " + strconv.Itoa(resp.StatusCode))
|
||||
t.Log("expected: " + strconv.Itoa(http.StatusNotModified))
|
||||
t.Fatal("wrong status code for etag")
|
||||
}
|
||||
require.Empty(t, data)
|
||||
require.Equal(t, resp.StatusCode, http.StatusNotModified, "wrong status code for etag")
|
||||
}
|
||||
|
||||
func CheckNoError(t *testing.T, resp *model.Response) {
|
||||
t.Helper()
|
||||
|
||||
if resp.Error != nil {
|
||||
t.Fatalf("Expected no error, got %q", resp.Error.Error())
|
||||
}
|
||||
require.Nil(t, resp.Error)
|
||||
}
|
||||
|
||||
func checkHTTPStatus(t *testing.T, resp *model.Response, expectedStatus int, expectError bool) {
|
||||
t.Helper()
|
||||
|
||||
switch {
|
||||
case resp == nil:
|
||||
t.Fatalf("Unexpected nil response, expected http:%v, expectError:%v)", expectedStatus, expectError)
|
||||
|
||||
case expectError && resp.Error == nil:
|
||||
t.Fatalf("Expected a non-nil error and http status:%v, got nil, %v", expectedStatus, resp.StatusCode)
|
||||
|
||||
case !expectError && resp.Error != nil:
|
||||
t.Fatalf("Expected no error and http status:%v, got %q, http:%v", expectedStatus, resp.Error, resp.StatusCode)
|
||||
|
||||
case resp.StatusCode != expectedStatus:
|
||||
t.Fatalf("Expected http status:%v, got %v (err: %q)", expectedStatus, resp.StatusCode, resp.Error)
|
||||
require.NotNilf(t, resp, "Unexpected nil response, expected http:%v, expectError:%v", expectedStatus, expectError)
|
||||
if expectError {
|
||||
require.NotNil(t, resp.Error, "Expected a non-nil error and http status:%v, got nil, %v", expectedStatus, resp.StatusCode)
|
||||
} else {
|
||||
require.Nil(t, resp.Error, "Expected no error and http status:%v, got %q, http:%v", expectedStatus, resp.Error, resp.StatusCode)
|
||||
}
|
||||
require.Equalf(t, expectedStatus, resp.StatusCode, "Expected http status:%v, got %v (err: %q)", expectedStatus, resp.StatusCode, resp.Error)
|
||||
}
|
||||
|
||||
func CheckOKStatus(t *testing.T, resp *model.Response) {
|
||||
@@ -661,16 +637,12 @@ func CheckInternalErrorStatus(t *testing.T, resp *model.Response) {
|
||||
func CheckErrorMessage(t *testing.T, resp *model.Response, errorId string) {
|
||||
t.Helper()
|
||||
|
||||
if resp.Error == nil {
|
||||
t.Fatal("should have errored with message:" + errorId)
|
||||
return
|
||||
require.NotNil(t, resp.Error)
|
||||
require.Equal(t, resp.Error.Id, errorId, "incorrect error message")
|
||||
}
|
||||
|
||||
if resp.Error.Id != errorId {
|
||||
t.Log("actual: " + resp.Error.Id)
|
||||
t.Log("expected: " + errorId)
|
||||
t.Fatal("incorrect error message")
|
||||
}
|
||||
func CheckStartsWith(t *testing.T, value, prefix, message string) {
|
||||
require.True(t, strings.HasPrefix(value, prefix), message, value)
|
||||
}
|
||||
|
||||
// Similar to s3.New() but allows initialization of signature v2 or signature v4 client.
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -2502,15 +2503,80 @@ func TestRemoveChannelMember(t *testing.T) {
|
||||
_, resp = Client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
t.Run("success", func(t *testing.T) {
|
||||
// Setup the system administrator to listen for websocket events from the channels.
|
||||
th.LinkUserToTeam(th.SystemAdminUser, th.BasicTeam)
|
||||
_, err := th.App.AddUserToChannel(th.SystemAdminUser, th.BasicChannel)
|
||||
require.Nil(t, err)
|
||||
_, err = th.App.AddUserToChannel(th.SystemAdminUser, th.BasicChannel2)
|
||||
require.Nil(t, err)
|
||||
props := map[string]string{}
|
||||
props[model.DESKTOP_NOTIFY_PROP] = model.CHANNEL_NOTIFY_ALL
|
||||
_, resp = th.SystemAdminClient.UpdateChannelNotifyProps(th.BasicChannel.Id, th.SystemAdminUser.Id, props)
|
||||
_, resp = th.SystemAdminClient.UpdateChannelNotifyProps(th.BasicChannel2.Id, th.SystemAdminUser.Id, props)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
wsClient, err := th.CreateWebSocketSystemAdminClient()
|
||||
require.Nil(t, err)
|
||||
wsClient.Listen()
|
||||
var closeWsClient sync.Once
|
||||
defer closeWsClient.Do(func() {
|
||||
wsClient.Close()
|
||||
})
|
||||
|
||||
wsr := <-wsClient.EventChannel
|
||||
require.Equal(t, wsr.Event, model.WEBSOCKET_EVENT_HELLO)
|
||||
|
||||
// requirePost listens for websocket events and tries to find the post matching
|
||||
// the expected post's channel and message.
|
||||
requirePost := func(expectedPost *model.Post) {
|
||||
t.Helper()
|
||||
for {
|
||||
select {
|
||||
case event := <-wsClient.EventChannel:
|
||||
postData, ok := event.Data["post"]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
post := model.PostFromJson(strings.NewReader(postData.(string)))
|
||||
if post.ChannelId == expectedPost.ChannelId && post.Message == expectedPost.Message {
|
||||
return
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("failed to find expected post after 5 seconds")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
th.App.AddUserToChannel(th.BasicUser2, th.BasicChannel)
|
||||
_, resp = Client.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser2.Id)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
requirePost(&model.Post{
|
||||
Message: fmt.Sprintf("@%s left the channel.", th.BasicUser2.Username),
|
||||
ChannelId: th.BasicChannel.Id,
|
||||
})
|
||||
|
||||
_, resp = Client.RemoveUserFromChannel(th.BasicChannel2.Id, th.BasicUser.Id)
|
||||
CheckNoError(t, resp)
|
||||
requirePost(&model.Post{
|
||||
Message: fmt.Sprintf("@%s removed from the channel.", th.BasicUser.Username),
|
||||
ChannelId: th.BasicChannel2.Id,
|
||||
})
|
||||
|
||||
_, resp = th.SystemAdminClient.RemoveUserFromChannel(th.BasicChannel.Id, th.BasicUser.Id)
|
||||
CheckNoError(t, resp)
|
||||
requirePost(&model.Post{
|
||||
Message: fmt.Sprintf("@%s removed from the channel.", th.BasicUser.Username),
|
||||
ChannelId: th.BasicChannel.Id,
|
||||
})
|
||||
|
||||
closeWsClient.Do(func() {
|
||||
wsClient.Close()
|
||||
})
|
||||
})
|
||||
|
||||
// Leave deleted channel
|
||||
th.LoginBasic()
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHelpCommand(t *testing.T) {
|
||||
@@ -23,15 +24,11 @@ func TestHelpCommand(t *testing.T) {
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.SupportSettings.HelpLink = "" })
|
||||
rs1, _ := Client.ExecuteCommand(channel.Id, "/help ")
|
||||
if rs1.GotoLocation != model.SUPPORT_SETTINGS_DEFAULT_HELP_LINK {
|
||||
t.Fatal("failed to default help link")
|
||||
}
|
||||
assert.Equal(t, rs1.GotoLocation, model.SUPPORT_SETTINGS_DEFAULT_HELP_LINK, "failed to default help link")
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||
*cfg.SupportSettings.HelpLink = "https://docs.mattermost.com/guides/user.html"
|
||||
})
|
||||
rs2, _ := Client.ExecuteCommand(channel.Id, "/help ")
|
||||
if rs2.GotoLocation != "https://docs.mattermost.com/guides/user.html" {
|
||||
t.Fatal("failed to help link")
|
||||
}
|
||||
assert.Equal(t, rs2.GotoLocation, "https://docs.mattermost.com/guides/user.html", "failed to help link")
|
||||
}
|
||||
|
||||
@@ -39,12 +39,8 @@ func TestCreateCommand(t *testing.T) {
|
||||
createdCmd, resp := th.SystemAdminClient.CreateCommand(newCmd)
|
||||
CheckNoError(t, resp)
|
||||
CheckCreatedStatus(t, resp)
|
||||
if createdCmd.CreatorId != th.SystemAdminUser.Id {
|
||||
t.Fatal("user ids didn't match")
|
||||
}
|
||||
if createdCmd.TeamId != th.BasicTeam.Id {
|
||||
t.Fatal("team ids didn't match")
|
||||
}
|
||||
require.Equal(t, th.SystemAdminUser.Id, createdCmd.CreatorId, "user ids didn't match")
|
||||
require.Equal(t, th.BasicTeam.Id, createdCmd.TeamId, "team ids didn't match")
|
||||
|
||||
_, resp = th.SystemAdminClient.CreateCommand(newCmd)
|
||||
CheckBadRequestStatus(t, resp)
|
||||
@@ -100,34 +96,22 @@ func TestUpdateCommand(t *testing.T) {
|
||||
rcmd, resp := Client.UpdateCommand(cmd2)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if rcmd.Trigger != cmd2.Trigger {
|
||||
t.Fatal("Trigger should have updated")
|
||||
}
|
||||
require.Equal(t, cmd2.Trigger, rcmd.Trigger, "Trigger should have updated")
|
||||
|
||||
if rcmd.Method != cmd2.Method {
|
||||
t.Fatal("Method should have updated")
|
||||
}
|
||||
require.Equal(t, cmd2.Method, rcmd.Method, "Method should have updated")
|
||||
|
||||
if rcmd.URL != cmd2.URL {
|
||||
t.Fatal("URL should have updated")
|
||||
}
|
||||
require.Equal(t, cmd2.URL, rcmd.URL, "URL should have updated")
|
||||
|
||||
if rcmd.CreatorId != cmd1.CreatorId {
|
||||
t.Fatal("CreatorId should have not updated")
|
||||
}
|
||||
require.Equal(t, cmd1.CreatorId, rcmd.CreatorId, "CreatorId should have not updated")
|
||||
|
||||
if rcmd.Token != cmd1.Token {
|
||||
t.Fatal("Token should have not updated")
|
||||
}
|
||||
require.Equal(t, cmd1.Token, rcmd.Token, "Token should have not updated")
|
||||
|
||||
cmd2.Id = GenerateTestId()
|
||||
|
||||
rcmd, resp = Client.UpdateCommand(cmd2)
|
||||
CheckNotFoundStatus(t, resp)
|
||||
|
||||
if rcmd != nil {
|
||||
t.Fatal("should be empty")
|
||||
}
|
||||
require.Nil(t, rcmd, "should be empty")
|
||||
|
||||
cmd2.Id = "junk"
|
||||
|
||||
@@ -176,21 +160,15 @@ func TestDeleteCommand(t *testing.T) {
|
||||
ok, resp := Client.DeleteCommand(rcmd1.Id)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if !ok {
|
||||
t.Fatal("should have returned true")
|
||||
}
|
||||
require.True(t, ok)
|
||||
|
||||
rcmd1, _ = th.App.GetCommand(rcmd1.Id)
|
||||
if rcmd1 != nil {
|
||||
t.Fatal("should be nil")
|
||||
}
|
||||
require.Nil(t, rcmd1)
|
||||
|
||||
ok, resp = Client.DeleteCommand("junk")
|
||||
CheckBadRequestStatus(t, resp)
|
||||
|
||||
if ok {
|
||||
t.Fatal("should have returned false")
|
||||
}
|
||||
require.False(t, ok)
|
||||
|
||||
_, resp = Client.DeleteCommand(GenerateTestId())
|
||||
CheckNotFoundStatus(t, resp)
|
||||
@@ -248,24 +226,16 @@ func TestListCommands(t *testing.T) {
|
||||
foundCustom = true
|
||||
}
|
||||
}
|
||||
if !foundEcho {
|
||||
t.Fatal("Couldn't find echo command")
|
||||
}
|
||||
if !foundCustom {
|
||||
t.Fatal("Should list the custom command")
|
||||
}
|
||||
require.True(t, foundEcho, "Couldn't find echo command")
|
||||
require.True(t, foundCustom, "Should list the custom command")
|
||||
})
|
||||
|
||||
t.Run("ListCustomOnlyCommands", func(t *testing.T) {
|
||||
listCommands, resp := th.SystemAdminClient.ListCommands(th.BasicTeam.Id, true)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if len(listCommands) > 1 {
|
||||
t.Fatal("Should list just one custom command")
|
||||
}
|
||||
if listCommands[0].Trigger != "custom_command" {
|
||||
t.Fatal("Wrong custom command trigger")
|
||||
}
|
||||
require.Len(t, listCommands, 1, "Should list just one custom command")
|
||||
require.Equal(t, listCommands[0].Trigger, "custom_command", "Wrong custom command trigger")
|
||||
})
|
||||
|
||||
t.Run("UserWithNoPermissionForCustomCommands", func(t *testing.T) {
|
||||
@@ -287,12 +257,8 @@ func TestListCommands(t *testing.T) {
|
||||
foundCustom = true
|
||||
}
|
||||
}
|
||||
if !foundEcho {
|
||||
t.Fatal("Couldn't find echo command")
|
||||
}
|
||||
if foundCustom {
|
||||
t.Fatal("Should not list the custom command")
|
||||
}
|
||||
require.True(t, foundEcho, "Couldn't find echo command")
|
||||
require.False(t, foundCustom, "Should not list the custom command")
|
||||
})
|
||||
|
||||
t.Run("NoMember", func(t *testing.T) {
|
||||
@@ -344,12 +310,8 @@ func TestListAutocompleteCommands(t *testing.T) {
|
||||
foundCustom = true
|
||||
}
|
||||
}
|
||||
if !foundEcho {
|
||||
t.Fatal("Couldn't find echo command")
|
||||
}
|
||||
if foundCustom {
|
||||
t.Fatal("Should not list the custom command")
|
||||
}
|
||||
require.True(t, foundEcho, "Couldn't find echo command")
|
||||
require.False(t, foundCustom, "Should not list the custom command")
|
||||
})
|
||||
|
||||
t.Run("RegularUserCanListOnlySystemCommands", func(t *testing.T) {
|
||||
@@ -366,12 +328,8 @@ func TestListAutocompleteCommands(t *testing.T) {
|
||||
foundCustom = true
|
||||
}
|
||||
}
|
||||
if !foundEcho {
|
||||
t.Fatal("Couldn't find echo command")
|
||||
}
|
||||
if foundCustom {
|
||||
t.Fatal("Should not list the custom command")
|
||||
}
|
||||
require.True(t, foundEcho, "Couldn't find echo command")
|
||||
require.False(t, foundCustom, "Should not list the custom command")
|
||||
})
|
||||
|
||||
t.Run("NoMember", func(t *testing.T) {
|
||||
@@ -414,15 +372,11 @@ func TestRegenToken(t *testing.T) {
|
||||
|
||||
token, resp := th.SystemAdminClient.RegenCommandToken(createdCmd.Id)
|
||||
CheckNoError(t, resp)
|
||||
if token == createdCmd.Token {
|
||||
t.Fatal("should update the token")
|
||||
}
|
||||
require.NotEqual(t, createdCmd.Token, token, "should update the token")
|
||||
|
||||
token, resp = Client.RegenCommandToken(createdCmd.Id)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
if token != "" {
|
||||
t.Fatal("should not return the token")
|
||||
}
|
||||
require.Empty(t, token, "should not return the token")
|
||||
}
|
||||
|
||||
func TestExecuteInvalidCommand(t *testing.T) {
|
||||
@@ -457,9 +411,8 @@ func TestExecuteInvalidCommand(t *testing.T) {
|
||||
Trigger: "getcommand",
|
||||
}
|
||||
|
||||
if _, err := th.App.CreateCommand(getCmd); err != nil {
|
||||
t.Fatal("failed to create get command")
|
||||
}
|
||||
_, err := th.App.CreateCommand(getCmd)
|
||||
require.Nil(t, err, "failed to create get command")
|
||||
|
||||
_, resp := Client.ExecuteCommand(channel.Id, "")
|
||||
CheckBadRequestStatus(t, resp)
|
||||
@@ -537,9 +490,8 @@ func TestExecuteGetCommand(t *testing.T) {
|
||||
Token: token,
|
||||
}
|
||||
|
||||
if _, err := th.App.CreateCommand(getCmd); err != nil {
|
||||
t.Fatal("failed to create get command")
|
||||
}
|
||||
_, err := th.App.CreateCommand(getCmd)
|
||||
require.Nil(t, err, "failed to create get command")
|
||||
|
||||
commandResponse, resp := Client.ExecuteCommand(channel.Id, "/getcommand")
|
||||
CheckNoError(t, resp)
|
||||
@@ -597,9 +549,8 @@ func TestExecutePostCommand(t *testing.T) {
|
||||
Token: token,
|
||||
}
|
||||
|
||||
if _, err := th.App.CreateCommand(postCmd); err != nil {
|
||||
t.Fatal("failed to create get command")
|
||||
}
|
||||
_, err := th.App.CreateCommand(postCmd)
|
||||
require.Nil(t, err, "failed to create get command")
|
||||
|
||||
commandResponse, resp := Client.ExecuteCommand(channel.Id, "/postcommand")
|
||||
CheckNoError(t, resp)
|
||||
@@ -652,9 +603,8 @@ func TestExecuteCommandAgainstChannelOnAnotherTeam(t *testing.T) {
|
||||
Method: model.COMMAND_METHOD_POST,
|
||||
Trigger: "postcommand",
|
||||
}
|
||||
if _, err := th.App.CreateCommand(postCmd); err != nil {
|
||||
t.Fatal("failed to create post command")
|
||||
}
|
||||
_, err := th.App.CreateCommand(postCmd)
|
||||
require.Nil(t, err, "failed to create post command")
|
||||
|
||||
// the execute command endpoint will always search for the command by trigger and team id, inferring team id from the
|
||||
// channel id, so there is no way to use that slash command on a channel that belongs to some other team
|
||||
@@ -702,15 +652,13 @@ func TestExecuteCommandAgainstChannelUserIsNotIn(t *testing.T) {
|
||||
Method: model.COMMAND_METHOD_POST,
|
||||
Trigger: "postcommand",
|
||||
}
|
||||
if _, err := th.App.CreateCommand(postCmd); err != nil {
|
||||
t.Fatal("failed to create post command")
|
||||
}
|
||||
_, err := th.App.CreateCommand(postCmd)
|
||||
require.Nil(t, err, "failed to create post command")
|
||||
|
||||
// make a channel on that team, ensuring that our test user isn't in it
|
||||
channel2 := th.CreateChannelWithClientAndTeam(client, model.CHANNEL_OPEN, team2.Id)
|
||||
if success, _ := client.RemoveUserFromChannel(channel2.Id, th.BasicUser.Id); !success {
|
||||
t.Fatal("Failed to remove user from channel")
|
||||
}
|
||||
success, _ := client.RemoveUserFromChannel(channel2.Id, th.BasicUser.Id)
|
||||
require.True(t, success, "Failed to remove user from channel")
|
||||
|
||||
// we should not be able to run the slash command in channel2, because we aren't in it
|
||||
_, resp := client.ExecuteCommandWithTeam(channel2.Id, team2.Id, "/postcommand")
|
||||
@@ -760,9 +708,8 @@ func TestExecuteCommandInDirectMessageChannel(t *testing.T) {
|
||||
Method: model.COMMAND_METHOD_POST,
|
||||
Trigger: "postcommand",
|
||||
}
|
||||
if _, err := th.App.CreateCommand(postCmd); err != nil {
|
||||
t.Fatal("failed to create post command")
|
||||
}
|
||||
_, err := th.App.CreateCommand(postCmd)
|
||||
require.Nil(t, err, "failed to create post command")
|
||||
|
||||
// make a direct message channel
|
||||
dmChannel, response := client.CreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id)
|
||||
@@ -823,9 +770,8 @@ func TestExecuteCommandInTeamUserIsNotOn(t *testing.T) {
|
||||
Method: model.COMMAND_METHOD_POST,
|
||||
Trigger: "postcommand",
|
||||
}
|
||||
if _, err := th.App.CreateCommand(postCmd); err != nil {
|
||||
t.Fatal("failed to create post command")
|
||||
}
|
||||
_, err := th.App.CreateCommand(postCmd)
|
||||
require.Nil(t, err, "failed to create post command")
|
||||
|
||||
// make a direct message channel
|
||||
dmChannel, response := client.CreateDirectChannel(th.BasicUser.Id, th.BasicUser2.Id)
|
||||
@@ -836,9 +782,9 @@ func TestExecuteCommandInTeamUserIsNotOn(t *testing.T) {
|
||||
CheckOKStatus(t, resp)
|
||||
|
||||
// if the user is removed from the team, they should NOT be able to run the slash command in the DM channel
|
||||
if success, _ := client.RemoveTeamMember(team2.Id, th.BasicUser.Id); !success {
|
||||
t.Fatal("Failed to remove user from team")
|
||||
}
|
||||
success, _ := client.RemoveTeamMember(team2.Id, th.BasicUser.Id)
|
||||
require.True(t, success, "Failed to remove user from team")
|
||||
|
||||
_, resp = client.ExecuteCommandWithTeam(dmChannel.Id, team2.Id, "/postcommand")
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -127,16 +128,12 @@ func TestCORSRequestHandling(t *testing.T) {
|
||||
url := fmt.Sprintf("%v/api/v4/system/ping", host)
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
testcase.ModifyRequest(req)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.Equal(t, testcase.ExpectedAllowOrigin, resp.Header.Get(acAllowOrigin))
|
||||
assert.Equal(t, testcase.ExpectedExposeHeaders, resp.Header.Get(acExposeHeaders))
|
||||
@@ -146,5 +143,4 @@ func TestCORSRequestHandling(t *testing.T) {
|
||||
assert.Equal(t, "", resp.Header.Get(acAllowHeaders))
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
86
api4/file.go
86
api4/file.go
@@ -65,92 +65,6 @@ func (api *API) InitFile() {
|
||||
|
||||
}
|
||||
|
||||
func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
defer io.Copy(ioutil.Discard, r.Body)
|
||||
|
||||
if !*c.App.Config().FileSettings.EnableFileAttachments {
|
||||
c.Err = model.NewAppError("uploadFile", "api.file.attachments.disabled.app_error", nil, "", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
if r.ContentLength > *c.App.Config().FileSettings.MaxFileSize {
|
||||
c.Err = model.NewAppError("uploadFile", "api.file.upload_file.too_large.app_error", nil, "", http.StatusRequestEntityTooLarge)
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
var resStruct *model.FileUploadResponse
|
||||
var appErr *model.AppError
|
||||
|
||||
if err := r.ParseMultipartForm(*c.App.Config().FileSettings.MaxFileSize); err != nil && err != http.ErrNotMultipart {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
} else if err == http.ErrNotMultipart {
|
||||
defer r.Body.Close()
|
||||
|
||||
c.RequireChannelId()
|
||||
c.RequireFilename()
|
||||
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
channelId := c.Params.ChannelId
|
||||
filename := c.Params.Filename
|
||||
|
||||
if !c.App.SessionHasPermissionToChannel(c.App.Session, channelId, model.PERMISSION_UPLOAD_FILE) {
|
||||
c.SetPermissionError(model.PERMISSION_UPLOAD_FILE)
|
||||
return
|
||||
}
|
||||
|
||||
resStruct, appErr = c.App.UploadFiles(
|
||||
FILE_TEAM_ID,
|
||||
channelId,
|
||||
c.App.Session.UserId,
|
||||
[]io.ReadCloser{r.Body},
|
||||
[]string{filename},
|
||||
[]string{},
|
||||
now,
|
||||
)
|
||||
} else {
|
||||
m := r.MultipartForm
|
||||
|
||||
props := m.Value
|
||||
if len(props["channel_id"]) == 0 {
|
||||
c.SetInvalidParam("channel_id")
|
||||
return
|
||||
}
|
||||
channelId := props["channel_id"][0]
|
||||
c.Params.ChannelId = channelId
|
||||
c.RequireChannelId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionToChannel(c.App.Session, channelId, model.PERMISSION_UPLOAD_FILE) {
|
||||
c.SetPermissionError(model.PERMISSION_UPLOAD_FILE)
|
||||
return
|
||||
}
|
||||
|
||||
resStruct, appErr = c.App.UploadMultipartFiles(
|
||||
FILE_TEAM_ID,
|
||||
channelId,
|
||||
c.App.Session.UserId,
|
||||
m.File["files"],
|
||||
m.Value["client_ids"],
|
||||
now,
|
||||
)
|
||||
}
|
||||
|
||||
if appErr != nil {
|
||||
c.Err = appErr
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte(resStruct.ToJson()))
|
||||
}
|
||||
|
||||
func parseMultipartRequestHeader(req *http.Request) (boundary string, err error) {
|
||||
v := req.Header.Get("Content-Type")
|
||||
if v == "" {
|
||||
|
||||
@@ -40,26 +40,20 @@ func escapeQuotes(s string) string {
|
||||
return quoteEscaper.Replace(s)
|
||||
}
|
||||
|
||||
func randomBytes(n int) []byte {
|
||||
func randomBytes(t *testing.T, n int) []byte {
|
||||
bb := make([]byte, n)
|
||||
_, err := rand.Read(bb)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
return bb
|
||||
}
|
||||
|
||||
func fileBytes(path string) []byte {
|
||||
func fileBytes(t *testing.T, path string) []byte {
|
||||
path = filepath.Join(testDir, path)
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
defer f.Close()
|
||||
bb, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
require.NoError(t, err)
|
||||
return bb
|
||||
}
|
||||
|
||||
@@ -183,7 +177,7 @@ func testUploadFilesMultipart(
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
mw.Close()
|
||||
require.NoError(t, mw.Close())
|
||||
return testDoUploadFileRequest(t, c, "", mwBody.Bytes(), mw.FormDataContentType(), -1)
|
||||
}
|
||||
|
||||
@@ -251,7 +245,7 @@ func TestUploadFiles(t *testing.T) {
|
||||
{
|
||||
title: "Happy invalid image",
|
||||
names: []string{"testgif.gif"},
|
||||
blobs: [][]byte{fileBytes("test-search.md")},
|
||||
blobs: [][]byte{fileBytes(t, "test-search.md")},
|
||||
skipPayloadValidation: true,
|
||||
expectedCreatorId: th.BasicUser.Id,
|
||||
},
|
||||
@@ -382,7 +376,7 @@ func TestUploadFiles(t *testing.T) {
|
||||
useChunkedInSimplePost: true,
|
||||
skipPayloadValidation: true,
|
||||
names: []string{"1Mb-stream"},
|
||||
blobs: [][]byte{randomBytes(1024 * 1024)},
|
||||
blobs: [][]byte{randomBytes(t, 1024*1024)},
|
||||
setupConfig: func(a *app.App) func(a *app.App) {
|
||||
maxFileSize := *a.Config().FileSettings.MaxFileSize
|
||||
a.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.MaxFileSize = 1024 * 1024 })
|
||||
@@ -480,7 +474,7 @@ func TestUploadFiles(t *testing.T) {
|
||||
title: "Error stream too large",
|
||||
skipPayloadValidation: true,
|
||||
names: []string{"1Mb-stream"},
|
||||
blobs: [][]byte{randomBytes(1024 * 1024)},
|
||||
blobs: [][]byte{randomBytes(t, 1024*1024)},
|
||||
skipSuccessValidation: true,
|
||||
checkResponse: CheckRequestEntityTooLargeStatus,
|
||||
setupConfig: func(a *app.App) func(a *app.App) {
|
||||
@@ -532,7 +526,7 @@ func TestUploadFiles(t *testing.T) {
|
||||
blobs := tc.blobs
|
||||
if len(blobs) == 0 {
|
||||
for _, name := range tc.names {
|
||||
blobs = append(blobs, fileBytes(name))
|
||||
blobs = append(blobs, fileBytes(t, name))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,9 +549,9 @@ func TestUploadFiles(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
if fileResp == nil || len(fileResp.FileInfos) == 0 || len(fileResp.FileInfos) != len(tc.names) {
|
||||
t.Fatal("Empty or mismatched actual or expected FileInfos")
|
||||
}
|
||||
require.NotNil(t, fileResp, "Nil fileResp")
|
||||
require.NotEqual(t, 0, len(fileResp.FileInfos), "Empty FileInfos")
|
||||
require.Equal(t, len(tc.names), len(fileResp.FileInfos), "Mismatched actual or expected FileInfos")
|
||||
|
||||
for i, ri := range fileResp.FileInfos {
|
||||
// The returned file info from the upload call will be missing some fields that will be stored in the database
|
||||
@@ -613,8 +607,7 @@ func TestUploadFiles(t *testing.T) {
|
||||
|
||||
expected, err := ioutil.ReadFile(filepath.Join(testDir, name))
|
||||
require.Nil(t, err)
|
||||
|
||||
if bytes.Compare(data, expected) != 0 {
|
||||
if !bytes.Equal(data, expected) {
|
||||
tf, err := ioutil.TempFile("", fmt.Sprintf("test_%v_*_%s", i, name))
|
||||
require.Nil(t, err)
|
||||
_, _ = io.Copy(tf, bytes.NewReader(data))
|
||||
@@ -653,29 +646,20 @@ func TestGetFile(t *testing.T) {
|
||||
t.Skip("skipping because no file driver is enabled")
|
||||
}
|
||||
|
||||
fileId := ""
|
||||
var sent []byte
|
||||
var err error
|
||||
if sent, err = testutils.ReadTestFile("test.png"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
sent, err := testutils.ReadTestFile("test.png")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png")
|
||||
CheckNoError(t, resp)
|
||||
|
||||
fileId = fileResp.FileInfos[0].Id
|
||||
}
|
||||
fileId := fileResp.FileInfos[0].Id
|
||||
|
||||
data, resp := Client.GetFile(fileId)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if len(data) == 0 {
|
||||
t.Fatal("should not be empty")
|
||||
}
|
||||
require.NotEqual(t, 0, len(data), "should not be empty")
|
||||
|
||||
for i := range data {
|
||||
if data[i] != sent[i] {
|
||||
t.Fatal("received file didn't match sent one")
|
||||
}
|
||||
require.Equal(t, sent[i], data[i], "received file didn't match sent one")
|
||||
}
|
||||
|
||||
_, resp = Client.GetFile("junk")
|
||||
@@ -713,30 +697,19 @@ func TestGetFileHeaders(t *testing.T) {
|
||||
_, resp = Client.GetFile(fileId)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if contentType := resp.Header.Get("Content-Type"); !strings.HasPrefix(contentType, expectedContentType) {
|
||||
t.Fatal("returned incorrect Content-Type", contentType)
|
||||
}
|
||||
CheckStartsWith(t, resp.Header.Get("Content-Type"), expectedContentType, "returned incorrect Content-Type")
|
||||
|
||||
if getInline {
|
||||
if contentDisposition := resp.Header.Get("Content-Disposition"); !strings.HasPrefix(contentDisposition, "inline") {
|
||||
t.Fatal("returned incorrect Content-Disposition", contentDisposition)
|
||||
}
|
||||
CheckStartsWith(t, resp.Header.Get("Content-Disposition"), "inline", "returned incorrect Content-Disposition")
|
||||
} else {
|
||||
if contentDisposition := resp.Header.Get("Content-Disposition"); !strings.HasPrefix(contentDisposition, "attachment") {
|
||||
t.Fatal("returned incorrect Content-Disposition", contentDisposition)
|
||||
}
|
||||
CheckStartsWith(t, resp.Header.Get("Content-Disposition"), "attachment", "returned incorrect Content-Disposition")
|
||||
}
|
||||
|
||||
_, resp = Client.DownloadFile(fileId, true)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if contentType := resp.Header.Get("Content-Type"); !strings.HasPrefix(contentType, expectedContentType) {
|
||||
t.Fatal("returned incorrect Content-Type", contentType)
|
||||
}
|
||||
|
||||
if contentDisposition := resp.Header.Get("Content-Disposition"); !strings.HasPrefix(contentDisposition, "attachment") {
|
||||
t.Fatal("returned incorrect Content-Disposition", contentDisposition)
|
||||
}
|
||||
CheckStartsWith(t, resp.Header.Get("Content-Type"), expectedContentType, "returned incorrect Content-Type")
|
||||
CheckStartsWith(t, resp.Header.Get("Content-Disposition"), "attachment", "returned incorrect Content-Disposition")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -768,27 +741,20 @@ func TestGetFileThumbnail(t *testing.T) {
|
||||
t.Skip("skipping because no file driver is enabled")
|
||||
}
|
||||
|
||||
fileId := ""
|
||||
var sent []byte
|
||||
var err error
|
||||
if sent, err = testutils.ReadTestFile("test.png"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
sent, err := testutils.ReadTestFile("test.png")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png")
|
||||
CheckNoError(t, resp)
|
||||
|
||||
fileId = fileResp.FileInfos[0].Id
|
||||
}
|
||||
fileId := fileResp.FileInfos[0].Id
|
||||
|
||||
// Wait a bit for files to ready
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
data, resp := Client.GetFileThumbnail(fileId)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if len(data) == 0 {
|
||||
t.Fatal("should not be empty")
|
||||
}
|
||||
require.NotEqual(t, 0, len(data), "should not be empty")
|
||||
|
||||
_, resp = Client.GetFileThumbnail("junk")
|
||||
CheckBadRequestStatus(t, resp)
|
||||
@@ -823,21 +789,19 @@ func TestGetFileLink(t *testing.T) {
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true })
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = model.NewRandomString(32) })
|
||||
|
||||
fileId := ""
|
||||
if data, err := testutils.ReadTestFile("test.png"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
fileResp, resp := Client.UploadFile(data, channel.Id, "test.png")
|
||||
CheckNoError(t, resp)
|
||||
data, err := testutils.ReadTestFile("test.png")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileId = fileResp.FileInfos[0].Id
|
||||
}
|
||||
fileResp, uploadResp := Client.UploadFile(data, channel.Id, "test.png")
|
||||
CheckNoError(t, uploadResp)
|
||||
|
||||
fileId := fileResp.FileInfos[0].Id
|
||||
|
||||
_, resp := Client.GetFileLink(fileId)
|
||||
CheckBadRequestStatus(t, resp)
|
||||
|
||||
// Hacky way to assign file to a post (usually would be done by CreatePost call)
|
||||
err := th.App.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id, th.BasicUser.Id)
|
||||
err = th.App.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id, th.BasicUser.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = false })
|
||||
@@ -850,10 +814,7 @@ func TestGetFileLink(t *testing.T) {
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true })
|
||||
link, resp := Client.GetFileLink(fileId)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if link == "" {
|
||||
t.Fatal("should've received public link")
|
||||
}
|
||||
require.NotEqual(t, "", link, "should've received public link")
|
||||
|
||||
_, resp = Client.GetFileLink("junk")
|
||||
CheckBadRequestStatus(t, resp)
|
||||
@@ -889,27 +850,19 @@ func TestGetFilePreview(t *testing.T) {
|
||||
t.Skip("skipping because no file driver is enabled")
|
||||
}
|
||||
|
||||
fileId := ""
|
||||
var sent []byte
|
||||
var err error
|
||||
if sent, err = testutils.ReadTestFile("test.png"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
sent, err := testutils.ReadTestFile("test.png")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png")
|
||||
CheckNoError(t, resp)
|
||||
|
||||
fileId = fileResp.FileInfos[0].Id
|
||||
}
|
||||
fileId := fileResp.FileInfos[0].Id
|
||||
|
||||
// Wait a bit for files to ready
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
data, resp := Client.GetFilePreview(fileId)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if len(data) == 0 {
|
||||
t.Fatal("should not be empty")
|
||||
}
|
||||
require.NotEqual(t, 0, len(data), "should not be empty")
|
||||
|
||||
_, resp = Client.GetFilePreview("junk")
|
||||
CheckBadRequestStatus(t, resp)
|
||||
@@ -942,17 +895,12 @@ func TestGetFileInfo(t *testing.T) {
|
||||
t.Skip("skipping because no file driver is enabled")
|
||||
}
|
||||
|
||||
fileId := ""
|
||||
var sent []byte
|
||||
var err error
|
||||
if sent, err = testutils.ReadTestFile("test.png"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
sent, err := testutils.ReadTestFile("test.png")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileResp, resp := Client.UploadFile(sent, channel.Id, "test.png")
|
||||
CheckNoError(t, resp)
|
||||
|
||||
fileId = fileResp.FileInfos[0].Id
|
||||
}
|
||||
fileId := fileResp.FileInfos[0].Id
|
||||
|
||||
// Wait a bit for files to ready
|
||||
time.Sleep(2 * time.Second)
|
||||
@@ -960,23 +908,14 @@ func TestGetFileInfo(t *testing.T) {
|
||||
info, resp := Client.GetFileInfo(fileId)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if info.Id != fileId {
|
||||
t.Fatal("got incorrect file")
|
||||
} else if info.CreatorId != user.Id {
|
||||
t.Fatal("file should be assigned to user")
|
||||
} else if info.PostId != "" {
|
||||
t.Fatal("file shouldn't have a post")
|
||||
} else if info.Path != "" {
|
||||
t.Fatal("file path shouldn't have been returned to client")
|
||||
} else if info.ThumbnailPath != "" {
|
||||
t.Fatal("file thumbnail path shouldn't have been returned to client")
|
||||
} else if info.PreviewPath != "" {
|
||||
t.Fatal("file preview path shouldn't have been returned to client")
|
||||
} else if info.MimeType != "image/png" {
|
||||
t.Fatal("mime type should've been image/png")
|
||||
}
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, fileId, info.Id, "got incorrect file")
|
||||
require.Equal(t, user.Id, info.CreatorId, "file should be assigned to user")
|
||||
require.Equal(t, "", info.PostId, "file shouldn't have a post")
|
||||
require.Equal(t, "", info.Path, "file path shouldn't have been returned to client")
|
||||
require.Equal(t, "", info.ThumbnailPath, "file thumbnail path shouldn't have been returned to client")
|
||||
require.Equal(t, "", info.PreviewPath, "file preview path shouldn't have been returned to client")
|
||||
require.Equal(t, "image/png", info.MimeType, "mime type should've been image/png")
|
||||
|
||||
_, resp = Client.GetFileInfo("junk")
|
||||
CheckBadRequestStatus(t, resp)
|
||||
@@ -1007,18 +946,16 @@ func TestGetPublicFile(t *testing.T) {
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true })
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = model.NewRandomString(32) })
|
||||
|
||||
fileId := ""
|
||||
if data, err := testutils.ReadTestFile("test.png"); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
fileResp, resp := Client.UploadFile(data, channel.Id, "test.png")
|
||||
CheckNoError(t, resp)
|
||||
data, err := testutils.ReadTestFile("test.png")
|
||||
require.NoError(t, err)
|
||||
|
||||
fileId = fileResp.FileInfos[0].Id
|
||||
}
|
||||
fileResp, httpResp := Client.UploadFile(data, channel.Id, "test.png")
|
||||
CheckNoError(t, httpResp)
|
||||
|
||||
fileId := fileResp.FileInfos[0].Id
|
||||
|
||||
// Hacky way to assign file to a post (usually would be done by CreatePost call)
|
||||
err := th.App.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id, th.BasicUser.Id)
|
||||
err = th.App.Srv.Store.FileInfo().AttachToPost(fileId, th.BasicPost.Id, th.BasicUser.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
info, err := th.App.Srv.Store.FileInfo().Get(fileId)
|
||||
@@ -1028,31 +965,31 @@ func TestGetPublicFile(t *testing.T) {
|
||||
// Wait a bit for files to ready
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
if resp, err := http.Get(link); err != nil || resp.StatusCode != http.StatusOK {
|
||||
t.Log(link)
|
||||
t.Fatal("failed to get image with public link", err)
|
||||
}
|
||||
resp, err := http.Get(link)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode, "failed to get image with public link")
|
||||
|
||||
if resp, err := http.Get(link[:strings.LastIndex(link, "?")]); err == nil && resp.StatusCode != http.StatusBadRequest {
|
||||
t.Fatal("should've failed to get image with public link without hash", resp.Status)
|
||||
}
|
||||
resp, err = http.Get(link[:strings.LastIndex(link, "?")])
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusBadRequest, resp.StatusCode, "should've failed to get image with public link without hash", resp.Status)
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = false })
|
||||
if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusNotImplemented {
|
||||
t.Fatal("should've failed to get image with disabled public link")
|
||||
}
|
||||
|
||||
resp, err = http.Get(link)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusNotImplemented, resp.StatusCode, "should've failed to get image with disabled public link")
|
||||
|
||||
// test after the salt has changed
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = true })
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.PublicLinkSalt = model.NewRandomString(32) })
|
||||
|
||||
if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusBadRequest {
|
||||
t.Fatal("should've failed to get image with public link after salt changed")
|
||||
}
|
||||
resp, err = http.Get(link)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusBadRequest, resp.StatusCode, "should've failed to get image with public link after salt changed")
|
||||
|
||||
if resp, err := http.Get(link); err == nil && resp.StatusCode != http.StatusBadRequest {
|
||||
t.Fatal("should've failed to get image with public link after salt changed")
|
||||
}
|
||||
resp, err = http.Get(link)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusBadRequest, resp.StatusCode, "should've failed to get image with public link after salt changed")
|
||||
|
||||
fileInfo, err := th.App.Srv.Store.FileInfo().Get(fileId)
|
||||
require.Nil(t, err)
|
||||
|
||||
@@ -13,11 +13,6 @@ import (
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
)
|
||||
|
||||
const (
|
||||
groupMemberActionCreate = iota
|
||||
groupMemberActionDelete
|
||||
)
|
||||
|
||||
func (api *API) InitGroup() {
|
||||
// GET /api/v4/groups
|
||||
api.BaseRoutes.Groups.Handle("", api.ApiSessionRequired(getGroups)).Methods("GET")
|
||||
|
||||
@@ -112,7 +112,7 @@ func TestOpenDialog(t *testing.T) {
|
||||
CallbackId: "callbackid",
|
||||
Title: "Some Title",
|
||||
Elements: []model.DialogElement{
|
||||
model.DialogElement{
|
||||
{
|
||||
DisplayName: "Element Name",
|
||||
Name: "element_name",
|
||||
Type: "text",
|
||||
|
||||
@@ -23,7 +23,7 @@ func TestCreateJob(t *testing.T) {
|
||||
}
|
||||
|
||||
received, resp := th.SystemAdminClient.CreateJob(job)
|
||||
CheckNoError(t, resp)
|
||||
require.Nil(t, resp.Error)
|
||||
|
||||
defer th.App.Srv.Store.Job().Delete(received.Id)
|
||||
|
||||
@@ -52,11 +52,10 @@ func TestGetJob(t *testing.T) {
|
||||
defer th.App.Srv.Store.Job().Delete(job.Id)
|
||||
|
||||
received, resp := th.SystemAdminClient.GetJob(job.Id)
|
||||
CheckNoError(t, resp)
|
||||
require.Nil(t, resp.Error)
|
||||
|
||||
if received.Id != job.Id || received.Status != job.Status {
|
||||
t.Fatal("incorrect job received")
|
||||
}
|
||||
require.Equal(t, job.Id, received.Id, "incorrect job received")
|
||||
require.Equal(t, job.Status, received.Status, "incorrect job received")
|
||||
|
||||
_, resp = th.SystemAdminClient.GetJob("1234")
|
||||
CheckBadRequestStatus(t, resp)
|
||||
@@ -100,22 +99,16 @@ func TestGetJobs(t *testing.T) {
|
||||
}
|
||||
|
||||
received, resp := th.SystemAdminClient.GetJobs(0, 2)
|
||||
CheckNoError(t, resp)
|
||||
require.Nil(t, resp.Error)
|
||||
|
||||
if len(received) != 2 {
|
||||
t.Fatal("received wrong number of jobs")
|
||||
} else if received[0].Id != jobs[2].Id {
|
||||
t.Fatal("should've received newest job first")
|
||||
} else if received[1].Id != jobs[0].Id {
|
||||
t.Fatal("should've received second newest job second")
|
||||
}
|
||||
require.Len(t, received, 2, "received wrong number of jobs")
|
||||
require.Equal(t, jobs[2].Id, received[0].Id, "should've received newest job first")
|
||||
require.Equal(t, jobs[0].Id, received[1].Id, "should've received second newest job second")
|
||||
|
||||
received, resp = th.SystemAdminClient.GetJobs(1, 2)
|
||||
CheckNoError(t, resp)
|
||||
require.Nil(t, resp.Error)
|
||||
|
||||
if received[0].Id != jobs[1].Id {
|
||||
t.Fatal("should've received oldest job last")
|
||||
}
|
||||
require.Equal(t,jobs[1].Id, received[0].Id, "should've received oldest job last")
|
||||
|
||||
_, resp = th.Client.GetJobs(0, 60)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
@@ -157,24 +150,17 @@ func TestGetJobsByType(t *testing.T) {
|
||||
}
|
||||
|
||||
received, resp := th.SystemAdminClient.GetJobsByType(jobType, 0, 2)
|
||||
CheckNoError(t, resp)
|
||||
require.Nil(t, resp.Error)
|
||||
|
||||
if len(received) != 2 {
|
||||
t.Fatal("received wrong number of jobs")
|
||||
} else if received[0].Id != jobs[2].Id {
|
||||
t.Fatal("should've received newest job first")
|
||||
} else if received[1].Id != jobs[0].Id {
|
||||
t.Fatal("should've received second newest job second")
|
||||
}
|
||||
require.Len(t, received, 2, "received wrong number of jobs")
|
||||
require.Equal(t, jobs[2].Id, received[0].Id, "should've received newest job first")
|
||||
require.Equal(t, jobs[0].Id, received[1].Id, "should've received second newest job second")
|
||||
|
||||
received, resp = th.SystemAdminClient.GetJobsByType(jobType, 1, 2)
|
||||
CheckNoError(t, resp)
|
||||
require.Nil(t, resp.Error)
|
||||
|
||||
if len(received) != 1 {
|
||||
t.Fatal("received wrong number of jobs")
|
||||
} else if received[0].Id != jobs[1].Id {
|
||||
t.Fatal("should've received oldest job last")
|
||||
}
|
||||
require.Len(t, received, 1, "received wrong number of jobs")
|
||||
require.Equal(t, jobs[1].Id, received[0].Id, "should've received oldest job last")
|
||||
|
||||
_, resp = th.SystemAdminClient.GetJobsByType("", 0, 60)
|
||||
CheckNotFoundStatus(t, resp)
|
||||
@@ -218,10 +204,10 @@ func TestCancelJob(t *testing.T) {
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
_, resp = th.SystemAdminClient.CancelJob(jobs[0].Id)
|
||||
CheckNoError(t, resp)
|
||||
require.Nil(t, resp.Error)
|
||||
|
||||
_, resp = th.SystemAdminClient.CancelJob(jobs[1].Id)
|
||||
CheckNoError(t, resp)
|
||||
require.Nil(t, resp.Error)
|
||||
|
||||
_, resp = th.SystemAdminClient.CancelJob(jobs[2].Id)
|
||||
CheckInternalErrorStatus(t, resp)
|
||||
|
||||
@@ -387,7 +387,7 @@ func TestDisableOnRemove(t *testing.T) {
|
||||
pluginsResp, resp := th.SystemAdminClient.GetPlugins()
|
||||
CheckNoError(t, resp)
|
||||
require.Len(t, pluginsResp.Active, 0)
|
||||
require.Equal(t, pluginsResp.Inactive, []*model.PluginInfo{&model.PluginInfo{
|
||||
require.Equal(t, pluginsResp.Inactive, []*model.PluginInfo{{
|
||||
Manifest: *manifest,
|
||||
}})
|
||||
|
||||
@@ -400,7 +400,7 @@ func TestDisableOnRemove(t *testing.T) {
|
||||
pluginsResp, resp = th.SystemAdminClient.GetPlugins()
|
||||
CheckNoError(t, resp)
|
||||
require.Len(t, pluginsResp.Inactive, 0)
|
||||
require.Equal(t, pluginsResp.Active, []*model.PluginInfo{&model.PluginInfo{
|
||||
require.Equal(t, pluginsResp.Active, []*model.PluginInfo{{
|
||||
Manifest: *manifest,
|
||||
}})
|
||||
|
||||
@@ -414,7 +414,7 @@ func TestDisableOnRemove(t *testing.T) {
|
||||
pluginsResp, resp = th.SystemAdminClient.GetPlugins()
|
||||
CheckNoError(t, resp)
|
||||
require.Len(t, pluginsResp.Inactive, 0)
|
||||
require.Equal(t, pluginsResp.Active, []*model.PluginInfo{&model.PluginInfo{
|
||||
require.Equal(t, pluginsResp.Active, []*model.PluginInfo{{
|
||||
Manifest: *manifest,
|
||||
}})
|
||||
}
|
||||
@@ -439,7 +439,7 @@ func TestDisableOnRemove(t *testing.T) {
|
||||
pluginsResp, resp = th.SystemAdminClient.GetPlugins()
|
||||
CheckNoError(t, resp)
|
||||
require.Len(t, pluginsResp.Active, 0)
|
||||
require.Equal(t, pluginsResp.Inactive, []*model.PluginInfo{&model.PluginInfo{
|
||||
require.Equal(t, pluginsResp.Inactive, []*model.PluginInfo{{
|
||||
Manifest: *manifest,
|
||||
}})
|
||||
|
||||
|
||||
@@ -476,7 +476,7 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
results, err := c.App.SearchPostsInTeamForUser(terms, c.App.Session.UserId, c.Params.TeamId, isOrSearch, includeDeletedChannels, int(timeZoneOffset), page, perPage)
|
||||
results, err := c.App.SearchPostsInTeamForUser(terms, c.App.Session.UserId, c.Params.TeamId, isOrSearch, includeDeletedChannels, timeZoneOffset, page, perPage)
|
||||
|
||||
elapsedTime := float64(time.Since(startTime)) / float64(time.Second)
|
||||
metrics := c.App.Metrics
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
)
|
||||
|
||||
@@ -42,14 +44,10 @@ func TestGetPreferences(t *testing.T) {
|
||||
|
||||
prefs, resp := Client.GetPreferences(user1.Id)
|
||||
CheckNoError(t, resp)
|
||||
if len(prefs) != 4 {
|
||||
t.Fatal("received the wrong number of preferences")
|
||||
}
|
||||
require.Equal(t, len(prefs), 4, "received the wrong number of preferences")
|
||||
|
||||
for _, preference := range prefs {
|
||||
if preference.UserId != th.BasicUser.Id {
|
||||
t.Fatal("user id does not match")
|
||||
}
|
||||
require.Equal(t, preference.UserId, th.BasicUser.Id, "user id does not match")
|
||||
}
|
||||
|
||||
th.LoginBasic2()
|
||||
@@ -57,9 +55,7 @@ func TestGetPreferences(t *testing.T) {
|
||||
prefs, resp = Client.GetPreferences(th.BasicUser2.Id)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if len(prefs) == 0 {
|
||||
t.Fatal("received the wrong number of preferences")
|
||||
}
|
||||
require.Greater(t, len(prefs), 0, "received the wrong number of preferences")
|
||||
|
||||
_, resp = Client.GetPreferences(th.BasicUser.Id)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
@@ -101,9 +97,7 @@ func TestGetPreferencesByCategory(t *testing.T) {
|
||||
prefs, resp := Client.GetPreferencesByCategory(user1.Id, category)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if len(prefs) != 2 {
|
||||
t.Fatalf("received the wrong number of preferences %v:%v", len(prefs), 2)
|
||||
}
|
||||
require.Equal(t, len(prefs), 2, "received the wrong number of preferences")
|
||||
|
||||
_, resp = Client.GetPreferencesByCategory(user1.Id, "junk")
|
||||
CheckNotFoundStatus(t, resp)
|
||||
@@ -119,9 +113,7 @@ func TestGetPreferencesByCategory(t *testing.T) {
|
||||
prefs, resp = Client.GetPreferencesByCategory(th.BasicUser2.Id, "junk")
|
||||
CheckNotFoundStatus(t, resp)
|
||||
|
||||
if len(prefs) != 0 {
|
||||
t.Fatal("received the wrong number of preferences")
|
||||
}
|
||||
require.Equal(t, len(prefs), 0, "received the wrong number of preferences")
|
||||
|
||||
Client.Logout()
|
||||
_, resp = Client.GetPreferencesByCategory(th.BasicUser2.Id, category)
|
||||
@@ -158,9 +150,9 @@ func TestGetPreferenceByCategoryAndName(t *testing.T) {
|
||||
pref, resp := Client.GetPreferenceByCategoryAndName(user.Id, model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, name)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
if (pref.UserId != preferences[0].UserId) && (pref.Category != preferences[0].Category) && (pref.Name != preferences[0].Name) {
|
||||
t.Fatal("preference saved incorrectly")
|
||||
}
|
||||
require.Equal(t, preferences[0].UserId, pref.UserId, "UserId preference not saved")
|
||||
require.Equal(t, preferences[0].Category, pref.Category, "Category preference not saved")
|
||||
require.Equal(t, preferences[0].Name, pref.Name, "Name preference not saved")
|
||||
|
||||
preferences[0].Value = model.NewId()
|
||||
Client.UpdatePreferences(user.Id, &preferences)
|
||||
@@ -247,15 +239,12 @@ func TestUpdatePreferencesWebsocket(t *testing.T) {
|
||||
defer th.TearDown()
|
||||
|
||||
WebSocketClient, err := th.CreateWebSocketClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, err)
|
||||
|
||||
WebSocketClient.Listen()
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Status != model.STATUS_OK {
|
||||
t.Fatal("should have responded OK to authentication challenge")
|
||||
}
|
||||
wsResp := <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, wsResp.Status, model.STATUS_OK, "expected OK from auth challenge")
|
||||
|
||||
userId := th.BasicUser.Id
|
||||
preferences := &model.Preferences{
|
||||
@@ -285,19 +274,17 @@ func TestUpdatePreferencesWebsocket(t *testing.T) {
|
||||
}
|
||||
|
||||
received, err := model.PreferencesFromJson(strings.NewReader(event.Data["preferences"].(string)))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
for i, preference := range *preferences {
|
||||
if preference.UserId != received[i].UserId || preference.Category != received[i].Category || preference.Name != received[i].Name {
|
||||
t.Fatal("received incorrect preference")
|
||||
}
|
||||
for i, p := range *preferences {
|
||||
require.Equal(t, received[i].UserId, p.UserId, "received incorrect UserId")
|
||||
require.Equal(t, received[i].Category, p.Category, "received incorrect Category")
|
||||
require.Equal(t, received[i].Name, p.Name, "received incorrect Name")
|
||||
}
|
||||
|
||||
waiting = false
|
||||
case <-timeout:
|
||||
t.Fatal("timed out waiting for preference update event")
|
||||
require.Fail(t, "timed timed out waiting for preference update event")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetUserStatus(t *testing.T) {
|
||||
@@ -13,44 +14,32 @@ func TestGetUserStatus(t *testing.T) {
|
||||
|
||||
userStatus, resp := Client.GetUserStatus(th.BasicUser.Id, "")
|
||||
CheckNoError(t, resp)
|
||||
if userStatus.Status != "offline" {
|
||||
t.Fatal("Should return offline status")
|
||||
}
|
||||
assert.Equal(t, "offline", userStatus.Status)
|
||||
|
||||
th.App.SetStatusOnline(th.BasicUser.Id, true)
|
||||
userStatus, resp = Client.GetUserStatus(th.BasicUser.Id, "")
|
||||
CheckNoError(t, resp)
|
||||
if userStatus.Status != "online" {
|
||||
t.Fatal("Should return online status")
|
||||
}
|
||||
assert.Equal(t, "online", userStatus.Status)
|
||||
|
||||
th.App.SetStatusAwayIfNeeded(th.BasicUser.Id, true)
|
||||
userStatus, resp = Client.GetUserStatus(th.BasicUser.Id, "")
|
||||
CheckNoError(t, resp)
|
||||
if userStatus.Status != "away" {
|
||||
t.Fatal("Should return away status")
|
||||
}
|
||||
assert.Equal(t, "away", userStatus.Status)
|
||||
|
||||
th.App.SetStatusDoNotDisturb(th.BasicUser.Id)
|
||||
userStatus, resp = Client.GetUserStatus(th.BasicUser.Id, "")
|
||||
CheckNoError(t, resp)
|
||||
if userStatus.Status != "dnd" {
|
||||
t.Fatal("Should return dnd status")
|
||||
}
|
||||
assert.Equal(t, "dnd", userStatus.Status)
|
||||
|
||||
th.App.SetStatusOffline(th.BasicUser.Id, true)
|
||||
userStatus, resp = Client.GetUserStatus(th.BasicUser.Id, "")
|
||||
CheckNoError(t, resp)
|
||||
if userStatus.Status != "offline" {
|
||||
t.Fatal("Should return offline status")
|
||||
}
|
||||
assert.Equal(t, "offline", userStatus.Status)
|
||||
|
||||
//Get user2 status logged as user1
|
||||
userStatus, resp = Client.GetUserStatus(th.BasicUser2.Id, "")
|
||||
CheckNoError(t, resp)
|
||||
if userStatus.Status != "offline" {
|
||||
t.Fatal("Should return offline status")
|
||||
}
|
||||
assert.Equal(t, "offline", userStatus.Status)
|
||||
|
||||
Client.Logout()
|
||||
|
||||
@@ -60,9 +49,7 @@ func TestGetUserStatus(t *testing.T) {
|
||||
th.LoginBasic2()
|
||||
userStatus, resp = Client.GetUserStatus(th.BasicUser2.Id, "")
|
||||
CheckNoError(t, resp)
|
||||
if userStatus.Status != "offline" {
|
||||
t.Fatal("Should return offline status")
|
||||
}
|
||||
assert.Equal(t, "offline", userStatus.Status)
|
||||
}
|
||||
|
||||
func TestGetUsersStatusesByIds(t *testing.T) {
|
||||
@@ -75,9 +62,7 @@ func TestGetUsersStatusesByIds(t *testing.T) {
|
||||
usersStatuses, resp := Client.GetUsersStatusesByIds(usersIds)
|
||||
CheckNoError(t, resp)
|
||||
for _, userStatus := range usersStatuses {
|
||||
if userStatus.Status != "offline" {
|
||||
t.Fatal("Status should be offline")
|
||||
}
|
||||
assert.Equal(t, "offline", userStatus.Status)
|
||||
}
|
||||
|
||||
th.App.SetStatusOnline(th.BasicUser.Id, true)
|
||||
@@ -85,9 +70,7 @@ func TestGetUsersStatusesByIds(t *testing.T) {
|
||||
usersStatuses, resp = Client.GetUsersStatusesByIds(usersIds)
|
||||
CheckNoError(t, resp)
|
||||
for _, userStatus := range usersStatuses {
|
||||
if userStatus.Status != "online" {
|
||||
t.Fatal("Status should be offline")
|
||||
}
|
||||
assert.Equal(t, "online", userStatus.Status)
|
||||
}
|
||||
|
||||
th.App.SetStatusAwayIfNeeded(th.BasicUser.Id, true)
|
||||
@@ -95,9 +78,7 @@ func TestGetUsersStatusesByIds(t *testing.T) {
|
||||
usersStatuses, resp = Client.GetUsersStatusesByIds(usersIds)
|
||||
CheckNoError(t, resp)
|
||||
for _, userStatus := range usersStatuses {
|
||||
if userStatus.Status != "away" {
|
||||
t.Fatal("Status should be offline")
|
||||
}
|
||||
assert.Equal(t, "away", userStatus.Status)
|
||||
}
|
||||
|
||||
th.App.SetStatusDoNotDisturb(th.BasicUser.Id)
|
||||
@@ -105,9 +86,7 @@ func TestGetUsersStatusesByIds(t *testing.T) {
|
||||
usersStatuses, resp = Client.GetUsersStatusesByIds(usersIds)
|
||||
CheckNoError(t, resp)
|
||||
for _, userStatus := range usersStatuses {
|
||||
if userStatus.Status != "dnd" {
|
||||
t.Fatal("Status should be offline")
|
||||
}
|
||||
assert.Equal(t, "dnd", userStatus.Status)
|
||||
}
|
||||
|
||||
Client.Logout()
|
||||
@@ -124,30 +103,22 @@ func TestUpdateUserStatus(t *testing.T) {
|
||||
toUpdateUserStatus := &model.Status{Status: "online", UserId: th.BasicUser.Id}
|
||||
updateUserStatus, resp := Client.UpdateUserStatus(th.BasicUser.Id, toUpdateUserStatus)
|
||||
CheckNoError(t, resp)
|
||||
if updateUserStatus.Status != "online" {
|
||||
t.Fatal("Should return online status")
|
||||
}
|
||||
assert.Equal(t, "online", updateUserStatus.Status)
|
||||
|
||||
toUpdateUserStatus.Status = "away"
|
||||
updateUserStatus, resp = Client.UpdateUserStatus(th.BasicUser.Id, toUpdateUserStatus)
|
||||
CheckNoError(t, resp)
|
||||
if updateUserStatus.Status != "away" {
|
||||
t.Fatal("Should return away status")
|
||||
}
|
||||
assert.Equal(t, "away", updateUserStatus.Status)
|
||||
|
||||
toUpdateUserStatus.Status = "dnd"
|
||||
updateUserStatus, resp = Client.UpdateUserStatus(th.BasicUser.Id, toUpdateUserStatus)
|
||||
CheckNoError(t, resp)
|
||||
if updateUserStatus.Status != "dnd" {
|
||||
t.Fatal("Should return dnd status")
|
||||
}
|
||||
assert.Equal(t, "dnd", updateUserStatus.Status)
|
||||
|
||||
toUpdateUserStatus.Status = "offline"
|
||||
updateUserStatus, resp = Client.UpdateUserStatus(th.BasicUser.Id, toUpdateUserStatus)
|
||||
CheckNoError(t, resp)
|
||||
if updateUserStatus.Status != "offline" {
|
||||
t.Fatal("Should return offline status")
|
||||
}
|
||||
assert.Equal(t, "offline", updateUserStatus.Status)
|
||||
|
||||
toUpdateUserStatus.Status = "online"
|
||||
toUpdateUserStatus.UserId = th.BasicUser2.Id
|
||||
@@ -156,9 +127,7 @@ func TestUpdateUserStatus(t *testing.T) {
|
||||
|
||||
toUpdateUserStatus.Status = "online"
|
||||
updateUserStatus, _ = th.SystemAdminClient.UpdateUserStatus(th.BasicUser2.Id, toUpdateUserStatus)
|
||||
if updateUserStatus.Status != "online" {
|
||||
t.Fatal("Should return online status")
|
||||
}
|
||||
assert.Equal(t, "online", updateUserStatus.Status)
|
||||
|
||||
_, resp = Client.UpdateUserStatus(th.BasicUser.Id, toUpdateUserStatus)
|
||||
CheckBadRequestStatus(t, resp)
|
||||
|
||||
@@ -397,7 +397,6 @@ func getRedirectLocation(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
m["location"] = location
|
||||
|
||||
w.Write([]byte(model.MapToJson(m)))
|
||||
return
|
||||
}
|
||||
|
||||
func pushNotificationAck(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
@@ -415,5 +414,4 @@ func pushNotificationAck(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
ReturnStatusOK(w)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -911,7 +911,7 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
data := map[string]string{}
|
||||
data["results"] = base64.StdEncoding.EncodeToString([]byte(log.Bytes()))
|
||||
data["results"] = base64.StdEncoding.EncodeToString(log.Bytes())
|
||||
if c.Err != nil {
|
||||
w.WriteHeader(c.Err.StatusCode)
|
||||
}
|
||||
|
||||
@@ -1422,8 +1422,6 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
user.TermsOfServiceCreateAt = userTermsOfService.CreateAt
|
||||
}
|
||||
|
||||
c.App.Session = *session
|
||||
|
||||
user.Sanitize(map[string]bool{})
|
||||
|
||||
w.Write([]byte(user.ToJson()))
|
||||
|
||||
@@ -1369,7 +1369,8 @@ func TestGetUsersByGroupChannelIds(t *testing.T) {
|
||||
usersByChannelId, resp := th.Client.GetUsersByGroupChannelIds([]string{gc1.Id})
|
||||
CheckNoError(t, resp)
|
||||
|
||||
users, _ := usersByChannelId[gc1.Id]
|
||||
users, ok := usersByChannelId[gc1.Id]
|
||||
assert.True(t, ok)
|
||||
userIds := []string{}
|
||||
for _, user := range users {
|
||||
userIds = append(userIds, user.Id)
|
||||
@@ -1381,7 +1382,7 @@ func TestGetUsersByGroupChannelIds(t *testing.T) {
|
||||
usersByChannelId, resp = th.Client.GetUsersByGroupChannelIds([]string{gc1.Id})
|
||||
CheckNoError(t, resp)
|
||||
|
||||
_, ok := usersByChannelId[gc1.Id]
|
||||
_, ok = usersByChannelId[gc1.Id]
|
||||
require.False(t, ok)
|
||||
|
||||
th.Client.Logout()
|
||||
|
||||
@@ -12,7 +12,8 @@ import (
|
||||
)
|
||||
|
||||
func (api *API) InitWebSocket() {
|
||||
api.BaseRoutes.ApiRoot.Handle("/websocket", api.ApiHandlerTrustRequester(connectWebSocket)).Methods("GET")
|
||||
// Optionally supports a trailing slash
|
||||
api.BaseRoutes.ApiRoot.Handle("/{websocket:websocket(?:\\/)?}", api.ApiHandlerTrustRequester(connectWebSocket)).Methods("GET")
|
||||
}
|
||||
|
||||
func connectWebSocket(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -20,62 +20,59 @@ func TestWebSocket(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
defer th.TearDown()
|
||||
WebSocketClient, err := th.CreateWebSocketClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, err)
|
||||
defer WebSocketClient.Close()
|
||||
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
|
||||
// Test closing and reconnecting
|
||||
WebSocketClient.Close()
|
||||
if err := WebSocketClient.Connect(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = WebSocketClient.Connect()
|
||||
require.Nil(t, err)
|
||||
|
||||
WebSocketClient.Listen()
|
||||
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Status != model.STATUS_OK {
|
||||
t.Fatal("should have responded OK to authentication challenge")
|
||||
}
|
||||
resp := <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, resp.Status, model.STATUS_OK, "should have responded OK to authentication challenge")
|
||||
|
||||
WebSocketClient.SendMessage("ping", nil)
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Data["text"].(string) != "pong" {
|
||||
t.Fatal("wrong response")
|
||||
}
|
||||
resp = <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, resp.Data["text"].(string), "pong", "wrong response")
|
||||
|
||||
WebSocketClient.SendMessage("", nil)
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Error.Id != "api.web_socket_router.no_action.app_error" {
|
||||
t.Fatal("should have been no action response")
|
||||
}
|
||||
resp = <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, resp.Error.Id, "api.web_socket_router.no_action.app_error", "should have been no action response")
|
||||
|
||||
WebSocketClient.SendMessage("junk", nil)
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Error.Id != "api.web_socket_router.bad_action.app_error" {
|
||||
t.Fatal("should have been bad action response")
|
||||
}
|
||||
resp = <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, resp.Error.Id, "api.web_socket_router.bad_action.app_error", "should have been bad action response")
|
||||
|
||||
req := &model.WebSocketRequest{}
|
||||
req.Seq = 0
|
||||
req.Action = "ping"
|
||||
WebSocketClient.Conn.WriteJSON(req)
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Error.Id != "api.web_socket_router.bad_seq.app_error" {
|
||||
t.Fatal("should have been bad action response")
|
||||
}
|
||||
resp = <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, resp.Error.Id, "api.web_socket_router.bad_seq.app_error", "should have been bad action response")
|
||||
|
||||
WebSocketClient.UserTyping("", "")
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Error.Id != "api.websocket_handler.invalid_param.app_error" {
|
||||
t.Fatal("should have been invalid param response")
|
||||
} else {
|
||||
if resp.Error.DetailedError != "" {
|
||||
t.Fatal("detailed error not cleared")
|
||||
}
|
||||
resp = <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, resp.Error.Id, "api.websocket_handler.invalid_param.app_error", "should have been invalid param response")
|
||||
require.Equal(t, resp.Error.DetailedError, "", "detailed error not cleared")
|
||||
}
|
||||
|
||||
func TestWebSocketTrailingSlash(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
url := fmt.Sprintf("ws://localhost:%v", th.App.Srv.ListenAddr.Port)
|
||||
_, _, err := websocket.DefaultDialer.Dial(url+model.API_URL_SUFFIX+"/websocket/", nil)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestWebSocketEvent(t *testing.T) {
|
||||
@@ -83,17 +80,14 @@ func TestWebSocketEvent(t *testing.T) {
|
||||
defer th.TearDown()
|
||||
|
||||
WebSocketClient, err := th.CreateWebSocketClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, err)
|
||||
defer WebSocketClient.Close()
|
||||
|
||||
WebSocketClient.Listen()
|
||||
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Status != model.STATUS_OK {
|
||||
t.Fatal("should have responded OK to authentication challenge")
|
||||
}
|
||||
resp := <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, resp.Status, model.STATUS_OK, "should have responded OK to authentication challenge")
|
||||
|
||||
omitUser := make(map[string]bool, 1)
|
||||
omitUser["somerandomid"] = true
|
||||
@@ -123,9 +117,7 @@ func TestWebSocketEvent(t *testing.T) {
|
||||
|
||||
stop <- true
|
||||
|
||||
if !eventHit {
|
||||
t.Fatal("did not receive typing event")
|
||||
}
|
||||
require.True(t, eventHit, "did not receive typing event")
|
||||
|
||||
evt2 := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_TYPING, "", "somerandomid", "", nil)
|
||||
th.App.Publish(evt2)
|
||||
@@ -150,9 +142,7 @@ func TestWebSocketEvent(t *testing.T) {
|
||||
|
||||
stop <- true
|
||||
|
||||
if eventHit {
|
||||
t.Fatal("got typing event for bad channel id")
|
||||
}
|
||||
require.False(t, eventHit, "got typing event for bad channel id")
|
||||
}
|
||||
|
||||
func TestCreateDirectChannelWithSocket(t *testing.T) {
|
||||
@@ -170,21 +160,16 @@ func TestCreateDirectChannelWithSocket(t *testing.T) {
|
||||
}
|
||||
|
||||
WebSocketClient, err := th.CreateWebSocketClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, err)
|
||||
defer WebSocketClient.Close()
|
||||
WebSocketClient.Listen()
|
||||
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Status != model.STATUS_OK {
|
||||
t.Fatal("should have responded OK to authentication challenge")
|
||||
}
|
||||
resp := <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, resp.Status, model.STATUS_OK, "should have responded OK to authentication challenge")
|
||||
|
||||
wsr := <-WebSocketClient.EventChannel
|
||||
if wsr.Event != model.WEBSOCKET_EVENT_HELLO {
|
||||
t.Fatal("missing hello")
|
||||
}
|
||||
require.Equal(t, wsr.Event, model.WEBSOCKET_EVENT_HELLO, "missing hello")
|
||||
|
||||
stop := make(chan bool)
|
||||
count := 0
|
||||
@@ -205,19 +190,15 @@ func TestCreateDirectChannelWithSocket(t *testing.T) {
|
||||
|
||||
for _, user := range users {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if _, resp := Client.CreateDirectChannel(th.BasicUser.Id, user.Id); resp.Error != nil {
|
||||
t.Fatal("failed to create DM channel")
|
||||
}
|
||||
_, resp := Client.CreateDirectChannel(th.BasicUser.Id, user.Id)
|
||||
require.Nil(t, resp.Error, "failed to create DM channel")
|
||||
}
|
||||
|
||||
time.Sleep(5000 * time.Millisecond)
|
||||
|
||||
stop <- true
|
||||
|
||||
if count != len(users) {
|
||||
t.Fatal("We didn't get the proper amount of direct_added messages")
|
||||
}
|
||||
|
||||
require.Equal(t, count, len(users), "We didn't get the proper amount of direct_added messages")
|
||||
}
|
||||
|
||||
func TestWebsocketOriginSecurity(t *testing.T) {
|
||||
@@ -230,53 +211,42 @@ func TestWebsocketOriginSecurity(t *testing.T) {
|
||||
_, _, err := websocket.DefaultDialer.Dial(url+model.API_URL_SUFFIX+"/websocket", http.Header{
|
||||
"Origin": []string{"http://www.evil.com"},
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("Should have errored because Origin does not match host! SECURITY ISSUE!")
|
||||
}
|
||||
|
||||
require.NotNil(t, err, "Should have errored because Origin does not match host! SECURITY ISSUE!")
|
||||
|
||||
// We are not a browser so we can spoof this just fine
|
||||
_, _, err = websocket.DefaultDialer.Dial(url+model.API_URL_SUFFIX+"/websocket", http.Header{
|
||||
"Origin": []string{fmt.Sprintf("http://localhost:%v", th.App.Srv.ListenAddr.Port)},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, err, err)
|
||||
|
||||
// Should succeed now because open CORS
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowCorsFrom = "*" })
|
||||
_, _, err = websocket.DefaultDialer.Dial(url+model.API_URL_SUFFIX+"/websocket", http.Header{
|
||||
"Origin": []string{"http://www.evil.com"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, err, err)
|
||||
|
||||
// Should succeed now because matching CORS
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowCorsFrom = "http://www.evil.com" })
|
||||
_, _, err = websocket.DefaultDialer.Dial(url+model.API_URL_SUFFIX+"/websocket", http.Header{
|
||||
"Origin": []string{"http://www.evil.com"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, err, err)
|
||||
|
||||
// Should fail because non-matching CORS
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowCorsFrom = "http://www.good.com" })
|
||||
_, _, err = websocket.DefaultDialer.Dial(url+model.API_URL_SUFFIX+"/websocket", http.Header{
|
||||
"Origin": []string{"http://www.evil.com"},
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("Should have errored because Origin contain AllowCorsFrom")
|
||||
}
|
||||
require.NotNil(t, err, "Should have errored because Origin contain AllowCorsFrom")
|
||||
|
||||
// Should fail because non-matching CORS
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowCorsFrom = "http://www.good.com" })
|
||||
_, _, err = websocket.DefaultDialer.Dial(url+model.API_URL_SUFFIX+"/websocket", http.Header{
|
||||
"Origin": []string{"http://www.good.co"},
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("Should have errored because Origin does not match host! SECURITY ISSUE!")
|
||||
}
|
||||
require.NotNil(t, err, "Should have errored because Origin does not match host! SECURITY ISSUE!")
|
||||
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowCorsFrom = "" })
|
||||
}
|
||||
@@ -287,16 +257,13 @@ func TestWebSocketStatuses(t *testing.T) {
|
||||
|
||||
Client := th.Client
|
||||
WebSocketClient, err := th.CreateWebSocketClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, err, err)
|
||||
defer WebSocketClient.Close()
|
||||
WebSocketClient.Listen()
|
||||
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Status != model.STATUS_OK {
|
||||
t.Fatal("should have responded OK to authentication challenge")
|
||||
}
|
||||
resp := <-WebSocketClient.ResponseChannel
|
||||
require.Equal(t, resp.Status, model.STATUS_OK, "should have responded OK to authentication challenge")
|
||||
|
||||
team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
|
||||
rteam, _ := Client.CreateTeam(&team)
|
||||
@@ -318,79 +285,53 @@ func TestWebSocketStatuses(t *testing.T) {
|
||||
th.LoginBasic2()
|
||||
|
||||
WebSocketClient2, err2 := th.CreateWebSocketClient()
|
||||
if err2 != nil {
|
||||
t.Fatal(err2)
|
||||
}
|
||||
require.Nil(t, err2, err2)
|
||||
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
|
||||
WebSocketClient.GetStatuses()
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Error != nil {
|
||||
t.Fatal(resp.Error)
|
||||
} else {
|
||||
if resp.SeqReply != WebSocketClient.Sequence-1 {
|
||||
t.Fatal("bad sequence number")
|
||||
}
|
||||
resp = <-WebSocketClient.ResponseChannel
|
||||
require.Nil(t, resp.Error, resp.Error)
|
||||
|
||||
require.Equal(t, resp.SeqReply, WebSocketClient.Sequence-1, "bad sequence number")
|
||||
|
||||
allowedValues := [4]string{model.STATUS_OFFLINE, model.STATUS_AWAY, model.STATUS_ONLINE, model.STATUS_DND}
|
||||
for _, status := range resp.Data {
|
||||
if status != model.STATUS_OFFLINE && status != model.STATUS_AWAY && status != model.STATUS_ONLINE && status != model.STATUS_DND {
|
||||
t.Fatalf("one of the statuses had an invalid value status=%v", status)
|
||||
}
|
||||
require.Containsf(t, allowedValues, status, "one of the statuses had an invalid value status=%v", status)
|
||||
}
|
||||
|
||||
if status, ok := resp.Data[th.BasicUser2.Id]; !ok {
|
||||
t.Log(resp.Data)
|
||||
t.Fatal("should have had user status")
|
||||
} else if status != model.STATUS_ONLINE {
|
||||
t.Log(status)
|
||||
t.Fatal("status should have been online")
|
||||
}
|
||||
}
|
||||
status, ok := resp.Data[th.BasicUser2.Id]
|
||||
require.True(t, ok, "should have had user status")
|
||||
|
||||
require.Equal(t, status, model.STATUS_ONLINE, "status should have been online status=%v", status)
|
||||
|
||||
WebSocketClient.GetStatusesByIds([]string{th.BasicUser2.Id})
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Error != nil {
|
||||
t.Fatal(resp.Error)
|
||||
} else {
|
||||
if resp.SeqReply != WebSocketClient.Sequence-1 {
|
||||
t.Fatal("bad sequence number")
|
||||
}
|
||||
resp = <-WebSocketClient.ResponseChannel
|
||||
require.Nil(t, resp.Error, resp.Error)
|
||||
|
||||
require.Equal(t, resp.SeqReply, WebSocketClient.Sequence-1, "bad sequence number")
|
||||
|
||||
allowedValues = [4]string{model.STATUS_OFFLINE, model.STATUS_AWAY, model.STATUS_ONLINE}
|
||||
for _, status := range resp.Data {
|
||||
if status != model.STATUS_OFFLINE && status != model.STATUS_AWAY && status != model.STATUS_ONLINE {
|
||||
t.Fatal("one of the statuses had an invalid value")
|
||||
}
|
||||
require.Containsf(t, allowedValues, status, "one of the statuses had an invalid value status")
|
||||
}
|
||||
|
||||
if status, ok := resp.Data[th.BasicUser2.Id]; !ok {
|
||||
t.Log(len(resp.Data))
|
||||
t.Fatal("should have had user status")
|
||||
} else if status != model.STATUS_ONLINE {
|
||||
t.Log(status)
|
||||
t.Fatal("status should have been online")
|
||||
} else if len(resp.Data) != 1 {
|
||||
t.Fatal("only 1 status should be returned")
|
||||
}
|
||||
}
|
||||
status, ok = resp.Data[th.BasicUser2.Id]
|
||||
require.True(t, ok, "should have had user status")
|
||||
|
||||
require.Equal(t, status, model.STATUS_ONLINE, "status should have been online status=%v", status)
|
||||
require.Equal(t, len(resp.Data), 1, "only 1 status should be returned")
|
||||
|
||||
WebSocketClient.GetStatusesByIds([]string{ruser2.Id, "junk"})
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Error != nil {
|
||||
t.Fatal(resp.Error)
|
||||
} else {
|
||||
if resp.SeqReply != WebSocketClient.Sequence-1 {
|
||||
t.Fatal("bad sequence number")
|
||||
}
|
||||
|
||||
if len(resp.Data) != 2 {
|
||||
t.Fatal("2 statuses should be returned")
|
||||
}
|
||||
}
|
||||
resp = <-WebSocketClient.ResponseChannel
|
||||
require.Nil(t, resp.Error, resp.Error)
|
||||
require.Equal(t, resp.SeqReply, WebSocketClient.Sequence-1, "bad sequence number")
|
||||
require.Equal(t, len(resp.Data), 2, "2 statuses should be returned")
|
||||
|
||||
WebSocketClient.GetStatusesByIds([]string{})
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Error == nil {
|
||||
if resp.SeqReply != WebSocketClient.Sequence-1 {
|
||||
t.Fatal("bad sequence number")
|
||||
}
|
||||
t.Fatal("should have errored - empty user ids")
|
||||
if resp2 := <-WebSocketClient.ResponseChannel; resp2.Error == nil {
|
||||
require.Equal(t, resp2.SeqReply, WebSocketClient.Sequence-1, "bad sequence number")
|
||||
require.NotNil(t, resp2.Error, "should have errored - empty user ids")
|
||||
}
|
||||
|
||||
WebSocketClient2.Close()
|
||||
@@ -411,17 +352,12 @@ func TestWebSocketStatuses(t *testing.T) {
|
||||
time.Sleep(1500 * time.Millisecond)
|
||||
|
||||
WebSocketClient.GetStatuses()
|
||||
if resp := <-WebSocketClient.ResponseChannel; resp.Error != nil {
|
||||
t.Fatal(resp.Error)
|
||||
} else {
|
||||
if resp.SeqReply != WebSocketClient.Sequence-1 {
|
||||
t.Fatal("bad sequence number")
|
||||
}
|
||||
resp = <-WebSocketClient.ResponseChannel
|
||||
require.Nil(t, resp.Error)
|
||||
|
||||
if _, ok := resp.Data[th.BasicUser2.Id]; ok {
|
||||
t.Fatal("should not have had user status")
|
||||
}
|
||||
}
|
||||
require.Equal(t, resp.SeqReply, WebSocketClient.Sequence-1, "bad sequence number")
|
||||
_, ok = resp.Data[th.BasicUser2.Id]
|
||||
require.False(t, ok, "should not have had user status")
|
||||
|
||||
stop := make(chan bool)
|
||||
onlineHit := false
|
||||
@@ -449,12 +385,8 @@ func TestWebSocketStatuses(t *testing.T) {
|
||||
|
||||
stop <- true
|
||||
|
||||
if !onlineHit {
|
||||
t.Fatal("didn't get online event")
|
||||
}
|
||||
if !awayHit {
|
||||
t.Fatal("didn't get away event")
|
||||
}
|
||||
require.True(t, onlineHit, "didn't get online event")
|
||||
require.True(t, awayHit, "didn't get away event")
|
||||
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
assert.Equal(t, len(roles1), len(roleNames))
|
||||
|
||||
expected1 := map[string][]string{
|
||||
"channel_user": []string{
|
||||
"channel_user": {
|
||||
model.PERMISSION_READ_CHANNEL.Id,
|
||||
model.PERMISSION_ADD_REACTION.Id,
|
||||
model.PERMISSION_REMOVE_REACTION.Id,
|
||||
@@ -86,10 +86,10 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_POST.Id,
|
||||
model.PERMISSION_EDIT_POST.Id,
|
||||
},
|
||||
"channel_admin": []string{
|
||||
"channel_admin": {
|
||||
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
|
||||
},
|
||||
"team_user": []string{
|
||||
"team_user": {
|
||||
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
@@ -99,13 +99,13 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_INVITE_USER.Id,
|
||||
model.PERMISSION_ADD_USER_TO_TEAM.Id,
|
||||
},
|
||||
"team_post_all": []string{
|
||||
"team_post_all": {
|
||||
model.PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
"team_post_all_public": []string{
|
||||
"team_post_all_public": {
|
||||
model.PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
"team_admin": []string{
|
||||
"team_admin": {
|
||||
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
|
||||
model.PERMISSION_MANAGE_TEAM.Id,
|
||||
model.PERMISSION_IMPORT_TEAM.Id,
|
||||
@@ -120,7 +120,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_POST.Id,
|
||||
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||
},
|
||||
"system_user": []string{
|
||||
"system_user": {
|
||||
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
@@ -128,18 +128,18 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
model.PERMISSION_CREATE_TEAM.Id,
|
||||
},
|
||||
"system_post_all": []string{
|
||||
"system_post_all": {
|
||||
model.PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
"system_post_all_public": []string{
|
||||
"system_post_all_public": {
|
||||
model.PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
"system_user_access_token": []string{
|
||||
"system_user_access_token": {
|
||||
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
|
||||
model.PERMISSION_READ_USER_ACCESS_TOKEN.Id,
|
||||
model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
|
||||
},
|
||||
"system_admin": []string{
|
||||
"system_admin": {
|
||||
model.PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
|
||||
model.PERMISSION_MANAGE_SYSTEM.Id,
|
||||
model.PERMISSION_MANAGE_ROLES.Id,
|
||||
@@ -254,7 +254,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
|
||||
// Check the role permissions.
|
||||
expected2 := map[string][]string{
|
||||
"channel_user": []string{
|
||||
"channel_user": {
|
||||
model.PERMISSION_READ_CHANNEL.Id,
|
||||
model.PERMISSION_ADD_REACTION.Id,
|
||||
model.PERMISSION_REMOVE_REACTION.Id,
|
||||
@@ -269,10 +269,10 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_POST.Id,
|
||||
model.PERMISSION_EDIT_POST.Id,
|
||||
},
|
||||
"channel_admin": []string{
|
||||
"channel_admin": {
|
||||
model.PERMISSION_MANAGE_CHANNEL_ROLES.Id,
|
||||
},
|
||||
"team_user": []string{
|
||||
"team_user": {
|
||||
model.PERMISSION_LIST_TEAM_CHANNELS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_CHANNELS.Id,
|
||||
model.PERMISSION_READ_PUBLIC_CHANNEL.Id,
|
||||
@@ -282,13 +282,13 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_INVITE_USER.Id,
|
||||
model.PERMISSION_ADD_USER_TO_TEAM.Id,
|
||||
},
|
||||
"team_post_all": []string{
|
||||
"team_post_all": {
|
||||
model.PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
"team_post_all_public": []string{
|
||||
"team_post_all_public": {
|
||||
model.PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
"team_admin": []string{
|
||||
"team_admin": {
|
||||
model.PERMISSION_REMOVE_USER_FROM_TEAM.Id,
|
||||
model.PERMISSION_MANAGE_TEAM.Id,
|
||||
model.PERMISSION_IMPORT_TEAM.Id,
|
||||
@@ -305,7 +305,7 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_DELETE_POST.Id,
|
||||
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||
},
|
||||
"system_user": []string{
|
||||
"system_user": {
|
||||
model.PERMISSION_LIST_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_JOIN_PUBLIC_TEAMS.Id,
|
||||
model.PERMISSION_CREATE_DIRECT_CHANNEL.Id,
|
||||
@@ -313,18 +313,18 @@ func TestDoAdvancedPermissionsMigration(t *testing.T) {
|
||||
model.PERMISSION_VIEW_MEMBERS.Id,
|
||||
model.PERMISSION_CREATE_TEAM.Id,
|
||||
},
|
||||
"system_post_all": []string{
|
||||
"system_post_all": {
|
||||
model.PERMISSION_CREATE_POST.Id,
|
||||
},
|
||||
"system_post_all_public": []string{
|
||||
"system_post_all_public": {
|
||||
model.PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||
},
|
||||
"system_user_access_token": []string{
|
||||
"system_user_access_token": {
|
||||
model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id,
|
||||
model.PERMISSION_READ_USER_ACCESS_TOKEN.Id,
|
||||
model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
|
||||
},
|
||||
"system_admin": []string{
|
||||
"system_admin": {
|
||||
model.PERMISSION_ASSIGN_SYSTEM_ADMIN_ROLE.Id,
|
||||
model.PERMISSION_MANAGE_SYSTEM.Id,
|
||||
model.PERMISSION_MANAGE_ROLES.Id,
|
||||
|
||||
@@ -1525,7 +1525,10 @@ func (a *App) LeaveChannel(channelId string, userId string) *model.AppError {
|
||||
func (a *App) postLeaveChannelMessage(user *model.User, channel *model.Channel) *model.AppError {
|
||||
post := &model.Post{
|
||||
ChannelId: channel.Id,
|
||||
Message: fmt.Sprintf(utils.T("api.channel.leave.left"), user.Username),
|
||||
// Message here embeds `@username`, not just `username`, to ensure that mentions
|
||||
// treat this as a username mention even though the user has now left the channel.
|
||||
// The client renders its own system message, ignoring this value altogether.
|
||||
Message: fmt.Sprintf(utils.T("api.channel.leave.left"), fmt.Sprintf("@%s", user.Username)),
|
||||
Type: model.POST_LEAVE_CHANNEL,
|
||||
UserId: user.Id,
|
||||
Props: model.StringInterface{
|
||||
@@ -1595,7 +1598,10 @@ func (a *App) postAddToTeamMessage(user *model.User, addedUser *model.User, chan
|
||||
func (a *App) postRemoveFromChannelMessage(removerUserId string, removedUser *model.User, channel *model.Channel) *model.AppError {
|
||||
post := &model.Post{
|
||||
ChannelId: channel.Id,
|
||||
Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), removedUser.Username),
|
||||
// Message here embeds `@username`, not just `username`, to ensure that mentions
|
||||
// treat this as a username mention even though the user has now left the channel.
|
||||
// The client renders its own system message, ignoring this value altogether.
|
||||
Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), fmt.Sprintf("@%s", removedUser.Username)),
|
||||
Type: model.POST_REMOVE_FROM_CHANNEL,
|
||||
UserId: removerUserId,
|
||||
Props: model.StringInterface{
|
||||
|
||||
@@ -39,8 +39,13 @@ func GetCommandProvider(name string) CommandProvider {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) CreateCommandPost(post *model.Post, teamId string, response *model.CommandResponse) (*model.Post, *model.AppError) {
|
||||
func (a *App) CreateCommandPost(post *model.Post, teamId string, response *model.CommandResponse, skipSlackParsing bool) (*model.Post, *model.AppError) {
|
||||
if skipSlackParsing {
|
||||
post.Message = response.Text
|
||||
} else {
|
||||
post.Message = model.ParseSlackLinksToMarkdown(response.Text)
|
||||
}
|
||||
|
||||
post.CreateAt = model.GetMillis()
|
||||
|
||||
if strings.HasPrefix(post.Type, model.POST_SYSTEM_MESSAGE_PREFIX) {
|
||||
@@ -430,11 +435,16 @@ func (a *App) HandleCommandResponsePost(command *model.Command, args *model.Comm
|
||||
post.AddProp("from_webhook", "true")
|
||||
}
|
||||
|
||||
// Do not process text if this is a code block
|
||||
skipSlackParsing := command.Trigger == "code"
|
||||
|
||||
// Process Slack text replacements
|
||||
if !skipSlackParsing {
|
||||
response.Text = a.ProcessSlackText(response.Text)
|
||||
response.Attachments = a.ProcessSlackAttachments(response.Attachments)
|
||||
}
|
||||
|
||||
if _, err := a.CreateCommandPost(post, args.TeamId, response); err != nil {
|
||||
if _, err := a.CreateCommandPost(post, args.TeamId, response, skipSlackParsing); err != nil {
|
||||
return post, err
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ func TestCreateCommandPost(t *testing.T) {
|
||||
Text: "some message",
|
||||
}
|
||||
|
||||
_, err := th.App.CreateCommandPost(post, th.BasicTeam.Id, resp)
|
||||
skipSlackParsing := false
|
||||
_, err := th.App.CreateCommandPost(post, th.BasicTeam.Id, resp, skipSlackParsing)
|
||||
if err == nil || err.Id != "api.context.invalid_param.app_error" {
|
||||
t.Fatal("should have failed - bad post type")
|
||||
}
|
||||
@@ -188,7 +189,7 @@ func TestHandleCommandResponsePost(t *testing.T) {
|
||||
|
||||
// Test Slack attachments text conversion.
|
||||
resp.Attachments = []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: "<!here>",
|
||||
},
|
||||
}
|
||||
@@ -205,7 +206,23 @@ func TestHandleCommandResponsePost(t *testing.T) {
|
||||
if err == nil || err.Id != "api.command.command_post.forbidden.app_error" {
|
||||
t.Fatal("should have failed - forbidden channel post")
|
||||
}
|
||||
|
||||
// Test that /code text is not converted with the Slack text conversion.
|
||||
command.Trigger = "code"
|
||||
resp.ChannelId = ""
|
||||
resp.Text = "<test.com|test website>"
|
||||
resp.Attachments = []*model.SlackAttachment{
|
||||
{
|
||||
Text: "<!here>",
|
||||
},
|
||||
}
|
||||
post, err = th.App.HandleCommandResponsePost(command, args, resp, builtIn)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, resp.Text, post.Message, "/code text should not be converted to Slack links")
|
||||
assert.Equal(t, "<!here>", resp.Attachments[0].Text)
|
||||
}
|
||||
|
||||
func TestHandleCommandResponse(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
@@ -240,10 +257,10 @@ func TestHandleCommandResponse(t *testing.T) {
|
||||
resp = &model.CommandResponse{
|
||||
Text: "message 1",
|
||||
ExtraResponses: []*model.CommandResponse{
|
||||
&model.CommandResponse{
|
||||
{
|
||||
Text: "message 2",
|
||||
},
|
||||
&model.CommandResponse{
|
||||
{
|
||||
Type: model.POST_SYSTEM_GENERIC,
|
||||
Text: "message 3",
|
||||
},
|
||||
@@ -257,8 +274,8 @@ func TestHandleCommandResponse(t *testing.T) {
|
||||
|
||||
resp = &model.CommandResponse{
|
||||
ExtraResponses: []*model.CommandResponse{
|
||||
&model.CommandResponse{},
|
||||
&model.CommandResponse{},
|
||||
{},
|
||||
{},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -300,6 +300,7 @@ func (a *App) trackConfig() {
|
||||
"disable_bots_when_owner_is_deactivated": *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated,
|
||||
"enable_bot_account_creation": *cfg.ServiceSettings.EnableBotAccountCreation,
|
||||
"enable_svgs": *cfg.ServiceSettings.EnableSVGs,
|
||||
"enable_latex": *cfg.ServiceSettings.EnableLatex,
|
||||
})
|
||||
|
||||
a.SendDiagnostic(TRACK_CONFIG_TEAM, map[string]interface{}{
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
func TestPluginSetting(t *testing.T) {
|
||||
settings := &model.PluginSettings{
|
||||
Plugins: map[string]map[string]interface{}{
|
||||
"test": map[string]interface{}{
|
||||
"test": {
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
@@ -31,10 +31,10 @@ func TestPluginSetting(t *testing.T) {
|
||||
|
||||
func TestPluginActivated(t *testing.T) {
|
||||
states := map[string]*model.PluginState{
|
||||
"foo": &model.PluginState{
|
||||
"foo": {
|
||||
Enable: true,
|
||||
},
|
||||
"bar": &model.PluginState{
|
||||
"bar": {
|
||||
Enable: false,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -64,11 +64,11 @@ func TestHandleNewNotifications(t *testing.T) {
|
||||
job.Add(&model.User{Id: id1}, &model.Post{UserId: id1, Message: "test4"}, &model.Team{Name: "team"})
|
||||
job.Add(&model.User{Id: id2}, &model.Post{UserId: id1, Message: "test5"}, &model.Team{Name: "team"})
|
||||
job.handleNewNotifications()
|
||||
assert.Equal(t, job.pendingNotifications[id1][0].post.Message, "test1", "incorrect order of received posts for user1");
|
||||
assert.Equal(t, job.pendingNotifications[id1][1].post.Message, "test2", "incorrect order of received posts for user1");
|
||||
assert.Equal(t, job.pendingNotifications[id1][2].post.Message, "test4", "incorrect order of received posts for user1");
|
||||
assert.Equal(t, job.pendingNotifications[id2][0].post.Message, "test3", "incorrect order of received posts for user2");
|
||||
assert.Equal(t, job.pendingNotifications[id2][1].post.Message, "test5", "incorrect order of received posts for user2");
|
||||
assert.Equal(t, job.pendingNotifications[id1][0].post.Message, "test1", "incorrect order of received posts for user1")
|
||||
assert.Equal(t, job.pendingNotifications[id1][1].post.Message, "test2", "incorrect order of received posts for user1")
|
||||
assert.Equal(t, job.pendingNotifications[id1][2].post.Message, "test4", "incorrect order of received posts for user1")
|
||||
assert.Equal(t, job.pendingNotifications[id2][0].post.Message, "test3", "incorrect order of received posts for user2")
|
||||
assert.Equal(t, job.pendingNotifications[id2][1].post.Message, "test5", "incorrect order of received posts for user2")
|
||||
}
|
||||
|
||||
func TestCheckPendingNotifications(t *testing.T) {
|
||||
|
||||
@@ -11,6 +11,10 @@ func (a *App) GetGroup(id string) (*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().Get(id)
|
||||
}
|
||||
|
||||
func (a *App) GetGroupByName(name string) (*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().GetByName(name)
|
||||
}
|
||||
|
||||
func (a *App) GetGroupByRemoteID(remoteID string, groupSource model.GroupSource) (*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().GetByRemoteID(remoteID, groupSource)
|
||||
}
|
||||
@@ -19,6 +23,10 @@ func (a *App) GetGroupsBySource(groupSource model.GroupSource) ([]*model.Group,
|
||||
return a.Srv.Store.Group().GetAllBySource(groupSource)
|
||||
}
|
||||
|
||||
func (a *App) GetGroupsByUserId(userId string) ([]*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().GetByUser(userId)
|
||||
}
|
||||
|
||||
func (a *App) CreateGroup(group *model.Group) (*model.Group, *model.AppError) {
|
||||
return a.Srv.Store.Group().Create(group)
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@ func TestImportValidateUserImportData(t *testing.T) {
|
||||
|
||||
data.Username = ptrStr("i am a username with spaces and !!!")
|
||||
err = validateUserImportData(&data)
|
||||
require.NotNil(t, err, "Validation should have failed due to invalid characters in Username.");
|
||||
require.NotNil(t, err, "Validation should have failed due to invalid characters in Username.")
|
||||
|
||||
data.Username = ptrStr("bob")
|
||||
|
||||
@@ -759,7 +759,6 @@ func TestImportValidateReactionImportData(t *testing.T) {
|
||||
err = validateReactionImportData(&data, parentCreateAt)
|
||||
require.NotNil(t, err, "Should have failed due to missing required property.")
|
||||
|
||||
|
||||
data = ReactionImportData{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
@@ -938,13 +937,13 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
require.NotNil(t, err, "Should have failed due to 0 create-at value.")
|
||||
|
||||
// Test with valid all optional parameters.
|
||||
reactions := []ReactionImportData{ReactionImportData{
|
||||
reactions := []ReactionImportData{{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}}
|
||||
|
||||
replies := []ReplyImportData{ReplyImportData{
|
||||
replies := []ReplyImportData{{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
@@ -1240,13 +1239,13 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
require.Nil(t, err, "Validation should succeed with post flagged by members")
|
||||
|
||||
// Test with valid all optional parameters.
|
||||
reactions := []ReactionImportData{ReactionImportData{
|
||||
reactions := []ReactionImportData{{
|
||||
User: ptrStr("username"),
|
||||
EmojiName: ptrStr("emoji"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}}
|
||||
|
||||
replies := []ReplyImportData{ReplyImportData{
|
||||
replies := []ReplyImportData{{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
|
||||
@@ -52,7 +52,7 @@ func (a *App) GetLdapGroup(ldapGroupID string) (*model.Group, *model.AppError) {
|
||||
}
|
||||
} else {
|
||||
ae := model.NewAppError("GetLdapGroup", "ent.ldap.app_error", nil, "", http.StatusNotImplemented)
|
||||
mlog.Error(fmt.Sprintf("%v", ae.Error()))
|
||||
mlog.Error("Unable to use ldap", mlog.String("ldap_group_id", ldapGroupID), mlog.Err(ae))
|
||||
return nil, ae
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func (a *App) GetAllLdapGroupsPage(page int, perPage int, opts model.LdapGroupSe
|
||||
}
|
||||
} else {
|
||||
ae := model.NewAppError("GetAllLdapGroupsPage", "ent.ldap.app_error", nil, "", http.StatusNotImplemented)
|
||||
mlog.Error(fmt.Sprintf("%v", ae.Error()))
|
||||
mlog.Error("Unable to use ldap", mlog.Err(ae))
|
||||
return nil, 0, ae
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +162,7 @@ func (a *App) DoLogin(w http.ResponseWriter, r *http.Request, user *model.User,
|
||||
}
|
||||
|
||||
w.Header().Set(model.HEADER_TOKEN, session.Token)
|
||||
a.Session = *session
|
||||
|
||||
if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil {
|
||||
a.Srv.Go(func() {
|
||||
|
||||
@@ -95,9 +95,9 @@ func (a *App) DoEmojisPermissionsMigration() {
|
||||
return
|
||||
}
|
||||
|
||||
var role *model.Role = nil
|
||||
var systemAdminRole *model.Role = nil
|
||||
var err *model.AppError = nil
|
||||
var role *model.Role
|
||||
var systemAdminRole *model.Role
|
||||
var err *model.AppError
|
||||
|
||||
mlog.Info("Migrating emojis config to database.")
|
||||
switch *a.Config().ServiceSettings.DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation {
|
||||
|
||||
@@ -100,7 +100,7 @@ func (a *App) sendNotificationEmail(notification *postNotification, user *model.
|
||||
|
||||
a.Srv.Go(func() {
|
||||
if err := a.SendNotificationMail(user.Email, html.UnescapeString(subjectText), bodyText); err != nil {
|
||||
mlog.Error(fmt.Sprint("Error to send the email", user.Email, err))
|
||||
mlog.Error("Error while sending the email", mlog.String("email", user.Email), mlog.Err(err))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -320,7 +320,7 @@ func (a *App) GetMessageForNotification(post *model.Post, translateFunc i18n.Tra
|
||||
// extract the filenames from their paths and determine what type of files are attached
|
||||
infos, err := a.Srv.Store.FileInfo().GetForPost(post.Id, true, false, true)
|
||||
if err != nil {
|
||||
mlog.Warn(fmt.Sprintf("Encountered error when getting files for notification message, post_id=%v, err=%v", post.Id, err), mlog.String("post_id", post.Id))
|
||||
mlog.Warn("Encountered error when getting files for notification message", mlog.String("post_id", post.Id), mlog.Err(err))
|
||||
}
|
||||
|
||||
filenames := make([]string, len(infos))
|
||||
|
||||
@@ -30,7 +30,6 @@ type PushNotificationsHub struct {
|
||||
}
|
||||
|
||||
type PushNotification struct {
|
||||
id string
|
||||
notificationType NotificationType
|
||||
currentSessionId string
|
||||
userId string
|
||||
@@ -368,8 +367,8 @@ func ShouldSendPushNotification(user *model.User, channelNotifyProps model.Strin
|
||||
func DoesNotifyPropsAllowPushNotification(user *model.User, channelNotifyProps model.StringMap, post *model.Post, wasMentioned bool) bool {
|
||||
userNotifyProps := user.NotifyProps
|
||||
userNotify := userNotifyProps[model.PUSH_NOTIFY_PROP]
|
||||
channelNotify, _ := channelNotifyProps[model.PUSH_NOTIFY_PROP]
|
||||
if channelNotify == "" {
|
||||
channelNotify, ok := channelNotifyProps[model.PUSH_NOTIFY_PROP]
|
||||
if !ok || channelNotify == "" {
|
||||
channelNotify = model.CHANNEL_NOTIFY_DEFAULT
|
||||
}
|
||||
|
||||
|
||||
@@ -282,11 +282,7 @@ func getAddManageGuestsPermissionsMigration() permissionsMap {
|
||||
return permissionsMap{
|
||||
permissionTransformation{
|
||||
On: isRole(model.SYSTEM_ADMIN_ROLE_ID),
|
||||
Add: []string{PERMISSION_PROMOTE_GUEST, PERMISSION_DEMOTE_TO_GUEST},
|
||||
},
|
||||
permissionTransformation{
|
||||
On: permissionExists(PERMISSION_INVITE_USER),
|
||||
Add: []string{PERMISSION_INVITE_GUEST},
|
||||
Add: []string{PERMISSION_PROMOTE_GUEST, PERMISSION_DEMOTE_TO_GUEST, PERMISSION_INVITE_GUEST},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,6 +445,18 @@ func (api *PluginAPI) DeleteChannelMember(channelId, userId string) *model.AppEr
|
||||
return api.app.LeaveChannel(channelId, userId)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetGroup(groupId string) (*model.Group, *model.AppError) {
|
||||
return api.app.GetGroup(groupId)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetGroupByName(name string) (*model.Group, *model.AppError) {
|
||||
return api.app.GetGroupByName(name)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetGroupsForUser(userId string) ([]*model.Group, *model.AppError) {
|
||||
return api.app.GetGroupsByUserId(userId)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) CreatePost(post *model.Post) (*model.Post, *model.AppError) {
|
||||
return api.app.CreatePostMissingChannel(post, true)
|
||||
}
|
||||
|
||||
@@ -73,8 +73,6 @@ func (a *App) OverrideIconURLIfEmoji(post *model.Post) {
|
||||
} else {
|
||||
mlog.Warn("Failed to retrieve URL for overriden profile icon (emoji)", mlog.String("emojiName", emojiName), mlog.Err(err))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (a *App) PreparePostForClient(originalPost *model.Post, isNewPost bool, isEditPost bool) *model.Post {
|
||||
@@ -87,6 +85,11 @@ func (a *App) PreparePostForClient(originalPost *model.Post, isNewPost bool, isE
|
||||
|
||||
post.Metadata = &model.PostMetadata{}
|
||||
|
||||
if post.DeleteAt > 0 {
|
||||
// Don't fill out metadata for deleted posts
|
||||
return post
|
||||
}
|
||||
|
||||
// Emojis and reaction counts
|
||||
if emojis, reactions, err := a.getEmojisAndReactionsForPost(post); err != nil {
|
||||
mlog.Warn("Failed to get emojis and reactions for a post", mlog.String("post_id", post.Id), mlog.Err(err))
|
||||
|
||||
@@ -307,18 +307,22 @@ func TestPreparePostForClient(t *testing.T) {
|
||||
t.Run("does not override icon URL", func(t *testing.T) {
|
||||
clientPost := prepare(false, url, emoji)
|
||||
|
||||
s, _ := clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_URL]
|
||||
s, ok := clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_URL]
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, url, s)
|
||||
s, _ = clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_EMOJI]
|
||||
s, ok = clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_EMOJI]
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, emoji, s)
|
||||
})
|
||||
|
||||
t.Run("overrides icon URL", func(t *testing.T) {
|
||||
clientPost := prepare(true, url, emoji)
|
||||
|
||||
s, _ := clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_URL]
|
||||
s, ok := clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_URL]
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, overridenUrl, s)
|
||||
s, _ = clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_EMOJI]
|
||||
s, ok = clientPost.Props[model.POST_PROPS_OVERRIDE_ICON_EMOJI]
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, emoji, s)
|
||||
})
|
||||
|
||||
@@ -477,6 +481,36 @@ func TestPreparePostForClient(t *testing.T) {
|
||||
}, imageDimensions[server.URL+"/test-image1.png"])
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("no metadata for deleted posts", func(t *testing.T) {
|
||||
th := setup()
|
||||
defer th.TearDown()
|
||||
|
||||
fileInfo, err := th.App.DoUploadFile(time.Now(), th.BasicTeam.Id, th.BasicChannel.Id, th.BasicUser.Id, "test.txt", []byte("test"))
|
||||
require.Nil(t, err)
|
||||
|
||||
post, err := th.App.CreatePost(&model.Post{
|
||||
Message: "test",
|
||||
FileIds: []string{fileInfo.Id},
|
||||
UserId: th.BasicUser.Id,
|
||||
ChannelId: th.BasicChannel.Id,
|
||||
}, th.BasicChannel, false)
|
||||
require.Nil(t, err)
|
||||
|
||||
th.AddReactionToPost(post, th.BasicUser, "taco")
|
||||
|
||||
post, err = th.App.DeletePost(post.Id, th.BasicUser.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
// DeleteAt isn't set on the post returned by App.DeletePost
|
||||
post.DeleteAt = model.GetMillis()
|
||||
|
||||
clientPost := th.App.PreparePostForClient(post, false, false)
|
||||
|
||||
assert.NotEqual(t, nil, clientPost.Metadata, "should've populated Metadata“")
|
||||
assert.Nil(t, clientPost.Metadata.Reactions, "should not have populated Reactions")
|
||||
assert.Nil(t, clientPost.Metadata.Files, "should not have populated Files")
|
||||
})
|
||||
}
|
||||
|
||||
func TestPreparePostForClientWithImageProxy(t *testing.T) {
|
||||
|
||||
@@ -633,7 +633,7 @@ func (a *App) OriginChecker() func(*http.Request) bool {
|
||||
|
||||
func (s *Server) checkPushNotificationServerUrl() {
|
||||
notificationServer := *s.Config().EmailSettings.PushNotificationServer
|
||||
if strings.HasPrefix(notificationServer, "http://") == true {
|
||||
if strings.HasPrefix(notificationServer, "http://") {
|
||||
mlog.Warn("Your push notification server is configured with HTTP. For improved security, update to HTTPS in your configuration.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1456,6 +1456,10 @@ func (a *App) PermanentDeleteUser(user *model.User) *model.AppError {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.Srv.Store.Group().PermanentDeleteMembersByUser(user.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.Srv.Store.Post().PermanentDeleteByUser(user.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -331,10 +331,7 @@ func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool {
|
||||
|
||||
// If the event is destined to a specific user
|
||||
if len(msg.Broadcast.UserId) > 0 {
|
||||
if webCon.UserId == msg.Broadcast.UserId {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return webCon.UserId == msg.Broadcast.UserId
|
||||
}
|
||||
|
||||
// if the user is omitted don't send the message
|
||||
@@ -397,10 +394,5 @@ func (webCon *WebConn) IsMemberOfTeam(teamId string) bool {
|
||||
currentSession = session
|
||||
}
|
||||
|
||||
member := currentSession.GetTeamByTeamId(teamId)
|
||||
|
||||
if member != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return currentSession.GetTeamByTeamId(teamId) != nil
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestHubStopWithMultipleConnections(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
s := httptest.NewServer(http.HandlerFunc(dummyWebsocketHandler(t)))
|
||||
s := httptest.NewServer(dummyWebsocketHandler(t))
|
||||
defer s.Close()
|
||||
|
||||
th.App.HubStart()
|
||||
@@ -68,7 +68,7 @@ func TestHubStopRaceCondition(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
s := httptest.NewServer(http.HandlerFunc(dummyWebsocketHandler(t)))
|
||||
s := httptest.NewServer(dummyWebsocketHandler(t))
|
||||
|
||||
th.App.HubStart()
|
||||
wc1 := registerDummyWebConn(t, th.App, s.Listener.Addr(), th.BasicUser.Id)
|
||||
|
||||
@@ -389,13 +389,13 @@ func TestSplitWebhookPost(t *testing.T) {
|
||||
Message: strings.Repeat("本", maxPostSize*3/2),
|
||||
Props: map[string]interface{}{
|
||||
"attachments": []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", 1000),
|
||||
},
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", 2000),
|
||||
},
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", model.POST_PROPS_MAX_USER_RUNES-1000),
|
||||
},
|
||||
},
|
||||
@@ -409,10 +409,10 @@ func TestSplitWebhookPost(t *testing.T) {
|
||||
Message: strings.Repeat("本", maxPostSize/2),
|
||||
Props: map[string]interface{}{
|
||||
"attachments": []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", 1000),
|
||||
},
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", 2000),
|
||||
},
|
||||
},
|
||||
@@ -421,7 +421,7 @@ func TestSplitWebhookPost(t *testing.T) {
|
||||
{
|
||||
Props: map[string]interface{}{
|
||||
"attachments": []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
{
|
||||
Text: strings.Repeat("本", model.POST_PROPS_MAX_USER_RUNES-1000),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -124,7 +124,7 @@ pipeline {
|
||||
withCredentials([usernamePassword(credentialsId: 'matterbuild-docker-hub', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
|
||||
sh 'docker login --username ${DOCKER_USER} --password ${DOCKER_PASS}'
|
||||
sh """
|
||||
export TAG='${env.BRANCH_NAME}.${env.BUILD_NUMBER}.${SERVER_GIT_COMMIT}'
|
||||
export TAG='${env.BRANCH_NAME}'
|
||||
docker build --no-cache --build-arg MM_PACKAGE=https://releases.mattermost.com/mattermost-platform/${env.BRANCH_NAME}/mattermost-enterprise-linux-amd64.tar.gz -t mattermost/mattermost-enterprise-edition:\${TAG} build
|
||||
docker push mattermost/mattermost-enterprise-edition:\${TAG}
|
||||
docker logout
|
||||
@@ -133,6 +133,25 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage ('Build Docker mattermost-team-edition') {
|
||||
agent {
|
||||
label 'default-mm-builder'
|
||||
}
|
||||
steps {
|
||||
dir('src/github.com/mattermost/mattermost-server') {
|
||||
withCredentials([usernamePassword(credentialsId: 'matterbuild-docker-hub', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
|
||||
sh 'docker login --username ${DOCKER_USER} --password ${DOCKER_PASS}'
|
||||
sh """
|
||||
export TAG='${env.BRANCH_NAME}'
|
||||
docker build --no-cache --build-arg MM_PACKAGE=https://releases.mattermost.com/mattermost-platform/${env.BRANCH_NAME}/mattermost-team-linux-amd64.tar.gz -t mattermost/mattermost-team-edition:\${TAG} build
|
||||
docker push mattermost/mattermost-team-edition:\${TAG}
|
||||
docker logout
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
|
||||
@@ -86,17 +86,17 @@ func TestListChannels(t *testing.T) {
|
||||
|
||||
output := th.CheckCommand(t, "channel", "list", th.BasicTeam.Name)
|
||||
|
||||
require.True(t, strings.Contains(string(output), "town-square"), "should have channels")
|
||||
require.True(t, strings.Contains(output, "town-square"), "should have channels")
|
||||
|
||||
require.True(t, strings.Contains(string(output), channel.Name+" (archived)"), "should have archived channel")
|
||||
require.True(t, strings.Contains(output, channel.Name+" (archived)"), "should have archived channel")
|
||||
|
||||
require.True(t, strings.Contains(string(output), privateChannel.Name+" (private)"), "should have private channel")
|
||||
require.True(t, strings.Contains(output, privateChannel.Name+" (private)"), "should have private channel")
|
||||
|
||||
th.Client.Must(th.Client.DeleteChannel(privateChannel.Id))
|
||||
|
||||
output = th.CheckCommand(t, "channel", "list", th.BasicTeam.Name)
|
||||
|
||||
require.True(t, strings.Contains(string(output), privateChannel.Name+" (archived) (private)"), "should have a channel both archived and private")
|
||||
require.True(t, strings.Contains(output, privateChannel.Name+" (archived) (private)"), "should have a channel both archived and private")
|
||||
}
|
||||
|
||||
func TestRestoreChannel(t *testing.T) {
|
||||
|
||||
@@ -153,7 +153,7 @@ func createCommandCmdF(command *cobra.Command, args []string) error {
|
||||
autocompleteHint, _ := command.Flags().GetString("autocompleteHint")
|
||||
post, errp := command.Flags().GetBool("post")
|
||||
method := "P"
|
||||
if errp != nil || post == false {
|
||||
if errp != nil || !post {
|
||||
method = "G"
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ func modifyCommandCmdF(command *cobra.Command, args []string) error {
|
||||
|
||||
post, err := command.Flags().GetBool("post")
|
||||
method := "P"
|
||||
if err != nil || post == false {
|
||||
if err != nil || !post {
|
||||
method = "G"
|
||||
}
|
||||
modifiedCommand.Method = method
|
||||
|
||||
@@ -119,14 +119,12 @@ func TestCreateCommand(t *testing.T) {
|
||||
require.Nil(t, response.Error, "Failed to list commands")
|
||||
|
||||
if testCase.ExpectedErr == "" {
|
||||
require.NotEmpty(t, cmds, "Failed to create command")
|
||||
require.Equal(t, "testcmd", cmds[0].Trigger)
|
||||
assert.Contains(t, string(actual), "PASS")
|
||||
assert.NotZero(t, len(cmds), "Failed to create command")
|
||||
assert.Equal(t, cmds[0].Trigger, "testcmd", "Failed to create command")
|
||||
assert.Contains(t, actual, "PASS")
|
||||
} else {
|
||||
if len(cmds) > 1 {
|
||||
require.Fail(t, "Created command that shouldn't have been created")
|
||||
}
|
||||
assert.Contains(t, string(actual), testCase.ExpectedErr)
|
||||
assert.LessOrEqual(t, len(cmds), 1, "Created command that shouldn't have been created")
|
||||
assert.Contains(t, actual, testCase.ExpectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -161,11 +159,11 @@ func TestShowCommand(t *testing.T) {
|
||||
assert.Equal(t, len(commands), 1)
|
||||
|
||||
output := th.CheckCommand(t, "command", "show", command.Id)
|
||||
assert.Contains(t, string(output), command.Id)
|
||||
assert.Contains(t, string(output), command.TeamId)
|
||||
assert.Contains(t, string(output), trigger)
|
||||
assert.Contains(t, string(output), displayName)
|
||||
assert.Contains(t, string(output), user.Username)
|
||||
assert.Contains(t, output, command.Id)
|
||||
assert.Contains(t, output, command.TeamId)
|
||||
assert.Contains(t, output, trigger)
|
||||
assert.Contains(t, output, displayName)
|
||||
assert.Contains(t, output, user.Username)
|
||||
})
|
||||
|
||||
t.Run("not existing command", func(t *testing.T) {
|
||||
@@ -255,14 +253,14 @@ func TestModifyCommand(t *testing.T) {
|
||||
t.Run("command not specified", func(t *testing.T) {
|
||||
args := []string{"command", "", command.Id, "--trigger-word", "sometrigger"}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
assert.Contains(t, string(output), "Error: unknown flag: --trigger-word")
|
||||
assert.Contains(t, output, "Error: unknown flag: --trigger-word")
|
||||
})
|
||||
|
||||
t.Run("modify command unchanged", func(t *testing.T) {
|
||||
args := []string{"command", "modify", command.Id}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
cmd, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd.DisplayName, command.DisplayName)
|
||||
assert.Equal(t, cmd.Method, command.Method)
|
||||
assert.Equal(t, cmd.TeamId, command.TeamId)
|
||||
@@ -279,7 +277,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
t.Run("misspelled flag", func(t *testing.T) {
|
||||
args := []string{"command", "", command.Id, "--trigger-wor", "sometrigger"}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
assert.Contains(t, string(output), "Error: unknown flag:")
|
||||
assert.Contains(t, output, "Error: unknown flag:")
|
||||
})
|
||||
|
||||
t.Run("multiple flags nil error", func(t *testing.T) {
|
||||
@@ -289,7 +287,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
args := []string{"command", "modify", command.Id, "--trigger-word", testName, "--url", testURL, "--description", testDescription}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
cmd, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd.Trigger, testName)
|
||||
assert.Equal(t, cmd.URL, testURL)
|
||||
assert.Equal(t, cmd.Description, testDescription)
|
||||
@@ -300,7 +298,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
args := []string{"command", "modify", command.Id, "--title", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
cmd, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd.DisplayName, testVal)
|
||||
})
|
||||
|
||||
@@ -309,7 +307,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
args := []string{"command", "modify", command.Id, "--description", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
cmd, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd.Description, testVal)
|
||||
})
|
||||
|
||||
@@ -318,7 +316,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
args := []string{"command", "modify", command.Id, "--trigger-word", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
cmd, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd.Trigger, testVal)
|
||||
})
|
||||
|
||||
@@ -326,14 +324,14 @@ func TestModifyCommand(t *testing.T) {
|
||||
testVal := "bad trigger"
|
||||
args := []string{"command", "modify", command.Id, "--trigger-word", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
assert.Contains(t, string(output), "Error: a trigger word must not contain spaces")
|
||||
assert.Contains(t, output, "Error: a trigger word must not contain spaces")
|
||||
})
|
||||
|
||||
t.Run("trigger with leading /", func(t *testing.T) {
|
||||
testVal := "/bad-trigger"
|
||||
args := []string{"command", "modify", command.Id, "--trigger-word", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
assert.Contains(t, string(output), "Error: a trigger word cannot begin with a /")
|
||||
assert.Contains(t, output, "Error: a trigger word cannot begin with a /")
|
||||
})
|
||||
|
||||
t.Run("blank trigger", func(t *testing.T) {
|
||||
@@ -343,7 +341,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
cmd_modified, _ := th.App.GetCommand(command.Id)
|
||||
|
||||
// assert trigger remains unchanged
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd_unmodified.Trigger, cmd_modified.Trigger)
|
||||
})
|
||||
|
||||
@@ -353,7 +351,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
args := []string{"command", "modify", command.Id, "--url", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
cmd, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd.URL, testVal)
|
||||
})
|
||||
|
||||
@@ -364,7 +362,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
cmd_modified, _ := th.App.GetCommand(command.Id)
|
||||
|
||||
//assert URL remains unchanged
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd_unmodified.URL, cmd_modified.URL)
|
||||
})
|
||||
|
||||
@@ -373,7 +371,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
args := []string{"command", "modify", command.Id, "--icon", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
cmd, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd.IconURL, testVal)
|
||||
})
|
||||
|
||||
@@ -382,7 +380,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
args := []string{"command", "modify", command.Id, "--creator", testVal.Username}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
cmd, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd.CreatorId, testVal.Id)
|
||||
})
|
||||
|
||||
@@ -390,14 +388,14 @@ func TestModifyCommand(t *testing.T) {
|
||||
testVal := "fakeuser"
|
||||
args := []string{"command", "modify", command.Id, "--creator", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
assert.Contains(t, string(output), "unable to find user")
|
||||
assert.Contains(t, output, "unable to find user")
|
||||
})
|
||||
|
||||
t.Run("creator not admin user", func(t *testing.T) {
|
||||
testVal := user.Username
|
||||
args := []string{"command", "modify", command.Id, "--creator", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
assert.Contains(t, string(output), "the creator must be a user who has permissions to manage slash commands")
|
||||
assert.Contains(t, output, "the creator must be a user who has permissions to manage slash commands")
|
||||
})
|
||||
|
||||
t.Run("response username nil error", func(t *testing.T) {
|
||||
@@ -405,7 +403,7 @@ func TestModifyCommand(t *testing.T) {
|
||||
args := []string{"command", "modify", command.Id, "--response-username", testVal}
|
||||
output, _ := th.RunCommandWithOutput(t, args...)
|
||||
cmd, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output), "PASS")
|
||||
assert.Contains(t, output, "PASS")
|
||||
assert.Equal(t, cmd.Username, testVal)
|
||||
})
|
||||
|
||||
@@ -416,13 +414,13 @@ func TestModifyCommand(t *testing.T) {
|
||||
// set post and check
|
||||
output_set, _ := th.RunCommandWithOutput(t, args_set...)
|
||||
cmd_set, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output_set), "PASS")
|
||||
assert.Contains(t, output_set, "PASS")
|
||||
assert.Equal(t, cmd_set.Method, "P")
|
||||
|
||||
// unset post and check
|
||||
output_unset, _ := th.RunCommandWithOutput(t, args_unset...)
|
||||
cmd_unset, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output_unset), "PASS")
|
||||
assert.Contains(t, output_unset, "PASS")
|
||||
assert.Equal(t, cmd_unset.Method, "G")
|
||||
})
|
||||
|
||||
@@ -433,13 +431,13 @@ func TestModifyCommand(t *testing.T) {
|
||||
// set autocomplete and check
|
||||
output_set, _ := th.RunCommandWithOutput(t, args_set...)
|
||||
cmd_set, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output_set), "PASS")
|
||||
assert.Contains(t, output_set, "PASS")
|
||||
assert.Equal(t, cmd_set.AutoComplete, true)
|
||||
|
||||
// unset autocomplete and check
|
||||
output_unset, _ := th.RunCommandWithOutput(t, args_unset...)
|
||||
cmd_unset, _ := th.App.GetCommand(command.Id)
|
||||
assert.Contains(t, string(output_unset), "PASS")
|
||||
assert.Contains(t, output_unset, "PASS")
|
||||
assert.Equal(t, cmd_unset.AutoComplete, false)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -111,10 +111,10 @@ func TestConfigGet(t *testing.T) {
|
||||
t.Run("check output", func(t *testing.T) {
|
||||
output := th.CheckCommand(t, "config", "get", "MessageExportSettings")
|
||||
|
||||
assert.Contains(t, string(output), "EnableExport")
|
||||
assert.Contains(t, string(output), "ExportFormat")
|
||||
assert.Contains(t, string(output), "DailyRunTime")
|
||||
assert.Contains(t, string(output), "ExportFromTimestamp")
|
||||
assert.Contains(t, output, "EnableExport")
|
||||
assert.Contains(t, output, "ExportFormat")
|
||||
assert.Contains(t, output, "DailyRunTime")
|
||||
assert.Contains(t, output, "ExportFromTimestamp")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -138,33 +138,33 @@ func TestConfigSet(t *testing.T) {
|
||||
t.Run("Error when the wrong value is set", func(t *testing.T) {
|
||||
assert.Error(t, th.RunCommand(t, "config", "set", "EmailSettings.ConnectionSecurity", "invalid-key"))
|
||||
output := th.CheckCommand(t, "config", "get", "EmailSettings.ConnectionSecurity")
|
||||
assert.NotContains(t, string(output), "invalid-key")
|
||||
assert.NotContains(t, output, "invalid-key")
|
||||
})
|
||||
|
||||
t.Run("Error when the parameter of an unknown plugin is set", func(t *testing.T) {
|
||||
output, err := th.RunCommandWithOutput(t, "config", "set", "PluginSettings.Plugins.someplugin", "true")
|
||||
assert.Error(t, err)
|
||||
assert.NotContains(t, string(output), "panic")
|
||||
assert.NotContains(t, output, "panic")
|
||||
})
|
||||
|
||||
t.Run("Error when the wrong locale is set", func(t *testing.T) {
|
||||
th.CheckCommand(t, "config", "set", "LocalizationSettings.DefaultServerLocale", "es")
|
||||
assert.Error(t, th.RunCommand(t, "config", "set", "LocalizationSettings.DefaultServerLocale", "invalid-key"))
|
||||
output := th.CheckCommand(t, "config", "get", "LocalizationSettings.DefaultServerLocale")
|
||||
assert.NotContains(t, string(output), "invalid-key")
|
||||
assert.NotContains(t, string(output), "\"en\"")
|
||||
assert.NotContains(t, output, "invalid-key")
|
||||
assert.NotContains(t, output, "\"en\"")
|
||||
})
|
||||
|
||||
t.Run("Success when a valid value is set", func(t *testing.T) {
|
||||
assert.NoError(t, th.RunCommand(t, "config", "set", "EmailSettings.ConnectionSecurity", "TLS"))
|
||||
output := th.CheckCommand(t, "config", "get", "EmailSettings.ConnectionSecurity")
|
||||
assert.Contains(t, string(output), "TLS")
|
||||
assert.Contains(t, output, "TLS")
|
||||
})
|
||||
|
||||
t.Run("Success when a valid locale is set", func(t *testing.T) {
|
||||
assert.NoError(t, th.RunCommand(t, "config", "set", "LocalizationSettings.DefaultServerLocale", "es"))
|
||||
output := th.CheckCommand(t, "config", "get", "LocalizationSettings.DefaultServerLocale")
|
||||
assert.Contains(t, string(output), "\"es\"")
|
||||
assert.Contains(t, output, "\"es\"")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -339,9 +339,9 @@ func TestConfigShow(t *testing.T) {
|
||||
|
||||
t.Run("successfully dumping config", func(t *testing.T) {
|
||||
output := th.CheckCommand(t, "config", "show")
|
||||
assert.Contains(t, string(output), "SqlSettings")
|
||||
assert.Contains(t, string(output), "MessageExportSettings")
|
||||
assert.Contains(t, string(output), "AnnouncementSettings")
|
||||
assert.Contains(t, output, "SqlSettings")
|
||||
assert.Contains(t, output, "MessageExportSettings")
|
||||
assert.Contains(t, output, "AnnouncementSettings")
|
||||
})
|
||||
|
||||
t.Run("successfully dumping config as json", func(t *testing.T) {
|
||||
|
||||
@@ -114,7 +114,7 @@ func TestChannelGroupStatus(t *testing.T) {
|
||||
|
||||
// get status, should be Disabled
|
||||
output := th.CheckCommand(t, "group", "channel", "status", th.BasicTeam.Name+":"+channel.Name)
|
||||
require.Contains(t, string(output), "Disabled")
|
||||
require.Contains(t, output, "Disabled")
|
||||
|
||||
// add group and enable
|
||||
id := model.NewId()
|
||||
@@ -143,7 +143,7 @@ func TestChannelGroupStatus(t *testing.T) {
|
||||
|
||||
// get status, should be enabled
|
||||
output = th.CheckCommand(t, "group", "channel", "status", th.BasicTeam.Name+":"+channel.Name)
|
||||
require.Contains(t, string(output), "Enabled")
|
||||
require.Contains(t, output, "Enabled")
|
||||
|
||||
// try to get status of nonexistent channel, should fail
|
||||
require.Error(t, th.RunCommand(t, "group", "channel", "status", th.BasicTeam.Name+":"+channel.Name+"asdf"))
|
||||
@@ -204,8 +204,8 @@ func TestChannelGroupList(t *testing.T) {
|
||||
|
||||
// list groups
|
||||
output := th.CheckCommand(t, "group", "channel", "list", th.BasicTeam.Name+":"+channel.Name)
|
||||
require.Contains(t, string(output), g1.DisplayName)
|
||||
require.Contains(t, string(output), g2.DisplayName)
|
||||
require.Contains(t, output, g1.DisplayName)
|
||||
require.Contains(t, output, g2.DisplayName)
|
||||
|
||||
// try to get list of nonexistent channel, should fail
|
||||
require.Error(t, th.RunCommand(t, "group", "channel", "list", th.BasicTeam.Name+":"+channel.Name+"asdf"))
|
||||
@@ -301,7 +301,7 @@ func TestTeamGroupStatus(t *testing.T) {
|
||||
|
||||
// get status, should be Disabled
|
||||
output := th.CheckCommand(t, "group", "team", "status", th.BasicTeam.Name)
|
||||
require.Contains(t, string(output), "Disabled")
|
||||
require.Contains(t, output, "Disabled")
|
||||
|
||||
// add group and enable
|
||||
id := model.NewId()
|
||||
@@ -330,7 +330,7 @@ func TestTeamGroupStatus(t *testing.T) {
|
||||
|
||||
// get status, should be enabled
|
||||
output = th.CheckCommand(t, "group", "team", "status", th.BasicTeam.Name)
|
||||
require.Contains(t, string(output), "Enabled")
|
||||
require.Contains(t, output, "Enabled")
|
||||
|
||||
// try to get status of nonexistent channel, should fail
|
||||
require.Error(t, th.RunCommand(t, "group", "team", "status", th.BasicTeam.Name+"asdf"))
|
||||
@@ -388,8 +388,8 @@ func TestTeamGroupList(t *testing.T) {
|
||||
|
||||
// list groups
|
||||
output := th.CheckCommand(t, "group", "team", "list", th.BasicTeam.Name)
|
||||
require.Contains(t, string(output), g1.DisplayName)
|
||||
require.Contains(t, string(output), g2.DisplayName)
|
||||
require.Contains(t, output, g1.DisplayName)
|
||||
require.Contains(t, output, g2.DisplayName)
|
||||
|
||||
// try to get list of nonexistent team, should fail
|
||||
require.Error(t, th.RunCommand(t, "group", "team", "list", th.BasicTeam.Name+"asdf"))
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
)
|
||||
|
||||
type ServerTestHelper struct {
|
||||
configStore config.Store
|
||||
disableConfigWatch bool
|
||||
interruptChan chan os.Signal
|
||||
originalInterval int
|
||||
|
||||
@@ -89,7 +89,6 @@ func TestChangeUserEmail(t *testing.T) {
|
||||
|
||||
require.Equal(t, user.Email, newEmail, "should've updated to the new email")
|
||||
|
||||
|
||||
// should fail because using an invalid email
|
||||
require.Error(t, th.RunCommand(t, "user", "email", th.BasicUser.Username, "wrong$email.com"))
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
|
||||
props["ExperimentalGroupUnreadChannels"] = *c.ServiceSettings.ExperimentalGroupUnreadChannels
|
||||
props["EnableSVGs"] = strconv.FormatBool(*c.ServiceSettings.EnableSVGs)
|
||||
props["EnableMarketplace"] = strconv.FormatBool(*c.PluginSettings.EnableMarketplace)
|
||||
props["EnableLatex"] = strconv.FormatBool(*c.ServiceSettings.EnableLatex)
|
||||
|
||||
// This setting is only temporary, so keep using the old setting name for the mobile and web apps
|
||||
props["ExperimentalEnablePostMetadata"] = "true"
|
||||
|
||||
@@ -764,7 +764,7 @@ func TestDatabaseStoreLoad(t *testing.T) {
|
||||
|
||||
func TestDatabaseGetFile(t *testing.T) {
|
||||
_, tearDown := setupConfigDatabase(t, minimalConfig, map[string][]byte{
|
||||
"empty-file": []byte{},
|
||||
"empty-file": {},
|
||||
"test-file": []byte("test"),
|
||||
})
|
||||
defer tearDown()
|
||||
|
||||
@@ -282,7 +282,7 @@ func TestMemoryGetFile(t *testing.T) {
|
||||
ms, err := config.NewMemoryStoreWithOptions(&config.MemoryStoreOptions{
|
||||
InitialConfig: minimalConfig,
|
||||
InitialFiles: map[string][]byte{
|
||||
"empty-file": []byte{},
|
||||
"empty-file": {},
|
||||
"test-file": []byte("test"),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -204,7 +204,3 @@ func sToP(s string) *string {
|
||||
func bToP(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
func iToP(i int) *int {
|
||||
return &i
|
||||
}
|
||||
|
||||
@@ -1320,10 +1320,6 @@
|
||||
"id": "api.file.upload_file.storage.app_error",
|
||||
"translation": "Unable to upload file. Image storage is not configured."
|
||||
},
|
||||
{
|
||||
"id": "api.file.upload_file.too_large.app_error",
|
||||
"translation": "Unable to upload file. File is too large."
|
||||
},
|
||||
{
|
||||
"id": "api.file.upload_file.too_large_detailed.app_error",
|
||||
"translation": "Unable to upload file {{.Filename}}. {{.Length}} bytes exceeds the maximum allowed {{.Limit}} bytes."
|
||||
@@ -6134,6 +6130,10 @@
|
||||
"id": "store.sql_group.no_rows_changed",
|
||||
"translation": "no rows changed"
|
||||
},
|
||||
{
|
||||
"id": "store.sql_group.permanent_delete_members_by_user.app_error",
|
||||
"translation": "Unable to remove the group members with UserID \"{{.UserId}}\""
|
||||
},
|
||||
{
|
||||
"id": "store.sql_group.unique_constraint",
|
||||
"translation": "a group with that name already exists"
|
||||
|
||||
@@ -41,7 +41,7 @@ func parseLogMessage(msg string) (result LogEntry, err error) {
|
||||
} else {
|
||||
d, ok := token.(json.Delim)
|
||||
if !ok || d != '{' {
|
||||
return result, errors.New(fmt.Sprintf("input is not a JSON object, found: %v", token))
|
||||
return result, fmt.Errorf("input is not a JSON object, found: %v", token)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ func parseLogMessage(msg string) (result LogEntry, err error) {
|
||||
} else {
|
||||
d, ok := token.(json.Delim)
|
||||
if !ok || d != '}' {
|
||||
return result, errors.New(fmt.Sprintf("failed to read '}', read: %v", token))
|
||||
return result, fmt.Errorf("failed to read '}', read: %v", token)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ type loggerWriter struct {
|
||||
func (l *loggerWriter) Write(p []byte) (int, error) {
|
||||
trimmed := string(bytes.TrimSpace(p))
|
||||
for _, line := range strings.Split(trimmed, "\n") {
|
||||
l.logFunc(string(line))
|
||||
l.logFunc(line)
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ func TestClient4CreatePost(t *testing.T) {
|
||||
post := &Post{
|
||||
Props: map[string]interface{}{
|
||||
"attachments": []*SlackAttachment{
|
||||
&SlackAttachment{
|
||||
{
|
||||
Actions: []*PostAction{
|
||||
&PostAction{
|
||||
{
|
||||
Integration: &PostActionIntegration{
|
||||
Context: map[string]interface{}{
|
||||
"foo": "bar",
|
||||
@@ -37,9 +37,9 @@ func TestClient4CreatePost(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
attachments := PostFromJson(r.Body).Attachments()
|
||||
assert.Equal(t, []*SlackAttachment{
|
||||
&SlackAttachment{
|
||||
{
|
||||
Actions: []*PostAction{
|
||||
&PostAction{
|
||||
{
|
||||
Integration: &PostActionIntegration{
|
||||
Context: map[string]interface{}{
|
||||
"foo": "bar",
|
||||
|
||||
@@ -146,7 +146,7 @@ func TestCommandResponseFromJson(t *testing.T) {
|
||||
&CommandResponse{
|
||||
Text: "message 1",
|
||||
ExtraResponses: []*CommandResponse{
|
||||
&CommandResponse{
|
||||
{
|
||||
Text: "message 2",
|
||||
},
|
||||
},
|
||||
@@ -180,7 +180,7 @@ func TestCommandResponseFromJson(t *testing.T) {
|
||||
},
|
||||
},
|
||||
ExtraResponses: []*CommandResponse{
|
||||
&CommandResponse{
|
||||
{
|
||||
Text: "message 2",
|
||||
Attachments: []*SlackAttachment{
|
||||
{
|
||||
|
||||
@@ -325,6 +325,7 @@ type ServiceSettings struct {
|
||||
DisableBotsWhenOwnerIsDeactivated *bool `restricted:"true"`
|
||||
EnableBotAccountCreation *bool
|
||||
EnableSVGs *bool
|
||||
EnableLatex *bool
|
||||
}
|
||||
|
||||
func (s *ServiceSettings) SetDefaults(isUpdate bool) {
|
||||
@@ -689,6 +690,14 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
|
||||
s.EnableSVGs = NewBool(false)
|
||||
}
|
||||
}
|
||||
|
||||
if s.EnableLatex == nil {
|
||||
if isUpdate {
|
||||
s.EnableLatex = NewBool(true)
|
||||
} else {
|
||||
s.EnableLatex = NewBool(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ClusterSettings struct {
|
||||
@@ -2871,7 +2880,7 @@ func (ss *ServiceSettings) isValid() *AppError {
|
||||
return NewAppError("Config.IsValid", "model.config.is_valid.webserver_security.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if *ss.ConnectionSecurity == CONN_SECURITY_TLS && *ss.UseLetsEncrypt == false {
|
||||
if *ss.ConnectionSecurity == CONN_SECURITY_TLS && !*ss.UseLetsEncrypt {
|
||||
appErr := NewAppError("Config.IsValid", "model.config.is_valid.tls_cert_file.app_error", nil, "", http.StatusBadRequest)
|
||||
|
||||
if *ss.TLSCertFile == "" {
|
||||
|
||||
@@ -186,7 +186,6 @@ func TestConfigIsValidFakeAlgorithm(t *testing.T) {
|
||||
require.Equal(t, "model.config.is_valid.saml_digest_algorithm.app_error", err.Message)
|
||||
*c1.SamlSettings.DigestAlgorithm = temp
|
||||
|
||||
temp = *c1.SamlSettings.SignatureAlgorithm
|
||||
*c1.SamlSettings.SignatureAlgorithm = "Fake Algorithm"
|
||||
err = c1.SamlSettings.isValid()
|
||||
if err == nil {
|
||||
|
||||
@@ -5,6 +5,8 @@ package model
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
_ "image/gif"
|
||||
_ "image/png"
|
||||
"io/ioutil"
|
||||
@@ -22,179 +24,109 @@ func TestFileInfoIsValid(t *testing.T) {
|
||||
Path: "fake/path.png",
|
||||
}
|
||||
|
||||
if err := info.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, info.IsValid())
|
||||
|
||||
info.Id = ""
|
||||
if err := info.IsValid(); err == nil {
|
||||
t.Fatal("empty Id isn't valid")
|
||||
}
|
||||
require.NotNil(t, info.IsValid(), "empty Id isn't valid")
|
||||
|
||||
info.Id = NewId()
|
||||
info.CreateAt = 0
|
||||
if err := info.IsValid(); err == nil {
|
||||
t.Fatal("empty CreateAt isn't valid")
|
||||
}
|
||||
require.NotNil(t, info.IsValid(), "empty CreateAt isn't valid")
|
||||
|
||||
info.CreateAt = 1234
|
||||
info.UpdateAt = 0
|
||||
if err := info.IsValid(); err == nil {
|
||||
t.Fatal("empty UpdateAt isn't valid")
|
||||
}
|
||||
require.NotNil(t, info.IsValid(), "empty UpdateAt isn't valid")
|
||||
|
||||
info.UpdateAt = 1234
|
||||
info.PostId = NewId()
|
||||
if err := info.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, info.IsValid())
|
||||
|
||||
info.Path = ""
|
||||
if err := info.IsValid(); err == nil {
|
||||
t.Fatal("empty Path isn't valid")
|
||||
}
|
||||
require.NotNil(t, info.IsValid(), "empty Path isn't valid")
|
||||
|
||||
info.Path = "fake/path.png"
|
||||
if err := info.IsValid(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, info.IsValid())
|
||||
}
|
||||
|
||||
func TestFileInfoIsImage(t *testing.T) {
|
||||
info := &FileInfo{
|
||||
MimeType: "image/png",
|
||||
}
|
||||
|
||||
if !info.IsImage() {
|
||||
t.Fatal("file is an image")
|
||||
}
|
||||
info := &FileInfo{MimeType: "image/png"}
|
||||
assert.True(t, info.IsImage(), "file is an image")
|
||||
|
||||
info.MimeType = "text/plain"
|
||||
if info.IsImage() {
|
||||
t.Fatal("file is not an image")
|
||||
}
|
||||
assert.False(t, info.IsImage(), "file is not an image")
|
||||
}
|
||||
|
||||
func TestGetInfoForFile(t *testing.T) {
|
||||
fakeFile := make([]byte, 1000)
|
||||
|
||||
if info, err := GetInfoForBytes("file.txt", fakeFile); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if info.Name != "file.txt" {
|
||||
t.Fatalf("Got incorrect filename: %v", info.Name)
|
||||
} else if info.Extension != "txt" {
|
||||
t.Fatalf("Got incorrect extension: %v", info.Extension)
|
||||
} else if info.Size != 1000 {
|
||||
t.Fatalf("Got incorrect size: %v", info.Size)
|
||||
} else if !strings.HasPrefix(info.MimeType, "text/plain") {
|
||||
t.Fatalf("Got incorrect mime type: %v", info.MimeType)
|
||||
} else if info.Width != 0 {
|
||||
t.Fatalf("Got incorrect width: %v", info.Width)
|
||||
} else if info.Height != 0 {
|
||||
t.Fatalf("Got incorrect height: %v", info.Height)
|
||||
} else if info.HasPreviewImage {
|
||||
t.Fatalf("Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
}
|
||||
info, errApp := GetInfoForBytes("file.txt", fakeFile)
|
||||
require.Nil(t, errApp)
|
||||
assert.Equalf(t, info.Name, "file.txt", "Got incorrect filename: %v", info.Name)
|
||||
assert.Equalf(t, info.Extension, "txt", "Got incorrect extension: %v", info.Extension)
|
||||
assert.EqualValuesf(t, info.Size, 1000, "Got incorrect size: %v", info.Size)
|
||||
assert.Truef(t, strings.HasPrefix(info.MimeType, "text/plain"), "Got incorrect mime type: %v", info.MimeType)
|
||||
assert.Equalf(t, info.Width, 0, "Got incorrect width: %v", info.Width)
|
||||
assert.Equalf(t, info.Height, 0, "Got incorrect height: %v", info.Height)
|
||||
assert.Falsef(t, info.HasPreviewImage, "Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
|
||||
pngFile, err := ioutil.ReadFile("../tests/test.png")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to load test.png: %v", err.Error())
|
||||
}
|
||||
if info, err := GetInfoForBytes("test.png", pngFile); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if info.Name != "test.png" {
|
||||
t.Fatalf("Got incorrect filename: %v", info.Name)
|
||||
} else if info.Extension != "png" {
|
||||
t.Fatalf("Got incorrect extension: %v", info.Extension)
|
||||
} else if info.Size != 279591 {
|
||||
t.Fatalf("Got incorrect size: %v", info.Size)
|
||||
} else if info.MimeType != "image/png" {
|
||||
t.Fatalf("Got incorrect mime type: %v", info.MimeType)
|
||||
} else if info.Width != 408 {
|
||||
t.Fatalf("Got incorrect width: %v", info.Width)
|
||||
} else if info.Height != 336 {
|
||||
t.Fatalf("Got incorrect height: %v", info.Height)
|
||||
} else if !info.HasPreviewImage {
|
||||
t.Fatalf("Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
}
|
||||
require.Nilf(t, err, "Failed to load test.png")
|
||||
|
||||
info, err = GetInfoForBytes("test.png", pngFile)
|
||||
require.Nil(t, err)
|
||||
assert.Equalf(t, info.Name, "test.png", "Got incorrect filename: %v", info.Name)
|
||||
assert.Equalf(t, info.Extension, "png", "Got incorrect extension: %v", info.Extension)
|
||||
assert.EqualValues(t, info.Size, 279591, "Got incorrect size: %v", info.Size)
|
||||
assert.Equalf(t, info.MimeType, "image/png", "Got incorrect mime type: %v", info.MimeType)
|
||||
assert.Equalf(t, info.Width, 408, "Got incorrect width: %v", info.Width)
|
||||
assert.Equalf(t, info.Height, 336, "Got incorrect height: %v", info.Height)
|
||||
assert.Truef(t, info.HasPreviewImage, "Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
|
||||
// base 64 encoded version of handtinywhite.gif from http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ever
|
||||
gifFile, _ := base64.StdEncoding.DecodeString("R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=")
|
||||
if info, err := GetInfoForBytes("handtinywhite.gif", gifFile); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if info.Name != "handtinywhite.gif" {
|
||||
t.Fatalf("Got incorrect filename: %v", info.Name)
|
||||
} else if info.Extension != "gif" {
|
||||
t.Fatalf("Got incorrect extension: %v", info.Extension)
|
||||
} else if info.Size != 35 {
|
||||
t.Fatalf("Got incorrect size: %v", info.Size)
|
||||
} else if info.MimeType != "image/gif" {
|
||||
t.Fatalf("Got incorrect mime type: %v", info.MimeType)
|
||||
} else if info.Width != 1 {
|
||||
t.Fatalf("Got incorrect width: %v", info.Width)
|
||||
} else if info.Height != 1 {
|
||||
t.Fatalf("Got incorrect height: %v", info.Height)
|
||||
} else if !info.HasPreviewImage {
|
||||
t.Fatalf("Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
}
|
||||
info, err = GetInfoForBytes("handtinywhite.gif", gifFile)
|
||||
require.Nil(t, err)
|
||||
assert.Equalf(t, info.Name, "handtinywhite.gif", "Got incorrect filename: %v", info.Name)
|
||||
assert.Equalf(t, info.Extension, "gif", "Got incorrect extension: %v", info.Extension)
|
||||
assert.EqualValuesf(t, info.Size, 35, "Got incorrect size: %v", info.Size)
|
||||
assert.Equalf(t, info.MimeType, "image/gif", "Got incorrect mime type: %v", info.MimeType)
|
||||
assert.Equalf(t, info.Width, 1, "Got incorrect width: %v", info.Width)
|
||||
assert.Equalf(t, info.Height, 1, "Got incorrect height: %v", info.Height)
|
||||
assert.Truef(t, info.HasPreviewImage, "Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
|
||||
animatedGifFile, err := ioutil.ReadFile("../tests/testgif.gif")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to load testgif.gif: %v", err.Error())
|
||||
}
|
||||
if info, err := GetInfoForBytes("testgif.gif", animatedGifFile); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if info.Name != "testgif.gif" {
|
||||
t.Fatalf("Got incorrect filename: %v", info.Name)
|
||||
} else if info.Extension != "gif" {
|
||||
t.Fatalf("Got incorrect extension: %v", info.Extension)
|
||||
} else if info.Size != 38689 {
|
||||
t.Fatalf("Got incorrect size: %v", info.Size)
|
||||
} else if info.MimeType != "image/gif" {
|
||||
t.Fatalf("Got incorrect mime type: %v", info.MimeType)
|
||||
} else if info.Width != 118 {
|
||||
t.Fatalf("Got incorrect width: %v", info.Width)
|
||||
} else if info.Height != 118 {
|
||||
t.Fatalf("Got incorrect height: %v", info.Height)
|
||||
} else if info.HasPreviewImage {
|
||||
t.Fatalf("Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
}
|
||||
require.Nilf(t, err, "Failed to load testgif.gif")
|
||||
|
||||
if info, err := GetInfoForBytes("filewithoutextension", fakeFile); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if info.Name != "filewithoutextension" {
|
||||
t.Fatalf("Got incorrect filename: %v", info.Name)
|
||||
} else if info.Extension != "" {
|
||||
t.Fatalf("Got incorrect extension: %v", info.Extension)
|
||||
} else if info.Size != 1000 {
|
||||
t.Fatalf("Got incorrect size: %v", info.Size)
|
||||
} else if info.MimeType != "" {
|
||||
t.Fatalf("Got incorrect mime type: %v", info.MimeType)
|
||||
} else if info.Width != 0 {
|
||||
t.Fatalf("Got incorrect width: %v", info.Width)
|
||||
} else if info.Height != 0 {
|
||||
t.Fatalf("Got incorrect height: %v", info.Height)
|
||||
} else if info.HasPreviewImage {
|
||||
t.Fatalf("Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
}
|
||||
info, err = GetInfoForBytes("testgif.gif", animatedGifFile)
|
||||
require.Nil(t, err)
|
||||
assert.Equalf(t, info.Name, "testgif.gif", "Got incorrect filename: %v", info.Name)
|
||||
assert.Equalf(t, info.Extension, "gif", "Got incorrect extension: %v", info.Extension)
|
||||
assert.EqualValuesf(t, info.Size, 38689, "Got incorrect size: %v", info.Size)
|
||||
assert.Equalf(t, info.MimeType, "image/gif", "Got incorrect mime type: %v", info.MimeType)
|
||||
assert.Equalf(t, info.Width, 118, "Got incorrect width: %v", info.Width)
|
||||
assert.Equalf(t, info.Height, 118, "Got incorrect height: %v", info.Height)
|
||||
assert.Falsef(t, info.HasPreviewImage, "Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
|
||||
info, err = GetInfoForBytes("filewithoutextension", fakeFile)
|
||||
require.Nil(t, err)
|
||||
assert.Equalf(t, info.Name, "filewithoutextension", "Got incorrect filename: %v", info.Name)
|
||||
assert.Equalf(t, info.Extension, "", "Got incorrect extension: %v", info.Extension)
|
||||
assert.EqualValuesf(t, info.Size, 1000, "Got incorrect size: %v", info.Size)
|
||||
assert.Equalf(t, info.MimeType, "", "Got incorrect mime type: %v", info.MimeType)
|
||||
assert.Equalf(t, info.Width, 0, "Got incorrect width: %v", info.Width)
|
||||
assert.Equalf(t, info.Height, 0, "Got incorrect height: %v", info.Height)
|
||||
assert.Falsef(t, info.HasPreviewImage, "Got incorrect has preview image: %v", info.HasPreviewImage)
|
||||
|
||||
// Always make the extension lower case to make it easier to use in other places
|
||||
if info, err := GetInfoForBytes("file.TXT", fakeFile); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if info.Name != "file.TXT" {
|
||||
t.Fatalf("Got incorrect filename: %v", info.Name)
|
||||
} else if info.Extension != "txt" {
|
||||
t.Fatalf("Got incorrect extension: %v", info.Extension)
|
||||
}
|
||||
info, err = GetInfoForBytes("file.TXT", fakeFile)
|
||||
require.Nil(t, err)
|
||||
assert.Equalf(t, info.Name, "file.TXT", "Got incorrect filename: %v", info.Name)
|
||||
assert.Equalf(t, info.Extension, "txt", "Got incorrect extension: %v", info.Extension)
|
||||
|
||||
// Don't error out for image formats we don't support
|
||||
if info, err := GetInfoForBytes("file.tif", fakeFile); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if info.Name != "file.tif" {
|
||||
t.Fatalf("Got incorrect filename: %v", info.Name)
|
||||
} else if info.Extension != "tif" {
|
||||
t.Fatalf("Got incorrect extension: %v", info.Extension)
|
||||
} else if info.MimeType != "image/tiff" && info.MimeType != "image/x-tiff" {
|
||||
t.Fatalf("Got incorrect mime type: %v", info.MimeType)
|
||||
}
|
||||
info, err = GetInfoForBytes("file.tif", fakeFile)
|
||||
require.Nil(t, err)
|
||||
assert.Equalf(t, info.Name, "file.tif", "Got incorrect filename: %v", info.Name)
|
||||
assert.Equalf(t, info.Extension, "tif", "Got incorrect extension: %v", info.Extension)
|
||||
assert.True(t, info.MimeType == "image/x-tiff" || info.MimeType == "image/tiff", "Got incorrect mime type: %v", info.MimeType)
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ func DecodeAndVerifyTriggerId(triggerId string, s *ecdsa.PrivateKey) (string, st
|
||||
R, S *big.Int
|
||||
}
|
||||
|
||||
if _, err := asn1.Unmarshal([]byte(signature), &esig); err != nil {
|
||||
if _, err := asn1.Unmarshal(signature, &esig); err != nil {
|
||||
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.signature_decode_failed", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
|
||||
@@ -305,8 +305,8 @@ func TestTruncateOpenGraph(t *testing.T) {
|
||||
sampleImage("metoo.gif"),
|
||||
sampleImage("fifth.ico"),
|
||||
sampleImage("notme.tiff")},
|
||||
Audios: []*opengraph.Audio{&opengraph.Audio{}},
|
||||
Videos: []*opengraph.Video{&opengraph.Video{}},
|
||||
Audios: []*opengraph.Audio{{}},
|
||||
Videos: []*opengraph.Video{{}},
|
||||
Article: &opengraph.Article{},
|
||||
Book: &opengraph.Book{},
|
||||
Profile: &opengraph.Profile{},
|
||||
|
||||
@@ -130,6 +130,12 @@ type Manifest struct {
|
||||
// A description of what your plugin is and does.
|
||||
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||
|
||||
// HomepageURL is an optional link to learn more about the plugin.
|
||||
HomepageURL string `json:"homepage_url,omitempty" yaml:"homepage_url,omitempty"`
|
||||
|
||||
// SupportURL is an optional URL where plugin issues can be reported.
|
||||
SupportURL string `json:"support_url,omitempty" yaml:"support_url,omitempty"`
|
||||
|
||||
// A relative file path in the bundle that points to the plugins svg icon for use with the Plugin Marketplace.
|
||||
// This should be relative to the root of your bundle and the location of the manifest file. Bitmap image formats are not supported.
|
||||
IconPath string `json:"icon_path,omitempty" yaml:"icon_path,omitempty"`
|
||||
|
||||
@@ -64,6 +64,8 @@ func TestFindManifest(t *testing.T) {
|
||||
func TestManifestUnmarshal(t *testing.T) {
|
||||
expected := Manifest{
|
||||
Id: "theid",
|
||||
HomepageURL: "https://example.com",
|
||||
SupportURL: "https://example.com/support",
|
||||
IconPath: "assets/icon.svg",
|
||||
MinServerVersion: "5.6.0",
|
||||
Server: &ManifestServer{
|
||||
@@ -81,7 +83,7 @@ func TestManifestUnmarshal(t *testing.T) {
|
||||
Header: "theheadertext",
|
||||
Footer: "thefootertext",
|
||||
Settings: []*PluginSetting{
|
||||
&PluginSetting{
|
||||
{
|
||||
Key: "thesetting",
|
||||
DisplayName: "thedisplayname",
|
||||
Type: "dropdown",
|
||||
@@ -89,7 +91,7 @@ func TestManifestUnmarshal(t *testing.T) {
|
||||
RegenerateHelpText: "theregeneratehelptext",
|
||||
Placeholder: "theplaceholder",
|
||||
Options: []*PluginOption{
|
||||
&PluginOption{
|
||||
{
|
||||
DisplayName: "theoptiondisplayname",
|
||||
Value: "thevalue",
|
||||
},
|
||||
@@ -103,6 +105,8 @@ func TestManifestUnmarshal(t *testing.T) {
|
||||
var yamlResult Manifest
|
||||
require.NoError(t, yaml.Unmarshal([]byte(`
|
||||
id: theid
|
||||
homepage_url: https://example.com
|
||||
support_url: https://example.com/support
|
||||
icon_path: assets/icon.svg
|
||||
min_server_version: 5.6.0
|
||||
server:
|
||||
@@ -133,6 +137,8 @@ settings_schema:
|
||||
var jsonResult Manifest
|
||||
require.NoError(t, json.Unmarshal([]byte(`{
|
||||
"id": "theid",
|
||||
"homepage_url": "https://example.com",
|
||||
"support_url": "https://example.com/support",
|
||||
"icon_path": "assets/icon.svg",
|
||||
"min_server_version": "5.6.0",
|
||||
"server": {
|
||||
@@ -226,7 +232,7 @@ func TestManifestJson(t *testing.T) {
|
||||
Header: "theheadertext",
|
||||
Footer: "thefootertext",
|
||||
Settings: []*PluginSetting{
|
||||
&PluginSetting{
|
||||
{
|
||||
Key: "thesetting",
|
||||
DisplayName: "thedisplayname",
|
||||
Type: "dropdown",
|
||||
@@ -234,7 +240,7 @@ func TestManifestJson(t *testing.T) {
|
||||
RegenerateHelpText: "theregeneratehelptext",
|
||||
Placeholder: "theplaceholder",
|
||||
Options: []*PluginOption{
|
||||
&PluginOption{
|
||||
{
|
||||
DisplayName: "theoptiondisplayname",
|
||||
Value: "thevalue",
|
||||
},
|
||||
@@ -293,7 +299,7 @@ func TestManifestClientManifest(t *testing.T) {
|
||||
Header: "theheadertext",
|
||||
Footer: "thefootertext",
|
||||
Settings: []*PluginSetting{
|
||||
&PluginSetting{
|
||||
{
|
||||
Key: "thesetting",
|
||||
DisplayName: "thedisplayname",
|
||||
Type: "dropdown",
|
||||
@@ -301,7 +307,7 @@ func TestManifestClientManifest(t *testing.T) {
|
||||
RegenerateHelpText: "theregeneratehelptext",
|
||||
Placeholder: "theplaceholder",
|
||||
Options: []*PluginOption{
|
||||
&PluginOption{
|
||||
{
|
||||
DisplayName: "theoptiondisplayname",
|
||||
Value: "thevalue",
|
||||
},
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSessionDeepCopy(t *testing.T) {
|
||||
@@ -17,7 +18,7 @@ func TestSessionDeepCopy(t *testing.T) {
|
||||
mapKey := "key"
|
||||
mapValue := "val"
|
||||
|
||||
session := &Session{Id: sessionId, Props: map[string]string{mapKey: mapValue}, TeamMembers: []*TeamMember{&TeamMember{UserId: userId, TeamId: "someteamId"}}}
|
||||
session := &Session{Id: sessionId, Props: map[string]string{mapKey: mapValue}, TeamMembers: []*TeamMember{{UserId: userId, TeamId: "someteamId"}}}
|
||||
|
||||
copySession := session.DeepCopy()
|
||||
copySession.Id = "changed"
|
||||
@@ -45,21 +46,16 @@ func TestSessionJson(t *testing.T) {
|
||||
json := session.ToJson()
|
||||
rsession := SessionFromJson(strings.NewReader(json))
|
||||
|
||||
if rsession.Id != session.Id {
|
||||
t.Fatal("Ids do not match")
|
||||
}
|
||||
require.Equal(t, rsession.Id, session.Id, "Ids do not match")
|
||||
|
||||
session.Sanitize()
|
||||
|
||||
if session.IsExpired() {
|
||||
t.Fatal("Shouldn't expire")
|
||||
}
|
||||
require.False(t, session.IsExpired(), "Shouldn't expire")
|
||||
|
||||
session.ExpiresAt = GetMillis()
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
if !session.IsExpired() {
|
||||
t.Fatal("Should expire")
|
||||
}
|
||||
|
||||
require.True(t, session.IsExpired(), "Should expire")
|
||||
|
||||
session.SetExpireInDays(10)
|
||||
}
|
||||
|
||||
@@ -111,11 +111,7 @@ func (s *SlackAttachment) Equals(input *SlackAttachment) bool {
|
||||
}
|
||||
}
|
||||
|
||||
if s.Timestamp != input.Timestamp {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return s.Timestamp == input.Timestamp
|
||||
}
|
||||
|
||||
type SlackAttachmentField struct {
|
||||
|
||||
@@ -63,7 +63,7 @@ func TestUserPreSave(t *testing.T) {
|
||||
user.PreSave()
|
||||
user.Etag(true, true)
|
||||
assert.NotNil(t, user.Timezone, "Timezone is nil")
|
||||
assert.Equal(t, user.Timezone["useAutomaticTimezone"], "true", "Timezone is not set to default");
|
||||
assert.Equal(t, user.Timezone["useAutomaticTimezone"], "true", "Timezone is not set to default")
|
||||
}
|
||||
|
||||
func TestUserPreUpdate(t *testing.T) {
|
||||
|
||||
@@ -378,6 +378,21 @@ type API interface {
|
||||
// Minimum server version: 5.2
|
||||
UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError)
|
||||
|
||||
// GetGroup gets a group by ID.
|
||||
//
|
||||
// Minimum server version: 5.18
|
||||
GetGroup(groupId string) (*model.Group, *model.AppError)
|
||||
|
||||
// GetGroupByName gets a group by name.
|
||||
//
|
||||
// Minimum server version: 5.18
|
||||
GetGroupByName(name string) (*model.Group, *model.AppError)
|
||||
|
||||
// GetGroupsForUser gets the groups a user is in.
|
||||
//
|
||||
// Minimum server version: 5.18
|
||||
GetGroupsForUser(userId string) ([]*model.Group, *model.AppError)
|
||||
|
||||
// DeleteChannelMember deletes a channel membership for a user.
|
||||
//
|
||||
// Minimum server version: 5.2
|
||||
|
||||
@@ -2498,6 +2498,93 @@ func (s *apiRPCServer) UpdateChannelMemberNotifications(args *Z_UpdateChannelMem
|
||||
return nil
|
||||
}
|
||||
|
||||
type Z_GetGroupArgs struct {
|
||||
A string
|
||||
}
|
||||
|
||||
type Z_GetGroupReturns struct {
|
||||
A *model.Group
|
||||
B *model.AppError
|
||||
}
|
||||
|
||||
func (g *apiRPCClient) GetGroup(groupId string) (*model.Group, *model.AppError) {
|
||||
_args := &Z_GetGroupArgs{groupId}
|
||||
_returns := &Z_GetGroupReturns{}
|
||||
if err := g.client.Call("Plugin.GetGroup", _args, _returns); err != nil {
|
||||
log.Printf("RPC call to GetGroup API failed: %s", err.Error())
|
||||
}
|
||||
return _returns.A, _returns.B
|
||||
}
|
||||
|
||||
func (s *apiRPCServer) GetGroup(args *Z_GetGroupArgs, returns *Z_GetGroupReturns) error {
|
||||
if hook, ok := s.impl.(interface {
|
||||
GetGroup(groupId string) (*model.Group, *model.AppError)
|
||||
}); ok {
|
||||
returns.A, returns.B = hook.GetGroup(args.A)
|
||||
} else {
|
||||
return encodableError(fmt.Errorf("API GetGroup called but not implemented."))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Z_GetGroupByNameArgs struct {
|
||||
A string
|
||||
}
|
||||
|
||||
type Z_GetGroupByNameReturns struct {
|
||||
A *model.Group
|
||||
B *model.AppError
|
||||
}
|
||||
|
||||
func (g *apiRPCClient) GetGroupByName(name string) (*model.Group, *model.AppError) {
|
||||
_args := &Z_GetGroupByNameArgs{name}
|
||||
_returns := &Z_GetGroupByNameReturns{}
|
||||
if err := g.client.Call("Plugin.GetGroupByName", _args, _returns); err != nil {
|
||||
log.Printf("RPC call to GetGroupByName API failed: %s", err.Error())
|
||||
}
|
||||
return _returns.A, _returns.B
|
||||
}
|
||||
|
||||
func (s *apiRPCServer) GetGroupByName(args *Z_GetGroupByNameArgs, returns *Z_GetGroupByNameReturns) error {
|
||||
if hook, ok := s.impl.(interface {
|
||||
GetGroupByName(name string) (*model.Group, *model.AppError)
|
||||
}); ok {
|
||||
returns.A, returns.B = hook.GetGroupByName(args.A)
|
||||
} else {
|
||||
return encodableError(fmt.Errorf("API GetGroupByName called but not implemented."))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Z_GetGroupsForUserArgs struct {
|
||||
A string
|
||||
}
|
||||
|
||||
type Z_GetGroupsForUserReturns struct {
|
||||
A []*model.Group
|
||||
B *model.AppError
|
||||
}
|
||||
|
||||
func (g *apiRPCClient) GetGroupsForUser(userId string) ([]*model.Group, *model.AppError) {
|
||||
_args := &Z_GetGroupsForUserArgs{userId}
|
||||
_returns := &Z_GetGroupsForUserReturns{}
|
||||
if err := g.client.Call("Plugin.GetGroupsForUser", _args, _returns); err != nil {
|
||||
log.Printf("RPC call to GetGroupsForUser API failed: %s", err.Error())
|
||||
}
|
||||
return _returns.A, _returns.B
|
||||
}
|
||||
|
||||
func (s *apiRPCServer) GetGroupsForUser(args *Z_GetGroupsForUserArgs, returns *Z_GetGroupsForUserReturns) error {
|
||||
if hook, ok := s.impl.(interface {
|
||||
GetGroupsForUser(userId string) ([]*model.Group, *model.AppError)
|
||||
}); ok {
|
||||
returns.A, returns.B = hook.GetGroupsForUser(args.A)
|
||||
} else {
|
||||
return encodableError(fmt.Errorf("API GetGroupsForUser called but not implemented."))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Z_DeleteChannelMemberArgs struct {
|
||||
A string
|
||||
B string
|
||||
|
||||
@@ -84,7 +84,7 @@ func TestKVSetJSON(t *testing.T) {
|
||||
|
||||
p := &plugin.HelpersImpl{API: api}
|
||||
|
||||
err := p.KVSetJSON("test-key", func() { return })
|
||||
err := p.KVSetJSON("test-key", func() {})
|
||||
api.AssertExpectations(t)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
@@ -124,7 +124,7 @@ func TestKVCompareAndSetJSON(t *testing.T) {
|
||||
api.AssertNotCalled(t, "KVCompareAndSet")
|
||||
p := &plugin.HelpersImpl{API: api}
|
||||
|
||||
ok, err := p.KVCompareAndSetJSON("test-key", func() { return }, map[string]interface{}{})
|
||||
ok, err := p.KVCompareAndSetJSON("test-key", func() {}, map[string]interface{}{})
|
||||
|
||||
api.AssertExpectations(t)
|
||||
assert.Equal(t, false, ok)
|
||||
@@ -137,7 +137,7 @@ func TestKVCompareAndSetJSON(t *testing.T) {
|
||||
|
||||
p := &plugin.HelpersImpl{API: api}
|
||||
|
||||
ok, err := p.KVCompareAndSetJSON("test-key", map[string]interface{}{}, func() { return })
|
||||
ok, err := p.KVCompareAndSetJSON("test-key", map[string]interface{}{}, func() {})
|
||||
|
||||
api.AssertExpectations(t)
|
||||
assert.False(t, ok)
|
||||
@@ -211,7 +211,7 @@ func TestKVCompareAndDeleteJSON(t *testing.T) {
|
||||
api.AssertNotCalled(t, "KVCompareAndDelete")
|
||||
p := &plugin.HelpersImpl{API: api}
|
||||
|
||||
ok, err := p.KVCompareAndDeleteJSON("test-key", func() { return })
|
||||
ok, err := p.KVCompareAndDeleteJSON("test-key", func() {})
|
||||
|
||||
api.AssertExpectations(t)
|
||||
assert.Equal(t, false, ok)
|
||||
@@ -266,7 +266,7 @@ func TestKVSetWithExpiryJSON(t *testing.T) {
|
||||
|
||||
p := &plugin.HelpersImpl{API: api}
|
||||
|
||||
err := p.KVSetWithExpiryJSON("test-key", func() { return }, 100)
|
||||
err := p.KVSetWithExpiryJSON("test-key", func() {}, 100)
|
||||
|
||||
api.AssertExpectations(t)
|
||||
assert.Error(t, err)
|
||||
|
||||
@@ -996,6 +996,56 @@ func (_m *API) GetFileLink(fileId string) (string, *model.AppError) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetGroup provides a mock function with given fields: groupId
|
||||
func (_m *API) GetGroup(groupId string) (*model.Group, *model.AppError) {
|
||||
ret := _m.Called(groupId)
|
||||
|
||||
var r0 *model.Group
|
||||
if rf, ok := ret.Get(0).(func(string) *model.Group); ok {
|
||||
r0 = rf(groupId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Group)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *model.AppError
|
||||
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
|
||||
r1 = rf(groupId)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*model.AppError)
|
||||
}
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetGroupByName provides a mock function with given fields: name
|
||||
func (_m *API) GetGroupByName(name string) (*model.Group, *model.AppError) {
|
||||
ret := _m.Called(name)
|
||||
|
||||
var r0 *model.Group
|
||||
if rf, ok := ret.Get(0).(func(string) *model.Group); ok {
|
||||
r0 = rf(name)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Group)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *model.AppError
|
||||
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
|
||||
r1 = rf(name)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*model.AppError)
|
||||
}
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetGroupChannel provides a mock function with given fields: userIds
|
||||
func (_m *API) GetGroupChannel(userIds []string) (*model.Channel, *model.AppError) {
|
||||
ret := _m.Called(userIds)
|
||||
@@ -1021,6 +1071,31 @@ func (_m *API) GetGroupChannel(userIds []string) (*model.Channel, *model.AppErro
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetGroupsForUser provides a mock function with given fields: userId
|
||||
func (_m *API) GetGroupsForUser(userId string) ([]*model.Group, *model.AppError) {
|
||||
ret := _m.Called(userId)
|
||||
|
||||
var r0 []*model.Group
|
||||
if rf, ok := ret.Get(0).(func(string) []*model.Group); ok {
|
||||
r0 = rf(userId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Group)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *model.AppError
|
||||
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
|
||||
r1 = rf(userId)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*model.AppError)
|
||||
}
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetLDAPUserAttributes provides a mock function with given fields: userId, attributes
|
||||
func (_m *API) GetLDAPUserAttributes(userId string, attributes []string) (map[string]string, *model.AppError) {
|
||||
ret := _m.Called(userId, attributes)
|
||||
|
||||
@@ -6,6 +6,7 @@ package httpservice
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -35,9 +36,7 @@ func TestHTTPClient(t *testing.T) {
|
||||
} {
|
||||
_, err := c.Get(tc.URL)
|
||||
if !tc.IsInternal {
|
||||
if err != nil {
|
||||
t.Fatal("google is down?")
|
||||
}
|
||||
require.Nil(t, err, "google is down?")
|
||||
} else {
|
||||
allowed := !tc.IsInternal || allowInternal
|
||||
success := err == nil
|
||||
@@ -47,9 +46,7 @@ func TestHTTPClient(t *testing.T) {
|
||||
case *url.Error:
|
||||
success = e.Err != AddressForbidden
|
||||
}
|
||||
if success != allowed {
|
||||
t.Fatalf("failed for %v. allowed: %v, success %v", tc.URL, allowed, success)
|
||||
}
|
||||
require.Equalf(t, success, allowed, "failed for %v. allowed: %v, success %v", tc.URL, allowed, success)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,18 +61,12 @@ func TestHTTPClientWithProxy(t *testing.T) {
|
||||
c.Transport.(*MattermostTransport).Transport.(*http.Transport).Proxy = http.ProxyURL(purl)
|
||||
|
||||
resp, err := c.Get("http://acme.com")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.Nil(t, err)
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(body) != "proxy" {
|
||||
t.FailNow()
|
||||
}
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, "proxy", string(body))
|
||||
}
|
||||
|
||||
func createProxyServer() *httptest.Server {
|
||||
@@ -113,11 +104,14 @@ func TestDialContextFilter(t *testing.T) {
|
||||
return nil, nil
|
||||
}, func(host string) bool { return host == "10.0.0.1" }, func(ip net.IP) bool { return !IsReservedIP(ip) })
|
||||
_, err := filter(context.Background(), "", tc.Addr)
|
||||
switch {
|
||||
case tc.IsValid == (err == AddressForbidden) || (err != nil && err != AddressForbidden):
|
||||
t.Errorf("unexpected err for %v (%v)", tc.Addr, err)
|
||||
case tc.IsValid != didDial:
|
||||
t.Errorf("unexpected didDial for %v", tc.Addr)
|
||||
|
||||
if tc.IsValid {
|
||||
require.Nil(t, err)
|
||||
require.True(t, didDial)
|
||||
} else {
|
||||
require.NotNil(t, err)
|
||||
require.Equal(t, err, AddressForbidden)
|
||||
require.False(t, didDial)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,19 +121,15 @@ func TestUserAgentIsSet(t *testing.T) {
|
||||
defaultUserAgent = testUserAgent
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
ua := req.UserAgent()
|
||||
if ua == "" {
|
||||
t.Error("expected user-agent to be non-empty")
|
||||
}
|
||||
if ua != testUserAgent {
|
||||
t.Errorf("expected user-agent to be %q but was %q", testUserAgent, ua)
|
||||
}
|
||||
assert.NotEqual(t, "", ua, "expected user-agent to be non-empty")
|
||||
assert.Equalf(t, testUserAgent, ua, "expected user-agent to be %q but was %q", testUserAgent, ua)
|
||||
}))
|
||||
defer ts.Close()
|
||||
client := NewHTTPClient(NewTransport(true, nil, nil))
|
||||
req, err := http.NewRequest("GET", ts.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatal("NewRequest failed", err)
|
||||
}
|
||||
|
||||
require.Nil(t, err, "NewRequest failed", err)
|
||||
|
||||
client.Do(req)
|
||||
}
|
||||
|
||||
@@ -164,9 +154,8 @@ func TestIsReservedIP(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := IsReservedIP(tt.ip); got != tt.want {
|
||||
t.Errorf("IsReservedIP() = %v, want %v", got, tt.want)
|
||||
}
|
||||
got := IsReservedIP(tt.ip)
|
||||
assert.Equalf(t, tt.want, got, "IsReservedIP() = %v, want %v", got, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -182,10 +171,8 @@ func TestIsOwnIP(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got, _ := IsOwnIP(tt.ip); got != tt.want {
|
||||
t.Errorf("IsOwnIP() = %v, want %v", got, tt.want)
|
||||
t.Errorf(tt.ip.String())
|
||||
}
|
||||
got, _ := IsOwnIP(tt.ip)
|
||||
assert.Equalf(t, tt.want, got, "IsOwnIP() = %v, want %v for IP %s", got, tt.want, tt.ip.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost-server/mlog"
|
||||
"github.com/mattermost/mattermost-server/services/httpservice"
|
||||
@@ -58,7 +57,7 @@ func makeLocalBackend(proxy *ImageProxy) *LocalBackend {
|
||||
impl.DefaultBaseURL = baseURL
|
||||
}
|
||||
|
||||
impl.Timeout = time.Duration(httpservice.RequestTimeout)
|
||||
impl.Timeout = httpservice.RequestTimeout
|
||||
impl.ContentTypes = imageContentTypes
|
||||
|
||||
return &LocalBackend{
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -29,24 +28,19 @@ func TestMailConnectionFromConfig(t *testing.T) {
|
||||
require.Nil(t, err)
|
||||
|
||||
cfg := fs.Get()
|
||||
conn, err := ConnectToSMTPServer(cfg)
|
||||
require.Nil(t, err, "Should connect to the SMTP Server %v", err)
|
||||
|
||||
if conn, err := ConnectToSMTPServer(cfg); err != nil {
|
||||
t.Log(err)
|
||||
t.Fatal("Should connect to the STMP Server")
|
||||
} else {
|
||||
if _, err1 := NewSMTPClient(conn, cfg); err1 != nil {
|
||||
t.Log(err)
|
||||
t.Fatal("Should get new smtp client")
|
||||
}
|
||||
}
|
||||
_, err = NewSMTPClient(conn, cfg)
|
||||
|
||||
require.Nil(t, err, "Should get new SMTP client")
|
||||
|
||||
*cfg.EmailSettings.SMTPServer = "wrongServer"
|
||||
*cfg.EmailSettings.SMTPPort = "553"
|
||||
|
||||
if _, err := ConnectToSMTPServer(cfg); err == nil {
|
||||
t.Log(err)
|
||||
t.Fatal("Should not to the STMP Server")
|
||||
}
|
||||
_, err = ConnectToSMTPServer(cfg)
|
||||
|
||||
require.NotNil(t, err, "Should not connect to the SMTP Server")
|
||||
}
|
||||
|
||||
func TestMailConnectionAdvanced(t *testing.T) {
|
||||
@@ -55,7 +49,7 @@ func TestMailConnectionAdvanced(t *testing.T) {
|
||||
|
||||
cfg := fs.Get()
|
||||
|
||||
if conn, err := ConnectToSMTPServerAdvanced(
|
||||
conn, err := ConnectToSMTPServerAdvanced(
|
||||
&SmtpConnectionInfo{
|
||||
ConnectionSecurity: *cfg.EmailSettings.ConnectionSecurity,
|
||||
SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
|
||||
@@ -63,11 +57,11 @@ func TestMailConnectionAdvanced(t *testing.T) {
|
||||
SmtpServerHost: *cfg.EmailSettings.SMTPServer,
|
||||
SmtpPort: *cfg.EmailSettings.SMTPPort,
|
||||
},
|
||||
); err != nil {
|
||||
t.Log(err)
|
||||
t.Fatal("Should connect to the STMP Server")
|
||||
} else {
|
||||
if _, err1 := NewSMTPClientAdvanced(
|
||||
)
|
||||
|
||||
require.Nil(t, err, "Should connect to the SMTP Server")
|
||||
|
||||
_, err2 := NewSMTPClientAdvanced(
|
||||
conn,
|
||||
utils.GetHostnameFromSiteURL(*cfg.ServiceSettings.SiteURL),
|
||||
&SmtpConnectionInfo{
|
||||
@@ -80,13 +74,11 @@ func TestMailConnectionAdvanced(t *testing.T) {
|
||||
SmtpUsername: *cfg.EmailSettings.SMTPUsername,
|
||||
SmtpPassword: *cfg.EmailSettings.SMTPPassword,
|
||||
},
|
||||
); err1 != nil {
|
||||
t.Log(err)
|
||||
t.Fatal("Should get new smtp client")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if _, err := ConnectToSMTPServerAdvanced(
|
||||
require.Nil(t, err2, "Should get new SMTP client")
|
||||
|
||||
_, err3 := ConnectToSMTPServerAdvanced(
|
||||
&SmtpConnectionInfo{
|
||||
ConnectionSecurity: *cfg.EmailSettings.ConnectionSecurity,
|
||||
SkipCertVerification: *cfg.EmailSettings.SkipServerCertificateVerification,
|
||||
@@ -94,11 +86,8 @@ func TestMailConnectionAdvanced(t *testing.T) {
|
||||
SmtpServerHost: "wrongServer",
|
||||
SmtpPort: "553",
|
||||
},
|
||||
); err == nil {
|
||||
t.Log(err)
|
||||
t.Fatal("Should not to the STMP Server")
|
||||
}
|
||||
|
||||
)
|
||||
require.NotNil(t, err3, "Should not connect to the SMTP Server")
|
||||
}
|
||||
|
||||
func TestSendMailUsingConfig(t *testing.T) {
|
||||
@@ -116,32 +105,25 @@ func TestSendMailUsingConfig(t *testing.T) {
|
||||
//Delete all the messages before check the sample email
|
||||
DeleteMailBox(emailTo)
|
||||
|
||||
if err := SendMailUsingConfig(emailTo, emailSubject, emailBody, cfg, true); err != nil {
|
||||
t.Log(err)
|
||||
t.Fatal("Should connect to the STMP Server")
|
||||
} else {
|
||||
err2 := SendMailUsingConfig(emailTo, emailSubject, emailBody, cfg, true)
|
||||
require.Nil(t, err2, "Should connect to the SMTP Server")
|
||||
|
||||
//Check if the email was send to the right email address
|
||||
var resultsMailbox JSONMessageHeaderInbucket
|
||||
err := RetryInbucket(5, func() error {
|
||||
err3 := RetryInbucket(5, func() error {
|
||||
var err error
|
||||
resultsMailbox, err = GetMailBox(emailTo)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
t.Log("No email was received, maybe due load on the server. Disabling this verification")
|
||||
}
|
||||
if err == nil && len(resultsMailbox) > 0 {
|
||||
if !strings.ContainsAny(resultsMailbox[0].To[0], emailTo) {
|
||||
t.Fatal("Wrong To recipient")
|
||||
if err3 != nil {
|
||||
t.Log(err3)
|
||||
t.Log("No email was received, maybe due load on the server. Skipping this verification")
|
||||
} else {
|
||||
if resultsEmail, err := GetMessageFromMailbox(emailTo, resultsMailbox[0].ID); err == nil {
|
||||
if !strings.Contains(resultsEmail.Body.Text, emailBody) {
|
||||
t.Log(resultsEmail.Body.Text)
|
||||
t.Fatal("Received message")
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(resultsMailbox) > 0 {
|
||||
require.Contains(t, resultsMailbox[0].To[0], emailTo, "Wrong To: recipient")
|
||||
resultsEmail, err := GetMessageFromMailbox(emailTo, resultsMailbox[0].ID)
|
||||
require.Nil(t, err, "Could not get message from mailbox")
|
||||
require.Contains(t, emailBody, resultsEmail.Body.Text, "Wrong received message %s", resultsEmail.Body.Text)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,9 +281,7 @@ func TestAuthMethods(t *testing.T) {
|
||||
if err != nil {
|
||||
got = err.Error()
|
||||
}
|
||||
if got != test.err {
|
||||
t.Errorf("%d. got error = %q; want %q", i, got, test.err)
|
||||
}
|
||||
assert.True(t, got == test.err, "%d. got error = %q; want %q", i, got, test.err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,11 +55,10 @@ func (s LocalCacheRoleStore) GetByNames(names []string) ([]*model.Role, *model.A
|
||||
|
||||
roles, _ := s.RoleStore.GetByNames(rolesToQuery)
|
||||
|
||||
if roles != nil {
|
||||
for _, role := range roles {
|
||||
s.rootStore.doStandardAddToCache(s.rootStore.roleCache, role.Name, role)
|
||||
}
|
||||
}
|
||||
|
||||
return append(foundRoles, roles...), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1790,7 +1790,7 @@ func (s SqlChannelStore) RemoveAllDeactivatedMembers(channelId string) *model.Ap
|
||||
|
||||
func (s SqlChannelStore) PermanentDeleteMembersByUser(userId string) *model.AppError {
|
||||
if _, err := s.GetMaster().Exec("DELETE FROM ChannelMembers WHERE UserId = :UserId", map[string]interface{}{"UserId": userId}); err != nil {
|
||||
return model.NewAppError("SqlChannelStore.RemoveMember", "store.sql_channel.permanent_delete_members_by_user.app_error", nil, "user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
|
||||
return model.NewAppError("SqlChannelStore.ChannelPermanentDeleteMembersByUser", "store.sql_channel.permanent_delete_members_by_user.app_error", nil, "user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -123,6 +123,18 @@ func (s *SqlGroupStore) Get(groupId string) (*model.Group, *model.AppError) {
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetByName(name string) (*model.Group, *model.AppError) {
|
||||
var group *model.Group
|
||||
if err := s.GetReplica().SelectOne(&group, "SELECT * from UserGroups WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, model.NewAppError("SqlGroupStore.GroupGetByName", "store.sql_group.no_rows", nil, err.Error(), http.StatusNotFound)
|
||||
}
|
||||
return nil, model.NewAppError("SqlGroupStore.GroupGetByName", "store.select_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetByIDs(groupIDs []string) ([]*model.Group, *model.AppError) {
|
||||
var groups []*model.Group
|
||||
query := s.getQueryBuilder().Select("*").From("UserGroups").Where(sq.Eq{"Id": groupIDs})
|
||||
@@ -158,6 +170,26 @@ func (s *SqlGroupStore) GetAllBySource(groupSource model.GroupSource) ([]*model.
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) GetByUser(userId string) ([]*model.Group, *model.AppError) {
|
||||
var groups []*model.Group
|
||||
|
||||
query := `
|
||||
SELECT
|
||||
UserGroups.*
|
||||
FROM
|
||||
GroupMembers
|
||||
JOIN UserGroups ON UserGroups.Id = GroupMembers.GroupId
|
||||
WHERE
|
||||
GroupMembers.DeleteAt = 0
|
||||
AND UserId = :UserId`
|
||||
|
||||
if _, err := s.GetReplica().Select(&groups, query, map[string]interface{}{"UserId": userId}); err != nil {
|
||||
return nil, model.NewAppError("SqlGroupStore.GetByUser", "store.select_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) Update(group *model.Group) (*model.Group, *model.AppError) {
|
||||
var retrievedGroup *model.Group
|
||||
if err := s.GetMaster().SelectOne(&retrievedGroup, "SELECT * FROM UserGroups WHERE Id = :Id", map[string]interface{}{"Id": group.Id}); err != nil {
|
||||
@@ -341,6 +373,13 @@ func (s *SqlGroupStore) DeleteMember(groupID string, userID string) (*model.Grou
|
||||
return retrievedMember, nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) PermanentDeleteMembersByUser(userId string) *model.AppError {
|
||||
if _, err := s.GetMaster().Exec("DELETE FROM GroupMembers WHERE UserId = :UserId", map[string]interface{}{"UserId": userId}); err != nil {
|
||||
return model.NewAppError("SqlGroupStore.GroupPermanentDeleteMembersByUser", "store.sql_group.permanent_delete_members_by_user.app_error", map[string]interface{}{"UserId": userId}, "", http.StatusInternalServerError)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SqlGroupStore) CreateGroupSyncable(groupSyncable *model.GroupSyncable) (*model.GroupSyncable, *model.AppError) {
|
||||
if err := groupSyncable.IsValid(); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -75,19 +75,15 @@ func createChannelMemberHistory(ss store.Store, channelId, userId string) *model
|
||||
}
|
||||
|
||||
func createChannelWithTeamId(ss store.Store, id string) *model.Channel {
|
||||
return createChannel(ss, id, model.NewId());
|
||||
return createChannel(ss, id, model.NewId())
|
||||
}
|
||||
|
||||
func createChannelWithCreatorId(ss store.Store, id string) *model.Channel {
|
||||
return createChannel(ss, model.NewId(), id);
|
||||
return createChannel(ss, model.NewId(), id)
|
||||
}
|
||||
|
||||
func createChannelMemberWithChannelId(ss store.Store, id string) *model.ChannelMember {
|
||||
return createChannelMember(ss, id, model.NewId());
|
||||
}
|
||||
|
||||
func createChannelMemberWithUserId(ss store.Store, id string) *model.ChannelMember {
|
||||
return createChannelMember(ss, model.NewId(), id);
|
||||
return createChannelMember(ss, id, model.NewId())
|
||||
}
|
||||
|
||||
func createCommandWebhook(ss store.Store, commandId, userId, channelId string) *model.CommandWebhook {
|
||||
@@ -192,11 +188,11 @@ func createPost(ss store.Store, channelId, userId, rootId, parentId string) *mod
|
||||
}
|
||||
|
||||
func createPostWithChannelId(ss store.Store, id string) *model.Post {
|
||||
return createPost(ss, id, model.NewId(), "", "");
|
||||
return createPost(ss, id, model.NewId(), "", "")
|
||||
}
|
||||
|
||||
func createPostWithUserId(ss store.Store, id string) *model.Post {
|
||||
return createPost(ss, model.NewId(), id, "", "");
|
||||
return createPost(ss, model.NewId(), id, "", "")
|
||||
}
|
||||
|
||||
func createPreferences(ss store.Store, userId string) *model.Preferences {
|
||||
|
||||
@@ -1346,7 +1346,6 @@ func (s *SqlPostStore) GetOldest() (*model.Post, *model.AppError) {
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) determineMaxPostSize() int {
|
||||
var maxPostSize int = model.POST_MESSAGE_MAX_RUNES_V1
|
||||
var maxPostSizeBytes int32
|
||||
|
||||
if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
|
||||
@@ -1384,7 +1383,7 @@ func (s *SqlPostStore) determineMaxPostSize() int {
|
||||
}
|
||||
|
||||
// Assume a worst-case representation of four bytes per rune.
|
||||
maxPostSize = int(maxPostSizeBytes) / 4
|
||||
maxPostSize := int(maxPostSizeBytes) / 4
|
||||
|
||||
// To maintain backwards compatibility, don't yield a maximum post
|
||||
// size smaller than the previous limit, even though it wasn't
|
||||
|
||||
@@ -699,7 +699,7 @@ func (ss *SqlSupplier) AlterColumnDefaultIfExists(tableName string, columnName s
|
||||
return false
|
||||
}
|
||||
|
||||
var defaultValue = ""
|
||||
var defaultValue string
|
||||
if ss.DriverName() == model.DATABASE_DRIVER_MYSQL {
|
||||
// Some column types in MySQL cannot have defaults, so don't try to configure anything.
|
||||
if mySqlColDefault == nil {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -602,33 +601,6 @@ func UpgradeDatabaseToVersion57(sqlStore SqlStore) {
|
||||
}
|
||||
}
|
||||
|
||||
func getRole(sqlStore SqlStore, name string) (*model.Role, error) {
|
||||
var dbRole Role
|
||||
|
||||
if err := sqlStore.GetReplica().SelectOne(&dbRole, "SELECT * from Roles WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, errors.Wrapf(err, "failed to find role %s", name)
|
||||
} else {
|
||||
return nil, errors.Wrapf(err, "failed to query role %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
return dbRole.ToModel(), nil
|
||||
}
|
||||
|
||||
func saveRole(sqlStore SqlStore, role *model.Role) error {
|
||||
dbRole := NewRoleFromModel(role)
|
||||
|
||||
dbRole.UpdateAt = model.GetMillis()
|
||||
if rowsChanged, err := sqlStore.GetMaster().Update(dbRole); err != nil {
|
||||
return errors.Wrap(err, "failed to update role")
|
||||
} else if rowsChanged != 1 {
|
||||
return errors.New("found no role to update")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpgradeDatabaseToVersion58(sqlStore SqlStore) {
|
||||
if shouldPerformUpgrade(sqlStore, VERSION_5_7_0, VERSION_5_8_0) {
|
||||
// idx_channels_txt was removed in `UpgradeDatabaseToVersion50`, but merged as part of
|
||||
|
||||
@@ -1267,7 +1267,7 @@ func generateSearchQuery(query sq.SelectBuilder, terms []string, fields []string
|
||||
func (us SqlUserStore) performSearch(query sq.SelectBuilder, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
|
||||
term = sanitizeSearchTerm(term, "*")
|
||||
|
||||
searchType := USER_SEARCH_TYPE_NAMES_NO_FULL_NAME
|
||||
var searchType []string
|
||||
if options.AllowEmails {
|
||||
if options.AllowFullNames {
|
||||
searchType = USER_SEARCH_TYPE_ALL
|
||||
@@ -1359,8 +1359,7 @@ func (us SqlUserStore) GetProfilesNotInTeam(teamId string, groupConstrained bool
|
||||
}
|
||||
|
||||
func (us SqlUserStore) GetEtagForProfilesNotInTeam(teamId string) string {
|
||||
var querystr string
|
||||
querystr = `
|
||||
querystr := `
|
||||
SELECT
|
||||
CONCAT(MAX(UpdateAt), '.', COUNT(Id)) as etag
|
||||
FROM
|
||||
|
||||
@@ -574,9 +574,11 @@ type UserTermsOfServiceStore interface {
|
||||
type GroupStore interface {
|
||||
Create(group *model.Group) (*model.Group, *model.AppError)
|
||||
Get(groupID string) (*model.Group, *model.AppError)
|
||||
GetByName(name string) (*model.Group, *model.AppError)
|
||||
GetByIDs(groupIDs []string) ([]*model.Group, *model.AppError)
|
||||
GetByRemoteID(remoteID string, groupSource model.GroupSource) (*model.Group, *model.AppError)
|
||||
GetAllBySource(groupSource model.GroupSource) ([]*model.Group, *model.AppError)
|
||||
GetByUser(userId string) ([]*model.Group, *model.AppError)
|
||||
Update(group *model.Group) (*model.Group, *model.AppError)
|
||||
Delete(groupID string) (*model.Group, *model.AppError)
|
||||
|
||||
@@ -585,6 +587,7 @@ type GroupStore interface {
|
||||
GetMemberCount(groupID string) (int64, *model.AppError)
|
||||
UpsertMember(groupID string, userID string) (*model.GroupMember, *model.AppError)
|
||||
DeleteMember(groupID string, userID string) (*model.GroupMember, *model.AppError)
|
||||
PermanentDeleteMembersByUser(userId string) *model.AppError
|
||||
|
||||
CreateGroupSyncable(groupSyncable *model.GroupSyncable) (*model.GroupSyncable, *model.AppError)
|
||||
GetGroupSyncable(groupID string, syncableID string, syncableType model.GroupSyncableType) (*model.GroupSyncable, *model.AppError)
|
||||
|
||||
@@ -175,13 +175,13 @@ func testBotStoreGetAll(t *testing.T, ss store.Store) {
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewId(),
|
||||
}
|
||||
if _, err := ss.User().Save(&deletedUser); err != nil {
|
||||
t.Fatal("couldn't save user", err)
|
||||
}
|
||||
_, err1 := ss.User().Save(&deletedUser)
|
||||
require.Nil(t, err1, "couldn't save user")
|
||||
|
||||
deletedUser.DeleteAt = model.GetMillis()
|
||||
if _, err := ss.User().Update(&deletedUser, true); err != nil {
|
||||
t.Fatal("couldn't delete user", err)
|
||||
}
|
||||
_, err2 := ss.User().Update(&deletedUser, true)
|
||||
require.Nil(t, err2, "couldn't delete user")
|
||||
|
||||
defer func() { require.Nil(t, ss.User().PermanentDelete(deletedUser.Id)) }()
|
||||
ob5, _ := makeBotWithUser(t, ss, &model.Bot{
|
||||
Username: "ob5",
|
||||
|
||||
@@ -4,14 +4,13 @@
|
||||
package storetest
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/mattermost/mattermost-server/store"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCommandWebhookStore(t *testing.T, ss store.Store) {
|
||||
@@ -29,17 +28,12 @@ func testCommandWebhookStore(t *testing.T, ss store.Store) {
|
||||
require.Nil(t, err)
|
||||
|
||||
var r1 *model.CommandWebhook
|
||||
if r1, err = cws.Get(h1.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
if *r1 != *h1 {
|
||||
t.Fatal("invalid returned webhook")
|
||||
}
|
||||
}
|
||||
r1, err = cws.Get(h1.Id)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, *r1, *h1, "invalid returned webhook")
|
||||
|
||||
if _, err = cws.Get("123"); err.StatusCode != http.StatusNotFound {
|
||||
t.Fatal("Should have set the status as not found for missing id")
|
||||
}
|
||||
_, err = cws.Get("123")
|
||||
assert.Equal(t, err.StatusCode, http.StatusNotFound, "Should have set the status as not found for missing id")
|
||||
|
||||
h2 := &model.CommandWebhook{}
|
||||
h2.CreateAt = model.GetMillis() - 2*model.COMMAND_WEBHOOK_LIFETIME
|
||||
@@ -49,25 +43,22 @@ func testCommandWebhookStore(t *testing.T, ss store.Store) {
|
||||
h2, err = cws.Save(h2)
|
||||
require.Nil(t, err)
|
||||
|
||||
if _, err := cws.Get(h2.Id); err == nil || err.StatusCode != http.StatusNotFound {
|
||||
t.Fatal("Should have set the status as not found for expired webhook")
|
||||
}
|
||||
_, err = cws.Get(h2.Id)
|
||||
require.NotNil(t, err, "Should have set the status as not found for expired webhook")
|
||||
assert.Equal(t, err.StatusCode, http.StatusNotFound, "Should have set the status as not found for expired webhook")
|
||||
|
||||
cws.Cleanup()
|
||||
|
||||
if _, err := cws.Get(h1.Id); err != nil {
|
||||
t.Fatal("Should have no error getting unexpired webhook")
|
||||
}
|
||||
_, err = cws.Get(h1.Id)
|
||||
require.Nil(t, err, "Should have no error getting unexpired webhook")
|
||||
|
||||
if _, err := cws.Get(h2.Id); err.StatusCode != http.StatusNotFound {
|
||||
t.Fatal("Should have set the status as not found for expired webhook")
|
||||
}
|
||||
_, err = cws.Get(h2.Id)
|
||||
assert.Equal(t, err.StatusCode, http.StatusNotFound, "Should have set the status as not found for expired webhook")
|
||||
|
||||
if err := cws.TryUse(h1.Id, 1); err != nil {
|
||||
t.Fatal("Should be able to use webhook once")
|
||||
}
|
||||
err = cws.TryUse(h1.Id, 1)
|
||||
require.Nil(t, err, "Should be able to use webhook once")
|
||||
|
||||
if err := cws.TryUse(h1.Id, 1); err == nil || err.StatusCode != http.StatusBadRequest {
|
||||
t.Fatal("Should be able to use webhook once")
|
||||
}
|
||||
err = cws.TryUse(h1.Id, 1)
|
||||
require.NotNil(t, err, "Should be able to use webhook once")
|
||||
assert.Equal(t, err.StatusCode, http.StatusBadRequest, "Should be able to use webhook once")
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
@@ -20,9 +21,11 @@ import (
|
||||
func TestGroupStore(t *testing.T, ss store.Store) {
|
||||
t.Run("Create", func(t *testing.T) { testGroupStoreCreate(t, ss) })
|
||||
t.Run("Get", func(t *testing.T) { testGroupStoreGet(t, ss) })
|
||||
t.Run("GetByName", func(t *testing.T) { testGroupStoreGetByName(t, ss) })
|
||||
t.Run("GetByIDs", func(t *testing.T) { testGroupStoreGetByIDs(t, ss) })
|
||||
t.Run("GetByRemoteID", func(t *testing.T) { testGroupStoreGetByRemoteID(t, ss) })
|
||||
t.Run("GetAllBySource", func(t *testing.T) { testGroupStoreGetAllByType(t, ss) })
|
||||
t.Run("GetByUser", func(t *testing.T) { testGroupStoreGetByUser(t, ss) })
|
||||
t.Run("Update", func(t *testing.T) { testGroupStoreUpdate(t, ss) })
|
||||
t.Run("Delete", func(t *testing.T) { testGroupStoreDelete(t, ss) })
|
||||
|
||||
@@ -30,6 +33,7 @@ func TestGroupStore(t *testing.T, ss store.Store) {
|
||||
t.Run("GetMemberUsersPage", func(t *testing.T) { testGroupGetMemberUsersPage(t, ss) })
|
||||
t.Run("UpsertMember", func(t *testing.T) { testUpsertMember(t, ss) })
|
||||
t.Run("DeleteMember", func(t *testing.T) { testGroupDeleteMember(t, ss) })
|
||||
t.Run("PermanentDeleteMembersByUser", func(t *testing.T) { testGroupPermanentDeleteMembersByUser(t, ss) })
|
||||
|
||||
t.Run("CreateGroupSyncable", func(t *testing.T) { testCreateGroupSyncable(t, ss) })
|
||||
t.Run("GetGroupSyncable", func(t *testing.T) { testGetGroupSyncable(t, ss) })
|
||||
@@ -181,6 +185,37 @@ func testGroupStoreGet(t *testing.T, ss store.Store) {
|
||||
require.Equal(t, err.Id, "store.sql_group.no_rows")
|
||||
}
|
||||
|
||||
func testGroupStoreGetByName(t *testing.T, ss store.Store) {
|
||||
// Create a group
|
||||
g1 := &model.Group{
|
||||
Name: model.NewId(),
|
||||
DisplayName: model.NewId(),
|
||||
Description: model.NewId(),
|
||||
Source: model.GroupSourceLdap,
|
||||
RemoteId: model.NewId(),
|
||||
}
|
||||
d1, err := ss.Group().Create(g1)
|
||||
require.Nil(t, err)
|
||||
require.Len(t, d1.Id, 26)
|
||||
|
||||
// Get the group
|
||||
d2, err := ss.Group().GetByName(d1.Name)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, d1.Id, d2.Id)
|
||||
require.Equal(t, d1.Name, d2.Name)
|
||||
require.Equal(t, d1.DisplayName, d2.DisplayName)
|
||||
require.Equal(t, d1.Description, d2.Description)
|
||||
require.Equal(t, d1.RemoteId, d2.RemoteId)
|
||||
require.Equal(t, d1.CreateAt, d2.CreateAt)
|
||||
require.Equal(t, d1.UpdateAt, d2.UpdateAt)
|
||||
require.Equal(t, d1.DeleteAt, d2.DeleteAt)
|
||||
|
||||
// Get an invalid group
|
||||
_, err = ss.Group().GetByName(model.NewId())
|
||||
require.NotNil(t, err)
|
||||
require.Equal(t, err.Id, "store.sql_group.no_rows")
|
||||
}
|
||||
|
||||
func testGroupStoreGetByIDs(t *testing.T, ss store.Store) {
|
||||
var group1 *model.Group
|
||||
var group2 *model.Group
|
||||
@@ -280,6 +315,76 @@ func testGroupStoreGetAllByType(t *testing.T, ss store.Store) {
|
||||
}
|
||||
}
|
||||
|
||||
func testGroupStoreGetByUser(t *testing.T, ss store.Store) {
|
||||
// Save a group
|
||||
g1 := &model.Group{
|
||||
Name: model.NewId(),
|
||||
DisplayName: model.NewId(),
|
||||
Description: model.NewId(),
|
||||
Source: model.GroupSourceLdap,
|
||||
RemoteId: model.NewId(),
|
||||
}
|
||||
g1, err := ss.Group().Create(g1)
|
||||
require.Nil(t, err)
|
||||
|
||||
g2 := &model.Group{
|
||||
Name: model.NewId(),
|
||||
DisplayName: model.NewId(),
|
||||
Description: model.NewId(),
|
||||
Source: model.GroupSourceLdap,
|
||||
RemoteId: model.NewId(),
|
||||
}
|
||||
g2, err = ss.Group().Create(g2)
|
||||
require.Nil(t, err)
|
||||
|
||||
u1 := &model.User{
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewId(),
|
||||
}
|
||||
u1, err = ss.User().Save(u1)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = ss.Group().UpsertMember(g1.Id, u1.Id)
|
||||
require.Nil(t, err)
|
||||
_, err = ss.Group().UpsertMember(g2.Id, u1.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
u2 := &model.User{
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewId(),
|
||||
}
|
||||
u2, err = ss.User().Save(u2)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = ss.Group().UpsertMember(g2.Id, u2.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
groups, err := ss.Group().GetByUser(u1.Id)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, 2, len(groups))
|
||||
found1 := false
|
||||
found2 := false
|
||||
for _, g := range groups {
|
||||
if g.Id == g1.Id {
|
||||
found1 = true
|
||||
}
|
||||
if g.Id == g2.Id {
|
||||
found2 = true
|
||||
}
|
||||
}
|
||||
assert.True(t, found1)
|
||||
assert.True(t, found2)
|
||||
|
||||
groups, err = ss.Group().GetByUser(u2.Id)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 1, len(groups))
|
||||
assert.Equal(t, g2.Id, groups[0].Id)
|
||||
|
||||
groups, err = ss.Group().GetByUser(model.NewId())
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, 0, len(groups))
|
||||
}
|
||||
|
||||
func testGroupStoreUpdate(t *testing.T, ss store.Store) {
|
||||
// Save a new group
|
||||
g1 := &model.Group{
|
||||
@@ -658,6 +763,42 @@ func testGroupDeleteMember(t *testing.T, ss store.Store) {
|
||||
require.Equal(t, err.Id, "store.sql_group.no_rows")
|
||||
}
|
||||
|
||||
func testGroupPermanentDeleteMembersByUser(t *testing.T, ss store.Store) {
|
||||
var g *model.Group
|
||||
var groups []*model.Group
|
||||
numberOfGroups := 5
|
||||
|
||||
for i := 0; i < numberOfGroups; i++ {
|
||||
g = &model.Group{
|
||||
Name: model.NewId(),
|
||||
DisplayName: model.NewId(),
|
||||
Source: model.GroupSourceLdap,
|
||||
RemoteId: model.NewId(),
|
||||
}
|
||||
group, err := ss.Group().Create(g)
|
||||
groups = append(groups, group)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
// Create user
|
||||
u1 := &model.User{
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewId(),
|
||||
}
|
||||
user, err := ss.User().Save(u1)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Create members
|
||||
for _, group := range groups {
|
||||
_, err = ss.Group().UpsertMember(group.Id, user.Id)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
// Happy path
|
||||
err = ss.Group().PermanentDeleteMembersByUser(user.Id)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
func testCreateGroupSyncable(t *testing.T, ss store.Store) {
|
||||
// Invalid GroupID
|
||||
_, err := ss.Group().CreateGroupSyncable(model.NewGroupTeam("x", model.NewId(), false))
|
||||
@@ -897,7 +1038,7 @@ func testDeleteGroupSyncable(t *testing.T, ss store.Store) {
|
||||
require.Equal(t, err.Id, "store.sql_group.no_rows")
|
||||
|
||||
// Non-existent Team
|
||||
_, err = ss.Group().DeleteGroupSyncable(groupTeam.GroupId, string(model.NewId()), model.GroupSyncableTypeTeam)
|
||||
_, err = ss.Group().DeleteGroupSyncable(groupTeam.GroupId, model.NewId(), model.GroupSyncableTypeTeam)
|
||||
require.Equal(t, err.Id, "store.sql_group.no_rows")
|
||||
|
||||
// Happy path...
|
||||
@@ -1654,10 +1795,10 @@ func testGetGroupsByChannel(t *testing.T, ss store.Store) {
|
||||
_, err = ss.User().Update(user2, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
group1WithMemberCount := model.Group(*group1)
|
||||
group1WithMemberCount := *group1
|
||||
group1WithMemberCount.MemberCount = model.NewInt(1)
|
||||
|
||||
group2WithMemberCount := model.Group(*group2)
|
||||
group2WithMemberCount := *group2
|
||||
group2WithMemberCount.MemberCount = model.NewInt(0)
|
||||
|
||||
testCases := []struct {
|
||||
@@ -1868,10 +2009,10 @@ func testGetGroupsByTeam(t *testing.T, ss store.Store) {
|
||||
_, err = ss.User().Update(user2, true)
|
||||
require.Nil(t, err)
|
||||
|
||||
group1WithMemberCount := model.Group(*group1)
|
||||
group1WithMemberCount := *group1
|
||||
group1WithMemberCount.MemberCount = model.NewInt(1)
|
||||
|
||||
group2WithMemberCount := model.Group(*group2)
|
||||
group2WithMemberCount := *group2
|
||||
group2WithMemberCount.MemberCount = model.NewInt(0)
|
||||
|
||||
testCases := []struct {
|
||||
|
||||
@@ -406,6 +406,31 @@ func (_m *GroupStore) GetByIDs(groupIDs []string) ([]*model.Group, *model.AppErr
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetByName provides a mock function with given fields: name
|
||||
func (_m *GroupStore) GetByName(name string) (*model.Group, *model.AppError) {
|
||||
ret := _m.Called(name)
|
||||
|
||||
var r0 *model.Group
|
||||
if rf, ok := ret.Get(0).(func(string) *model.Group); ok {
|
||||
r0 = rf(name)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Group)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *model.AppError
|
||||
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
|
||||
r1 = rf(name)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*model.AppError)
|
||||
}
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetByRemoteID provides a mock function with given fields: remoteID, groupSource
|
||||
func (_m *GroupStore) GetByRemoteID(remoteID string, groupSource model.GroupSource) (*model.Group, *model.AppError) {
|
||||
ret := _m.Called(remoteID, groupSource)
|
||||
@@ -431,6 +456,31 @@ func (_m *GroupStore) GetByRemoteID(remoteID string, groupSource model.GroupSour
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetByUser provides a mock function with given fields: userId
|
||||
func (_m *GroupStore) GetByUser(userId string) ([]*model.Group, *model.AppError) {
|
||||
ret := _m.Called(userId)
|
||||
|
||||
var r0 []*model.Group
|
||||
if rf, ok := ret.Get(0).(func(string) []*model.Group); ok {
|
||||
r0 = rf(userId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Group)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *model.AppError
|
||||
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
|
||||
r1 = rf(userId)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*model.AppError)
|
||||
}
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetGroupSyncable provides a mock function with given fields: groupID, syncableID, syncableType
|
||||
func (_m *GroupStore) GetGroupSyncable(groupID string, syncableID string, syncableType model.GroupSyncableType) (*model.GroupSyncable, *model.AppError) {
|
||||
ret := _m.Called(groupID, syncableID, syncableType)
|
||||
@@ -604,6 +654,22 @@ func (_m *GroupStore) GetMemberUsersPage(groupID string, page int, perPage int)
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// PermanentDeleteMembersByUser provides a mock function with given fields: userId
|
||||
func (_m *GroupStore) PermanentDeleteMembersByUser(userId string) *model.AppError {
|
||||
ret := _m.Called(userId)
|
||||
|
||||
var r0 *model.AppError
|
||||
if rf, ok := ret.Get(0).(func(string) *model.AppError); ok {
|
||||
r0 = rf(userId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.AppError)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// TeamMembersMinusGroupMembers provides a mock function with given fields: teamID, groupIDs, page, perPage
|
||||
func (_m *GroupStore) TeamMembersMinusGroupMembers(teamID string, groupIDs []string, page int, perPage int) ([]*model.UserWithGroups, *model.AppError) {
|
||||
ret := _m.Called(teamID, groupIDs, page, perPage)
|
||||
|
||||
@@ -213,7 +213,7 @@ func testOAuthStoreRemoveAccessData(t *testing.T, ss store.Store) {
|
||||
require.Nil(t, result, "did not delete access token")
|
||||
}
|
||||
|
||||
func testOAuthStoreRemoveAllAccessData(t *testing.T, ss store.Store) {
|
||||
func TestOAuthStoreRemoveAllAccessData(t *testing.T, ss store.Store) {
|
||||
a1 := model.AccessData{}
|
||||
a1.ClientId = model.NewId()
|
||||
a1.UserId = model.NewId()
|
||||
|
||||
@@ -42,26 +42,22 @@ func testPreferenceSave(t *testing.T, ss store.Store) {
|
||||
Value: "value1b",
|
||||
},
|
||||
}
|
||||
if err := ss.Preference().Save(&preferences); err != nil {
|
||||
t.Fatal("saving preference returned error")
|
||||
}
|
||||
err := ss.Preference().Save(&preferences)
|
||||
require.Nil(t, err, "saving preference returned error")
|
||||
|
||||
for _, preference := range preferences {
|
||||
if data, _ := ss.Preference().Get(preference.UserId, preference.Category, preference.Name); preference.ToJson() != data.ToJson() {
|
||||
t.Fatal("got incorrect preference after first Save")
|
||||
}
|
||||
data, _ := ss.Preference().Get(preference.UserId, preference.Category, preference.Name)
|
||||
require.Equal(t, data.ToJson(), preference.ToJson(), "got incorrect preference after first Save")
|
||||
}
|
||||
|
||||
preferences[0].Value = "value2a"
|
||||
preferences[1].Value = "value2b"
|
||||
if err := ss.Preference().Save(&preferences); err != nil {
|
||||
t.Fatal("saving preference returned error")
|
||||
}
|
||||
err = ss.Preference().Save(&preferences)
|
||||
require.Nil(t, err, "saving preference returned error")
|
||||
|
||||
for _, preference := range preferences {
|
||||
if data, _ := ss.Preference().Get(preference.UserId, preference.Category, preference.Name); preference.ToJson() != data.ToJson() {
|
||||
t.Fatal("got incorrect preference after second Save")
|
||||
}
|
||||
data, _ := ss.Preference().Get(preference.UserId, preference.Category, preference.Name)
|
||||
require.Equal(t, data.ToJson(), preference.ToJson(), "got incorrect preference after second Save")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,16 +92,13 @@ func testPreferenceGet(t *testing.T, ss store.Store) {
|
||||
err := ss.Preference().Save(&preferences)
|
||||
require.Nil(t, err)
|
||||
|
||||
if data, err := ss.Preference().Get(userId, category, name); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if data.ToJson() != preferences[0].ToJson() {
|
||||
t.Fatal("got incorrect preference")
|
||||
}
|
||||
data, err := ss.Preference().Get(userId, category, name)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, preferences[0].ToJson(), data.ToJson(), "got incorrect preference")
|
||||
|
||||
// make sure getting a missing preference fails
|
||||
if _, err := ss.Preference().Get(model.NewId(), model.NewId(), model.NewId()); err == nil {
|
||||
t.Fatal("no error on getting a missing preference")
|
||||
}
|
||||
_, err = ss.Preference().Get(model.NewId(), model.NewId(), model.NewId())
|
||||
require.NotNil(t, err, "no error on getting a missing preference")
|
||||
}
|
||||
|
||||
func testPreferenceGetCategory(t *testing.T, ss store.Store) {
|
||||
@@ -142,20 +135,19 @@ func testPreferenceGetCategory(t *testing.T, ss store.Store) {
|
||||
err := ss.Preference().Save(&preferences)
|
||||
require.Nil(t, err)
|
||||
|
||||
if preferencesByCategory, err := ss.Preference().GetCategory(userId, category); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(preferencesByCategory) != 2 {
|
||||
t.Fatal("got the wrong number of preferences")
|
||||
} else if !((preferencesByCategory[0] == preferences[0] && preferencesByCategory[1] == preferences[1]) || (preferencesByCategory[0] == preferences[1] && preferencesByCategory[1] == preferences[0])) {
|
||||
t.Fatal("got incorrect preferences")
|
||||
}
|
||||
preferencesByCategory, err := ss.Preference().GetCategory(userId, category)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 2, len(preferencesByCategory), "got the wrong number of preferences")
|
||||
require.True(
|
||||
t,
|
||||
((preferencesByCategory[0] == preferences[0] && preferencesByCategory[1] == preferences[1]) || (preferencesByCategory[0] == preferences[1] && preferencesByCategory[1] == preferences[0])),
|
||||
"got incorrect preferences",
|
||||
)
|
||||
|
||||
// make sure getting a missing preference category doesn't fail
|
||||
if preferencesByCategory, err := ss.Preference().GetCategory(model.NewId(), model.NewId()); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(preferencesByCategory) != 0 {
|
||||
t.Fatal("shouldn't have got any preferences")
|
||||
}
|
||||
preferencesByCategory, err = ss.Preference().GetCategory(model.NewId(), model.NewId())
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 0, len(preferencesByCategory), "shouldn't have got any preferences")
|
||||
}
|
||||
|
||||
func testPreferenceGetAll(t *testing.T, ss store.Store) {
|
||||
@@ -192,17 +184,14 @@ func testPreferenceGetAll(t *testing.T, ss store.Store) {
|
||||
err := ss.Preference().Save(&preferences)
|
||||
require.Nil(t, err)
|
||||
|
||||
if result, err := ss.Preference().GetAll(userId); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(result) != 3 {
|
||||
t.Fatal("got the wrong number of preferences")
|
||||
} else {
|
||||
result, err := ss.Preference().GetAll(userId)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 3, len(result), "got the wrong number of preferences")
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
if result[0] != preferences[i] && result[1] != preferences[i] && result[2] != preferences[i] {
|
||||
t.Fatal("got incorrect preferences")
|
||||
}
|
||||
}
|
||||
assert.Falsef(t, result[0] != preferences[i] && result[1] != preferences[i] && result[2] != preferences[i], "got incorrect preferences")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func testPreferenceDeleteByUser(t *testing.T, ss store.Store) {
|
||||
@@ -239,9 +228,8 @@ func testPreferenceDeleteByUser(t *testing.T, ss store.Store) {
|
||||
err := ss.Preference().Save(&preferences)
|
||||
require.Nil(t, err)
|
||||
|
||||
if err := ss.Preference().PermanentDeleteByUser(userId); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.Preference().PermanentDeleteByUser(userId)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
func testPreferenceDelete(t *testing.T, ss store.Store) {
|
||||
@@ -259,13 +247,11 @@ func testPreferenceDelete(t *testing.T, ss store.Store) {
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, preferences, 1, "should've returned 1 preference")
|
||||
|
||||
if err = ss.Preference().Delete(preference.UserId, preference.Category, preference.Name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.Preference().Delete(preference.UserId, preference.Category, preference.Name)
|
||||
require.Nil(t, err)
|
||||
preferences, err = ss.Preference().GetAll(preference.UserId)
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, preferences, 0, "should've returned no preferences")
|
||||
|
||||
}
|
||||
|
||||
func testPreferenceDeleteCategory(t *testing.T, ss store.Store) {
|
||||
@@ -293,9 +279,8 @@ func testPreferenceDeleteCategory(t *testing.T, ss store.Store) {
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, preferences, 2, "should've returned 2 preferences")
|
||||
|
||||
if err = ss.Preference().DeleteCategory(userId, category); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.Preference().DeleteCategory(userId, category)
|
||||
require.Nil(t, err)
|
||||
|
||||
preferences, err = ss.Preference().GetAll(userId)
|
||||
require.Nil(t, err)
|
||||
@@ -333,9 +318,8 @@ func testPreferenceDeleteCategoryAndName(t *testing.T, ss store.Store) {
|
||||
require.Nil(t, err)
|
||||
assert.Len(t, preferences, 1, "should've returned 1 preference")
|
||||
|
||||
if err = ss.Preference().DeleteCategoryAndName(category, name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.Preference().DeleteCategoryAndName(category, name)
|
||||
require.Nil(t, err)
|
||||
|
||||
preferences, err = ss.Preference().GetAll(userId)
|
||||
require.Nil(t, err)
|
||||
|
||||
@@ -30,13 +30,9 @@ func testSaveTermsOfService(t *testing.T, ss store.Store) {
|
||||
savedTermsOfService, err := ss.TermsOfService().Save(termsOfService)
|
||||
require.Nil(t, err)
|
||||
|
||||
if len(savedTermsOfService.Id) != 26 {
|
||||
t.Fatal("Id should have been populated")
|
||||
}
|
||||
require.Len(t, savedTermsOfService.Id, 26, "Id should have been populated")
|
||||
|
||||
if savedTermsOfService.CreateAt == 0 {
|
||||
t.Fatal("Create at should have been populated")
|
||||
}
|
||||
require.NotEqual(t, savedTermsOfService.CreateAt, 0, "Create at should have been populated")
|
||||
}
|
||||
|
||||
func testGetLatestTermsOfService(t *testing.T, ss store.Store) {
|
||||
|
||||
@@ -31,49 +31,36 @@ func testUserAccessTokenSaveGetDelete(t *testing.T, ss store.Store) {
|
||||
s1, err := ss.Session().Save(s1)
|
||||
require.Nil(t, err)
|
||||
|
||||
if _, err = ss.UserAccessToken().Save(uat); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = ss.UserAccessToken().Save(uat)
|
||||
require.Nil(t, err)
|
||||
|
||||
if result, terr := ss.UserAccessToken().Get(uat.Id); terr != nil {
|
||||
t.Fatal(terr)
|
||||
} else if result.Token != uat.Token {
|
||||
t.Fatal("received incorrect token after save")
|
||||
}
|
||||
result, terr := ss.UserAccessToken().Get(uat.Id)
|
||||
require.Nil(t, terr)
|
||||
require.Equal(t, result.Token, uat.Token, "received incorrect token after save")
|
||||
|
||||
if received, err2 := ss.UserAccessToken().GetByToken(uat.Token); err2 != nil {
|
||||
t.Fatal(err2)
|
||||
} else if received.Token != uat.Token {
|
||||
t.Fatal("received incorrect token after save")
|
||||
}
|
||||
received, err2 := ss.UserAccessToken().GetByToken(uat.Token)
|
||||
require.Nil(t, err2)
|
||||
require.Equal(t, received.Token, uat.Token, "received incorrect token after save")
|
||||
|
||||
if _, err = ss.UserAccessToken().GetByToken("notarealtoken"); err == nil {
|
||||
t.Fatal("should have failed on bad token")
|
||||
}
|
||||
_, err = ss.UserAccessToken().GetByToken("notarealtoken")
|
||||
require.NotNil(t, err, "should have failed on bad token")
|
||||
|
||||
if received, err2 := ss.UserAccessToken().GetByUser(uat.UserId, 0, 100); err2 != nil {
|
||||
t.Fatal(err2)
|
||||
} else if len(received) != 1 {
|
||||
t.Fatal("received incorrect number of tokens after save")
|
||||
}
|
||||
received2, err2 := ss.UserAccessToken().GetByUser(uat.UserId, 0, 100)
|
||||
require.Nil(t, err2)
|
||||
require.Equal(t, 1, len(received2), "received incorrect number of tokens after save")
|
||||
|
||||
if result, appError := ss.UserAccessToken().GetAll(0, 100); appError != nil {
|
||||
t.Fatal(appError)
|
||||
} else if len(result) != 1 {
|
||||
t.Fatal("received incorrect number of tokens after save")
|
||||
}
|
||||
result2, appError := ss.UserAccessToken().GetAll(0, 100)
|
||||
require.Nil(t, appError)
|
||||
require.Equal(t, 1, len(result2), "received incorrect number of tokens after save")
|
||||
|
||||
if err = ss.UserAccessToken().Delete(uat.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.UserAccessToken().Delete(uat.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
if _, err = ss.Session().Get(s1.Token); err == nil {
|
||||
t.Fatal("should error - session should be deleted")
|
||||
}
|
||||
_, err = ss.Session().Get(s1.Token)
|
||||
require.NotNil(t, err, "should error - session should be deleted")
|
||||
|
||||
if _, err = ss.UserAccessToken().GetByToken(s1.Token); err == nil {
|
||||
t.Fatal("should error - access token should be deleted")
|
||||
}
|
||||
_, err = ss.UserAccessToken().GetByToken(s1.Token)
|
||||
require.NotNil(t, err, "should error - access token should be deleted")
|
||||
|
||||
s2 := &model.Session{}
|
||||
s2.UserId = uat.UserId
|
||||
@@ -82,21 +69,17 @@ func testUserAccessTokenSaveGetDelete(t *testing.T, ss store.Store) {
|
||||
s2, err = ss.Session().Save(s2)
|
||||
require.Nil(t, err)
|
||||
|
||||
if _, err = ss.UserAccessToken().Save(uat); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = ss.UserAccessToken().Save(uat)
|
||||
require.Nil(t, err)
|
||||
|
||||
if err := ss.UserAccessToken().DeleteAllForUser(uat.UserId); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.UserAccessToken().DeleteAllForUser(uat.UserId)
|
||||
require.Nil(t, err)
|
||||
|
||||
if _, err := ss.Session().Get(s2.Token); err == nil {
|
||||
t.Fatal("should error - session should be deleted")
|
||||
}
|
||||
_, err = ss.Session().Get(s2.Token)
|
||||
require.NotNil(t, err, "should error - session should be deleted")
|
||||
|
||||
if _, err := ss.UserAccessToken().GetByToken(s2.Token); err == nil {
|
||||
t.Fatal("should error - access token should be deleted")
|
||||
}
|
||||
_, err = ss.UserAccessToken().GetByToken(s2.Token)
|
||||
require.NotNil(t, err, "should error - access token should be deleted")
|
||||
}
|
||||
|
||||
func testUserAccessTokenDisableEnable(t *testing.T, ss store.Store) {
|
||||
@@ -113,17 +96,14 @@ func testUserAccessTokenDisableEnable(t *testing.T, ss store.Store) {
|
||||
s1, err := ss.Session().Save(s1)
|
||||
require.Nil(t, err)
|
||||
|
||||
if _, err = ss.UserAccessToken().Save(uat); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = ss.UserAccessToken().Save(uat)
|
||||
require.Nil(t, err)
|
||||
|
||||
if err = ss.UserAccessToken().UpdateTokenDisable(uat.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.UserAccessToken().UpdateTokenDisable(uat.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
if _, err = ss.Session().Get(s1.Token); err == nil {
|
||||
t.Fatal("should error - session should be deleted")
|
||||
}
|
||||
_, err = ss.Session().Get(s1.Token)
|
||||
require.NotNil(t, err, "should error - session should be deleted")
|
||||
|
||||
s2 := &model.Session{}
|
||||
s2.UserId = uat.UserId
|
||||
@@ -132,9 +112,8 @@ func testUserAccessTokenDisableEnable(t *testing.T, ss store.Store) {
|
||||
s2, err = ss.Session().Save(s2)
|
||||
require.Nil(t, err)
|
||||
|
||||
if err = ss.UserAccessToken().UpdateTokenEnable(uat.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = ss.UserAccessToken().UpdateTokenEnable(uat.Id)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
func testUserAccessTokenSearch(t *testing.T, ss store.Store) {
|
||||
@@ -158,25 +137,19 @@ func testUserAccessTokenSearch(t *testing.T, ss store.Store) {
|
||||
s1, err = ss.Session().Save(s1)
|
||||
require.Nil(t, err)
|
||||
|
||||
if _, err = ss.UserAccessToken().Save(uat); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = ss.UserAccessToken().Save(uat)
|
||||
require.Nil(t, err)
|
||||
|
||||
if received, err := ss.UserAccessToken().Search(uat.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(received) != 1 {
|
||||
t.Fatal("received incorrect number of tokens after search")
|
||||
}
|
||||
received, err := ss.UserAccessToken().Search(uat.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
if received, err := ss.UserAccessToken().Search(uat.UserId); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(received) != 1 {
|
||||
t.Fatal("received incorrect number of tokens after search")
|
||||
}
|
||||
require.Equal(t, 1, len(received), "received incorrect number of tokens after search")
|
||||
|
||||
if received, err := ss.UserAccessToken().Search(u1.Username); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(received) != 1 {
|
||||
t.Fatal("received incorrect number of tokens after search")
|
||||
}
|
||||
received, err = ss.UserAccessToken().Search(uat.UserId)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 1, len(received), "received incorrect number of tokens after search")
|
||||
|
||||
received, err = ss.UserAccessToken().Search(u1.Username)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 1, len(received), "received incorrect number of tokens after search")
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ func TestWebhookStoreGetIncomingByTeamByUser(t *testing.T, ss store.Store) {
|
||||
})
|
||||
}
|
||||
|
||||
func testWebhookStoreGetIncomingByChannel(t *testing.T, ss store.Store) {
|
||||
func TestWebhookStoreGetIncomingByChannel(t *testing.T, ss store.Store) {
|
||||
o1 := buildIncomingWebhook()
|
||||
|
||||
o1, err := ss.Webhook().SaveIncoming(o1)
|
||||
|
||||
@@ -2776,6 +2776,23 @@ func (s *TimerLayerGroupStore) GetByIDs(groupIDs []string) ([]*model.Group, *mod
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) GetByName(name string) (*model.Group, *model.AppError) {
|
||||
start := timemodule.Now()
|
||||
|
||||
resultVar0, resultVar1 := s.GroupStore.GetByName(name)
|
||||
|
||||
t := timemodule.Now()
|
||||
elapsed := t.Sub(start)
|
||||
if s.Root.Metrics != nil {
|
||||
success := "false"
|
||||
if resultVar1 == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("GroupStore.GetByName", success, float64(elapsed))
|
||||
}
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) GetByRemoteID(remoteID string, groupSource model.GroupSource) (*model.Group, *model.AppError) {
|
||||
start := timemodule.Now()
|
||||
|
||||
@@ -2792,6 +2809,23 @@ func (s *TimerLayerGroupStore) GetByRemoteID(remoteID string, groupSource model.
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) GetByUser(userId string) ([]*model.Group, *model.AppError) {
|
||||
start := timemodule.Now()
|
||||
|
||||
resultVar0, resultVar1 := s.GroupStore.GetByUser(userId)
|
||||
|
||||
t := timemodule.Now()
|
||||
elapsed := t.Sub(start)
|
||||
if s.Root.Metrics != nil {
|
||||
success := "false"
|
||||
if resultVar1 == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("GroupStore.GetByUser", success, float64(elapsed))
|
||||
}
|
||||
return resultVar0, resultVar1
|
||||
}
|
||||
|
||||
func (s *TimerLayerGroupStore) GetGroupSyncable(groupID string, syncableID string, syncableType model.GroupSyncableType) (*model.GroupSyncable, *model.AppError) {
|
||||
start := timemodule.Now()
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ func getTestResourcesToSetup() []testResourceDetails {
|
||||
testResourcesToSetup[i].src = srcPath
|
||||
} else if testResource.resType == resourceTypeFolder {
|
||||
srcPath, found = findDir(testResource.src)
|
||||
if found == false {
|
||||
if !found {
|
||||
panic(fmt.Sprintf("Failed to find folder %s", testResource.src))
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user