Merge branch 'master' into mark-as-unread
Этот коммит содержится в:
4
Makefile
4
Makefile
@@ -59,7 +59,7 @@ LDFLAGS += -X "github.com/mattermost/mattermost-server/model.BuildEnterpriseRead
|
|||||||
GO_MAJOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1)
|
GO_MAJOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1)
|
||||||
GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
|
GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
|
||||||
MINIMUM_SUPPORTED_GO_MAJOR_VERSION = 1
|
MINIMUM_SUPPORTED_GO_MAJOR_VERSION = 1
|
||||||
MINIMUM_SUPPORTED_GO_MINOR_VERSION = 12
|
MINIMUM_SUPPORTED_GO_MINOR_VERSION = 13
|
||||||
GO_VERSION_VALIDATION_ERR_MSG = Golang version is not supported, please update to at least $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION).$(MINIMUM_SUPPORTED_GO_MINOR_VERSION)
|
GO_VERSION_VALIDATION_ERR_MSG = Golang version is not supported, please update to at least $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION).$(MINIMUM_SUPPORTED_GO_MINOR_VERSION)
|
||||||
|
|
||||||
# GOOS/GOARCH of the build host, used to determine whether we're cross-compiling or not
|
# GOOS/GOARCH of the build host, used to determine whether we're cross-compiling or not
|
||||||
@@ -81,7 +81,7 @@ TESTFLAGSEE ?= -short
|
|||||||
TE_PACKAGES=$(shell $(GO) list ./...)
|
TE_PACKAGES=$(shell $(GO) list ./...)
|
||||||
|
|
||||||
# Plugins Packages
|
# Plugins Packages
|
||||||
PLUGIN_PACKAGES=mattermost-plugin-zoom-v1.1.1
|
PLUGIN_PACKAGES=mattermost-plugin-zoom-v1.1.2
|
||||||
PLUGIN_PACKAGES += mattermost-plugin-autolink-v1.1.1
|
PLUGIN_PACKAGES += mattermost-plugin-autolink-v1.1.1
|
||||||
PLUGIN_PACKAGES += mattermost-plugin-nps-v1.0.3
|
PLUGIN_PACKAGES += mattermost-plugin-nps-v1.0.3
|
||||||
PLUGIN_PACKAGES += mattermost-plugin-custom-attributes-v1.0.2
|
PLUGIN_PACKAGES += mattermost-plugin-custom-attributes-v1.0.2
|
||||||
|
|||||||
@@ -25,31 +25,26 @@ func TestGetConfig(t *testing.T) {
|
|||||||
require.NotEqual(t, "", cfg.TeamSettings.SiteName)
|
require.NotEqual(t, "", cfg.TeamSettings.SiteName)
|
||||||
|
|
||||||
if *cfg.LdapSettings.BindPassword != model.FAKE_SETTING && len(*cfg.LdapSettings.BindPassword) != 0 {
|
if *cfg.LdapSettings.BindPassword != model.FAKE_SETTING && len(*cfg.LdapSettings.BindPassword) != 0 {
|
||||||
t.Fatal("did not sanitize properly")
|
require.FailNow(t, "did not sanitize properly")
|
||||||
}
|
|
||||||
if *cfg.FileSettings.PublicLinkSalt != model.FAKE_SETTING {
|
|
||||||
t.Fatal("did not sanitize properly")
|
|
||||||
}
|
}
|
||||||
|
require.Equal(t, model.FAKE_SETTING, *cfg.FileSettings.PublicLinkSalt, "did not sanitize properly")
|
||||||
|
|
||||||
if *cfg.FileSettings.AmazonS3SecretAccessKey != model.FAKE_SETTING && len(*cfg.FileSettings.AmazonS3SecretAccessKey) != 0 {
|
if *cfg.FileSettings.AmazonS3SecretAccessKey != model.FAKE_SETTING && len(*cfg.FileSettings.AmazonS3SecretAccessKey) != 0 {
|
||||||
t.Fatal("did not sanitize properly")
|
require.FailNow(t, "did not sanitize properly")
|
||||||
}
|
}
|
||||||
if *cfg.EmailSettings.SMTPPassword != model.FAKE_SETTING && len(*cfg.EmailSettings.SMTPPassword) != 0 {
|
if *cfg.EmailSettings.SMTPPassword != model.FAKE_SETTING && len(*cfg.EmailSettings.SMTPPassword) != 0 {
|
||||||
t.Fatal("did not sanitize properly")
|
require.FailNow(t, "did not sanitize properly")
|
||||||
}
|
}
|
||||||
if *cfg.GitLabSettings.Secret != model.FAKE_SETTING && len(*cfg.GitLabSettings.Secret) != 0 {
|
if *cfg.GitLabSettings.Secret != model.FAKE_SETTING && len(*cfg.GitLabSettings.Secret) != 0 {
|
||||||
t.Fatal("did not sanitize properly")
|
require.FailNow(t, "did not sanitize properly")
|
||||||
}
|
|
||||||
if *cfg.SqlSettings.DataSource != model.FAKE_SETTING {
|
|
||||||
t.Fatal("did not sanitize properly")
|
|
||||||
}
|
|
||||||
if *cfg.SqlSettings.AtRestEncryptKey != model.FAKE_SETTING {
|
|
||||||
t.Fatal("did not sanitize properly")
|
|
||||||
}
|
}
|
||||||
|
require.Equal(t, model.FAKE_SETTING, *cfg.SqlSettings.DataSource, "did not sanitize properly")
|
||||||
|
require.Equal(t, model.FAKE_SETTING, *cfg.SqlSettings.AtRestEncryptKey, "did not sanitize properly")
|
||||||
if !strings.Contains(strings.Join(cfg.SqlSettings.DataSourceReplicas, " "), model.FAKE_SETTING) && len(cfg.SqlSettings.DataSourceReplicas) != 0 {
|
if !strings.Contains(strings.Join(cfg.SqlSettings.DataSourceReplicas, " "), model.FAKE_SETTING) && len(cfg.SqlSettings.DataSourceReplicas) != 0 {
|
||||||
t.Fatal("did not sanitize properly")
|
require.FailNow(t, "did not sanitize properly")
|
||||||
}
|
}
|
||||||
if !strings.Contains(strings.Join(cfg.SqlSettings.DataSourceSearchReplicas, " "), model.FAKE_SETTING) && len(cfg.SqlSettings.DataSourceSearchReplicas) != 0 {
|
if !strings.Contains(strings.Join(cfg.SqlSettings.DataSourceSearchReplicas, " "), model.FAKE_SETTING) && len(cfg.SqlSettings.DataSourceSearchReplicas) != 0 {
|
||||||
t.Fatal("did not sanitize properly")
|
require.FailNow(t, "did not sanitize properly")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,17 +56,13 @@ func TestReloadConfig(t *testing.T) {
|
|||||||
t.Run("as system user", func(t *testing.T) {
|
t.Run("as system user", func(t *testing.T) {
|
||||||
ok, resp := Client.ReloadConfig()
|
ok, resp := Client.ReloadConfig()
|
||||||
CheckForbiddenStatus(t, resp)
|
CheckForbiddenStatus(t, resp)
|
||||||
if ok {
|
require.False(t, ok, "should not Reload the config due no permission.")
|
||||||
t.Fatal("should not Reload the config due no permission.")
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("as system admin", func(t *testing.T) {
|
t.Run("as system admin", func(t *testing.T) {
|
||||||
ok, resp := th.SystemAdminClient.ReloadConfig()
|
ok, resp := th.SystemAdminClient.ReloadConfig()
|
||||||
CheckNoError(t, resp)
|
CheckNoError(t, resp)
|
||||||
if !ok {
|
require.True(t, ok, "should Reload the config")
|
||||||
t.Fatal("should Reload the config")
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("as restricted system admin", func(t *testing.T) {
|
t.Run("as restricted system admin", func(t *testing.T) {
|
||||||
@@ -79,9 +70,7 @@ func TestReloadConfig(t *testing.T) {
|
|||||||
|
|
||||||
ok, resp := Client.ReloadConfig()
|
ok, resp := Client.ReloadConfig()
|
||||||
CheckForbiddenStatus(t, resp)
|
CheckForbiddenStatus(t, resp)
|
||||||
if ok {
|
require.False(t, ok, "should not Reload the config due no permission.")
|
||||||
t.Fatal("should not Reload the config due no permission.")
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,31 +234,28 @@ func TestGetEnvironmentConfig(t *testing.T) {
|
|||||||
envConfig, resp := SystemAdminClient.GetEnvironmentConfig()
|
envConfig, resp := SystemAdminClient.GetEnvironmentConfig()
|
||||||
CheckNoError(t, resp)
|
CheckNoError(t, resp)
|
||||||
|
|
||||||
if serviceSettings, ok := envConfig["ServiceSettings"]; !ok {
|
serviceSettings, ok := envConfig["ServiceSettings"]
|
||||||
t.Fatal("should've returned ServiceSettings")
|
require.True(t, ok, "should've returned ServiceSettings")
|
||||||
} else if serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{}); !ok {
|
|
||||||
t.Fatal("should've returned ServiceSettings as a map")
|
|
||||||
} else {
|
|
||||||
if siteURL, ok := serviceSettingsAsMap["SiteURL"]; !ok {
|
|
||||||
t.Fatal("should've returned ServiceSettings.SiteURL")
|
|
||||||
} else if siteURLAsBool, ok := siteURL.(bool); !ok {
|
|
||||||
t.Fatal("should've returned ServiceSettings.SiteURL as a boolean")
|
|
||||||
} else if !siteURLAsBool {
|
|
||||||
t.Fatal("should've returned ServiceSettings.SiteURL as true")
|
|
||||||
}
|
|
||||||
|
|
||||||
if enableCustomEmoji, ok := serviceSettingsAsMap["EnableCustomEmoji"]; !ok {
|
serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{})
|
||||||
t.Fatal("should've returned ServiceSettings.EnableCustomEmoji")
|
require.True(t, ok, "should've returned ServiceSettings as a map")
|
||||||
} else if enableCustomEmojiAsBool, ok := enableCustomEmoji.(bool); !ok {
|
|
||||||
t.Fatal("should've returned ServiceSettings.EnableCustomEmoji as a boolean")
|
|
||||||
} else if !enableCustomEmojiAsBool {
|
|
||||||
t.Fatal("should've returned ServiceSettings.EnableCustomEmoji as true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := envConfig["TeamSettings"]; ok {
|
siteURL, ok := serviceSettingsAsMap["SiteURL"]
|
||||||
t.Fatal("should not have returned TeamSettings")
|
require.True(t, ok, "should've returned ServiceSettings.SiteURL")
|
||||||
}
|
|
||||||
|
siteURLAsBool, ok := siteURL.(bool)
|
||||||
|
require.True(t, ok, "should've returned ServiceSettings.SiteURL as a boolean")
|
||||||
|
require.True(t, siteURLAsBool, "should've returned ServiceSettings.SiteURL as true")
|
||||||
|
|
||||||
|
enableCustomEmoji, ok := serviceSettingsAsMap["EnableCustomEmoji"]
|
||||||
|
require.True(t, ok, "should've returned ServiceSettings.EnableCustomEmoji")
|
||||||
|
|
||||||
|
enableCustomEmojiAsBool, ok := enableCustomEmoji.(bool)
|
||||||
|
require.True(t, ok, "should've returned ServiceSettings.EnableCustomEmoji as a boolean")
|
||||||
|
require.True(t, enableCustomEmojiAsBool, "should've returned ServiceSettings.EnableCustomEmoji as true")
|
||||||
|
|
||||||
|
_, ok = envConfig["TeamSettings"]
|
||||||
|
require.False(t, ok, "should not have returned TeamSettings")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("as team admin", func(t *testing.T) {
|
t.Run("as team admin", func(t *testing.T) {
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
@@ -242,19 +244,16 @@ func (a *App) DoPostActionWithCookie(postId, actionId, userId, selectedOption st
|
|||||||
|
|
||||||
// Perform an HTTP POST request to an integration's action endpoint.
|
// Perform an HTTP POST request to an integration's action endpoint.
|
||||||
// Caller must consume and close returned http.Response as necessary.
|
// Caller must consume and close returned http.Response as necessary.
|
||||||
|
// For internal requests, requests are routed directly to a plugin ServerHTTP hook
|
||||||
func (a *App) DoActionRequest(rawURL string, body []byte) (*http.Response, *model.AppError) {
|
func (a *App) DoActionRequest(rawURL string, body []byte) (*http.Response, *model.AppError) {
|
||||||
inURL, err := url.Parse(rawURL)
|
inURL, err := url.Parse(rawURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, model.NewAppError("DoActionRequest", "api.post.do_action.action_integration.app_error", nil, err.Error(), http.StatusBadRequest)
|
return nil, model.NewAppError("DoActionRequest", "api.post.do_action.action_integration.app_error", nil, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
siteURL, _ := url.Parse(*a.Config().ServiceSettings.SiteURL)
|
|
||||||
rawURLPath := path.Clean(rawURL)
|
rawURLPath := path.Clean(rawURL)
|
||||||
if siteURL != nil && (strings.HasPrefix(rawURLPath, "/plugins/") || strings.HasPrefix(rawURLPath, "plugins/")) {
|
if strings.HasPrefix(rawURLPath, "/plugins/") || strings.HasPrefix(rawURLPath, "plugins/") {
|
||||||
inURL.Scheme = siteURL.Scheme
|
return a.DoLocalRequest(rawURLPath, body)
|
||||||
inURL.Host = siteURL.Host
|
|
||||||
inURL.Path = path.Join("/", siteURL.Path, rawURLPath)
|
|
||||||
rawURL = inURL.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", rawURL, bytes.NewReader(body))
|
req, err := http.NewRequest("POST", rawURL, bytes.NewReader(body))
|
||||||
@@ -267,6 +266,7 @@ func (a *App) DoActionRequest(rawURL string, body []byte) (*http.Response, *mode
|
|||||||
// Allow access to plugin routes for action buttons
|
// Allow access to plugin routes for action buttons
|
||||||
var httpClient *http.Client
|
var httpClient *http.Client
|
||||||
subpath, _ := utils.GetSubpathFromConfig(a.Config())
|
subpath, _ := utils.GetSubpathFromConfig(a.Config())
|
||||||
|
siteURL, _ := url.Parse(*a.Config().ServiceSettings.SiteURL)
|
||||||
if (inURL.Hostname() == "localhost" || inURL.Hostname() == "127.0.0.1" || inURL.Hostname() == siteURL.Hostname()) && strings.HasPrefix(inURL.Path, path.Join(subpath, "plugins")) {
|
if (inURL.Hostname() == "localhost" || inURL.Hostname() == "127.0.0.1" || inURL.Hostname() == siteURL.Hostname()) && strings.HasPrefix(inURL.Path, path.Join(subpath, "plugins")) {
|
||||||
req.Header.Set(model.HEADER_AUTH, "Bearer "+a.Session.Token)
|
req.Header.Set(model.HEADER_AUTH, "Bearer "+a.Session.Token)
|
||||||
httpClient = a.HTTPService.MakeClient(true)
|
httpClient = a.HTTPService.MakeClient(true)
|
||||||
@@ -286,6 +286,74 @@ func (a *App) DoActionRequest(rawURL string, body []byte) (*http.Response, *mode
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LocalResponseWriter struct {
|
||||||
|
data []byte
|
||||||
|
headers http.Header
|
||||||
|
status int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *LocalResponseWriter) Header() http.Header {
|
||||||
|
if w.headers == nil {
|
||||||
|
w.headers = make(http.Header)
|
||||||
|
}
|
||||||
|
return w.headers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *LocalResponseWriter) Write(bytes []byte) (int, error) {
|
||||||
|
w.data = make([]byte, len(bytes))
|
||||||
|
copy(w.data, bytes)
|
||||||
|
return len(w.data), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *LocalResponseWriter) WriteHeader(statusCode int) {
|
||||||
|
w.status = statusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *App) DoLocalRequest(rawURL string, body []byte) (*http.Response, *model.AppError) {
|
||||||
|
rawURL = strings.TrimPrefix(rawURL, "/")
|
||||||
|
inURL, err := url.Parse(rawURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, model.NewAppError("DoActionRequest", "api.post.do_action.action_integration.app_error", nil, "err="+err.Error(), http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
result := strings.Split(inURL.Path, "/")
|
||||||
|
if len(result) < 2 {
|
||||||
|
return nil, model.NewAppError("DoActionRequest", "api.post.do_action.action_integration.app_error", nil, "err=Unable to find pluginId", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
if result[0] != "plugins" {
|
||||||
|
return nil, model.NewAppError("DoActionRequest", "api.post.do_action.action_integration.app_error", nil, "err=plugins not in path", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
pluginId := result[1]
|
||||||
|
|
||||||
|
path := strings.TrimPrefix(inURL.Path, "plugins/"+pluginId)
|
||||||
|
|
||||||
|
w := &LocalResponseWriter{}
|
||||||
|
r, err := http.NewRequest("POST", path, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, model.NewAppError("DoActionRequest", "api.post.do_action.action_integration.app_error", nil, "err="+err.Error(), http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
r.Header.Set("Mattermost-User-Id", a.Session.UserId)
|
||||||
|
r.Header.Set(model.HEADER_AUTH, "Bearer "+a.Session.Token)
|
||||||
|
params := make(map[string]string)
|
||||||
|
params["plugin_id"] = pluginId
|
||||||
|
r = mux.SetURLVars(r, params)
|
||||||
|
|
||||||
|
a.ServePluginRequest(w, r)
|
||||||
|
|
||||||
|
resp := &http.Response{
|
||||||
|
StatusCode: w.status,
|
||||||
|
Proto: "HTTP/1.1",
|
||||||
|
ProtoMajor: 1,
|
||||||
|
ProtoMinor: 1,
|
||||||
|
Header: w.headers,
|
||||||
|
Body: ioutil.NopCloser(bytes.NewReader(w.data)),
|
||||||
|
}
|
||||||
|
if resp.StatusCode == 0 {
|
||||||
|
resp.StatusCode = http.StatusOK
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) OpenInteractiveDialog(request model.OpenDialogRequest) *model.AppError {
|
func (a *App) OpenInteractiveDialog(request model.OpenDialogRequest) *model.AppError {
|
||||||
clientTriggerId, userId, err := request.DecodeAndVerifyTriggerId(a.AsymmetricSigningKey())
|
clientTriggerId, userId, err := request.DecodeAndVerifyTriggerId(a.AsymmetricSigningKey())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -443,6 +443,37 @@ func TestSubmitInteractiveDialog(t *testing.T) {
|
|||||||
}))
|
}))
|
||||||
defer ts.Close()
|
defer ts.Close()
|
||||||
|
|
||||||
|
setupPluginApiTest(t,
|
||||||
|
`
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"github.com/mattermost/mattermost-server/plugin"
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MyPlugin struct {
|
||||||
|
plugin.MattermostPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *MyPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
response := &model.SubmitDialogResponse{
|
||||||
|
Errors: map[string]string{"name1": "some error"},
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
_, _ = w.Write(response.ToJson())
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
plugin.ClientMain(&MyPlugin{})
|
||||||
|
}
|
||||||
|
`, `{"id": "myplugin", "backend": {"executable": "backend.exe"}}`, "myplugin", th.App)
|
||||||
|
|
||||||
|
hooks, err2 := th.App.GetPluginsEnvironment().HooksForPlugin("myplugin")
|
||||||
|
require.Nil(t, err2)
|
||||||
|
require.NotNil(t, hooks)
|
||||||
|
|
||||||
submit.URL = ts.URL
|
submit.URL = ts.URL
|
||||||
|
|
||||||
resp, err := th.App.SubmitInteractiveDialog(submit)
|
resp, err := th.App.SubmitInteractiveDialog(submit)
|
||||||
@@ -601,7 +632,8 @@ func TestPostActionRelativeURL(t *testing.T) {
|
|||||||
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
||||||
|
|
||||||
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
||||||
require.Nil(t, err)
|
require.NotNil(t, err)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("valid (but dirty) relative URL with SiteURL set", func(t *testing.T) {
|
t.Run("valid (but dirty) relative URL with SiteURL set", func(t *testing.T) {
|
||||||
@@ -641,7 +673,7 @@ func TestPostActionRelativeURL(t *testing.T) {
|
|||||||
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
||||||
|
|
||||||
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
||||||
require.Nil(t, err)
|
require.NotNil(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("valid relative URL with SiteURL set and no leading slash", func(t *testing.T) {
|
t.Run("valid relative URL with SiteURL set and no leading slash", func(t *testing.T) {
|
||||||
@@ -680,6 +712,200 @@ func TestPostActionRelativeURL(t *testing.T) {
|
|||||||
require.NotEmpty(t, attachments[0].Actions)
|
require.NotEmpty(t, attachments[0].Actions)
|
||||||
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
||||||
|
|
||||||
|
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
||||||
|
require.NotNil(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPostActionRelativePluginURL(t *testing.T) {
|
||||||
|
th := Setup(t).InitBasic()
|
||||||
|
defer th.TearDown()
|
||||||
|
|
||||||
|
setupPluginApiTest(t,
|
||||||
|
`
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"github.com/mattermost/mattermost-server/plugin"
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MyPlugin struct {
|
||||||
|
plugin.MattermostPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *MyPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
response := &model.PostActionIntegrationResponse{}
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
_, _ = w.Write(response.ToJson())
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
plugin.ClientMain(&MyPlugin{})
|
||||||
|
}
|
||||||
|
`, `{"id": "myplugin", "backend": {"executable": "backend.exe"}}`, "myplugin", th.App)
|
||||||
|
|
||||||
|
hooks, err2 := th.App.GetPluginsEnvironment().HooksForPlugin("myplugin")
|
||||||
|
require.Nil(t, err2)
|
||||||
|
require.NotNil(t, hooks)
|
||||||
|
|
||||||
|
t.Run("invalid relative URL", func(t *testing.T) {
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||||
|
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = ""
|
||||||
|
*cfg.ServiceSettings.SiteURL = ""
|
||||||
|
})
|
||||||
|
|
||||||
|
interactivePost := model.Post{
|
||||||
|
Message: "Interactive post",
|
||||||
|
ChannelId: th.BasicChannel.Id,
|
||||||
|
PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
|
||||||
|
UserId: th.BasicUser.Id,
|
||||||
|
Props: model.StringInterface{
|
||||||
|
"attachments": []*model.SlackAttachment{
|
||||||
|
{
|
||||||
|
Text: "hello",
|
||||||
|
Actions: []*model.PostAction{
|
||||||
|
{
|
||||||
|
Integration: &model.PostActionIntegration{
|
||||||
|
URL: "/notaplugin/some/path",
|
||||||
|
},
|
||||||
|
Name: "action",
|
||||||
|
Type: "some_type",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
post, err := th.App.CreatePostAsUser(&interactivePost, "")
|
||||||
|
require.Nil(t, err)
|
||||||
|
attachments, ok := post.Props["attachments"].([]*model.SlackAttachment)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.NotEmpty(t, attachments[0].Actions)
|
||||||
|
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
||||||
|
|
||||||
|
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
||||||
|
require.NotNil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("valid relative URL", func(t *testing.T) {
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||||
|
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = ""
|
||||||
|
*cfg.ServiceSettings.SiteURL = ""
|
||||||
|
})
|
||||||
|
|
||||||
|
interactivePost := model.Post{
|
||||||
|
Message: "Interactive post",
|
||||||
|
ChannelId: th.BasicChannel.Id,
|
||||||
|
PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
|
||||||
|
UserId: th.BasicUser.Id,
|
||||||
|
Props: model.StringInterface{
|
||||||
|
"attachments": []*model.SlackAttachment{
|
||||||
|
{
|
||||||
|
Text: "hello",
|
||||||
|
Actions: []*model.PostAction{
|
||||||
|
{
|
||||||
|
Integration: &model.PostActionIntegration{
|
||||||
|
URL: "/plugins/myplugin/myaction",
|
||||||
|
},
|
||||||
|
Name: "action",
|
||||||
|
Type: "some_type",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
post, err := th.App.CreatePostAsUser(&interactivePost, "")
|
||||||
|
require.Nil(t, err)
|
||||||
|
attachments, ok := post.Props["attachments"].([]*model.SlackAttachment)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.NotEmpty(t, attachments[0].Actions)
|
||||||
|
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
||||||
|
|
||||||
|
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
||||||
|
require.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("valid (but dirty) relative URL", func(t *testing.T) {
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||||
|
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = ""
|
||||||
|
*cfg.ServiceSettings.SiteURL = ""
|
||||||
|
})
|
||||||
|
|
||||||
|
interactivePost := model.Post{
|
||||||
|
Message: "Interactive post",
|
||||||
|
ChannelId: th.BasicChannel.Id,
|
||||||
|
PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
|
||||||
|
UserId: th.BasicUser.Id,
|
||||||
|
Props: model.StringInterface{
|
||||||
|
"attachments": []*model.SlackAttachment{
|
||||||
|
{
|
||||||
|
Text: "hello",
|
||||||
|
Actions: []*model.PostAction{
|
||||||
|
{
|
||||||
|
Integration: &model.PostActionIntegration{
|
||||||
|
URL: "//plugins/myplugin///myaction",
|
||||||
|
},
|
||||||
|
Name: "action",
|
||||||
|
Type: "some_type",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
post, err := th.App.CreatePostAsUser(&interactivePost, "")
|
||||||
|
require.Nil(t, err)
|
||||||
|
attachments, ok := post.Props["attachments"].([]*model.SlackAttachment)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.NotEmpty(t, attachments[0].Actions)
|
||||||
|
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
||||||
|
|
||||||
|
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
||||||
|
require.Nil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("valid relative URL and no leading slash", func(t *testing.T) {
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) {
|
||||||
|
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = ""
|
||||||
|
*cfg.ServiceSettings.SiteURL = ""
|
||||||
|
})
|
||||||
|
|
||||||
|
interactivePost := model.Post{
|
||||||
|
Message: "Interactive post",
|
||||||
|
ChannelId: th.BasicChannel.Id,
|
||||||
|
PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
|
||||||
|
UserId: th.BasicUser.Id,
|
||||||
|
Props: model.StringInterface{
|
||||||
|
"attachments": []*model.SlackAttachment{
|
||||||
|
{
|
||||||
|
Text: "hello",
|
||||||
|
Actions: []*model.PostAction{
|
||||||
|
{
|
||||||
|
Integration: &model.PostActionIntegration{
|
||||||
|
URL: "plugins/myplugin/myaction",
|
||||||
|
},
|
||||||
|
Name: "action",
|
||||||
|
Type: "some_type",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
post, err := th.App.CreatePostAsUser(&interactivePost, "")
|
||||||
|
require.Nil(t, err)
|
||||||
|
attachments, ok := post.Props["attachments"].([]*model.SlackAttachment)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.NotEmpty(t, attachments[0].Actions)
|
||||||
|
require.NotEmpty(t, attachments[0].Actions[0].Id)
|
||||||
|
|
||||||
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
_, err = th.App.DoPostAction(post.Id, attachments[0].Actions[0].Id, th.BasicUser.Id, "")
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -825,3 +826,29 @@ func (api *PluginAPI) DeleteBotIconImage(userId string) *model.AppError {
|
|||||||
|
|
||||||
return api.app.DeleteBotIconImage(userId)
|
return api.app.DeleteBotIconImage(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *PluginAPI) PluginHTTP(request *http.Request) *http.Response {
|
||||||
|
split := strings.SplitN(request.URL.Path, "/", 3)
|
||||||
|
if len(split) != 3 {
|
||||||
|
return &http.Response{
|
||||||
|
StatusCode: http.StatusBadRequest,
|
||||||
|
Body: ioutil.NopCloser(bytes.NewBufferString("Not enough URL. Form of URL should be /<pluginid>/*")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
destinationPluginId := split[1]
|
||||||
|
newURL, err := url.Parse("/" + split[2])
|
||||||
|
request.URL = newURL
|
||||||
|
if destinationPluginId == "" || err != nil {
|
||||||
|
message := "No plugin specified. Form of URL should be /<pluginid>/*"
|
||||||
|
if err != nil {
|
||||||
|
message = "Form of URL should be /<pluginid>/* Error: " + err.Error()
|
||||||
|
}
|
||||||
|
return &http.Response{
|
||||||
|
StatusCode: http.StatusBadRequest,
|
||||||
|
Body: ioutil.NopCloser(bytes.NewBufferString(message)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responseTransfer := &PluginResponseWriter{}
|
||||||
|
api.app.ServeInterPluginRequest(responseTransfer, request, api.id, destinationPluginId)
|
||||||
|
return responseTransfer.GenerateResponse()
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupPluginApiTest(t *testing.T, pluginCode string, pluginManifest string, pluginId string, app *App) string {
|
func setupMultiPluginApiTest(t *testing.T, pluginCodes []string, pluginManifests []string, pluginIds []string, app *App) string {
|
||||||
pluginDir, err := ioutil.TempDir("", "")
|
pluginDir, err := ioutil.TempDir("", "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
webappPluginDir, err := ioutil.TempDir("", "")
|
webappPluginDir, err := ioutil.TempDir("", "")
|
||||||
@@ -37,20 +37,29 @@ func setupPluginApiTest(t *testing.T, pluginCode string, pluginManifest string,
|
|||||||
env, err := plugin.NewEnvironment(app.NewPluginAPI, pluginDir, webappPluginDir, app.Log)
|
env, err := plugin.NewEnvironment(app.NewPluginAPI, pluginDir, webappPluginDir, app.Log)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
backend := filepath.Join(pluginDir, pluginId, "backend.exe")
|
require.Equal(t, len(pluginCodes), len(pluginIds))
|
||||||
utils.CompileGo(t, pluginCode, backend)
|
require.Equal(t, len(pluginManifests), len(pluginIds))
|
||||||
|
|
||||||
ioutil.WriteFile(filepath.Join(pluginDir, pluginId, "plugin.json"), []byte(pluginManifest), 0600)
|
for i, pluginId := range pluginIds {
|
||||||
|
backend := filepath.Join(pluginDir, pluginId, "backend.exe")
|
||||||
|
utils.CompileGo(t, pluginCodes[i], backend)
|
||||||
|
|
||||||
|
ioutil.WriteFile(filepath.Join(pluginDir, pluginId, "plugin.json"), []byte(pluginManifests[i]), 0600)
|
||||||
manifest, activated, reterr := env.Activate(pluginId)
|
manifest, activated, reterr := env.Activate(pluginId)
|
||||||
require.Nil(t, reterr)
|
require.Nil(t, reterr)
|
||||||
require.NotNil(t, manifest)
|
require.NotNil(t, manifest)
|
||||||
require.True(t, activated)
|
require.True(t, activated)
|
||||||
|
}
|
||||||
|
|
||||||
app.SetPluginsEnvironment(env)
|
app.SetPluginsEnvironment(env)
|
||||||
|
|
||||||
return pluginDir
|
return pluginDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupPluginApiTest(t *testing.T, pluginCode string, pluginManifest string, pluginId string, app *App) string {
|
||||||
|
return setupMultiPluginApiTest(t, []string{pluginCode}, []string{pluginManifest}, []string{pluginId}, app)
|
||||||
|
}
|
||||||
|
|
||||||
func TestPublicFilesPathConfiguration(t *testing.T) {
|
func TestPublicFilesPathConfiguration(t *testing.T) {
|
||||||
th := Setup(t).InitBasic()
|
th := Setup(t).InitBasic()
|
||||||
defer th.TearDown()
|
defer th.TearDown()
|
||||||
@@ -1462,3 +1471,98 @@ func TestPluginAddUserToChannel(t *testing.T) {
|
|||||||
require.Equal(t, th.BasicChannel.Id, member.ChannelId)
|
require.Equal(t, th.BasicChannel.Id, member.ChannelId)
|
||||||
require.Equal(t, th.BasicUser.Id, member.UserId)
|
require.Equal(t, th.BasicUser.Id, member.UserId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInterpluginPluginHTTP(t *testing.T) {
|
||||||
|
th := Setup(t).InitBasic()
|
||||||
|
defer th.TearDown()
|
||||||
|
|
||||||
|
setupMultiPluginApiTest(t,
|
||||||
|
[]string{`
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mattermost/mattermost-server/plugin"
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MyPlugin struct {
|
||||||
|
plugin.MattermostPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *MyPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.URL.Path != "/api/v2/test" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
buf.ReadFrom(r.Body)
|
||||||
|
resp := "we got:" + buf.String()
|
||||||
|
w.WriteHeader(598)
|
||||||
|
w.Write([]byte(resp))
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
plugin.ClientMain(&MyPlugin{})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mattermost/mattermost-server/plugin"
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MyPlugin struct {
|
||||||
|
plugin.MattermostPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *MyPlugin) MessageWillBePosted(c *plugin.Context, post *model.Post) (*model.Post, string) {
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
buf.WriteString("This is the request")
|
||||||
|
req, err := http.NewRequest("GET", "/testplugininterserver/api/v2/test", &buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err.Error()
|
||||||
|
}
|
||||||
|
req.Header.Add("Mattermost-User-Id", "userid")
|
||||||
|
resp := p.API.PluginHTTP(req)
|
||||||
|
if resp == nil {
|
||||||
|
return nil, "Nil resp"
|
||||||
|
}
|
||||||
|
if resp.Body == nil {
|
||||||
|
return nil, "Nil body"
|
||||||
|
}
|
||||||
|
respbody, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err.Error()
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 598 {
|
||||||
|
return nil, "wrong status " + string(respbody)
|
||||||
|
}
|
||||||
|
return nil, string(respbody)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
plugin.ClientMain(&MyPlugin{})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
[]string{
|
||||||
|
`{"id": "testplugininterserver", "backend": {"executable": "backend.exe"}}`,
|
||||||
|
`{"id": "testplugininterclient", "backend": {"executable": "backend.exe"}}`,
|
||||||
|
},
|
||||||
|
[]string{
|
||||||
|
"testplugininterserver",
|
||||||
|
"testplugininterclient",
|
||||||
|
},
|
||||||
|
th.App,
|
||||||
|
)
|
||||||
|
|
||||||
|
hooks, err := th.App.GetPluginsEnvironment().HooksForPlugin("testplugininterclient")
|
||||||
|
require.NoError(t, err)
|
||||||
|
_, ret := hooks.MessageWillBePosted(nil, nil)
|
||||||
|
assert.Equal(t, "we got:This is the request", ret)
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,6 +42,37 @@ func (a *App) ServePluginRequest(w http.ResponseWriter, r *http.Request) {
|
|||||||
a.servePluginRequest(w, r, hooks.ServeHTTP)
|
a.servePluginRequest(w, r, hooks.ServeHTTP)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) ServeInterPluginRequest(w http.ResponseWriter, r *http.Request, sourcePluginId, destinationPluginId string) {
|
||||||
|
pluginsEnvironment := a.GetPluginsEnvironment()
|
||||||
|
if pluginsEnvironment == nil {
|
||||||
|
err := model.NewAppError("ServeInterPluginRequest", "app.plugin.disabled.app_error", nil, "Plugin enviroment not found.", http.StatusNotImplemented)
|
||||||
|
a.Log.Error(err.Error())
|
||||||
|
w.WriteHeader(err.StatusCode)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Write([]byte(err.ToJson()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hooks, err := pluginsEnvironment.HooksForPlugin(destinationPluginId)
|
||||||
|
if err != nil {
|
||||||
|
a.Log.Error("Access to route for non-existent plugin in inter plugin request",
|
||||||
|
mlog.String("sourse_plugin_id", sourcePluginId),
|
||||||
|
mlog.String("destination_plugin_id", destinationPluginId),
|
||||||
|
mlog.Err(err),
|
||||||
|
)
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
context := &plugin.Context{
|
||||||
|
RequestId: model.NewId(),
|
||||||
|
UserAgent: r.UserAgent(),
|
||||||
|
SourcePluginId: sourcePluginId,
|
||||||
|
}
|
||||||
|
|
||||||
|
hooks.ServeHTTP(context, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
// ServePluginPublicRequest serves public plugin files
|
// ServePluginPublicRequest serves public plugin files
|
||||||
// at the URL http(s)://$SITE_URL/plugins/$PLUGIN_ID/public/{anything}
|
// at the URL http(s)://$SITE_URL/plugins/$PLUGIN_ID/public/{anything}
|
||||||
func (a *App) ServePluginPublicRequest(w http.ResponseWriter, r *http.Request) {
|
func (a *App) ServePluginPublicRequest(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
70
app/response_transfer.go
Обычный файл
70
app/response_transfer.go
Обычный файл
@@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginResponseWriter struct {
|
||||||
|
bytes.Buffer
|
||||||
|
headers http.Header
|
||||||
|
statusCode int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rt *PluginResponseWriter) Header() http.Header {
|
||||||
|
if rt.headers == nil {
|
||||||
|
rt.headers = make(http.Header)
|
||||||
|
}
|
||||||
|
return rt.headers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rt *PluginResponseWriter) WriteHeader(statusCode int) {
|
||||||
|
rt.statusCode = statusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// From net/http/httptest/recorder.go
|
||||||
|
func parseContentLength(cl string) int64 {
|
||||||
|
cl = strings.TrimSpace(cl)
|
||||||
|
if cl == "" {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
n, err := strconv.ParseInt(cl, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rt *PluginResponseWriter) GenerateResponse() *http.Response {
|
||||||
|
res := &http.Response{
|
||||||
|
Proto: "HTTP/1.1",
|
||||||
|
ProtoMajor: 1,
|
||||||
|
ProtoMinor: 1,
|
||||||
|
StatusCode: rt.statusCode,
|
||||||
|
Header: rt.headers.Clone(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.StatusCode == 0 {
|
||||||
|
res.StatusCode = http.StatusOK
|
||||||
|
}
|
||||||
|
|
||||||
|
res.Status = fmt.Sprintf("%03d %s", res.StatusCode, http.StatusText(res.StatusCode))
|
||||||
|
|
||||||
|
if rt.Len() > 0 {
|
||||||
|
res.Body = ioutil.NopCloser(rt)
|
||||||
|
} else {
|
||||||
|
res.Body = http.NoBody
|
||||||
|
}
|
||||||
|
|
||||||
|
res.ContentLength = parseContentLength(rt.headers.Get("Content-Length"))
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
@@ -61,7 +61,7 @@ func (s *Server) RunOldAppInitalization() error {
|
|||||||
|
|
||||||
if s.FakeApp().Srv.newStore == nil {
|
if s.FakeApp().Srv.newStore == nil {
|
||||||
s.FakeApp().Srv.newStore = func() store.Store {
|
s.FakeApp().Srv.newStore = func() store.Store {
|
||||||
return store.NewTimerLayer(localcachelayer.NewLocalCacheLayer(store.NewLayeredStore(sqlstore.NewSqlSupplier(s.FakeApp().Config().SqlSettings, s.Metrics), s.Metrics, s.Cluster), s.Metrics, s.Cluster), s.Metrics)
|
return store.NewTimerLayer(localcachelayer.NewLocalCacheLayer(sqlstore.NewSqlSupplier(s.FakeApp().Config().SqlSettings, s.Metrics), s.Metrics, s.Cluster), s.Metrics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/mlog"
|
"github.com/mattermost/mattermost-server/mlog"
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
"github.com/mattermost/mattermost-server/utils"
|
"github.com/mattermost/mattermost-server/utils"
|
||||||
@@ -215,11 +213,11 @@ func (a *App) SetStatusOnline(userId string, manual bool) {
|
|||||||
if status.Status != oldStatus || status.Manual != oldManual || status.LastActivityAt-oldTime > model.STATUS_MIN_UPDATE_TIME {
|
if status.Status != oldStatus || status.Manual != oldManual || status.LastActivityAt-oldTime > model.STATUS_MIN_UPDATE_TIME {
|
||||||
if broadcast {
|
if broadcast {
|
||||||
if err := a.Srv.Store.Status().SaveOrUpdate(status); err != nil {
|
if err := a.Srv.Store.Status().SaveOrUpdate(status); err != nil {
|
||||||
mlog.Error(fmt.Sprintf("Failed to save status for user_id=%v, err=%v", userId, err), mlog.String("user_id", userId))
|
mlog.Error("Failed to save status", mlog.String("user_id", userId), mlog.Err(err), mlog.String("user_id", userId))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := a.Srv.Store.Status().UpdateLastActivityAt(status.UserId, status.LastActivityAt); err != nil {
|
if err := a.Srv.Store.Status().UpdateLastActivityAt(status.UserId, status.LastActivityAt); err != nil {
|
||||||
mlog.Error(fmt.Sprintf("Failed to save status for user_id=%v, err=%v", userId, err), mlog.String("user_id", userId))
|
mlog.Error("Failed to save status", mlog.String("user_id", userId), mlog.Err(err), mlog.String("user_id", userId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,7 +302,7 @@ func (a *App) SaveAndBroadcastStatus(status *model.Status) {
|
|||||||
a.AddStatusCache(status)
|
a.AddStatusCache(status)
|
||||||
|
|
||||||
if err := a.Srv.Store.Status().SaveOrUpdate(status); err != nil {
|
if err := a.Srv.Store.Status().SaveOrUpdate(status); err != nil {
|
||||||
mlog.Error(fmt.Sprintf("Failed to save status for user_id=%v, err=%v", status.UserId, err))
|
mlog.Error("Failed to save status", mlog.String("user_id", status.UserId), mlog.Err(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
a.BroadcastStatus(status)
|
a.BroadcastStatus(status)
|
||||||
|
|||||||
@@ -91,6 +91,9 @@ type PluginSettingsSchema struct {
|
|||||||
// "id": "com.mycompany.myplugin",
|
// "id": "com.mycompany.myplugin",
|
||||||
// "name": "My Plugin",
|
// "name": "My Plugin",
|
||||||
// "description": "This is my plugin",
|
// "description": "This is my plugin",
|
||||||
|
// "homepage_url": "https://example.com",
|
||||||
|
// "support_url": "https://example.com/support",
|
||||||
|
// "icon_path": "assets/logo.svg",
|
||||||
// "version": "0.1.0",
|
// "version": "0.1.0",
|
||||||
// "min_server_version": "5.6.0",
|
// "min_server_version": "5.6.0",
|
||||||
// "server": {
|
// "server": {
|
||||||
|
|||||||
175
plugin/api.go
175
plugin/api.go
@@ -5,6 +5,7 @@ package plugin
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
plugin "github.com/hashicorp/go-plugin"
|
plugin "github.com/hashicorp/go-plugin"
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
@@ -19,17 +20,20 @@ type API interface {
|
|||||||
// LoadPluginConfiguration loads the plugin's configuration. dest should be a pointer to a
|
// LoadPluginConfiguration loads the plugin's configuration. dest should be a pointer to a
|
||||||
// struct that the configuration JSON can be unmarshalled to.
|
// struct that the configuration JSON can be unmarshalled to.
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
LoadPluginConfiguration(dest interface{}) error
|
LoadPluginConfiguration(dest interface{}) error
|
||||||
|
|
||||||
// RegisterCommand registers a custom slash command. When the command is triggered, your plugin
|
// RegisterCommand registers a custom slash command. When the command is triggered, your plugin
|
||||||
// can fulfill it via the ExecuteCommand hook.
|
// can fulfill it via the ExecuteCommand hook.
|
||||||
//
|
//
|
||||||
|
// @tag Command
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
RegisterCommand(command *model.Command) error
|
RegisterCommand(command *model.Command) error
|
||||||
|
|
||||||
// UnregisterCommand unregisters a command previously registered via RegisterCommand.
|
// UnregisterCommand unregisters a command previously registered via RegisterCommand.
|
||||||
//
|
//
|
||||||
|
// @tag Command
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UnregisterCommand(teamId, trigger string) error
|
UnregisterCommand(teamId, trigger string) error
|
||||||
|
|
||||||
@@ -40,139 +44,168 @@ type API interface {
|
|||||||
|
|
||||||
// GetConfig fetches the currently persisted config
|
// GetConfig fetches the currently persisted config
|
||||||
//
|
//
|
||||||
|
// @tag Configuration
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetConfig() *model.Config
|
GetConfig() *model.Config
|
||||||
|
|
||||||
// GetUnsanitizedConfig fetches the currently persisted config without removing secrets.
|
// GetUnsanitizedConfig fetches the currently persisted config without removing secrets.
|
||||||
//
|
//
|
||||||
|
// @tag Configuration
|
||||||
// Minimum server version: 5.16
|
// Minimum server version: 5.16
|
||||||
GetUnsanitizedConfig() *model.Config
|
GetUnsanitizedConfig() *model.Config
|
||||||
|
|
||||||
// SaveConfig sets the given config and persists the changes
|
// SaveConfig sets the given config and persists the changes
|
||||||
//
|
//
|
||||||
|
// @tag Configuration
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
SaveConfig(config *model.Config) *model.AppError
|
SaveConfig(config *model.Config) *model.AppError
|
||||||
|
|
||||||
// GetPluginConfig fetches the currently persisted config of plugin
|
// GetPluginConfig fetches the currently persisted config of plugin
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetPluginConfig() map[string]interface{}
|
GetPluginConfig() map[string]interface{}
|
||||||
|
|
||||||
// SavePluginConfig sets the given config for plugin and persists the changes
|
// SavePluginConfig sets the given config for plugin and persists the changes
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
SavePluginConfig(config map[string]interface{}) *model.AppError
|
SavePluginConfig(config map[string]interface{}) *model.AppError
|
||||||
|
|
||||||
// GetBundlePath returns the absolute path where the plugin's bundle was unpacked.
|
// GetBundlePath returns the absolute path where the plugin's bundle was unpacked.
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
GetBundlePath() (string, error)
|
GetBundlePath() (string, error)
|
||||||
|
|
||||||
// GetLicense returns the current license used by the Mattermost server. Returns nil if the
|
// GetLicense returns the current license used by the Mattermost server. Returns nil if the
|
||||||
// the server does not have a license.
|
// the server does not have a license.
|
||||||
//
|
//
|
||||||
|
// @tag Server
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
GetLicense() *model.License
|
GetLicense() *model.License
|
||||||
|
|
||||||
// GetServerVersion return the current Mattermost server version
|
// GetServerVersion return the current Mattermost server version
|
||||||
//
|
//
|
||||||
|
// @tag Server
|
||||||
// Minimum server version: 5.4
|
// Minimum server version: 5.4
|
||||||
GetServerVersion() string
|
GetServerVersion() string
|
||||||
|
|
||||||
// GetSystemInstallDate returns the time that Mattermost was first installed and ran.
|
// GetSystemInstallDate returns the time that Mattermost was first installed and ran.
|
||||||
//
|
//
|
||||||
|
// @tag Server
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
GetSystemInstallDate() (int64, *model.AppError)
|
GetSystemInstallDate() (int64, *model.AppError)
|
||||||
|
|
||||||
// GetDiagnosticId returns a unique identifier used by the server for diagnostic reports.
|
// GetDiagnosticId returns a unique identifier used by the server for diagnostic reports.
|
||||||
//
|
//
|
||||||
|
// @tag Server
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
GetDiagnosticId() string
|
GetDiagnosticId() string
|
||||||
|
|
||||||
// CreateUser creates a user.
|
// CreateUser creates a user.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
CreateUser(user *model.User) (*model.User, *model.AppError)
|
CreateUser(user *model.User) (*model.User, *model.AppError)
|
||||||
|
|
||||||
// DeleteUser deletes a user.
|
// DeleteUser deletes a user.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
DeleteUser(userId string) *model.AppError
|
DeleteUser(userId string) *model.AppError
|
||||||
|
|
||||||
// GetUsers a list of users based on search options.
|
// GetUsers a list of users based on search options.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
GetUsers(options *model.UserGetOptions) ([]*model.User, *model.AppError)
|
GetUsers(options *model.UserGetOptions) ([]*model.User, *model.AppError)
|
||||||
|
|
||||||
// GetUser gets a user.
|
// GetUser gets a user.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetUser(userId string) (*model.User, *model.AppError)
|
GetUser(userId string) (*model.User, *model.AppError)
|
||||||
|
|
||||||
// GetUserByEmail gets a user by their email address.
|
// GetUserByEmail gets a user by their email address.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetUserByEmail(email string) (*model.User, *model.AppError)
|
GetUserByEmail(email string) (*model.User, *model.AppError)
|
||||||
|
|
||||||
// GetUserByUsername gets a user by their username.
|
// GetUserByUsername gets a user by their username.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetUserByUsername(name string) (*model.User, *model.AppError)
|
GetUserByUsername(name string) (*model.User, *model.AppError)
|
||||||
|
|
||||||
// GetUsersByUsernames gets users by their usernames.
|
// GetUsersByUsernames gets users by their usernames.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetUsersByUsernames(usernames []string) ([]*model.User, *model.AppError)
|
GetUsersByUsernames(usernames []string) ([]*model.User, *model.AppError)
|
||||||
|
|
||||||
// GetUsersInTeam gets users in team.
|
// GetUsersInTeam gets users in team.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetUsersInTeam(teamId string, page int, perPage int) ([]*model.User, *model.AppError)
|
GetUsersInTeam(teamId string, page int, perPage int) ([]*model.User, *model.AppError)
|
||||||
|
|
||||||
// GetTeamIcon gets the team icon.
|
// GetTeamIcon gets the team icon.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetTeamIcon(teamId string) ([]byte, *model.AppError)
|
GetTeamIcon(teamId string) ([]byte, *model.AppError)
|
||||||
|
|
||||||
// SetTeamIcon sets the team icon.
|
// SetTeamIcon sets the team icon.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
SetTeamIcon(teamId string, data []byte) *model.AppError
|
SetTeamIcon(teamId string, data []byte) *model.AppError
|
||||||
|
|
||||||
// RemoveTeamIcon removes the team icon.
|
// RemoveTeamIcon removes the team icon.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
RemoveTeamIcon(teamId string) *model.AppError
|
RemoveTeamIcon(teamId string) *model.AppError
|
||||||
|
|
||||||
// UpdateUser updates a user.
|
// UpdateUser updates a user.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UpdateUser(user *model.User) (*model.User, *model.AppError)
|
UpdateUser(user *model.User) (*model.User, *model.AppError)
|
||||||
|
|
||||||
// GetUserStatus will get a user's status.
|
// GetUserStatus will get a user's status.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetUserStatus(userId string) (*model.Status, *model.AppError)
|
GetUserStatus(userId string) (*model.Status, *model.AppError)
|
||||||
|
|
||||||
// GetUserStatusesByIds will return a list of user statuses based on the provided slice of user IDs.
|
// GetUserStatusesByIds will return a list of user statuses based on the provided slice of user IDs.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetUserStatusesByIds(userIds []string) ([]*model.Status, *model.AppError)
|
GetUserStatusesByIds(userIds []string) ([]*model.Status, *model.AppError)
|
||||||
|
|
||||||
// UpdateUserStatus will set a user's status until the user, or another integration/plugin, sets it back to online.
|
// UpdateUserStatus will set a user's status until the user, or another integration/plugin, sets it back to online.
|
||||||
// The status parameter can be: "online", "away", "dnd", or "offline".
|
// The status parameter can be: "online", "away", "dnd", or "offline".
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UpdateUserStatus(userId, status string) (*model.Status, *model.AppError)
|
UpdateUserStatus(userId, status string) (*model.Status, *model.AppError)
|
||||||
|
|
||||||
// UpdateUserActive deactivates or reactivates an user.
|
// UpdateUserActive deactivates or reactivates an user.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.8
|
// Minimum server version: 5.8
|
||||||
UpdateUserActive(userId string, active bool) *model.AppError
|
UpdateUserActive(userId string, active bool) *model.AppError
|
||||||
|
|
||||||
// GetUsersInChannel returns a page of users in a channel. Page counting starts at 0.
|
// GetUsersInChannel returns a page of users in a channel. Page counting starts at 0.
|
||||||
// The sortBy parameter can be: "username" or "status".
|
// The sortBy parameter can be: "username" or "status".
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetUsersInChannel(channelId, sortBy string, page, perPage int) ([]*model.User, *model.AppError)
|
GetUsersInChannel(channelId, sortBy string, page, perPage int) ([]*model.User, *model.AppError)
|
||||||
|
|
||||||
@@ -181,312 +214,403 @@ type API interface {
|
|||||||
// Returns a map with attribute names as keys and the user's attributes as values.
|
// Returns a map with attribute names as keys and the user's attributes as values.
|
||||||
// Requires an enterprise license, LDAP to be configured and for the user to use LDAP as an authentication method.
|
// Requires an enterprise license, LDAP to be configured and for the user to use LDAP as an authentication method.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.3
|
// Minimum server version: 5.3
|
||||||
GetLDAPUserAttributes(userId string, attributes []string) (map[string]string, *model.AppError)
|
GetLDAPUserAttributes(userId string, attributes []string) (map[string]string, *model.AppError)
|
||||||
|
|
||||||
// CreateTeam creates a team.
|
// CreateTeam creates a team.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
CreateTeam(team *model.Team) (*model.Team, *model.AppError)
|
CreateTeam(team *model.Team) (*model.Team, *model.AppError)
|
||||||
|
|
||||||
// DeleteTeam deletes a team.
|
// DeleteTeam deletes a team.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
DeleteTeam(teamId string) *model.AppError
|
DeleteTeam(teamId string) *model.AppError
|
||||||
|
|
||||||
// GetTeam gets all teams.
|
// GetTeam gets all teams.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetTeams() ([]*model.Team, *model.AppError)
|
GetTeams() ([]*model.Team, *model.AppError)
|
||||||
|
|
||||||
// GetTeam gets a team.
|
// GetTeam gets a team.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetTeam(teamId string) (*model.Team, *model.AppError)
|
GetTeam(teamId string) (*model.Team, *model.AppError)
|
||||||
|
|
||||||
// GetTeamByName gets a team by its name.
|
// GetTeamByName gets a team by its name.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetTeamByName(name string) (*model.Team, *model.AppError)
|
GetTeamByName(name string) (*model.Team, *model.AppError)
|
||||||
|
|
||||||
// GetTeamsUnreadForUser gets the unread message and mention counts for each team to which the given user belongs.
|
// GetTeamsUnreadForUser gets the unread message and mention counts for each team to which the given user belongs.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetTeamsUnreadForUser(userId string) ([]*model.TeamUnread, *model.AppError)
|
GetTeamsUnreadForUser(userId string) ([]*model.TeamUnread, *model.AppError)
|
||||||
|
|
||||||
// UpdateTeam updates a team.
|
// UpdateTeam updates a team.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UpdateTeam(team *model.Team) (*model.Team, *model.AppError)
|
UpdateTeam(team *model.Team) (*model.Team, *model.AppError)
|
||||||
|
|
||||||
// SearchTeams search a team.
|
// SearchTeams search a team.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.8
|
// Minimum server version: 5.8
|
||||||
SearchTeams(term string) ([]*model.Team, *model.AppError)
|
SearchTeams(term string) ([]*model.Team, *model.AppError)
|
||||||
|
|
||||||
// GetTeamsForUser returns list of teams of given user ID.
|
// GetTeamsForUser returns list of teams of given user ID.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetTeamsForUser(userId string) ([]*model.Team, *model.AppError)
|
GetTeamsForUser(userId string) ([]*model.Team, *model.AppError)
|
||||||
|
|
||||||
// CreateTeamMember creates a team membership.
|
// CreateTeamMember creates a team membership.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
CreateTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError)
|
CreateTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError)
|
||||||
|
|
||||||
// CreateTeamMember creates a team membership for all provided user ids.
|
// CreateTeamMembers creates a team membership for all provided user ids.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
CreateTeamMembers(teamId string, userIds []string, requestorId string) ([]*model.TeamMember, *model.AppError)
|
CreateTeamMembers(teamId string, userIds []string, requestorId string) ([]*model.TeamMember, *model.AppError)
|
||||||
|
|
||||||
// DeleteTeamMember deletes a team membership.
|
// DeleteTeamMember deletes a team membership.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
DeleteTeamMember(teamId, userId, requestorId string) *model.AppError
|
DeleteTeamMember(teamId, userId, requestorId string) *model.AppError
|
||||||
|
|
||||||
// GetTeamMembers returns the memberships of a specific team.
|
// GetTeamMembers returns the memberships of a specific team.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetTeamMembers(teamId string, page, perPage int) ([]*model.TeamMember, *model.AppError)
|
GetTeamMembers(teamId string, page, perPage int) ([]*model.TeamMember, *model.AppError)
|
||||||
|
|
||||||
// GetTeamMember returns a specific membership.
|
// GetTeamMember returns a specific membership.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError)
|
GetTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError)
|
||||||
|
|
||||||
// GetTeamMembersForUser returns all team memberships for a user.
|
// GetTeamMembersForUser returns all team memberships for a user.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
GetTeamMembersForUser(userId string, page int, perPage int) ([]*model.TeamMember, *model.AppError)
|
GetTeamMembersForUser(userId string, page int, perPage int) ([]*model.TeamMember, *model.AppError)
|
||||||
|
|
||||||
// UpdateTeamMemberRoles updates the role for a team membership.
|
// UpdateTeamMemberRoles updates the role for a team membership.
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UpdateTeamMemberRoles(teamId, userId, newRoles string) (*model.TeamMember, *model.AppError)
|
UpdateTeamMemberRoles(teamId, userId, newRoles string) (*model.TeamMember, *model.AppError)
|
||||||
|
|
||||||
// CreateChannel creates a channel.
|
// CreateChannel creates a channel.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
CreateChannel(channel *model.Channel) (*model.Channel, *model.AppError)
|
CreateChannel(channel *model.Channel) (*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// DeleteChannel deletes a channel.
|
// DeleteChannel deletes a channel.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
DeleteChannel(channelId string) *model.AppError
|
DeleteChannel(channelId string) *model.AppError
|
||||||
|
|
||||||
// GetPublicChannelsForTeam gets a list of all channels.
|
// GetPublicChannelsForTeam gets a list of all channels.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetPublicChannelsForTeam(teamId string, page, perPage int) ([]*model.Channel, *model.AppError)
|
GetPublicChannelsForTeam(teamId string, page, perPage int) ([]*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// GetChannel gets a channel.
|
// GetChannel gets a channel.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetChannel(channelId string) (*model.Channel, *model.AppError)
|
GetChannel(channelId string) (*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// GetChannelByName gets a channel by its name, given a team id.
|
// GetChannelByName gets a channel by its name, given a team id.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetChannelByName(teamId, name string, includeDeleted bool) (*model.Channel, *model.AppError)
|
GetChannelByName(teamId, name string, includeDeleted bool) (*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// GetChannelByNameForTeamName gets a channel by its name, given a team name.
|
// GetChannelByNameForTeamName gets a channel by its name, given a team name.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetChannelByNameForTeamName(teamName, channelName string, includeDeleted bool) (*model.Channel, *model.AppError)
|
GetChannelByNameForTeamName(teamName, channelName string, includeDeleted bool) (*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// GetChannelsForTeamForUser gets a list of channels for given user ID in given team ID.
|
// GetChannelsForTeamForUser gets a list of channels for given user ID in given team ID.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag Team
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetChannelsForTeamForUser(teamId, userId string, includeDeleted bool) ([]*model.Channel, *model.AppError)
|
GetChannelsForTeamForUser(teamId, userId string, includeDeleted bool) ([]*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// GetChannelStats gets statistics for a channel.
|
// GetChannelStats gets statistics for a channel.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetChannelStats(channelId string) (*model.ChannelStats, *model.AppError)
|
GetChannelStats(channelId string) (*model.ChannelStats, *model.AppError)
|
||||||
|
|
||||||
// GetDirectChannel gets a direct message channel.
|
// GetDirectChannel gets a direct message channel.
|
||||||
// If the channel does not exist it will create it.
|
// If the channel does not exist it will create it.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError)
|
GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// GetGroupChannel gets a group message channel.
|
// GetGroupChannel gets a group message channel.
|
||||||
// If the channel does not exist it will create it.
|
// If the channel does not exist it will create it.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetGroupChannel(userIds []string) (*model.Channel, *model.AppError)
|
GetGroupChannel(userIds []string) (*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// UpdateChannel updates a channel.
|
// UpdateChannel updates a channel.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError)
|
UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// SearchChannels returns the channels on a team matching the provided search term.
|
// SearchChannels returns the channels on a team matching the provided search term.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
SearchChannels(teamId string, term string) ([]*model.Channel, *model.AppError)
|
SearchChannels(teamId string, term string) ([]*model.Channel, *model.AppError)
|
||||||
|
|
||||||
// SearchUsers returns a list of users based on some search criteria.
|
// SearchUsers returns a list of users based on some search criteria.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
SearchUsers(search *model.UserSearch) ([]*model.User, *model.AppError)
|
SearchUsers(search *model.UserSearch) ([]*model.User, *model.AppError)
|
||||||
|
|
||||||
// SearchPostsInTeam returns a list of posts in a specific team that match the given params.
|
// SearchPostsInTeam returns a list of posts in a specific team that match the given params.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
SearchPostsInTeam(teamId string, paramsList []*model.SearchParams) ([]*model.Post, *model.AppError)
|
SearchPostsInTeam(teamId string, paramsList []*model.SearchParams) ([]*model.Post, *model.AppError)
|
||||||
|
|
||||||
// AddChannelMember joins a user to a channel (as if they joined themselves)
|
// AddChannelMember joins a user to a channel (as if they joined themselves)
|
||||||
// This means the user will not receive notifications for joining the channel.
|
// This means the user will not receive notifications for joining the channel.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
AddChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError)
|
AddChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError)
|
||||||
|
|
||||||
// AddUserToChannel adds a user to a channel as if the specified user had invited them.
|
// AddUserToChannel adds a user to a channel as if the specified user had invited them.
|
||||||
// This means the user will receive the regular notifications for being added to the channel.
|
// This means the user will receive the regular notifications for being added to the channel.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.18
|
// Minimum server version: 5.18
|
||||||
AddUserToChannel(channelId, userId, asUserId string) (*model.ChannelMember, *model.AppError)
|
AddUserToChannel(channelId, userId, asUserId string) (*model.ChannelMember, *model.AppError)
|
||||||
|
|
||||||
// GetChannelMember gets a channel membership for a user.
|
// GetChannelMember gets a channel membership for a user.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError)
|
GetChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError)
|
||||||
|
|
||||||
// GetChannelMembers gets a channel membership for all users.
|
// GetChannelMembers gets a channel membership for all users.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetChannelMembers(channelId string, page, perPage int) (*model.ChannelMembers, *model.AppError)
|
GetChannelMembers(channelId string, page, perPage int) (*model.ChannelMembers, *model.AppError)
|
||||||
|
|
||||||
// GetChannelMembersByIds gets a channel membership for a particular User
|
// GetChannelMembersByIds gets a channel membership for a particular User
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetChannelMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError)
|
GetChannelMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError)
|
||||||
|
|
||||||
// GetChannelMembersForUser returns all channel memberships on a team for a user.
|
// GetChannelMembersForUser returns all channel memberships on a team for a user.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
GetChannelMembersForUser(teamId, userId string, page, perPage int) ([]*model.ChannelMember, *model.AppError)
|
GetChannelMembersForUser(teamId, userId string, page, perPage int) ([]*model.ChannelMember, *model.AppError)
|
||||||
|
|
||||||
// UpdateChannelMemberRoles updates a user's roles for a channel.
|
// UpdateChannelMemberRoles updates a user's roles for a channel.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UpdateChannelMemberRoles(channelId, userId, newRoles string) (*model.ChannelMember, *model.AppError)
|
UpdateChannelMemberRoles(channelId, userId, newRoles string) (*model.ChannelMember, *model.AppError)
|
||||||
|
|
||||||
// UpdateChannelMemberNotifications updates a user's notification properties for a channel.
|
// UpdateChannelMemberNotifications updates a user's notification properties for a channel.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError)
|
UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError)
|
||||||
|
|
||||||
// GetGroup gets a group by ID.
|
// GetGroup gets a group by ID.
|
||||||
//
|
//
|
||||||
|
// @tag Group
|
||||||
// Minimum server version: 5.18
|
// Minimum server version: 5.18
|
||||||
GetGroup(groupId string) (*model.Group, *model.AppError)
|
GetGroup(groupId string) (*model.Group, *model.AppError)
|
||||||
|
|
||||||
// GetGroupByName gets a group by name.
|
// GetGroupByName gets a group by name.
|
||||||
//
|
//
|
||||||
|
// @tag Group
|
||||||
// Minimum server version: 5.18
|
// Minimum server version: 5.18
|
||||||
GetGroupByName(name string) (*model.Group, *model.AppError)
|
GetGroupByName(name string) (*model.Group, *model.AppError)
|
||||||
|
|
||||||
// GetGroupsForUser gets the groups a user is in.
|
// GetGroupsForUser gets the groups a user is in.
|
||||||
//
|
//
|
||||||
|
// @tag Group
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.18
|
// Minimum server version: 5.18
|
||||||
GetGroupsForUser(userId string) ([]*model.Group, *model.AppError)
|
GetGroupsForUser(userId string) ([]*model.Group, *model.AppError)
|
||||||
|
|
||||||
// DeleteChannelMember deletes a channel membership for a user.
|
// DeleteChannelMember deletes a channel membership for a user.
|
||||||
//
|
//
|
||||||
|
// @tag Channel
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
DeleteChannelMember(channelId, userId string) *model.AppError
|
DeleteChannelMember(channelId, userId string) *model.AppError
|
||||||
|
|
||||||
// CreatePost creates a post.
|
// CreatePost creates a post.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
CreatePost(post *model.Post) (*model.Post, *model.AppError)
|
CreatePost(post *model.Post) (*model.Post, *model.AppError)
|
||||||
|
|
||||||
// AddReaction add a reaction to a post.
|
// AddReaction add a reaction to a post.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.3
|
// Minimum server version: 5.3
|
||||||
AddReaction(reaction *model.Reaction) (*model.Reaction, *model.AppError)
|
AddReaction(reaction *model.Reaction) (*model.Reaction, *model.AppError)
|
||||||
|
|
||||||
// RemoveReaction remove a reaction from a post.
|
// RemoveReaction remove a reaction from a post.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.3
|
// Minimum server version: 5.3
|
||||||
RemoveReaction(reaction *model.Reaction) *model.AppError
|
RemoveReaction(reaction *model.Reaction) *model.AppError
|
||||||
|
|
||||||
// GetReaction get the reactions of a post.
|
// GetReaction get the reactions of a post.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.3
|
// Minimum server version: 5.3
|
||||||
GetReactions(postId string) ([]*model.Reaction, *model.AppError)
|
GetReactions(postId string) ([]*model.Reaction, *model.AppError)
|
||||||
|
|
||||||
// SendEphemeralPost creates an ephemeral post.
|
// SendEphemeralPost creates an ephemeral post.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
SendEphemeralPost(userId string, post *model.Post) *model.Post
|
SendEphemeralPost(userId string, post *model.Post) *model.Post
|
||||||
|
|
||||||
// UpdateEphemeralPost updates an ephemeral message previously sent to the user.
|
// UpdateEphemeralPost updates an ephemeral message previously sent to the user.
|
||||||
// EXPERIMENTAL: This API is experimental and can be changed without advance notice.
|
// EXPERIMENTAL: This API is experimental and can be changed without advance notice.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UpdateEphemeralPost(userId string, post *model.Post) *model.Post
|
UpdateEphemeralPost(userId string, post *model.Post) *model.Post
|
||||||
|
|
||||||
// DeleteEphemeralPost deletes an ephemeral message previously sent to the user.
|
// DeleteEphemeralPost deletes an ephemeral message previously sent to the user.
|
||||||
// EXPERIMENTAL: This API is experimental and can be changed without advance notice.
|
// EXPERIMENTAL: This API is experimental and can be changed without advance notice.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
DeleteEphemeralPost(userId, postId string)
|
DeleteEphemeralPost(userId, postId string)
|
||||||
|
|
||||||
// DeletePost deletes a post.
|
// DeletePost deletes a post.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
DeletePost(postId string) *model.AppError
|
DeletePost(postId string) *model.AppError
|
||||||
|
|
||||||
// GetPostThread gets a post with all the other posts in the same thread.
|
// GetPostThread gets a post with all the other posts in the same thread.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetPostThread(postId string) (*model.PostList, *model.AppError)
|
GetPostThread(postId string) (*model.PostList, *model.AppError)
|
||||||
|
|
||||||
// GetPost gets a post.
|
// GetPost gets a post.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
GetPost(postId string) (*model.Post, *model.AppError)
|
GetPost(postId string) (*model.Post, *model.AppError)
|
||||||
|
|
||||||
// GetPostsSince gets posts created after a specified time as Unix time in milliseconds.
|
// GetPostsSince gets posts created after a specified time as Unix time in milliseconds.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetPostsSince(channelId string, time int64) (*model.PostList, *model.AppError)
|
GetPostsSince(channelId string, time int64) (*model.PostList, *model.AppError)
|
||||||
|
|
||||||
// GetPostsAfter gets a page of posts that were posted after the post provided.
|
// GetPostsAfter gets a page of posts that were posted after the post provided.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetPostsAfter(channelId, postId string, page, perPage int) (*model.PostList, *model.AppError)
|
GetPostsAfter(channelId, postId string, page, perPage int) (*model.PostList, *model.AppError)
|
||||||
|
|
||||||
// GetPostsBefore gets a page of posts that were posted before the post provided.
|
// GetPostsBefore gets a page of posts that were posted before the post provided.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetPostsBefore(channelId, postId string, page, perPage int) (*model.PostList, *model.AppError)
|
GetPostsBefore(channelId, postId string, page, perPage int) (*model.PostList, *model.AppError)
|
||||||
|
|
||||||
// GetPostsForChannel gets a list of posts for a channel.
|
// GetPostsForChannel gets a list of posts for a channel.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetPostsForChannel(channelId string, page, perPage int) (*model.PostList, *model.AppError)
|
GetPostsForChannel(channelId string, page, perPage int) (*model.PostList, *model.AppError)
|
||||||
|
|
||||||
// GetTeamStats gets a team's statistics
|
// GetTeamStats gets a team's statistics
|
||||||
//
|
//
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.8
|
// Minimum server version: 5.8
|
||||||
GetTeamStats(teamId string) (*model.TeamStats, *model.AppError)
|
GetTeamStats(teamId string) (*model.TeamStats, *model.AppError)
|
||||||
|
|
||||||
// UpdatePost updates a post.
|
// UpdatePost updates a post.
|
||||||
//
|
//
|
||||||
|
// @tag Post
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
UpdatePost(post *model.Post) (*model.Post, *model.AppError)
|
UpdatePost(post *model.Post) (*model.Post, *model.AppError)
|
||||||
|
|
||||||
// GetProfileImage gets user's profile image.
|
// GetProfileImage gets user's profile image.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetProfileImage(userId string) ([]byte, *model.AppError)
|
GetProfileImage(userId string) ([]byte, *model.AppError)
|
||||||
|
|
||||||
// SetProfileImage sets a user's profile image.
|
// SetProfileImage sets a user's profile image.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
SetProfileImage(userId string, data []byte) *model.AppError
|
SetProfileImage(userId string, data []byte) *model.AppError
|
||||||
|
|
||||||
@@ -494,16 +618,19 @@ type API interface {
|
|||||||
//
|
//
|
||||||
// The sortBy parameter can be: "name".
|
// The sortBy parameter can be: "name".
|
||||||
//
|
//
|
||||||
|
// @tag Emoji
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetEmojiList(sortBy string, page, perPage int) ([]*model.Emoji, *model.AppError)
|
GetEmojiList(sortBy string, page, perPage int) ([]*model.Emoji, *model.AppError)
|
||||||
|
|
||||||
// GetEmojiByName gets an emoji by it's name.
|
// GetEmojiByName gets an emoji by it's name.
|
||||||
//
|
//
|
||||||
|
// @tag Emoji
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetEmojiByName(name string) (*model.Emoji, *model.AppError)
|
GetEmojiByName(name string) (*model.Emoji, *model.AppError)
|
||||||
|
|
||||||
// GetEmoji returns a custom emoji based on the emojiId string.
|
// GetEmoji returns a custom emoji based on the emojiId string.
|
||||||
//
|
//
|
||||||
|
// @tag Emoji
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetEmoji(emojiId string) (*model.Emoji, *model.AppError)
|
GetEmoji(emojiId string) (*model.Emoji, *model.AppError)
|
||||||
|
|
||||||
@@ -514,36 +641,45 @@ type API interface {
|
|||||||
// to CreatePost. Use this API to duplicate a post and its file attachments without
|
// to CreatePost. Use this API to duplicate a post and its file attachments without
|
||||||
// actually duplicating the uploaded files.
|
// actually duplicating the uploaded files.
|
||||||
//
|
//
|
||||||
|
// @tag File
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
CopyFileInfos(userId string, fileIds []string) ([]string, *model.AppError)
|
CopyFileInfos(userId string, fileIds []string) ([]string, *model.AppError)
|
||||||
|
|
||||||
// GetFileInfo gets a File Info for a specific fileId
|
// GetFileInfo gets a File Info for a specific fileId
|
||||||
//
|
//
|
||||||
|
// @tag File
|
||||||
// Minimum server version: 5.3
|
// Minimum server version: 5.3
|
||||||
GetFileInfo(fileId string) (*model.FileInfo, *model.AppError)
|
GetFileInfo(fileId string) (*model.FileInfo, *model.AppError)
|
||||||
|
|
||||||
// GetFile gets content of a file by it's ID
|
// GetFile gets content of a file by it's ID
|
||||||
//
|
//
|
||||||
|
// @tag File
|
||||||
// Minimum server version: 5.8
|
// Minimum server version: 5.8
|
||||||
GetFile(fileId string) ([]byte, *model.AppError)
|
GetFile(fileId string) ([]byte, *model.AppError)
|
||||||
|
|
||||||
// GetFileLink gets the public link to a file by fileId.
|
// GetFileLink gets the public link to a file by fileId.
|
||||||
//
|
//
|
||||||
|
// @tag File
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetFileLink(fileId string) (string, *model.AppError)
|
GetFileLink(fileId string) (string, *model.AppError)
|
||||||
|
|
||||||
// ReadFileAtPath reads the file from the backend for a specific path
|
// ReadFileAtPath reads the file from the backend for a specific path
|
||||||
//
|
//
|
||||||
|
// @tag File
|
||||||
// Minimum server version: 5.3
|
// Minimum server version: 5.3
|
||||||
ReadFile(path string) ([]byte, *model.AppError)
|
ReadFile(path string) ([]byte, *model.AppError)
|
||||||
|
|
||||||
// GetEmojiImage returns the emoji image.
|
// GetEmojiImage returns the emoji image.
|
||||||
//
|
//
|
||||||
|
// @tag Emoji
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetEmojiImage(emojiId string) ([]byte, string, *model.AppError)
|
GetEmojiImage(emojiId string) ([]byte, string, *model.AppError)
|
||||||
|
|
||||||
// UploadFile will upload a file to a channel using a multipart request, to be later attached to a post.
|
// UploadFile will upload a file to a channel using a multipart request, to be later attached to a post.
|
||||||
//
|
//
|
||||||
|
// @tag File
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
UploadFile(data []byte, channelId string, filename string) (*model.FileInfo, *model.AppError)
|
UploadFile(data []byte, channelId string, filename string) (*model.FileInfo, *model.AppError)
|
||||||
|
|
||||||
@@ -558,32 +694,38 @@ type API interface {
|
|||||||
|
|
||||||
// GetPlugins will return a list of plugin manifests for currently active plugins.
|
// GetPlugins will return a list of plugin manifests for currently active plugins.
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetPlugins() ([]*model.Manifest, *model.AppError)
|
GetPlugins() ([]*model.Manifest, *model.AppError)
|
||||||
|
|
||||||
// EnablePlugin will enable an plugin installed.
|
// EnablePlugin will enable an plugin installed.
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
EnablePlugin(id string) *model.AppError
|
EnablePlugin(id string) *model.AppError
|
||||||
|
|
||||||
// DisablePlugin will disable an enabled plugin.
|
// DisablePlugin will disable an enabled plugin.
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
DisablePlugin(id string) *model.AppError
|
DisablePlugin(id string) *model.AppError
|
||||||
|
|
||||||
// RemovePlugin will disable and delete a plugin.
|
// RemovePlugin will disable and delete a plugin.
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
RemovePlugin(id string) *model.AppError
|
RemovePlugin(id string) *model.AppError
|
||||||
|
|
||||||
// GetPluginStatus will return the status of a plugin.
|
// GetPluginStatus will return the status of a plugin.
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
GetPluginStatus(id string) (*model.PluginStatus, *model.AppError)
|
GetPluginStatus(id string) (*model.PluginStatus, *model.AppError)
|
||||||
|
|
||||||
// InstallPlugin will upload another plugin with tar.gz file.
|
// InstallPlugin will upload another plugin with tar.gz file.
|
||||||
// Previous version will be replaced on replace true.
|
// Previous version will be replaced on replace true.
|
||||||
//
|
//
|
||||||
|
// @tag Plugin
|
||||||
// Minimum server version: 5.18
|
// Minimum server version: 5.18
|
||||||
InstallPlugin(file io.Reader, replace bool) (*model.Manifest, *model.AppError)
|
InstallPlugin(file io.Reader, replace bool) (*model.Manifest, *model.AppError)
|
||||||
|
|
||||||
@@ -592,6 +734,7 @@ type API interface {
|
|||||||
// KVSet stores a key-value pair, unique per plugin.
|
// KVSet stores a key-value pair, unique per plugin.
|
||||||
// Provided helper functions and internal plugin code will use the prefix `mmi_` before keys. Do not use this prefix.
|
// Provided helper functions and internal plugin code will use the prefix `mmi_` before keys. Do not use this prefix.
|
||||||
//
|
//
|
||||||
|
// @tag KeyValueStore
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
KVSet(key string, value []byte) *model.AppError
|
KVSet(key string, value []byte) *model.AppError
|
||||||
|
|
||||||
@@ -601,6 +744,7 @@ type API interface {
|
|||||||
// Returns (false, nil) if current value != oldValue or key already exists when inserting
|
// Returns (false, nil) if current value != oldValue or key already exists when inserting
|
||||||
// Returns (true, nil) if current value == oldValue or new key is inserted
|
// Returns (true, nil) if current value == oldValue or new key is inserted
|
||||||
//
|
//
|
||||||
|
// @tag KeyValueStore
|
||||||
// Minimum server version: 5.12
|
// Minimum server version: 5.12
|
||||||
KVCompareAndSet(key string, oldValue, newValue []byte) (bool, *model.AppError)
|
KVCompareAndSet(key string, oldValue, newValue []byte) (bool, *model.AppError)
|
||||||
|
|
||||||
@@ -609,6 +753,7 @@ type API interface {
|
|||||||
// Returns (false, nil) if current value != oldValue or key does not exist when deleting
|
// Returns (false, nil) if current value != oldValue or key does not exist when deleting
|
||||||
// Returns (true, nil) if current value == oldValue and the key was deleted
|
// Returns (true, nil) if current value == oldValue and the key was deleted
|
||||||
//
|
//
|
||||||
|
// @tag KeyValueStore
|
||||||
// Minimum server version: 5.16
|
// Minimum server version: 5.16
|
||||||
KVCompareAndDelete(key string, oldValue []byte) (bool, *model.AppError)
|
KVCompareAndDelete(key string, oldValue []byte) (bool, *model.AppError)
|
||||||
|
|
||||||
@@ -623,26 +768,31 @@ type API interface {
|
|||||||
|
|
||||||
// KVSet stores a key-value pair with an expiry time, unique per plugin.
|
// KVSet stores a key-value pair with an expiry time, unique per plugin.
|
||||||
//
|
//
|
||||||
|
// @tag KeyValueStore
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
KVSetWithExpiry(key string, value []byte, expireInSeconds int64) *model.AppError
|
KVSetWithExpiry(key string, value []byte, expireInSeconds int64) *model.AppError
|
||||||
|
|
||||||
// KVGet retrieves a value based on the key, unique per plugin. Returns nil for non-existent keys.
|
// KVGet retrieves a value based on the key, unique per plugin. Returns nil for non-existent keys.
|
||||||
//
|
//
|
||||||
|
// @tag KeyValueStore
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
KVGet(key string) ([]byte, *model.AppError)
|
KVGet(key string) ([]byte, *model.AppError)
|
||||||
|
|
||||||
// KVDelete removes a key-value pair, unique per plugin. Returns nil for non-existent keys.
|
// KVDelete removes a key-value pair, unique per plugin. Returns nil for non-existent keys.
|
||||||
//
|
//
|
||||||
|
// @tag KeyValueStore
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
KVDelete(key string) *model.AppError
|
KVDelete(key string) *model.AppError
|
||||||
|
|
||||||
// KVDeleteAll removes all key-value pairs for a plugin.
|
// KVDeleteAll removes all key-value pairs for a plugin.
|
||||||
//
|
//
|
||||||
|
// @tag KeyValueStore
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
KVDeleteAll() *model.AppError
|
KVDeleteAll() *model.AppError
|
||||||
|
|
||||||
// KVList lists all keys for a plugin.
|
// KVList lists all keys for a plugin.
|
||||||
//
|
//
|
||||||
|
// @tag KeyValueStore
|
||||||
// Minimum server version: 5.6
|
// Minimum server version: 5.6
|
||||||
KVList(page, perPage int) ([]string, *model.AppError)
|
KVList(page, perPage int) ([]string, *model.AppError)
|
||||||
|
|
||||||
@@ -656,16 +806,21 @@ type API interface {
|
|||||||
|
|
||||||
// HasPermissionTo check if the user has the permission at system scope.
|
// HasPermissionTo check if the user has the permission at system scope.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
// Minimum server version: 5.3
|
// Minimum server version: 5.3
|
||||||
HasPermissionTo(userId string, permission *model.Permission) bool
|
HasPermissionTo(userId string, permission *model.Permission) bool
|
||||||
|
|
||||||
// HasPermissionToTeam check if the user has the permission at team scope.
|
// HasPermissionToTeam check if the user has the permission at team scope.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
|
// @tag Team
|
||||||
// Minimum server version: 5.3
|
// Minimum server version: 5.3
|
||||||
HasPermissionToTeam(userId, teamId string, permission *model.Permission) bool
|
HasPermissionToTeam(userId, teamId string, permission *model.Permission) bool
|
||||||
|
|
||||||
// HasPermissionToChannel check if the user has the permission at channel scope.
|
// HasPermissionToChannel check if the user has the permission at channel scope.
|
||||||
//
|
//
|
||||||
|
// @tag User
|
||||||
|
// @tag Channel
|
||||||
// Minimum server version: 5.3
|
// Minimum server version: 5.3
|
||||||
HasPermissionToChannel(userId, channelId string, permission *model.Permission) bool
|
HasPermissionToChannel(userId, channelId string, permission *model.Permission) bool
|
||||||
|
|
||||||
@@ -673,6 +828,7 @@ type API interface {
|
|||||||
// Appropriate context such as the plugin name will already be added as fields so plugins
|
// Appropriate context such as the plugin name will already be added as fields so plugins
|
||||||
// do not need to add that info.
|
// do not need to add that info.
|
||||||
//
|
//
|
||||||
|
// @tag Logging
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
LogDebug(msg string, keyValuePairs ...interface{})
|
LogDebug(msg string, keyValuePairs ...interface{})
|
||||||
|
|
||||||
@@ -680,6 +836,7 @@ type API interface {
|
|||||||
// Appropriate context such as the plugin name will already be added as fields so plugins
|
// Appropriate context such as the plugin name will already be added as fields so plugins
|
||||||
// do not need to add that info.
|
// do not need to add that info.
|
||||||
//
|
//
|
||||||
|
// @tag Logging
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
LogInfo(msg string, keyValuePairs ...interface{})
|
LogInfo(msg string, keyValuePairs ...interface{})
|
||||||
|
|
||||||
@@ -687,6 +844,7 @@ type API interface {
|
|||||||
// Appropriate context such as the plugin name will already be added as fields so plugins
|
// Appropriate context such as the plugin name will already be added as fields so plugins
|
||||||
// do not need to add that info.
|
// do not need to add that info.
|
||||||
//
|
//
|
||||||
|
// @tag Logging
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
LogError(msg string, keyValuePairs ...interface{})
|
LogError(msg string, keyValuePairs ...interface{})
|
||||||
|
|
||||||
@@ -694,6 +852,7 @@ type API interface {
|
|||||||
// Appropriate context such as the plugin name will already be added as fields so plugins
|
// Appropriate context such as the plugin name will already be added as fields so plugins
|
||||||
// do not need to add that info.
|
// do not need to add that info.
|
||||||
//
|
//
|
||||||
|
// @tag Logging
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
LogWarn(msg string, keyValuePairs ...interface{})
|
LogWarn(msg string, keyValuePairs ...interface{})
|
||||||
|
|
||||||
@@ -704,49 +863,63 @@ type API interface {
|
|||||||
|
|
||||||
// CreateBot creates the given bot and corresponding user.
|
// CreateBot creates the given bot and corresponding user.
|
||||||
//
|
//
|
||||||
|
// @tag Bot
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
CreateBot(bot *model.Bot) (*model.Bot, *model.AppError)
|
CreateBot(bot *model.Bot) (*model.Bot, *model.AppError)
|
||||||
|
|
||||||
// PatchBot applies the given patch to the bot and corresponding user.
|
// PatchBot applies the given patch to the bot and corresponding user.
|
||||||
//
|
//
|
||||||
|
// @tag Bot
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
PatchBot(botUserId string, botPatch *model.BotPatch) (*model.Bot, *model.AppError)
|
PatchBot(botUserId string, botPatch *model.BotPatch) (*model.Bot, *model.AppError)
|
||||||
|
|
||||||
// GetBot returns the given bot.
|
// GetBot returns the given bot.
|
||||||
//
|
//
|
||||||
|
// @tag Bot
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
GetBot(botUserId string, includeDeleted bool) (*model.Bot, *model.AppError)
|
GetBot(botUserId string, includeDeleted bool) (*model.Bot, *model.AppError)
|
||||||
|
|
||||||
// GetBots returns the requested page of bots.
|
// GetBots returns the requested page of bots.
|
||||||
//
|
//
|
||||||
|
// @tag Bot
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
GetBots(options *model.BotGetOptions) ([]*model.Bot, *model.AppError)
|
GetBots(options *model.BotGetOptions) ([]*model.Bot, *model.AppError)
|
||||||
|
|
||||||
// UpdateBotActive marks a bot as active or inactive, along with its corresponding user.
|
// UpdateBotActive marks a bot as active or inactive, along with its corresponding user.
|
||||||
//
|
//
|
||||||
|
// @tag Bot
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
UpdateBotActive(botUserId string, active bool) (*model.Bot, *model.AppError)
|
UpdateBotActive(botUserId string, active bool) (*model.Bot, *model.AppError)
|
||||||
|
|
||||||
// PermanentDeleteBot permanently deletes a bot and its corresponding user.
|
// PermanentDeleteBot permanently deletes a bot and its corresponding user.
|
||||||
//
|
//
|
||||||
|
// @tag Bot
|
||||||
// Minimum server version: 5.10
|
// Minimum server version: 5.10
|
||||||
PermanentDeleteBot(botUserId string) *model.AppError
|
PermanentDeleteBot(botUserId string) *model.AppError
|
||||||
|
|
||||||
// GetBotIconImage gets LHS bot icon image.
|
// GetBotIconImage gets LHS bot icon image.
|
||||||
//
|
//
|
||||||
|
// @tag Bot
|
||||||
// Minimum server version: 5.14
|
// Minimum server version: 5.14
|
||||||
GetBotIconImage(botUserId string) ([]byte, *model.AppError)
|
GetBotIconImage(botUserId string) ([]byte, *model.AppError)
|
||||||
|
|
||||||
// SetBotIconImage sets LHS bot icon image.
|
// SetBotIconImage sets LHS bot icon image.
|
||||||
// Icon image must be SVG format, all other formats are rejected.
|
// Icon image must be SVG format, all other formats are rejected.
|
||||||
//
|
//
|
||||||
|
// @tag Bot
|
||||||
// Minimum server version: 5.14
|
// Minimum server version: 5.14
|
||||||
SetBotIconImage(botUserId string, data []byte) *model.AppError
|
SetBotIconImage(botUserId string, data []byte) *model.AppError
|
||||||
|
|
||||||
// DeleteBotIconImage deletes LHS bot icon image.
|
// DeleteBotIconImage deletes LHS bot icon image.
|
||||||
//
|
//
|
||||||
|
// @tag Bot
|
||||||
// Minimum server version: 5.14
|
// Minimum server version: 5.14
|
||||||
DeleteBotIconImage(botUserId string) *model.AppError
|
DeleteBotIconImage(botUserId string) *model.AppError
|
||||||
|
|
||||||
|
// PluginHTTP allows inter-plugin requests to plugin APIs.
|
||||||
|
//
|
||||||
|
// Minimum server version: 5.18
|
||||||
|
PluginHTTP(request *http.Request) *http.Response
|
||||||
}
|
}
|
||||||
|
|
||||||
var handshake = plugin.HandshakeConfig{
|
var handshake = plugin.HandshakeConfig{
|
||||||
|
|||||||
@@ -57,10 +57,12 @@ func (p *hooksPlugin) Client(b *plugin.MuxBroker, client *rpc.Client) (interface
|
|||||||
|
|
||||||
type apiRPCClient struct {
|
type apiRPCClient struct {
|
||||||
client *rpc.Client
|
client *rpc.Client
|
||||||
|
muxBroker *plugin.MuxBroker
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiRPCServer struct {
|
type apiRPCServer struct {
|
||||||
impl API
|
impl API
|
||||||
|
muxBroker *plugin.MuxBroker
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorString is a fallback for sending unregistered implementations of the error interface across
|
// ErrorString is a fallback for sending unregistered implementations of the error interface across
|
||||||
@@ -172,6 +174,7 @@ func (g *hooksRPCClient) OnActivate() error {
|
|||||||
muxId := g.muxBroker.NextId()
|
muxId := g.muxBroker.NextId()
|
||||||
go g.muxBroker.AcceptAndServe(muxId, &apiRPCServer{
|
go g.muxBroker.AcceptAndServe(muxId, &apiRPCServer{
|
||||||
impl: g.apiImpl,
|
impl: g.apiImpl,
|
||||||
|
muxBroker: g.muxBroker,
|
||||||
})
|
})
|
||||||
|
|
||||||
_args := &Z_OnActivateArgs{
|
_args := &Z_OnActivateArgs{
|
||||||
@@ -193,6 +196,7 @@ func (s *hooksRPCServer) OnActivate(args *Z_OnActivateArgs, returns *Z_OnActivat
|
|||||||
|
|
||||||
s.apiRPCClient = &apiRPCClient{
|
s.apiRPCClient = &apiRPCClient{
|
||||||
client: rpc.NewClient(connection),
|
client: rpc.NewClient(connection),
|
||||||
|
muxBroker: s.muxBroker,
|
||||||
}
|
}
|
||||||
|
|
||||||
if mmplugin, ok := s.impl.(interface {
|
if mmplugin, ok := s.impl.(interface {
|
||||||
@@ -363,6 +367,76 @@ func (s *hooksRPCServer) ServeHTTP(args *Z_ServeHTTPArgs, returns *struct{}) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Z_PluginHTTPArgs struct {
|
||||||
|
Request *http.Request
|
||||||
|
RequestBody []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type Z_PluginHTTPReturns struct {
|
||||||
|
Response *http.Response
|
||||||
|
ResponseBody []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *apiRPCClient) PluginHTTP(request *http.Request) *http.Response {
|
||||||
|
forwardedRequest := &http.Request{
|
||||||
|
Method: request.Method,
|
||||||
|
URL: request.URL,
|
||||||
|
Proto: request.Proto,
|
||||||
|
ProtoMajor: request.ProtoMajor,
|
||||||
|
ProtoMinor: request.ProtoMinor,
|
||||||
|
Header: request.Header,
|
||||||
|
Host: request.Host,
|
||||||
|
RemoteAddr: request.RemoteAddr,
|
||||||
|
RequestURI: request.RequestURI,
|
||||||
|
}
|
||||||
|
|
||||||
|
requestBody, err := ioutil.ReadAll(request.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("RPC call to PluginHTTP API failed: %s", err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
request.Body.Close()
|
||||||
|
request.Body = nil
|
||||||
|
|
||||||
|
_args := &Z_PluginHTTPArgs{
|
||||||
|
Request: forwardedRequest,
|
||||||
|
RequestBody: requestBody,
|
||||||
|
}
|
||||||
|
|
||||||
|
_returns := &Z_PluginHTTPReturns{}
|
||||||
|
if err := g.client.Call("Plugin.PluginHTTP", _args, _returns); err != nil {
|
||||||
|
log.Printf("RPC call to PluginHTTP API failed: %s", err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_returns.Response.Body = ioutil.NopCloser(bytes.NewBuffer(_returns.ResponseBody))
|
||||||
|
|
||||||
|
return _returns.Response
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *apiRPCServer) PluginHTTP(args *Z_PluginHTTPArgs, returns *Z_PluginHTTPReturns) error {
|
||||||
|
args.Request.Body = ioutil.NopCloser(bytes.NewBuffer(args.RequestBody))
|
||||||
|
|
||||||
|
if hook, ok := s.impl.(interface {
|
||||||
|
PluginHTTP(request *http.Request) *http.Response
|
||||||
|
}); ok {
|
||||||
|
response := hook.PluginHTTP(args.Request)
|
||||||
|
|
||||||
|
responseBody, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return encodableError(fmt.Errorf("RPC call to PluginHTTP API failed: %s", err.Error()))
|
||||||
|
}
|
||||||
|
response.Body.Close()
|
||||||
|
response.Body = nil
|
||||||
|
|
||||||
|
returns.Response = response
|
||||||
|
returns.ResponseBody = responseBody
|
||||||
|
} else {
|
||||||
|
return encodableError(fmt.Errorf("API PluginHTTP called but not implemented."))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
hookNameToId["FileWillBeUploaded"] = FileWillBeUploadedId
|
hookNameToId["FileWillBeUploaded"] = FileWillBeUploadedId
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,4 +12,5 @@ type Context struct {
|
|||||||
IpAddress string
|
IpAddress string
|
||||||
AcceptLanguage string
|
AcceptLanguage string
|
||||||
UserAgent string
|
UserAgent string
|
||||||
|
SourcePluginId string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,11 @@
|
|||||||
|
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import "github.com/mattermost/mattermost-server/model"
|
import (
|
||||||
|
"github.com/blang/semver"
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
type Helpers interface {
|
type Helpers interface {
|
||||||
// EnsureBot either returns an existing bot user matching the given bot, or creates a bot user from the given bot.
|
// EnsureBot either returns an existing bot user matching the given bot, or creates a bot user from the given bot.
|
||||||
@@ -54,3 +58,14 @@ type Helpers interface {
|
|||||||
type HelpersImpl struct {
|
type HelpersImpl struct {
|
||||||
API API
|
API API
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *HelpersImpl) ensureServerVersion(required string) error {
|
||||||
|
serverVersion := p.API.GetServerVersion()
|
||||||
|
currentVersion := semver.MustParse(serverVersion)
|
||||||
|
requiredVersion := semver.MustParse(required)
|
||||||
|
|
||||||
|
if currentVersion.LT(requiredVersion) {
|
||||||
|
return errors.Errorf("incompatible server version for plugin, minimum required version: %s, current version: %s", required, serverVersion)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *HelpersImpl) EnsureBot(bot *model.Bot) (retBotId string, retErr error) {
|
func (p *HelpersImpl) EnsureBot(bot *model.Bot) (retBotId string, retErr error) {
|
||||||
|
err := p.ensureServerVersion("5.10.0")
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "failed to ensure bot")
|
||||||
|
}
|
||||||
|
|
||||||
// Must provide a bot with a username
|
// Must provide a bot with a username
|
||||||
if bot == nil || len(bot.Username) < 1 {
|
if bot == nil || len(bot.Username) < 1 {
|
||||||
return "", errors.New("passed a bad bot, nil or no username")
|
return "", errors.New("passed a bad bot, nil or no username")
|
||||||
|
|||||||
@@ -24,15 +24,37 @@ func TestEnsureBot(t *testing.T) {
|
|||||||
Description: "testbotdescription",
|
Description: "testbotdescription",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t.Run("server version incompatible", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.On("GetServerVersion").Return("5.9.0")
|
||||||
|
defer api.AssertExpectations(t)
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{}
|
||||||
|
p.API = api
|
||||||
|
|
||||||
|
_, retErr := p.EnsureBot(nil)
|
||||||
|
|
||||||
|
assert.NotNil(t, retErr)
|
||||||
|
assert.Equal(t, "failed to ensure bot: incompatible server version for plugin, minimum required version: 5.10.0, current version: 5.9.0", retErr.Error())
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("bad parameters", func(t *testing.T) {
|
t.Run("bad parameters", func(t *testing.T) {
|
||||||
t.Run("no bot", func(t *testing.T) {
|
t.Run("no bot", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
|
|
||||||
p := &plugin.HelpersImpl{}
|
p := &plugin.HelpersImpl{}
|
||||||
|
p.API = api
|
||||||
botId, err := p.EnsureBot(nil)
|
botId, err := p.EnsureBot(nil)
|
||||||
assert.Equal(t, "", botId)
|
assert.Equal(t, "", botId)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
})
|
})
|
||||||
t.Run("bad username", func(t *testing.T) {
|
t.Run("bad username", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
|
|
||||||
p := &plugin.HelpersImpl{}
|
p := &plugin.HelpersImpl{}
|
||||||
|
p.API = api
|
||||||
botId, err := p.EnsureBot(&model.Bot{
|
botId, err := p.EnsureBot(&model.Bot{
|
||||||
Username: "",
|
Username: "",
|
||||||
})
|
})
|
||||||
@@ -46,6 +68,7 @@ func TestEnsureBot(t *testing.T) {
|
|||||||
expectedBotId := model.NewId()
|
expectedBotId := model.NewId()
|
||||||
|
|
||||||
api := setupAPI()
|
api := setupAPI()
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
api.On("KVGet", plugin.BOT_USER_KEY).Return([]byte(expectedBotId), nil)
|
api.On("KVGet", plugin.BOT_USER_KEY).Return([]byte(expectedBotId), nil)
|
||||||
defer api.AssertExpectations(t)
|
defer api.AssertExpectations(t)
|
||||||
|
|
||||||
@@ -60,6 +83,7 @@ func TestEnsureBot(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("should return an error if unable to get bot", func(t *testing.T) {
|
t.Run("should return an error if unable to get bot", func(t *testing.T) {
|
||||||
api := setupAPI()
|
api := setupAPI()
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, &model.AppError{})
|
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, &model.AppError{})
|
||||||
defer api.AssertExpectations(t)
|
defer api.AssertExpectations(t)
|
||||||
|
|
||||||
@@ -78,6 +102,7 @@ func TestEnsureBot(t *testing.T) {
|
|||||||
expectedBotId := model.NewId()
|
expectedBotId := model.NewId()
|
||||||
|
|
||||||
api := setupAPI()
|
api := setupAPI()
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, nil)
|
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, nil)
|
||||||
api.On("GetUserByUsername", testbot.Username).Return(nil, nil)
|
api.On("GetUserByUsername", testbot.Username).Return(nil, nil)
|
||||||
api.On("CreateBot", testbot).Return(&model.Bot{
|
api.On("CreateBot", testbot).Return(&model.Bot{
|
||||||
@@ -99,6 +124,7 @@ func TestEnsureBot(t *testing.T) {
|
|||||||
expectedBotId := model.NewId()
|
expectedBotId := model.NewId()
|
||||||
|
|
||||||
api := setupAPI()
|
api := setupAPI()
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, nil)
|
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, nil)
|
||||||
api.On("GetUserByUsername", testbot.Username).Return(&model.User{
|
api.On("GetUserByUsername", testbot.Username).Return(&model.User{
|
||||||
Id: expectedBotId,
|
Id: expectedBotId,
|
||||||
@@ -119,6 +145,7 @@ func TestEnsureBot(t *testing.T) {
|
|||||||
t.Run("should return the non-bot account but log a message if user exists with the same name and is not a bot", func(t *testing.T) {
|
t.Run("should return the non-bot account but log a message if user exists with the same name and is not a bot", func(t *testing.T) {
|
||||||
expectedBotId := model.NewId()
|
expectedBotId := model.NewId()
|
||||||
api := setupAPI()
|
api := setupAPI()
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, nil)
|
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, nil)
|
||||||
api.On("GetUserByUsername", testbot.Username).Return(&model.User{
|
api.On("GetUserByUsername", testbot.Username).Return(&model.User{
|
||||||
Id: expectedBotId,
|
Id: expectedBotId,
|
||||||
@@ -138,6 +165,7 @@ func TestEnsureBot(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("should fail if create bot fails", func(t *testing.T) {
|
t.Run("should fail if create bot fails", func(t *testing.T) {
|
||||||
api := setupAPI()
|
api := setupAPI()
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, nil)
|
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, nil)
|
||||||
api.On("GetUserByUsername", testbot.Username).Return(nil, nil)
|
api.On("GetUserByUsername", testbot.Username).Return(nil, nil)
|
||||||
api.On("CreateBot", testbot).Return(nil, &model.AppError{})
|
api.On("CreateBot", testbot).Return(nil, &model.AppError{})
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import (
|
|||||||
|
|
||||||
// KVSetJSON implements Helpers.KVSetJSON.
|
// KVSetJSON implements Helpers.KVSetJSON.
|
||||||
func (p *HelpersImpl) KVSetJSON(key string, value interface{}) error {
|
func (p *HelpersImpl) KVSetJSON(key string, value interface{}) error {
|
||||||
|
err := p.ensureServerVersion("5.2.0")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
data, err := json.Marshal(value)
|
data, err := json.Marshal(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -26,9 +31,14 @@ func (p *HelpersImpl) KVSetJSON(key string, value interface{}) error {
|
|||||||
|
|
||||||
// KVCompareAndSetJSON implements Helpers.KVCompareAndSetJSON.
|
// KVCompareAndSetJSON implements Helpers.KVCompareAndSetJSON.
|
||||||
func (p *HelpersImpl) KVCompareAndSetJSON(key string, oldValue interface{}, newValue interface{}) (bool, error) {
|
func (p *HelpersImpl) KVCompareAndSetJSON(key string, oldValue interface{}, newValue interface{}) (bool, error) {
|
||||||
var oldData, newData []byte
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
err = p.ensureServerVersion("5.12.0")
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
var oldData, newData []byte
|
||||||
|
|
||||||
if oldValue != nil {
|
if oldValue != nil {
|
||||||
oldData, err = json.Marshal(oldValue)
|
oldData, err = json.Marshal(oldValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -53,9 +63,15 @@ func (p *HelpersImpl) KVCompareAndSetJSON(key string, oldValue interface{}, newV
|
|||||||
|
|
||||||
// KVCompareAndDeleteJSON implements Helpers.KVCompareAndDeleteJSON.
|
// KVCompareAndDeleteJSON implements Helpers.KVCompareAndDeleteJSON.
|
||||||
func (p *HelpersImpl) KVCompareAndDeleteJSON(key string, oldValue interface{}) (bool, error) {
|
func (p *HelpersImpl) KVCompareAndDeleteJSON(key string, oldValue interface{}) (bool, error) {
|
||||||
var oldData []byte
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
err = p.ensureServerVersion("5.16.0")
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldData []byte
|
||||||
|
|
||||||
if oldValue != nil {
|
if oldValue != nil {
|
||||||
oldData, err = json.Marshal(oldValue)
|
oldData, err = json.Marshal(oldValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -73,6 +89,11 @@ func (p *HelpersImpl) KVCompareAndDeleteJSON(key string, oldValue interface{}) (
|
|||||||
|
|
||||||
// KVGetJSON implements Helpers.KVGetJSON.
|
// KVGetJSON implements Helpers.KVGetJSON.
|
||||||
func (p *HelpersImpl) KVGetJSON(key string, value interface{}) (bool, error) {
|
func (p *HelpersImpl) KVGetJSON(key string, value interface{}) (bool, error) {
|
||||||
|
err := p.ensureServerVersion("5.2.0")
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
data, appErr := p.API.KVGet(key)
|
data, appErr := p.API.KVGet(key)
|
||||||
if appErr != nil {
|
if appErr != nil {
|
||||||
return false, appErr
|
return false, appErr
|
||||||
@@ -81,7 +102,7 @@ func (p *HelpersImpl) KVGetJSON(key string, value interface{}) (bool, error) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := json.Unmarshal(data, value)
|
err = json.Unmarshal(data, value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -89,8 +110,13 @@ func (p *HelpersImpl) KVGetJSON(key string, value interface{}) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// KVSetWithExpiryJSON implements Helpers.KVSetWithExpiryJSON.
|
// KVSetWithExpiryJSON is a wrapper around KVSetWithExpiry to simplify atomically writing a JSON object with expiry to the key value store.
|
||||||
func (p *HelpersImpl) KVSetWithExpiryJSON(key string, value interface{}, expireInSeconds int64) error {
|
func (p *HelpersImpl) KVSetWithExpiryJSON(key string, value interface{}, expireInSeconds int64) error {
|
||||||
|
err := p.ensureServerVersion("5.6.0")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
data, err := json.Marshal(value)
|
data, err := json.Marshal(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -10,10 +10,26 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestKVGetJSON(t *testing.T) {
|
func TestKVGetJSON(t *testing.T) {
|
||||||
|
t.Run("incompatible server version", func(t *testing.T) {
|
||||||
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.1.0")
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
var dat map[string]interface{}
|
||||||
|
|
||||||
|
ok, err := p.KVGetJSON("test-key", dat)
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.False(t, ok)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "incompatible server version for plugin, minimum required version: 5.2.0, current version: 5.1.0", err.Error())
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("KVGet error", func(t *testing.T) {
|
t.Run("KVGet error", func(t *testing.T) {
|
||||||
p := &plugin.HelpersImpl{}
|
p := &plugin.HelpersImpl{}
|
||||||
|
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.2.0")
|
||||||
api.On("KVGet", "test-key").Return(nil, &model.AppError{})
|
api.On("KVGet", "test-key").Return(nil, &model.AppError{})
|
||||||
p.API = api
|
p.API = api
|
||||||
|
|
||||||
@@ -30,6 +46,7 @@ func TestKVGetJSON(t *testing.T) {
|
|||||||
p := &plugin.HelpersImpl{}
|
p := &plugin.HelpersImpl{}
|
||||||
|
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.2.0")
|
||||||
api.On("KVGet", "test-key").Return(nil, nil)
|
api.On("KVGet", "test-key").Return(nil, nil)
|
||||||
p.API = api
|
p.API = api
|
||||||
|
|
||||||
@@ -46,6 +63,7 @@ func TestKVGetJSON(t *testing.T) {
|
|||||||
p := &plugin.HelpersImpl{}
|
p := &plugin.HelpersImpl{}
|
||||||
|
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.2.0")
|
||||||
api.On("KVGet", "test-key").Return([]byte(`{{:}"val-a": 10}`), nil)
|
api.On("KVGet", "test-key").Return([]byte(`{{:}"val-a": 10}`), nil)
|
||||||
p.API = api
|
p.API = api
|
||||||
|
|
||||||
@@ -62,6 +80,7 @@ func TestKVGetJSON(t *testing.T) {
|
|||||||
p := &plugin.HelpersImpl{}
|
p := &plugin.HelpersImpl{}
|
||||||
|
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.2.0")
|
||||||
api.On("KVGet", "test-key").Return([]byte(`{"val-a": 10}`), nil)
|
api.On("KVGet", "test-key").Return([]byte(`{"val-a": 10}`), nil)
|
||||||
p.API = api
|
p.API = api
|
||||||
|
|
||||||
@@ -78,9 +97,25 @@ func TestKVGetJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestKVSetJSON(t *testing.T) {
|
func TestKVSetJSON(t *testing.T) {
|
||||||
|
t.Run("incompatible server version", func(t *testing.T) {
|
||||||
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.1.0")
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
err := p.KVSetJSON("test-key", map[string]interface{}{
|
||||||
|
"val-a": float64(10),
|
||||||
|
})
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "incompatible server version for plugin, minimum required version: 5.2.0, current version: 5.1.0", err.Error())
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("JSON marshal error", func(t *testing.T) {
|
t.Run("JSON marshal error", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
api.AssertNotCalled(t, "KVSet")
|
api.AssertNotCalled(t, "KVSet")
|
||||||
|
api.On("GetServerVersion").Return("5.2.0")
|
||||||
|
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -92,6 +127,7 @@ func TestKVSetJSON(t *testing.T) {
|
|||||||
t.Run("KVSet error", func(t *testing.T) {
|
t.Run("KVSet error", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
api.On("KVSet", "test-key", []byte(`{"val-a":10}`)).Return(&model.AppError{})
|
api.On("KVSet", "test-key", []byte(`{"val-a":10}`)).Return(&model.AppError{})
|
||||||
|
api.On("GetServerVersion").Return("5.2.0")
|
||||||
|
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -106,6 +142,7 @@ func TestKVSetJSON(t *testing.T) {
|
|||||||
t.Run("marshallable struct", func(t *testing.T) {
|
t.Run("marshallable struct", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
api.On("KVSet", "test-key", []byte(`{"val-a":10}`)).Return(nil)
|
api.On("KVSet", "test-key", []byte(`{"val-a":10}`)).Return(nil)
|
||||||
|
api.On("GetServerVersion").Return("5.2.0")
|
||||||
|
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -119,9 +156,24 @@ func TestKVSetJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestKVCompareAndSetJSON(t *testing.T) {
|
func TestKVCompareAndSetJSON(t *testing.T) {
|
||||||
|
t.Run("incompatible server version", func(t *testing.T) {
|
||||||
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
ok, err := p.KVCompareAndSetJSON("test-key", nil, map[string]interface{}{
|
||||||
|
"val-b": 20,
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, false, ok)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "incompatible server version for plugin, minimum required version: 5.12.0, current version: 5.10.0", err.Error())
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("old value JSON marshal error", func(t *testing.T) {
|
t.Run("old value JSON marshal error", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
api.AssertNotCalled(t, "KVCompareAndSet")
|
api.AssertNotCalled(t, "KVCompareAndSet")
|
||||||
|
api.On("GetServerVersion").Return("5.12.0")
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
ok, err := p.KVCompareAndSetJSON("test-key", func() {}, map[string]interface{}{})
|
ok, err := p.KVCompareAndSetJSON("test-key", func() {}, map[string]interface{}{})
|
||||||
@@ -133,6 +185,7 @@ func TestKVCompareAndSetJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("new value JSON marshal error", func(t *testing.T) {
|
t.Run("new value JSON marshal error", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.12.0")
|
||||||
api.AssertNotCalled(t, "KVCompareAndSet")
|
api.AssertNotCalled(t, "KVCompareAndSet")
|
||||||
|
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
@@ -146,6 +199,7 @@ func TestKVCompareAndSetJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("KVCompareAndSet error", func(t *testing.T) {
|
t.Run("KVCompareAndSet error", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.12.0")
|
||||||
api.On("KVCompareAndSet", "test-key", []byte(`{"val-a":10}`), []byte(`{"val-b":20}`)).Return(false, &model.AppError{})
|
api.On("KVCompareAndSet", "test-key", []byte(`{"val-a":10}`), []byte(`{"val-b":20}`)).Return(false, &model.AppError{})
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -162,6 +216,7 @@ func TestKVCompareAndSetJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("old value nil", func(t *testing.T) {
|
t.Run("old value nil", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.12.0")
|
||||||
api.On("KVCompareAndSet", "test-key", []byte(nil), []byte(`{"val-b":20}`)).Return(true, nil)
|
api.On("KVCompareAndSet", "test-key", []byte(nil), []byte(`{"val-b":20}`)).Return(true, nil)
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -176,6 +231,7 @@ func TestKVCompareAndSetJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("old value non-nil", func(t *testing.T) {
|
t.Run("old value non-nil", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.12.0")
|
||||||
api.On("KVCompareAndSet", "test-key", []byte(`{"val-a":10}`), []byte(`{"val-b":20}`)).Return(true, nil)
|
api.On("KVCompareAndSet", "test-key", []byte(`{"val-a":10}`), []byte(`{"val-b":20}`)).Return(true, nil)
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -192,6 +248,7 @@ func TestKVCompareAndSetJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("new value nil", func(t *testing.T) {
|
t.Run("new value nil", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.12.0")
|
||||||
api.On("KVCompareAndSet", "test-key", []byte(`{"val-a":10}`), []byte(nil)).Return(true, nil)
|
api.On("KVCompareAndSet", "test-key", []byte(`{"val-a":10}`), []byte(nil)).Return(true, nil)
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -206,8 +263,23 @@ func TestKVCompareAndSetJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestKVCompareAndDeleteJSON(t *testing.T) {
|
func TestKVCompareAndDeleteJSON(t *testing.T) {
|
||||||
|
t.Run("incompatible server version", func(t *testing.T) {
|
||||||
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.10.0")
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
ok, err := p.KVCompareAndDeleteJSON("test-key", map[string]interface{}{
|
||||||
|
"val-a": 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, false, ok)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "incompatible server version for plugin, minimum required version: 5.16.0, current version: 5.10.0", err.Error())
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("old value JSON marshal error", func(t *testing.T) {
|
t.Run("old value JSON marshal error", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.16.0")
|
||||||
api.AssertNotCalled(t, "KVCompareAndDelete")
|
api.AssertNotCalled(t, "KVCompareAndDelete")
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -220,6 +292,7 @@ func TestKVCompareAndDeleteJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("KVCompareAndDelete error", func(t *testing.T) {
|
t.Run("KVCompareAndDelete error", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.16.0")
|
||||||
api.On("KVCompareAndDelete", "test-key", []byte(`{"val-a":10}`)).Return(false, &model.AppError{})
|
api.On("KVCompareAndDelete", "test-key", []byte(`{"val-a":10}`)).Return(false, &model.AppError{})
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -234,6 +307,7 @@ func TestKVCompareAndDeleteJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("old value nil", func(t *testing.T) {
|
t.Run("old value nil", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.16.0")
|
||||||
api.On("KVCompareAndDelete", "test-key", []byte(nil)).Return(true, nil)
|
api.On("KVCompareAndDelete", "test-key", []byte(nil)).Return(true, nil)
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -246,6 +320,7 @@ func TestKVCompareAndDeleteJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("old value non-nil", func(t *testing.T) {
|
t.Run("old value non-nil", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.16.0")
|
||||||
api.On("KVCompareAndDelete", "test-key", []byte(`{"val-a":10}`)).Return(true, nil)
|
api.On("KVCompareAndDelete", "test-key", []byte(`{"val-a":10}`)).Return(true, nil)
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -260,8 +335,24 @@ func TestKVCompareAndDeleteJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestKVSetWithExpiryJSON(t *testing.T) {
|
func TestKVSetWithExpiryJSON(t *testing.T) {
|
||||||
|
t.Run("incompatible server version", func(t *testing.T) {
|
||||||
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.4.0")
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
err := p.KVSetWithExpiryJSON("test-key", map[string]interface{}{
|
||||||
|
"val-a": float64(10),
|
||||||
|
}, 100)
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "incompatible server version for plugin, minimum required version: 5.6.0, current version: 5.4.0", err.Error())
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("JSON marshal error", func(t *testing.T) {
|
t.Run("JSON marshal error", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.6.0")
|
||||||
api.AssertNotCalled(t, "KVSetWithExpiry")
|
api.AssertNotCalled(t, "KVSetWithExpiry")
|
||||||
|
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
@@ -274,6 +365,7 @@ func TestKVSetWithExpiryJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("KVSetWithExpiry error", func(t *testing.T) {
|
t.Run("KVSetWithExpiry error", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.6.0")
|
||||||
api.On("KVSetWithExpiry", "test-key", []byte(`{"val-a":10}`), int64(100)).Return(&model.AppError{})
|
api.On("KVSetWithExpiry", "test-key", []byte(`{"val-a":10}`), int64(100)).Return(&model.AppError{})
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
@@ -287,6 +379,7 @@ func TestKVSetWithExpiryJSON(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("wellformed JSON", func(t *testing.T) {
|
t.Run("wellformed JSON", func(t *testing.T) {
|
||||||
api := &plugintest.API{}
|
api := &plugintest.API{}
|
||||||
|
api.On("GetServerVersion").Return("5.6.0")
|
||||||
api.On("KVSetWithExpiry", "test-key", []byte(`{"val-a":10}`), int64(100)).Return(nil)
|
api.On("KVSetWithExpiry", "test-key", []byte(`{"val-a":10}`), int64(100)).Return(nil)
|
||||||
|
|
||||||
p := &plugin.HelpersImpl{API: api}
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|||||||
@@ -392,17 +392,18 @@ func getPluginPackageDir() string {
|
|||||||
func removeExcluded(info *PluginInterfaceInfo) *PluginInterfaceInfo {
|
func removeExcluded(info *PluginInterfaceInfo) *PluginInterfaceInfo {
|
||||||
toBeExcluded := func(item string) bool {
|
toBeExcluded := func(item string) bool {
|
||||||
excluded := []string{
|
excluded := []string{
|
||||||
"OnActivate",
|
"FileWillBeUploaded",
|
||||||
"Implemented",
|
"Implemented",
|
||||||
"LoadPluginConfiguration",
|
"LoadPluginConfiguration",
|
||||||
"ServeHTTP",
|
|
||||||
"FileWillBeUploaded",
|
|
||||||
"MessageWillBePosted",
|
|
||||||
"MessageWillBeUpdated",
|
|
||||||
"LogDebug",
|
"LogDebug",
|
||||||
|
"LogError",
|
||||||
"LogInfo",
|
"LogInfo",
|
||||||
"LogWarn",
|
"LogWarn",
|
||||||
"LogError",
|
"MessageWillBePosted",
|
||||||
|
"MessageWillBeUpdated",
|
||||||
|
"OnActivate",
|
||||||
|
"PluginHTTP",
|
||||||
|
"ServeHTTP",
|
||||||
}
|
}
|
||||||
for _, exclusion := range excluded {
|
for _, exclusion := range excluded {
|
||||||
if exclusion == item {
|
if exclusion == item {
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ package plugintest
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
io "io"
|
io "io"
|
||||||
|
http "net/http"
|
||||||
|
|
||||||
|
mock "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
model "github.com/mattermost/mattermost-server/model"
|
model "github.com/mattermost/mattermost-server/model"
|
||||||
mock "github.com/stretchr/testify/mock"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// API is an autogenerated mock type for the API type
|
// API is an autogenerated mock type for the API type
|
||||||
@@ -2334,6 +2336,22 @@ func (_m *API) PermanentDeleteBot(botUserId string) *model.AppError {
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PluginHTTP provides a mock function with given fields: request
|
||||||
|
func (_m *API) PluginHTTP(request *http.Request) *http.Response {
|
||||||
|
ret := _m.Called(request)
|
||||||
|
|
||||||
|
var r0 *http.Response
|
||||||
|
if rf, ok := ret.Get(0).(func(*http.Request) *http.Response); ok {
|
||||||
|
r0 = rf(request)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*http.Response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// PublishWebSocketEvent provides a mock function with given fields: event, payload, broadcast
|
// PublishWebSocketEvent provides a mock function with given fields: event, payload, broadcast
|
||||||
func (_m *API) PublishWebSocketEvent(event string, payload map[string]interface{}, broadcast *model.WebsocketBroadcast) {
|
func (_m *API) PublishWebSocketEvent(event string, payload map[string]interface{}, broadcast *model.WebsocketBroadcast) {
|
||||||
_m.Called(event, payload, broadcast)
|
_m.Called(event, payload, broadcast)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ echo "Checking prerequisites"
|
|||||||
|
|
||||||
REQUIREDNODEVERSION=8.9.0
|
REQUIREDNODEVERSION=8.9.0
|
||||||
REQUIREDNPMVERSION=5.6.0
|
REQUIREDNPMVERSION=5.6.0
|
||||||
REQUIREDGOVERSION=1.12.0
|
REQUIREDGOVERSION=1.13.0
|
||||||
REQUIREDDOCKERVERSION=17.0
|
REQUIREDDOCKERVERSION=17.0
|
||||||
|
|
||||||
NODEVERSION=$(sed 's/v//' <<< $(node -v))
|
NODEVERSION=$(sed 's/v//' <<< $(node -v))
|
||||||
|
|||||||
@@ -1,203 +0,0 @@
|
|||||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
|
||||||
// See License.txt for license information.
|
|
||||||
|
|
||||||
package store
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/einterfaces"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LayeredStoreDatabaseLayer interface {
|
|
||||||
LayeredStoreSupplier
|
|
||||||
Store
|
|
||||||
}
|
|
||||||
|
|
||||||
type LayeredStore struct {
|
|
||||||
TmpContext context.Context
|
|
||||||
DatabaseLayer LayeredStoreDatabaseLayer
|
|
||||||
LocalCacheLayer *LocalCacheSupplier
|
|
||||||
LayerChainHead LayeredStoreSupplier
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLayeredStore(db LayeredStoreDatabaseLayer, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface) Store {
|
|
||||||
store := &LayeredStore{
|
|
||||||
TmpContext: context.TODO(),
|
|
||||||
DatabaseLayer: db,
|
|
||||||
LocalCacheLayer: NewLocalCacheSupplier(metrics, cluster),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup the chain
|
|
||||||
store.LocalCacheLayer.SetChainNext(store.DatabaseLayer)
|
|
||||||
store.LayerChainHead = store.LocalCacheLayer
|
|
||||||
|
|
||||||
return store
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryFunction func(LayeredStoreSupplier) *LayeredStoreSupplierResult
|
|
||||||
|
|
||||||
func (s *LayeredStore) GetCurrentSchemaVersion() string {
|
|
||||||
return s.DatabaseLayer.GetCurrentSchemaVersion()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Team() TeamStore {
|
|
||||||
return s.DatabaseLayer.Team()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Channel() ChannelStore {
|
|
||||||
return s.DatabaseLayer.Channel()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Post() PostStore {
|
|
||||||
return s.DatabaseLayer.Post()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) User() UserStore {
|
|
||||||
return s.DatabaseLayer.User()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Bot() BotStore {
|
|
||||||
return s.DatabaseLayer.Bot()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Audit() AuditStore {
|
|
||||||
return s.DatabaseLayer.Audit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) ClusterDiscovery() ClusterDiscoveryStore {
|
|
||||||
return s.DatabaseLayer.ClusterDiscovery()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Compliance() ComplianceStore {
|
|
||||||
return s.DatabaseLayer.Compliance()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Session() SessionStore {
|
|
||||||
return s.DatabaseLayer.Session()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) OAuth() OAuthStore {
|
|
||||||
return s.DatabaseLayer.OAuth()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) System() SystemStore {
|
|
||||||
return s.DatabaseLayer.System()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Webhook() WebhookStore {
|
|
||||||
return s.DatabaseLayer.Webhook()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Command() CommandStore {
|
|
||||||
return s.DatabaseLayer.Command()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) CommandWebhook() CommandWebhookStore {
|
|
||||||
return s.DatabaseLayer.CommandWebhook()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Preference() PreferenceStore {
|
|
||||||
return s.DatabaseLayer.Preference()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) License() LicenseStore {
|
|
||||||
return s.DatabaseLayer.License()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Token() TokenStore {
|
|
||||||
return s.DatabaseLayer.Token()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Emoji() EmojiStore {
|
|
||||||
return s.DatabaseLayer.Emoji()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Status() StatusStore {
|
|
||||||
return s.DatabaseLayer.Status()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) FileInfo() FileInfoStore {
|
|
||||||
return s.DatabaseLayer.FileInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Reaction() ReactionStore {
|
|
||||||
return s.DatabaseLayer.Reaction()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Job() JobStore {
|
|
||||||
return s.DatabaseLayer.Job()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) UserAccessToken() UserAccessTokenStore {
|
|
||||||
return s.DatabaseLayer.UserAccessToken()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) ChannelMemberHistory() ChannelMemberHistoryStore {
|
|
||||||
return s.DatabaseLayer.ChannelMemberHistory()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Plugin() PluginStore {
|
|
||||||
return s.DatabaseLayer.Plugin()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Role() RoleStore {
|
|
||||||
return s.DatabaseLayer.Role()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) TermsOfService() TermsOfServiceStore {
|
|
||||||
return s.DatabaseLayer.TermsOfService()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) UserTermsOfService() UserTermsOfServiceStore {
|
|
||||||
return s.DatabaseLayer.UserTermsOfService()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Scheme() SchemeStore {
|
|
||||||
return s.DatabaseLayer.Scheme()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Group() GroupStore {
|
|
||||||
return s.DatabaseLayer.Group()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) LinkMetadata() LinkMetadataStore {
|
|
||||||
return s.DatabaseLayer.LinkMetadata()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) MarkSystemRanUnitTests() {
|
|
||||||
s.DatabaseLayer.MarkSystemRanUnitTests()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) Close() {
|
|
||||||
s.DatabaseLayer.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) LockToMaster() {
|
|
||||||
s.DatabaseLayer.LockToMaster()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) UnlockFromMaster() {
|
|
||||||
s.DatabaseLayer.UnlockFromMaster()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) DropAllTables() {
|
|
||||||
defer s.LocalCacheLayer.Invalidate()
|
|
||||||
s.DatabaseLayer.DropAllTables()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) TotalMasterDbConnections() int {
|
|
||||||
return s.DatabaseLayer.TotalMasterDbConnections()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) TotalReadDbConnections() int {
|
|
||||||
return s.DatabaseLayer.TotalReadDbConnections()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) TotalSearchDbConnections() int {
|
|
||||||
return s.DatabaseLayer.TotalSearchDbConnections()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LayeredStore) CheckIntegrity() <-chan IntegrityCheckResult {
|
|
||||||
return s.DatabaseLayer.CheckIntegrity()
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
|
||||||
// See License.txt for license information.
|
|
||||||
|
|
||||||
package store
|
|
||||||
|
|
||||||
type LayeredStoreHint int
|
|
||||||
|
|
||||||
const (
|
|
||||||
LSH_NO_CACHE LayeredStoreHint = iota
|
|
||||||
LSH_MASTER_ONLY
|
|
||||||
)
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
|
||||||
// See License.txt for license information.
|
|
||||||
|
|
||||||
package store
|
|
||||||
|
|
||||||
type LayeredStoreSupplierResult struct {
|
|
||||||
StoreResult
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSupplierResult() *LayeredStoreSupplierResult {
|
|
||||||
return &LayeredStoreSupplierResult{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type LayeredStoreSupplier interface {
|
|
||||||
//
|
|
||||||
// Control
|
|
||||||
//
|
|
||||||
SetChainNext(LayeredStoreSupplier)
|
|
||||||
Next() LayeredStoreSupplier
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
|
||||||
// See License.txt for license information.
|
|
||||||
|
|
||||||
package store
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/einterfaces"
|
|
||||||
"github.com/mattermost/mattermost-server/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
CLEAR_CACHE_MESSAGE_DATA = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
type LocalCacheSupplier struct {
|
|
||||||
next LayeredStoreSupplier
|
|
||||||
metrics einterfaces.MetricsInterface
|
|
||||||
cluster einterfaces.ClusterInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caching Interface
|
|
||||||
type ObjectCache interface {
|
|
||||||
AddWithExpiresInSecs(key, value interface{}, expireAtSecs int64)
|
|
||||||
AddWithDefaultExpires(key, value interface{})
|
|
||||||
Purge()
|
|
||||||
Get(key interface{}) (value interface{}, ok bool)
|
|
||||||
Remove(key interface{})
|
|
||||||
Len() int
|
|
||||||
Name() string
|
|
||||||
GetInvalidateClusterEvent() string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLocalCacheSupplier(metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface) *LocalCacheSupplier {
|
|
||||||
supplier := &LocalCacheSupplier{
|
|
||||||
metrics: metrics,
|
|
||||||
cluster: cluster,
|
|
||||||
}
|
|
||||||
|
|
||||||
return supplier
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LocalCacheSupplier) SetChainNext(next LayeredStoreSupplier) {
|
|
||||||
s.next = next
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LocalCacheSupplier) Next() LayeredStoreSupplier {
|
|
||||||
return s.next
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LocalCacheSupplier) doStandardAddToCache(ctx context.Context, cache ObjectCache, key string, result *LayeredStoreSupplierResult, hints ...LayeredStoreHint) {
|
|
||||||
if result.Err == nil && result.Data != nil {
|
|
||||||
cache.AddWithDefaultExpires(key, result.Data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LocalCacheSupplier) doInvalidateCacheCluster(cache ObjectCache, key string) {
|
|
||||||
cache.Remove(key)
|
|
||||||
if s.cluster != nil {
|
|
||||||
msg := &model.ClusterMessage{
|
|
||||||
Event: cache.GetInvalidateClusterEvent(),
|
|
||||||
SendType: model.CLUSTER_SEND_BEST_EFFORT,
|
|
||||||
Data: key,
|
|
||||||
}
|
|
||||||
s.cluster.SendClusterMessage(msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LocalCacheSupplier) doClearCacheCluster(cache ObjectCache) {
|
|
||||||
cache.Purge()
|
|
||||||
if s.cluster != nil {
|
|
||||||
msg := &model.ClusterMessage{
|
|
||||||
Event: cache.GetInvalidateClusterEvent(),
|
|
||||||
SendType: model.CLUSTER_SEND_BEST_EFFORT,
|
|
||||||
Data: CLEAR_CACHE_MESSAGE_DATA,
|
|
||||||
}
|
|
||||||
s.cluster.SendClusterMessage(msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *LocalCacheSupplier) Invalidate() {
|
|
||||||
}
|
|
||||||
@@ -58,7 +58,7 @@ func initStores() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
st.SqlSupplier = sqlstore.NewSqlSupplier(*st.SqlSettings, nil)
|
st.SqlSupplier = sqlstore.NewSqlSupplier(*st.SqlSettings, nil)
|
||||||
st.Store = NewLocalCacheLayer(store.NewLayeredStore(st.SqlSupplier, nil, nil), nil, nil)
|
st.Store = NewLocalCacheLayer(st.SqlSupplier, nil, nil)
|
||||||
st.Store.DropAllTables()
|
st.Store.DropAllTables()
|
||||||
st.Store.MarkSystemRanUnitTests()
|
st.Store.MarkSystemRanUnitTests()
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ func TestCheckIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckParentChildIntegrity(t *testing.T) {
|
func TestCheckParentChildIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
t.Run("should receive an error", func(t *testing.T) {
|
t.Run("should receive an error", func(t *testing.T) {
|
||||||
config := relationalCheckConfig{
|
config := relationalCheckConfig{
|
||||||
parentName: "NotValid",
|
parentName: "NotValid",
|
||||||
@@ -379,7 +379,7 @@ func TestCheckParentChildIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckChannelsCommandWebhooksIntegrity(t *testing.T) {
|
func TestCheckChannelsCommandWebhooksIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -407,7 +407,7 @@ func TestCheckChannelsCommandWebhooksIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckChannelsChannelMemberHistoryIntegrity(t *testing.T) {
|
func TestCheckChannelsChannelMemberHistoryIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -437,7 +437,7 @@ func TestCheckChannelsChannelMemberHistoryIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckChannelsChannelMembersIntegrity(t *testing.T) {
|
func TestCheckChannelsChannelMembersIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -465,7 +465,7 @@ func TestCheckChannelsChannelMembersIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckChannelsIncomingWebhooksIntegrity(t *testing.T) {
|
func TestCheckChannelsIncomingWebhooksIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -493,7 +493,7 @@ func TestCheckChannelsIncomingWebhooksIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckChannelsOutgoingWebhooksIntegrity(t *testing.T) {
|
func TestCheckChannelsOutgoingWebhooksIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -523,7 +523,7 @@ func TestCheckChannelsOutgoingWebhooksIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckChannelsPostsIntegrity(t *testing.T) {
|
func TestCheckChannelsPostsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -550,7 +550,7 @@ func TestCheckChannelsPostsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckCommandsCommandWebhooksIntegrity(t *testing.T) {
|
func TestCheckCommandsCommandWebhooksIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -578,7 +578,7 @@ func TestCheckCommandsCommandWebhooksIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckPostsFileInfoIntegrity(t *testing.T) {
|
func TestCheckPostsFileInfoIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -605,7 +605,7 @@ func TestCheckPostsFileInfoIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckPostsPostsParentIdIntegrity(t *testing.T) {
|
func TestCheckPostsPostsParentIdIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -637,7 +637,7 @@ func TestCheckPostsPostsParentIdIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckPostsPostsRootIdIntegrity(t *testing.T) {
|
func TestCheckPostsPostsRootIdIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -667,7 +667,7 @@ func TestCheckPostsPostsRootIdIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckPostsReactionsIntegrity(t *testing.T) {
|
func TestCheckPostsReactionsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -694,7 +694,7 @@ func TestCheckPostsReactionsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckSchemesChannelsIntegrity(t *testing.T) {
|
func TestCheckSchemesChannelsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -725,7 +725,7 @@ func TestCheckSchemesChannelsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckSchemesTeamsIntegrity(t *testing.T) {
|
func TestCheckSchemesTeamsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -756,7 +756,7 @@ func TestCheckSchemesTeamsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckSessionsAuditsIntegrity(t *testing.T) {
|
func TestCheckSessionsAuditsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -787,7 +787,7 @@ func TestCheckSessionsAuditsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckTeamsChannelsIntegrity(t *testing.T) {
|
func TestCheckTeamsChannelsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -814,7 +814,7 @@ func TestCheckTeamsChannelsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckTeamsCommandsIntegrity(t *testing.T) {
|
func TestCheckTeamsCommandsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -842,7 +842,7 @@ func TestCheckTeamsCommandsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckTeamsIncomingWebhooksIntegrity(t *testing.T) {
|
func TestCheckTeamsIncomingWebhooksIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -870,7 +870,7 @@ func TestCheckTeamsIncomingWebhooksIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckTeamsOutgoingWebhooksIntegrity(t *testing.T) {
|
func TestCheckTeamsOutgoingWebhooksIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -898,7 +898,7 @@ func TestCheckTeamsOutgoingWebhooksIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckTeamsTeamMembersIntegrity(t *testing.T) {
|
func TestCheckTeamsTeamMembersIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -926,7 +926,7 @@ func TestCheckTeamsTeamMembersIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersAuditsIntegrity(t *testing.T) {
|
func TestCheckUsersAuditsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -956,7 +956,7 @@ func TestCheckUsersAuditsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersCommandWebhooksIntegrity(t *testing.T) {
|
func TestCheckUsersCommandWebhooksIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -984,7 +984,7 @@ func TestCheckUsersCommandWebhooksIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersChannelsIntegrity(t *testing.T) {
|
func TestCheckUsersChannelsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1011,7 +1011,7 @@ func TestCheckUsersChannelsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersChannelMemberHistoryIntegrity(t *testing.T) {
|
func TestCheckUsersChannelMemberHistoryIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1041,7 +1041,7 @@ func TestCheckUsersChannelMemberHistoryIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersChannelMembersIntegrity(t *testing.T) {
|
func TestCheckUsersChannelMembersIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1071,7 +1071,7 @@ func TestCheckUsersChannelMembersIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersCommandsIntegrity(t *testing.T) {
|
func TestCheckUsersCommandsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1099,7 +1099,7 @@ func TestCheckUsersCommandsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersCompliancesIntegrity(t *testing.T) {
|
func TestCheckUsersCompliancesIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1129,7 +1129,7 @@ func TestCheckUsersCompliancesIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersEmojiIntegrity(t *testing.T) {
|
func TestCheckUsersEmojiIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1159,7 +1159,7 @@ func TestCheckUsersEmojiIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersFileInfoIntegrity(t *testing.T) {
|
func TestCheckUsersFileInfoIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1188,7 +1188,7 @@ func TestCheckUsersFileInfoIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersIncomingWebhooksIntegrity(t *testing.T) {
|
func TestCheckUsersIncomingWebhooksIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1216,7 +1216,7 @@ func TestCheckUsersIncomingWebhooksIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersOAuthAccessDataIntegrity(t *testing.T) {
|
func TestCheckUsersOAuthAccessDataIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1246,7 +1246,7 @@ func TestCheckUsersOAuthAccessDataIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersOAuthAppsIntegrity(t *testing.T) {
|
func TestCheckUsersOAuthAppsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1276,7 +1276,7 @@ func TestCheckUsersOAuthAppsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersOAuthAuthDataIntegrity(t *testing.T) {
|
func TestCheckUsersOAuthAuthDataIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1306,7 +1306,7 @@ func TestCheckUsersOAuthAuthDataIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersOutgoingWebhooksIntegrity(t *testing.T) {
|
func TestCheckUsersOutgoingWebhooksIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1334,7 +1334,7 @@ func TestCheckUsersOutgoingWebhooksIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersPostsIntegrity(t *testing.T) {
|
func TestCheckUsersPostsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1361,7 +1361,7 @@ func TestCheckUsersPostsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersPreferencesIntegrity(t *testing.T) {
|
func TestCheckUsersPreferencesIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1390,7 +1390,7 @@ func TestCheckUsersPreferencesIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersReactionsIntegrity(t *testing.T) {
|
func TestCheckUsersReactionsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1419,7 +1419,7 @@ func TestCheckUsersReactionsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersSessionsIntegrity(t *testing.T) {
|
func TestCheckUsersSessionsIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1447,7 +1447,7 @@ func TestCheckUsersSessionsIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersStatusIntegrity(t *testing.T) {
|
func TestCheckUsersStatusIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1476,7 +1476,7 @@ func TestCheckUsersStatusIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersTeamMembersIntegrity(t *testing.T) {
|
func TestCheckUsersTeamMembersIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
@@ -1506,7 +1506,7 @@ func TestCheckUsersTeamMembersIntegrity(t *testing.T) {
|
|||||||
|
|
||||||
func TestCheckUsersUserAccessTokensIntegrity(t *testing.T) {
|
func TestCheckUsersUserAccessTokensIntegrity(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
supplier := ss.(*store.LayeredStore).DatabaseLayer.(*SqlSupplier)
|
supplier := ss.(*SqlSupplier)
|
||||||
dbmap := supplier.GetMaster()
|
dbmap := supplier.GetMaster()
|
||||||
|
|
||||||
t.Run("should generate a report with no records", func(t *testing.T) {
|
t.Run("should generate a report with no records", func(t *testing.T) {
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ func initStores() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
st.SqlSupplier = NewSqlSupplier(*st.SqlSettings, nil)
|
st.SqlSupplier = NewSqlSupplier(*st.SqlSettings, nil)
|
||||||
st.Store = store.NewLayeredStore(st.SqlSupplier, nil, nil)
|
st.Store = st.SqlSupplier
|
||||||
st.Store.DropAllTables()
|
st.Store.DropAllTables()
|
||||||
st.Store.MarkSystemRanUnitTests()
|
st.Store.MarkSystemRanUnitTests()
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ const (
|
|||||||
EXIT_DOES_COLUMN_EXISTS_SQLITE = 138
|
EXIT_DOES_COLUMN_EXISTS_SQLITE = 138
|
||||||
)
|
)
|
||||||
|
|
||||||
type SqlSupplierOldStores struct {
|
type SqlSupplierStores struct {
|
||||||
team store.TeamStore
|
team store.TeamStore
|
||||||
channel store.ChannelStore
|
channel store.ChannelStore
|
||||||
post store.PostStore
|
post store.PostStore
|
||||||
@@ -106,11 +106,10 @@ type SqlSupplier struct {
|
|||||||
// See https://github.com/mattermost/mattermost-server/pull/7281
|
// See https://github.com/mattermost/mattermost-server/pull/7281
|
||||||
rrCounter int64
|
rrCounter int64
|
||||||
srCounter int64
|
srCounter int64
|
||||||
next store.LayeredStoreSupplier
|
|
||||||
master *gorp.DbMap
|
master *gorp.DbMap
|
||||||
replicas []*gorp.DbMap
|
replicas []*gorp.DbMap
|
||||||
searchReplicas []*gorp.DbMap
|
searchReplicas []*gorp.DbMap
|
||||||
oldStores SqlSupplierOldStores
|
stores SqlSupplierStores
|
||||||
settings *model.SqlSettings
|
settings *model.SqlSettings
|
||||||
lockedToMaster bool
|
lockedToMaster bool
|
||||||
}
|
}
|
||||||
@@ -124,37 +123,37 @@ func NewSqlSupplier(settings model.SqlSettings, metrics einterfaces.MetricsInter
|
|||||||
|
|
||||||
supplier.initConnection()
|
supplier.initConnection()
|
||||||
|
|
||||||
supplier.oldStores.team = NewSqlTeamStore(supplier, metrics)
|
supplier.stores.team = NewSqlTeamStore(supplier, metrics)
|
||||||
supplier.oldStores.channel = NewSqlChannelStore(supplier, metrics)
|
supplier.stores.channel = NewSqlChannelStore(supplier, metrics)
|
||||||
supplier.oldStores.post = NewSqlPostStore(supplier, metrics)
|
supplier.stores.post = NewSqlPostStore(supplier, metrics)
|
||||||
supplier.oldStores.user = NewSqlUserStore(supplier, metrics)
|
supplier.stores.user = NewSqlUserStore(supplier, metrics)
|
||||||
supplier.oldStores.bot = NewSqlBotStore(supplier, metrics)
|
supplier.stores.bot = NewSqlBotStore(supplier, metrics)
|
||||||
supplier.oldStores.audit = NewSqlAuditStore(supplier)
|
supplier.stores.audit = NewSqlAuditStore(supplier)
|
||||||
supplier.oldStores.cluster = NewSqlClusterDiscoveryStore(supplier)
|
supplier.stores.cluster = NewSqlClusterDiscoveryStore(supplier)
|
||||||
supplier.oldStores.compliance = NewSqlComplianceStore(supplier)
|
supplier.stores.compliance = NewSqlComplianceStore(supplier)
|
||||||
supplier.oldStores.session = NewSqlSessionStore(supplier)
|
supplier.stores.session = NewSqlSessionStore(supplier)
|
||||||
supplier.oldStores.oauth = NewSqlOAuthStore(supplier)
|
supplier.stores.oauth = NewSqlOAuthStore(supplier)
|
||||||
supplier.oldStores.system = NewSqlSystemStore(supplier)
|
supplier.stores.system = NewSqlSystemStore(supplier)
|
||||||
supplier.oldStores.webhook = NewSqlWebhookStore(supplier, metrics)
|
supplier.stores.webhook = NewSqlWebhookStore(supplier, metrics)
|
||||||
supplier.oldStores.command = NewSqlCommandStore(supplier)
|
supplier.stores.command = NewSqlCommandStore(supplier)
|
||||||
supplier.oldStores.commandWebhook = NewSqlCommandWebhookStore(supplier)
|
supplier.stores.commandWebhook = NewSqlCommandWebhookStore(supplier)
|
||||||
supplier.oldStores.preference = NewSqlPreferenceStore(supplier)
|
supplier.stores.preference = NewSqlPreferenceStore(supplier)
|
||||||
supplier.oldStores.license = NewSqlLicenseStore(supplier)
|
supplier.stores.license = NewSqlLicenseStore(supplier)
|
||||||
supplier.oldStores.token = NewSqlTokenStore(supplier)
|
supplier.stores.token = NewSqlTokenStore(supplier)
|
||||||
supplier.oldStores.emoji = NewSqlEmojiStore(supplier, metrics)
|
supplier.stores.emoji = NewSqlEmojiStore(supplier, metrics)
|
||||||
supplier.oldStores.status = NewSqlStatusStore(supplier)
|
supplier.stores.status = NewSqlStatusStore(supplier)
|
||||||
supplier.oldStores.fileInfo = NewSqlFileInfoStore(supplier, metrics)
|
supplier.stores.fileInfo = NewSqlFileInfoStore(supplier, metrics)
|
||||||
supplier.oldStores.job = NewSqlJobStore(supplier)
|
supplier.stores.job = NewSqlJobStore(supplier)
|
||||||
supplier.oldStores.userAccessToken = NewSqlUserAccessTokenStore(supplier)
|
supplier.stores.userAccessToken = NewSqlUserAccessTokenStore(supplier)
|
||||||
supplier.oldStores.channelMemberHistory = NewSqlChannelMemberHistoryStore(supplier)
|
supplier.stores.channelMemberHistory = NewSqlChannelMemberHistoryStore(supplier)
|
||||||
supplier.oldStores.plugin = NewSqlPluginStore(supplier)
|
supplier.stores.plugin = NewSqlPluginStore(supplier)
|
||||||
supplier.oldStores.TermsOfService = NewSqlTermsOfServiceStore(supplier, metrics)
|
supplier.stores.TermsOfService = NewSqlTermsOfServiceStore(supplier, metrics)
|
||||||
supplier.oldStores.UserTermsOfService = NewSqlUserTermsOfServiceStore(supplier)
|
supplier.stores.UserTermsOfService = NewSqlUserTermsOfServiceStore(supplier)
|
||||||
supplier.oldStores.linkMetadata = NewSqlLinkMetadataStore(supplier)
|
supplier.stores.linkMetadata = NewSqlLinkMetadataStore(supplier)
|
||||||
supplier.oldStores.reaction = NewSqlReactionStore(supplier)
|
supplier.stores.reaction = NewSqlReactionStore(supplier)
|
||||||
supplier.oldStores.role = NewSqlRoleStore(supplier)
|
supplier.stores.role = NewSqlRoleStore(supplier)
|
||||||
supplier.oldStores.scheme = NewSqlSchemeStore(supplier)
|
supplier.stores.scheme = NewSqlSchemeStore(supplier)
|
||||||
supplier.oldStores.group = NewSqlGroupStore(supplier)
|
supplier.stores.group = NewSqlGroupStore(supplier)
|
||||||
|
|
||||||
err := supplier.GetMaster().CreateTablesIfNotExists()
|
err := supplier.GetMaster().CreateTablesIfNotExists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -170,46 +169,37 @@ func NewSqlSupplier(settings model.SqlSettings, metrics einterfaces.MetricsInter
|
|||||||
os.Exit(EXIT_GENERIC_FAILURE)
|
os.Exit(EXIT_GENERIC_FAILURE)
|
||||||
}
|
}
|
||||||
|
|
||||||
supplier.oldStores.team.(*SqlTeamStore).CreateIndexesIfNotExists()
|
supplier.stores.team.(*SqlTeamStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
|
supplier.stores.channel.(*SqlChannelStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.post.(*SqlPostStore).CreateIndexesIfNotExists()
|
supplier.stores.post.(*SqlPostStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.user.(*SqlUserStore).CreateIndexesIfNotExists()
|
supplier.stores.user.(*SqlUserStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.bot.(*SqlBotStore).CreateIndexesIfNotExists()
|
supplier.stores.bot.(*SqlBotStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.audit.(*SqlAuditStore).CreateIndexesIfNotExists()
|
supplier.stores.audit.(*SqlAuditStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.compliance.(*SqlComplianceStore).CreateIndexesIfNotExists()
|
supplier.stores.compliance.(*SqlComplianceStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.session.(*SqlSessionStore).CreateIndexesIfNotExists()
|
supplier.stores.session.(*SqlSessionStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.oauth.(*SqlOAuthStore).CreateIndexesIfNotExists()
|
supplier.stores.oauth.(*SqlOAuthStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.system.(*SqlSystemStore).CreateIndexesIfNotExists()
|
supplier.stores.system.(*SqlSystemStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.webhook.(*SqlWebhookStore).CreateIndexesIfNotExists()
|
supplier.stores.webhook.(*SqlWebhookStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.command.(*SqlCommandStore).CreateIndexesIfNotExists()
|
supplier.stores.command.(*SqlCommandStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.commandWebhook.(*SqlCommandWebhookStore).CreateIndexesIfNotExists()
|
supplier.stores.commandWebhook.(*SqlCommandWebhookStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.preference.(*SqlPreferenceStore).CreateIndexesIfNotExists()
|
supplier.stores.preference.(*SqlPreferenceStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.license.(*SqlLicenseStore).CreateIndexesIfNotExists()
|
supplier.stores.license.(*SqlLicenseStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.token.(*SqlTokenStore).CreateIndexesIfNotExists()
|
supplier.stores.token.(*SqlTokenStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.emoji.(*SqlEmojiStore).CreateIndexesIfNotExists()
|
supplier.stores.emoji.(*SqlEmojiStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.status.(*SqlStatusStore).CreateIndexesIfNotExists()
|
supplier.stores.status.(*SqlStatusStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.fileInfo.(*SqlFileInfoStore).CreateIndexesIfNotExists()
|
supplier.stores.fileInfo.(*SqlFileInfoStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.job.(*SqlJobStore).CreateIndexesIfNotExists()
|
supplier.stores.job.(*SqlJobStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.userAccessToken.(*SqlUserAccessTokenStore).CreateIndexesIfNotExists()
|
supplier.stores.userAccessToken.(*SqlUserAccessTokenStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.plugin.(*SqlPluginStore).CreateIndexesIfNotExists()
|
supplier.stores.plugin.(*SqlPluginStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.TermsOfService.(SqlTermsOfServiceStore).CreateIndexesIfNotExists()
|
supplier.stores.TermsOfService.(SqlTermsOfServiceStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.UserTermsOfService.(SqlUserTermsOfServiceStore).CreateIndexesIfNotExists()
|
supplier.stores.UserTermsOfService.(SqlUserTermsOfServiceStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.linkMetadata.(*SqlLinkMetadataStore).CreateIndexesIfNotExists()
|
supplier.stores.linkMetadata.(*SqlLinkMetadataStore).CreateIndexesIfNotExists()
|
||||||
supplier.oldStores.group.(*SqlGroupStore).CreateIndexesIfNotExists()
|
supplier.stores.group.(*SqlGroupStore).CreateIndexesIfNotExists()
|
||||||
|
supplier.stores.preference.(*SqlPreferenceStore).DeleteUnusedFeatures()
|
||||||
supplier.oldStores.preference.(*SqlPreferenceStore).DeleteUnusedFeatures()
|
|
||||||
|
|
||||||
return supplier
|
return supplier
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SqlSupplier) SetChainNext(next store.LayeredStoreSupplier) {
|
|
||||||
s.next = next
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SqlSupplier) Next() store.LayeredStoreSupplier {
|
|
||||||
return s.next
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupConnection(con_type string, dataSource string, settings *model.SqlSettings) *gorp.DbMap {
|
func setupConnection(con_type string, dataSource string, settings *model.SqlSettings) *gorp.DbMap {
|
||||||
db, err := dbsql.Open(*settings.DriverName, dataSource)
|
db, err := dbsql.Open(*settings.DriverName, dataSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -930,127 +920,127 @@ func (ss *SqlSupplier) UnlockFromMaster() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Team() store.TeamStore {
|
func (ss *SqlSupplier) Team() store.TeamStore {
|
||||||
return ss.oldStores.team
|
return ss.stores.team
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Channel() store.ChannelStore {
|
func (ss *SqlSupplier) Channel() store.ChannelStore {
|
||||||
return ss.oldStores.channel
|
return ss.stores.channel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Post() store.PostStore {
|
func (ss *SqlSupplier) Post() store.PostStore {
|
||||||
return ss.oldStores.post
|
return ss.stores.post
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) User() store.UserStore {
|
func (ss *SqlSupplier) User() store.UserStore {
|
||||||
return ss.oldStores.user
|
return ss.stores.user
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Bot() store.BotStore {
|
func (ss *SqlSupplier) Bot() store.BotStore {
|
||||||
return ss.oldStores.bot
|
return ss.stores.bot
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Session() store.SessionStore {
|
func (ss *SqlSupplier) Session() store.SessionStore {
|
||||||
return ss.oldStores.session
|
return ss.stores.session
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Audit() store.AuditStore {
|
func (ss *SqlSupplier) Audit() store.AuditStore {
|
||||||
return ss.oldStores.audit
|
return ss.stores.audit
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) ClusterDiscovery() store.ClusterDiscoveryStore {
|
func (ss *SqlSupplier) ClusterDiscovery() store.ClusterDiscoveryStore {
|
||||||
return ss.oldStores.cluster
|
return ss.stores.cluster
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Compliance() store.ComplianceStore {
|
func (ss *SqlSupplier) Compliance() store.ComplianceStore {
|
||||||
return ss.oldStores.compliance
|
return ss.stores.compliance
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) OAuth() store.OAuthStore {
|
func (ss *SqlSupplier) OAuth() store.OAuthStore {
|
||||||
return ss.oldStores.oauth
|
return ss.stores.oauth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) System() store.SystemStore {
|
func (ss *SqlSupplier) System() store.SystemStore {
|
||||||
return ss.oldStores.system
|
return ss.stores.system
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Webhook() store.WebhookStore {
|
func (ss *SqlSupplier) Webhook() store.WebhookStore {
|
||||||
return ss.oldStores.webhook
|
return ss.stores.webhook
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Command() store.CommandStore {
|
func (ss *SqlSupplier) Command() store.CommandStore {
|
||||||
return ss.oldStores.command
|
return ss.stores.command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) CommandWebhook() store.CommandWebhookStore {
|
func (ss *SqlSupplier) CommandWebhook() store.CommandWebhookStore {
|
||||||
return ss.oldStores.commandWebhook
|
return ss.stores.commandWebhook
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Preference() store.PreferenceStore {
|
func (ss *SqlSupplier) Preference() store.PreferenceStore {
|
||||||
return ss.oldStores.preference
|
return ss.stores.preference
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) License() store.LicenseStore {
|
func (ss *SqlSupplier) License() store.LicenseStore {
|
||||||
return ss.oldStores.license
|
return ss.stores.license
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Token() store.TokenStore {
|
func (ss *SqlSupplier) Token() store.TokenStore {
|
||||||
return ss.oldStores.token
|
return ss.stores.token
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Emoji() store.EmojiStore {
|
func (ss *SqlSupplier) Emoji() store.EmojiStore {
|
||||||
return ss.oldStores.emoji
|
return ss.stores.emoji
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Status() store.StatusStore {
|
func (ss *SqlSupplier) Status() store.StatusStore {
|
||||||
return ss.oldStores.status
|
return ss.stores.status
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) FileInfo() store.FileInfoStore {
|
func (ss *SqlSupplier) FileInfo() store.FileInfoStore {
|
||||||
return ss.oldStores.fileInfo
|
return ss.stores.fileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Reaction() store.ReactionStore {
|
func (ss *SqlSupplier) Reaction() store.ReactionStore {
|
||||||
return ss.oldStores.reaction
|
return ss.stores.reaction
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Job() store.JobStore {
|
func (ss *SqlSupplier) Job() store.JobStore {
|
||||||
return ss.oldStores.job
|
return ss.stores.job
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) UserAccessToken() store.UserAccessTokenStore {
|
func (ss *SqlSupplier) UserAccessToken() store.UserAccessTokenStore {
|
||||||
return ss.oldStores.userAccessToken
|
return ss.stores.userAccessToken
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) ChannelMemberHistory() store.ChannelMemberHistoryStore {
|
func (ss *SqlSupplier) ChannelMemberHistory() store.ChannelMemberHistoryStore {
|
||||||
return ss.oldStores.channelMemberHistory
|
return ss.stores.channelMemberHistory
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Plugin() store.PluginStore {
|
func (ss *SqlSupplier) Plugin() store.PluginStore {
|
||||||
return ss.oldStores.plugin
|
return ss.stores.plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Role() store.RoleStore {
|
func (ss *SqlSupplier) Role() store.RoleStore {
|
||||||
return ss.oldStores.role
|
return ss.stores.role
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) TermsOfService() store.TermsOfServiceStore {
|
func (ss *SqlSupplier) TermsOfService() store.TermsOfServiceStore {
|
||||||
return ss.oldStores.TermsOfService
|
return ss.stores.TermsOfService
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) UserTermsOfService() store.UserTermsOfServiceStore {
|
func (ss *SqlSupplier) UserTermsOfService() store.UserTermsOfServiceStore {
|
||||||
return ss.oldStores.UserTermsOfService
|
return ss.stores.UserTermsOfService
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Scheme() store.SchemeStore {
|
func (ss *SqlSupplier) Scheme() store.SchemeStore {
|
||||||
return ss.oldStores.scheme
|
return ss.stores.scheme
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) Group() store.GroupStore {
|
func (ss *SqlSupplier) Group() store.GroupStore {
|
||||||
return ss.oldStores.group
|
return ss.stores.group
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) LinkMetadata() store.LinkMetadataStore {
|
func (ss *SqlSupplier) LinkMetadata() store.LinkMetadataStore {
|
||||||
return ss.oldStores.linkMetadata
|
return ss.stores.linkMetadata
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) DropAllTables() {
|
func (ss *SqlSupplier) DropAllTables() {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
func TestStoreUpgrade(t *testing.T) {
|
func TestStoreUpgrade(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
sqlStore := ss.(*store.LayeredStore).DatabaseLayer.(SqlStore)
|
sqlStore := ss.(SqlStore)
|
||||||
|
|
||||||
t.Run("invalid currentModelVersion", func(t *testing.T) {
|
t.Run("invalid currentModelVersion", func(t *testing.T) {
|
||||||
err := UpgradeDatabase(sqlStore, "notaversion")
|
err := UpgradeDatabase(sqlStore, "notaversion")
|
||||||
@@ -81,7 +81,7 @@ func TestStoreUpgrade(t *testing.T) {
|
|||||||
|
|
||||||
func TestSaveSchemaVersion(t *testing.T) {
|
func TestSaveSchemaVersion(t *testing.T) {
|
||||||
StoreTest(t, func(t *testing.T, ss store.Store) {
|
StoreTest(t, func(t *testing.T, ss store.Store) {
|
||||||
sqlStore := ss.(*store.LayeredStore).DatabaseLayer.(SqlStore)
|
sqlStore := ss.(SqlStore)
|
||||||
|
|
||||||
t.Run("set earliest version", func(t *testing.T) {
|
t.Run("set earliest version", func(t *testing.T) {
|
||||||
saveSchemaVersion(sqlStore, VERSION_3_0_0)
|
saveSchemaVersion(sqlStore, VERSION_3_0_0)
|
||||||
|
|||||||
@@ -30,33 +30,26 @@ func testEmojiSaveDelete(t *testing.T, ss store.Store) {
|
|||||||
Name: model.NewId(),
|
Name: model.NewId(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := ss.Emoji().Save(emoji1); err != nil {
|
_, err := ss.Emoji().Save(emoji1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if len(emoji1.Id) != 26 {
|
assert.Len(t, emoji1.Id, 26, "should've set id for emoji")
|
||||||
t.Fatal("should've set id for emoji")
|
|
||||||
}
|
|
||||||
|
|
||||||
emoji2 := model.Emoji{
|
emoji2 := model.Emoji{
|
||||||
CreatorId: model.NewId(),
|
CreatorId: model.NewId(),
|
||||||
Name: emoji1.Name,
|
Name: emoji1.Name,
|
||||||
}
|
}
|
||||||
if _, err := ss.Emoji().Save(&emoji2); err == nil {
|
_, err = ss.Emoji().Save(&emoji2)
|
||||||
t.Fatal("shouldn't be able to save emoji with duplicate name")
|
require.NotNil(t, err, "shouldn't be able to save emoji with duplicate name")
|
||||||
}
|
|
||||||
|
|
||||||
if err := ss.Emoji().Delete(emoji1, time.Now().Unix()); err != nil {
|
err = ss.Emoji().Delete(emoji1, time.Now().Unix())
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Emoji().Save(&emoji2); err != nil {
|
_, err = ss.Emoji().Save(&emoji2)
|
||||||
t.Fatal("should be able to save emoji with duplicate name now that original has been deleted", err)
|
require.Nil(t, err, "should be able to save emoji with duplicate name now that original has been deleted")
|
||||||
}
|
|
||||||
|
|
||||||
if err := ss.Emoji().Delete(&emoji2, time.Now().Unix()+1); err != nil {
|
err = ss.Emoji().Delete(&emoji2, time.Now().Unix()+1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEmojiGet(t *testing.T, ss store.Store) {
|
func testEmojiGet(t *testing.T, ss store.Store) {
|
||||||
@@ -88,15 +81,13 @@ func testEmojiGet(t *testing.T, ss store.Store) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
for _, emoji := range emojis {
|
for _, emoji := range emojis {
|
||||||
if _, err := ss.Emoji().Get(emoji.Id, false); err != nil {
|
_, err := ss.Emoji().Get(emoji.Id, false)
|
||||||
t.Fatalf("failed to get emoji with id %v: %v", emoji.Id, err)
|
require.Nilf(t, err, "failed to get emoji with id %v", emoji.Id)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, emoji := range emojis {
|
for _, emoji := range emojis {
|
||||||
if _, err := ss.Emoji().Get(emoji.Id, true); err != nil {
|
_, err := ss.Emoji().Get(emoji.Id, true)
|
||||||
t.Fatalf("failed to get emoji with id %v: %v", emoji.Id, err)
|
require.Nilf(t, err, "failed to get emoji with id %v", emoji.Id)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,9 +175,8 @@ func testEmojiGetByName(t *testing.T, ss store.Store) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
for _, emoji := range emojis {
|
for _, emoji := range emojis {
|
||||||
if _, err := ss.Emoji().GetByName(emoji.Name, true); err != nil {
|
_, err := ss.Emoji().GetByName(emoji.Name, true)
|
||||||
t.Fatalf("failed to get emoji with name %v: %v", emoji.Name, err)
|
require.Nilf(t, err, "failed to get emoji with name %v", emoji.Name)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,35 +209,28 @@ func testEmojiGetMultipleByName(t *testing.T, ss store.Store) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
t.Run("one emoji", func(t *testing.T) {
|
t.Run("one emoji", func(t *testing.T) {
|
||||||
if received, err := ss.Emoji().GetMultipleByName([]string{emojis[0].Name}); err != nil {
|
received, err := ss.Emoji().GetMultipleByName([]string{emojis[0].Name})
|
||||||
t.Fatal("could not get emoji", err)
|
require.Nilf(t, err, "could not get emoji")
|
||||||
} else if len(received) != 1 || *received[0] != emojis[0] {
|
require.Len(t, received, 1, "got incorrect emoji")
|
||||||
t.Fatal("got incorrect emoji")
|
require.Equal(t, *received[0], emojis[0], "got incorrect emoji")
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("multiple emojis", func(t *testing.T) {
|
t.Run("multiple emojis", func(t *testing.T) {
|
||||||
if received, err := ss.Emoji().GetMultipleByName([]string{emojis[0].Name, emojis[1].Name, emojis[2].Name}); err != nil {
|
received, err := ss.Emoji().GetMultipleByName([]string{emojis[0].Name, emojis[1].Name, emojis[2].Name})
|
||||||
t.Fatal("could not get emojis", err)
|
require.Nil(t, err, "could not get emojis")
|
||||||
} else if len(received) != 3 {
|
require.Len(t, received, 3, "got incorrect emojis")
|
||||||
t.Fatal("got incorrect emojis")
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("one nonexistent emoji", func(t *testing.T) {
|
t.Run("one nonexistent emoji", func(t *testing.T) {
|
||||||
if received, err := ss.Emoji().GetMultipleByName([]string{"ab"}); err != nil {
|
received, err := ss.Emoji().GetMultipleByName([]string{"ab"})
|
||||||
t.Fatal("could not get emoji", err)
|
require.Nilf(t, err, "%v, could not get emoji", err)
|
||||||
} else if len(received) != 0 {
|
require.Len(t, received, 0, "got incorrect emoji")
|
||||||
t.Fatal("got incorrect emoji")
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("multiple emojis with nonexistent names", func(t *testing.T) {
|
t.Run("multiple emojis with nonexistent names", func(t *testing.T) {
|
||||||
if received, err := ss.Emoji().GetMultipleByName([]string{emojis[0].Name, emojis[1].Name, emojis[2].Name, "abcd", "1234"}); err != nil {
|
received, err := ss.Emoji().GetMultipleByName([]string{emojis[0].Name, emojis[1].Name, emojis[2].Name, "abcd", "1234"})
|
||||||
t.Fatal("could not get emojis", err)
|
require.Nil(t, err, "could not get emojis")
|
||||||
} else if len(received) != 3 {
|
require.Len(t, received, 3, "got incorrect emojis")
|
||||||
t.Fatal("got incorrect emojis")
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,9 +275,7 @@ func testEmojiGetList(t *testing.T, ss store.Store) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
require.Truef(t, found, "failed to get emoji with id %v", emoji.Id)
|
||||||
t.Fatalf("failed to get emoji with id %v", emoji.Id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,9 +328,8 @@ func testEmojiSearch(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
shouldFind := []bool{true, false, false, false}
|
shouldFind := []bool{true, false, false, false}
|
||||||
|
|
||||||
if result, err := ss.Emoji().Search("blargh", true, 100); err != nil {
|
result, err := ss.Emoji().Search("blargh", true, 100)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
for i, emoji := range emojis {
|
for i, emoji := range emojis {
|
||||||
found := false
|
found := false
|
||||||
|
|
||||||
@@ -362,12 +342,10 @@ func testEmojiSearch(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
assert.Equal(t, shouldFind[i], found, emoji.Name)
|
assert.Equal(t, shouldFind[i], found, emoji.Name)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
shouldFind = []bool{true, true, true, false}
|
shouldFind = []bool{true, true, true, false}
|
||||||
if result, err := ss.Emoji().Search("blargh", false, 100); err != nil {
|
result, err = ss.Emoji().Search("blargh", false, 100)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
for i, emoji := range emojis {
|
for i, emoji := range emojis {
|
||||||
found := false
|
found := false
|
||||||
|
|
||||||
@@ -381,4 +359,3 @@ func testEmojiSearch(t *testing.T, ss store.Store) {
|
|||||||
assert.Equal(t, shouldFind[i], found, emoji.Name)
|
assert.Equal(t, shouldFind[i], found, emoji.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,629 +0,0 @@
|
|||||||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
|
||||||
|
|
||||||
// Regenerate this file using `make store-mocks`.
|
|
||||||
|
|
||||||
package mocks
|
|
||||||
|
|
||||||
import (
|
|
||||||
store "github.com/mattermost/mattermost-server/store"
|
|
||||||
mock "github.com/stretchr/testify/mock"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LayeredStoreDatabaseLayer is an autogenerated mock type for the LayeredStoreDatabaseLayer type
|
|
||||||
type LayeredStoreDatabaseLayer struct {
|
|
||||||
mock.Mock
|
|
||||||
}
|
|
||||||
|
|
||||||
// Audit provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Audit() store.AuditStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.AuditStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.AuditStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.AuditStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bot provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Bot() store.BotStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.BotStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.BotStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.BotStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Channel() store.ChannelStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.ChannelStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.ChannelStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.ChannelStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChannelMemberHistory provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) ChannelMemberHistory() store.ChannelMemberHistoryStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.ChannelMemberHistoryStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.ChannelMemberHistoryStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.ChannelMemberHistoryStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckIntegrity provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) CheckIntegrity() <-chan store.IntegrityCheckResult {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 <-chan store.IntegrityCheckResult
|
|
||||||
if rf, ok := ret.Get(0).(func() <-chan store.IntegrityCheckResult); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(<-chan store.IntegrityCheckResult)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Close() {
|
|
||||||
_m.Called()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClusterDiscovery provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) ClusterDiscovery() store.ClusterDiscoveryStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.ClusterDiscoveryStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.ClusterDiscoveryStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.ClusterDiscoveryStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Command provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Command() store.CommandStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.CommandStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.CommandStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.CommandStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommandWebhook provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) CommandWebhook() store.CommandWebhookStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.CommandWebhookStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.CommandWebhookStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.CommandWebhookStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compliance provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Compliance() store.ComplianceStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.ComplianceStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.ComplianceStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.ComplianceStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// DropAllTables provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) DropAllTables() {
|
|
||||||
_m.Called()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emoji provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Emoji() store.EmojiStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.EmojiStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.EmojiStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.EmojiStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileInfo provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) FileInfo() store.FileInfoStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.FileInfoStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.FileInfoStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.FileInfoStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCurrentSchemaVersion provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) GetCurrentSchemaVersion() string {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 string
|
|
||||||
if rf, ok := ret.Get(0).(func() string); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
r0 = ret.Get(0).(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Group() store.GroupStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.GroupStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.GroupStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.GroupStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Job provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Job() store.JobStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.JobStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.JobStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.JobStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// License provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) License() store.LicenseStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.LicenseStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.LicenseStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.LicenseStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinkMetadata provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) LinkMetadata() store.LinkMetadataStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.LinkMetadataStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.LinkMetadataStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.LinkMetadataStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// LockToMaster provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) LockToMaster() {
|
|
||||||
_m.Called()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkSystemRanUnitTests provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) MarkSystemRanUnitTests() {
|
|
||||||
_m.Called()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Next() store.LayeredStoreSupplier {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.LayeredStoreSupplier
|
|
||||||
if rf, ok := ret.Get(0).(func() store.LayeredStoreSupplier); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.LayeredStoreSupplier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// OAuth provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) OAuth() store.OAuthStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.OAuthStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.OAuthStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.OAuthStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Plugin provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Plugin() store.PluginStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.PluginStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.PluginStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.PluginStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Post() store.PostStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.PostStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.PostStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.PostStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preference provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Preference() store.PreferenceStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.PreferenceStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.PreferenceStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.PreferenceStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reaction provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Reaction() store.ReactionStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.ReactionStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.ReactionStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.ReactionStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Role provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Role() store.RoleStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.RoleStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.RoleStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.RoleStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scheme provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Scheme() store.SchemeStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.SchemeStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.SchemeStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.SchemeStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Session provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Session() store.SessionStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.SessionStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.SessionStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.SessionStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChainNext provides a mock function with given fields: _a0
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) SetChainNext(_a0 store.LayeredStoreSupplier) {
|
|
||||||
_m.Called(_a0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Status() store.StatusStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.StatusStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.StatusStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.StatusStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// System provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) System() store.SystemStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.SystemStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.SystemStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.SystemStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Team provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Team() store.TeamStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.TeamStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.TeamStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.TeamStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// TermsOfService provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) TermsOfService() store.TermsOfServiceStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.TermsOfServiceStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.TermsOfServiceStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.TermsOfServiceStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Token provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Token() store.TokenStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.TokenStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.TokenStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.TokenStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// TotalMasterDbConnections provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) TotalMasterDbConnections() int {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 int
|
|
||||||
if rf, ok := ret.Get(0).(func() int); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
r0 = ret.Get(0).(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// TotalReadDbConnections provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) TotalReadDbConnections() int {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 int
|
|
||||||
if rf, ok := ret.Get(0).(func() int); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
r0 = ret.Get(0).(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// TotalSearchDbConnections provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) TotalSearchDbConnections() int {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 int
|
|
||||||
if rf, ok := ret.Get(0).(func() int); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
r0 = ret.Get(0).(int)
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnlockFromMaster provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) UnlockFromMaster() {
|
|
||||||
_m.Called()
|
|
||||||
}
|
|
||||||
|
|
||||||
// User provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) User() store.UserStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.UserStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.UserStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.UserStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserAccessToken provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) UserAccessToken() store.UserAccessTokenStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.UserAccessTokenStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.UserAccessTokenStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.UserAccessTokenStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserTermsOfService provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) UserTermsOfService() store.UserTermsOfServiceStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.UserTermsOfServiceStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.UserTermsOfServiceStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.UserTermsOfServiceStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Webhook provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreDatabaseLayer) Webhook() store.WebhookStore {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.WebhookStore
|
|
||||||
if rf, ok := ret.Get(0).(func() store.WebhookStore); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.WebhookStore)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
|
||||||
|
|
||||||
// Regenerate this file using `make store-mocks`.
|
|
||||||
|
|
||||||
package mocks
|
|
||||||
|
|
||||||
import (
|
|
||||||
store "github.com/mattermost/mattermost-server/store"
|
|
||||||
mock "github.com/stretchr/testify/mock"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LayeredStoreSupplier is an autogenerated mock type for the LayeredStoreSupplier type
|
|
||||||
type LayeredStoreSupplier struct {
|
|
||||||
mock.Mock
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next provides a mock function with given fields:
|
|
||||||
func (_m *LayeredStoreSupplier) Next() store.LayeredStoreSupplier {
|
|
||||||
ret := _m.Called()
|
|
||||||
|
|
||||||
var r0 store.LayeredStoreSupplier
|
|
||||||
if rf, ok := ret.Get(0).(func() store.LayeredStoreSupplier); ok {
|
|
||||||
r0 = rf()
|
|
||||||
} else {
|
|
||||||
if ret.Get(0) != nil {
|
|
||||||
r0 = ret.Get(0).(store.LayeredStoreSupplier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChainNext provides a mock function with given fields: _a0
|
|
||||||
func (_m *LayeredStoreSupplier) SetChainNext(_a0 store.LayeredStoreSupplier) {
|
|
||||||
_m.Called(_a0)
|
|
||||||
}
|
|
||||||
@@ -69,18 +69,15 @@ func testTeamStoreSave(t *testing.T, ss store.Store) {
|
|||||||
o1.Email = MakeEmail()
|
o1.Email = MakeEmail()
|
||||||
o1.Type = model.TEAM_OPEN
|
o1.Type = model.TEAM_OPEN
|
||||||
|
|
||||||
if _, err := ss.Team().Save(&o1); err != nil {
|
_, err := ss.Team().Save(&o1)
|
||||||
t.Fatal("couldn't save item", err)
|
require.Nil(t, err, "couldn't save item")
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Team().Save(&o1); err == nil {
|
_, err = ss.Team().Save(&o1)
|
||||||
t.Fatal("shouldn't be able to update from save")
|
require.NotNil(t, err, "shouldn't be able to update from save")
|
||||||
}
|
|
||||||
|
|
||||||
o1.Id = ""
|
o1.Id = ""
|
||||||
if _, err := ss.Team().Save(&o1); err == nil {
|
_, err = ss.Team().Save(&o1)
|
||||||
t.Fatal("should be unique domain")
|
require.NotNil(t, err, "should be unique domain")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTeamStoreUpdate(t *testing.T, ss store.Store) {
|
func testTeamStoreUpdate(t *testing.T, ss store.Store) {
|
||||||
@@ -89,25 +86,21 @@ func testTeamStoreUpdate(t *testing.T, ss store.Store) {
|
|||||||
o1.Name = "z-z-z" + model.NewId() + "b"
|
o1.Name = "z-z-z" + model.NewId() + "b"
|
||||||
o1.Email = MakeEmail()
|
o1.Email = MakeEmail()
|
||||||
o1.Type = model.TEAM_OPEN
|
o1.Type = model.TEAM_OPEN
|
||||||
if _, err := ss.Team().Save(&o1); err != nil {
|
_, err := ss.Team().Save(&o1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
if _, err := ss.Team().Update(&o1); err != nil {
|
_, err = ss.Team().Update(&o1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
o1.Id = "missing"
|
o1.Id = "missing"
|
||||||
if _, err := ss.Team().Update(&o1); err == nil {
|
_, err = ss.Team().Update(&o1)
|
||||||
t.Fatal("Update should have failed because of missing key")
|
require.NotNil(t, err, "Update should have failed because of missing key")
|
||||||
}
|
|
||||||
|
|
||||||
o1.Id = model.NewId()
|
o1.Id = model.NewId()
|
||||||
if _, err := ss.Team().Update(&o1); err == nil {
|
_, err = ss.Team().Update(&o1)
|
||||||
t.Fatal("Update should have faile because id change")
|
require.NotNil(t, err, "Update should have faile because id change")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTeamStoreGet(t *testing.T, ss store.Store) {
|
func testTeamStoreGet(t *testing.T, ss store.Store) {
|
||||||
@@ -134,21 +127,15 @@ func testTeamStoreGetByName(t *testing.T, ss store.Store) {
|
|||||||
o1.Email = MakeEmail()
|
o1.Email = MakeEmail()
|
||||||
o1.Type = model.TEAM_OPEN
|
o1.Type = model.TEAM_OPEN
|
||||||
|
|
||||||
if _, err := ss.Team().Save(&o1); err != nil {
|
_, err := ss.Team().Save(&o1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if team, err := ss.Team().GetByName(o1.Name); err != nil {
|
team, err := ss.Team().GetByName(o1.Name)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Equal(t, *team, o1, "invalid returned team")
|
||||||
if team.ToJson() != o1.ToJson() {
|
|
||||||
t.Fatal("invalid returned team")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Team().GetByName(""); err == nil {
|
_, err = ss.Team().GetByName("")
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTeamStoreSearchAll(t *testing.T, ss store.Store) {
|
func testTeamStoreSearchAll(t *testing.T, ss store.Store) {
|
||||||
@@ -363,9 +350,7 @@ func testTeamStoreGetByInviteId(t *testing.T, ss store.Store) {
|
|||||||
o1.InviteId = model.NewId()
|
o1.InviteId = model.NewId()
|
||||||
|
|
||||||
save1, err := ss.Team().Save(&o1)
|
save1, err := ss.Team().Save(&o1)
|
||||||
if err != nil {
|
require.Nil(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
o2 := model.Team{}
|
o2 := model.Team{}
|
||||||
o2.DisplayName = "DisplayName"
|
o2.DisplayName = "DisplayName"
|
||||||
@@ -373,17 +358,12 @@ func testTeamStoreGetByInviteId(t *testing.T, ss store.Store) {
|
|||||||
o2.Email = MakeEmail()
|
o2.Email = MakeEmail()
|
||||||
o2.Type = model.TEAM_OPEN
|
o2.Type = model.TEAM_OPEN
|
||||||
|
|
||||||
if r1, err := ss.Team().GetByInviteId(save1.InviteId); err != nil {
|
r1, err := ss.Team().GetByInviteId(save1.InviteId)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Equal(t, *r1, o1, "invalid returned team")
|
||||||
if r1.ToJson() != o1.ToJson() {
|
|
||||||
t.Fatal("invalid returned team")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Team().GetByInviteId(""); err == nil {
|
_, err = ss.Team().GetByInviteId("")
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTeamStoreByUserId(t *testing.T, ss store.Store) {
|
func testTeamStoreByUserId(t *testing.T, ss store.Store) {
|
||||||
@@ -400,18 +380,10 @@ func testTeamStoreByUserId(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Team().SaveMember(m1, -1)
|
_, err = ss.Team().SaveMember(m1, -1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if teams, err := ss.Team().GetTeamsByUserId(m1.UserId); err != nil {
|
teams, err := ss.Team().GetTeamsByUserId(m1.UserId)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Len(t, teams, 1, "Should return a team")
|
||||||
if len(teams) == 0 {
|
require.Equal(t, teams[0].Id, o1.Id, "should be a member")
|
||||||
t.Fatal("Should return a team")
|
|
||||||
}
|
|
||||||
|
|
||||||
if teams[0].Id != o1.Id {
|
|
||||||
t.Fatal("should be a member")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetAllTeamListing(t *testing.T, ss store.Store) {
|
func testGetAllTeamListing(t *testing.T, ss store.Store) {
|
||||||
@@ -449,19 +421,13 @@ func testGetAllTeamListing(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Team().Save(&o4)
|
_, err = ss.Team().Save(&o4)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if teams, err := ss.Team().GetAllTeamListing(); err != nil {
|
teams, err := ss.Team().GetAllTeamListing()
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
if !team.AllowOpenInvite {
|
require.True(t, team.AllowOpenInvite, "should have returned team with AllowOpenInvite as true")
|
||||||
t.Fatal("should have returned team with AllowOpenInvite as true")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(teams) == 0 {
|
require.NotEmpty(t, teams, "failed team listing")
|
||||||
t.Fatal("failed team listing")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetAllTeamPageListing(t *testing.T, ss store.Store) {
|
func testGetAllTeamPageListing(t *testing.T, ss store.Store) {
|
||||||
@@ -505,14 +471,10 @@ func testGetAllTeamPageListing(t *testing.T, ss store.Store) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
if !team.AllowOpenInvite {
|
require.True(t, team.AllowOpenInvite, "should have returned team with AllowOpenInvite as true")
|
||||||
t.Fatal("should have returned team with AllowOpenInvite as true")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(teams) > 10 {
|
require.LessOrEqual(t, len(teams), 10, "should have returned max of 10 teams")
|
||||||
t.Fatal("should have returned max of 10 teams")
|
|
||||||
}
|
|
||||||
|
|
||||||
o5 := model.Team{}
|
o5 := model.Team{}
|
||||||
o5.DisplayName = "DisplayName"
|
o5.DisplayName = "DisplayName"
|
||||||
@@ -527,27 +489,19 @@ func testGetAllTeamPageListing(t *testing.T, ss store.Store) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
if !team.AllowOpenInvite {
|
require.True(t, team.AllowOpenInvite, "should have returned team with AllowOpenInvite as true")
|
||||||
t.Fatal("should have returned team with AllowOpenInvite as true")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(teams) > 4 {
|
require.LessOrEqual(t, len(teams), 4, "should have returned max of 4 teams")
|
||||||
t.Fatal("should have returned max of 4 teams")
|
|
||||||
}
|
|
||||||
|
|
||||||
teams, err = ss.Team().GetAllTeamPageListing(1, 1)
|
teams, err = ss.Team().GetAllTeamPageListing(1, 1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
if !team.AllowOpenInvite {
|
require.True(t, team.AllowOpenInvite, "should have returned team with AllowOpenInvite as true")
|
||||||
t.Fatal("should have returned team with AllowOpenInvite as true")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(teams) > 1 {
|
require.LessOrEqual(t, len(teams), 1, "should have returned max of 1 team")
|
||||||
t.Fatal("should have returned max of 1 team")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetAllPrivateTeamListing(t *testing.T, ss store.Store) {
|
func testGetAllPrivateTeamListing(t *testing.T, ss store.Store) {
|
||||||
@@ -585,18 +539,12 @@ func testGetAllPrivateTeamListing(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Team().Save(&o4)
|
_, err = ss.Team().Save(&o4)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if teams, err := ss.Team().GetAllPrivateTeamListing(); err != nil {
|
teams, err := ss.Team().GetAllPrivateTeamListing()
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.NotEmpty(t, teams, "failed team listing")
|
||||||
for _, team := range teams {
|
|
||||||
if team.AllowOpenInvite {
|
|
||||||
t.Fatal("should have returned team with AllowOpenInvite as false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(teams) == 0 {
|
for _, team := range teams {
|
||||||
t.Fatal("failed team listing")
|
require.False(t, team.AllowOpenInvite, "should have returned team with AllowOpenInvite as false")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,19 +585,13 @@ func testGetAllPrivateTeamPageListing(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Team().Save(&o4)
|
_, err = ss.Team().Save(&o4)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if teams, listErr := ss.Team().GetAllPrivateTeamPageListing(0, 10); listErr != nil {
|
teams, listErr := ss.Team().GetAllPrivateTeamPageListing(0, 10)
|
||||||
t.Fatal(listErr)
|
require.Nil(t, listErr)
|
||||||
} else {
|
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
if team.AllowOpenInvite {
|
require.False(t, team.AllowOpenInvite, "should have returned team with AllowOpenInvite as false")
|
||||||
t.Fatal("should have returned team with AllowOpenInvite as false")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(teams) > 10 {
|
require.LessOrEqual(t, len(teams), 10, "should have returned max of 10 teams")
|
||||||
t.Fatal("should have returned max of 10 teams")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
o5 := model.Team{}
|
o5 := model.Team{}
|
||||||
o5.DisplayName = "DisplayName"
|
o5.DisplayName = "DisplayName"
|
||||||
@@ -660,33 +602,21 @@ func testGetAllPrivateTeamPageListing(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Team().Save(&o5)
|
_, err = ss.Team().Save(&o5)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if teams, listErr := ss.Team().GetAllPrivateTeamPageListing(0, 4); listErr != nil {
|
teams, listErr = ss.Team().GetAllPrivateTeamPageListing(0, 4)
|
||||||
t.Fatal(listErr)
|
require.Nil(t, listErr)
|
||||||
} else {
|
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
if team.AllowOpenInvite {
|
require.False(t, team.AllowOpenInvite, "should have returned team with AllowOpenInvite as false")
|
||||||
t.Fatal("should have returned team with AllowOpenInvite as false")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(teams) > 4 {
|
require.LessOrEqual(t, len(teams), 4, "should have returned max of 4 teams")
|
||||||
t.Fatal("should have returned max of 4 teams")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if teams, listErr := ss.Team().GetAllPrivateTeamPageListing(1, 1); listErr != nil {
|
teams, listErr = ss.Team().GetAllPrivateTeamPageListing(1, 1)
|
||||||
t.Fatal(listErr)
|
require.Nil(t, listErr)
|
||||||
} else {
|
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
if team.AllowOpenInvite {
|
require.False(t, team.AllowOpenInvite, "should have returned team with AllowOpenInvite as false")
|
||||||
t.Fatal("should have returned team with AllowOpenInvite as false")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(teams) > 1 {
|
require.LessOrEqual(t, len(teams), 1, "should have returned max of 1 team")
|
||||||
t.Fatal("should have returned max of 1 team")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetAllPublicTeamPageListing(t *testing.T, ss store.Store) {
|
func testGetAllPublicTeamPageListing(t *testing.T, ss store.Store) {
|
||||||
@@ -767,9 +697,8 @@ func testDelete(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Team().Save(&o2)
|
_, err = ss.Team().Save(&o2)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if r1 := ss.Team().PermanentDelete(o1.Id); r1 != nil {
|
r1 := ss.Team().PermanentDelete(o1.Id)
|
||||||
t.Fatal(r1)
|
require.Nil(t, r1)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPublicTeamCount(t *testing.T, ss store.Store) {
|
func testPublicTeamCount(t *testing.T, ss store.Store) {
|
||||||
@@ -852,13 +781,9 @@ func testTeamCount(t *testing.T, ss store.Store) {
|
|||||||
_, err := ss.Team().Save(&o1)
|
_, err := ss.Team().Save(&o1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if teamCount, err := ss.Team().AnalyticsTeamCount(); err != nil {
|
teamCount, err := ss.Team().AnalyticsTeamCount()
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.NotEqual(t, 0, int(teamCount), "should be at least 1 team")
|
||||||
if teamCount == 0 {
|
|
||||||
t.Fatal("should be at least 1 team")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTeamMembers(t *testing.T, ss store.Store) {
|
func testTeamMembers(t *testing.T, ss store.Store) {
|
||||||
@@ -880,47 +805,33 @@ func testTeamMembers(t *testing.T, ss store.Store) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
assert.Len(t, ms, 2)
|
assert.Len(t, ms, 2)
|
||||||
|
|
||||||
if ms, err = ss.Team().GetMembers(teamId2, 0, 100, nil); err != nil {
|
ms, err = ss.Team().GetMembers(teamId2, 0, 100, nil)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
|
|
||||||
require.Len(t, ms, 1)
|
require.Len(t, ms, 1)
|
||||||
require.Equal(t, m3.UserId, ms[0].UserId)
|
require.Equal(t, m3.UserId, ms[0].UserId)
|
||||||
}
|
|
||||||
|
|
||||||
if ms, err = ss.Team().GetTeamsForUser(m1.UserId); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
ms, err = ss.Team().GetTeamsForUser(m1.UserId)
|
||||||
|
require.Nil(t, err)
|
||||||
require.Len(t, ms, 1)
|
require.Len(t, ms, 1)
|
||||||
require.Equal(t, m1.TeamId, ms[0].TeamId)
|
require.Equal(t, m1.TeamId, ms[0].TeamId)
|
||||||
}
|
|
||||||
|
|
||||||
if err = ss.Team().RemoveMember(teamId1, m1.UserId); err != nil {
|
err = ss.Team().RemoveMember(teamId1, m1.UserId)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if ms, err = ss.Team().GetMembers(teamId1, 0, 100, nil); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
ms, err = ss.Team().GetMembers(teamId1, 0, 100, nil)
|
||||||
|
require.Nil(t, err)
|
||||||
require.Len(t, ms, 1)
|
require.Len(t, ms, 1)
|
||||||
require.Equal(t, m2.UserId, ms[0].UserId)
|
require.Equal(t, m2.UserId, ms[0].UserId)
|
||||||
}
|
|
||||||
|
|
||||||
_, err = ss.Team().SaveMember(m1, -1)
|
_, err = ss.Team().SaveMember(m1, -1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if err = ss.Team().RemoveAllMembersByTeam(teamId1); err != nil {
|
err = ss.Team().RemoveAllMembersByTeam(teamId1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if ms, err = ss.Team().GetMembers(teamId1, 0, 100, nil); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
ms, err = ss.Team().GetMembers(teamId1, 0, 100, nil)
|
||||||
|
require.Nil(t, err)
|
||||||
require.Len(t, ms, 0)
|
require.Len(t, ms, 0)
|
||||||
}
|
|
||||||
|
|
||||||
uid := model.NewId()
|
uid := model.NewId()
|
||||||
m4 := &model.TeamMember{TeamId: teamId1, UserId: uid}
|
m4 := &model.TeamMember{TeamId: teamId1, UserId: uid}
|
||||||
@@ -930,24 +841,17 @@ func testTeamMembers(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Team().SaveMember(m5, -1)
|
_, err = ss.Team().SaveMember(m5, -1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if ms, err = ss.Team().GetTeamsForUser(uid); err != nil {
|
ms, err = ss.Team().GetTeamsForUser(uid)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
|
|
||||||
require.Len(t, ms, 2)
|
require.Len(t, ms, 2)
|
||||||
}
|
|
||||||
|
|
||||||
if err = ss.Team().RemoveAllMembersByUser(uid); err != nil {
|
err = ss.Team().RemoveAllMembersByUser(uid)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if ms, err = ss.Team().GetTeamsForUser(m1.UserId); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
ms, err = ss.Team().GetTeamsForUser(m1.UserId)
|
||||||
|
require.Nil(t, err)
|
||||||
require.Len(t, ms, 0)
|
require.Len(t, ms, 0)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func testTeamMembersWithPagination(t *testing.T, ss store.Store) {
|
func testTeamMembersWithPagination(t *testing.T, ss store.Store) {
|
||||||
teamId1 := model.NewId()
|
teamId1 := model.NewId()
|
||||||
@@ -1044,11 +948,9 @@ func testSaveTeamMemberMaxMembers(t *testing.T, ss store.Store) {
|
|||||||
}(userIds[i])
|
}(userIds[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
if totalMemberCount, err := ss.Team().GetTotalMemberCount(team.Id, nil); err != nil {
|
totalMemberCount, err := ss.Team().GetTotalMemberCount(team.Id, nil)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else if int(totalMemberCount) != maxUsersPerTeam {
|
require.Equal(t, int(totalMemberCount), maxUsersPerTeam, "should start with 5 team members, had %v instead", totalMemberCount)
|
||||||
t.Fatalf("should start with 5 team members, had %v instead", totalMemberCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := ss.User().Save(&model.User{
|
user, err := ss.User().Save(&model.User{
|
||||||
Username: model.NewId(),
|
Username: model.NewId(),
|
||||||
@@ -1060,47 +962,36 @@ func testSaveTeamMemberMaxMembers(t *testing.T, ss store.Store) {
|
|||||||
ss.User().PermanentDelete(newUserId)
|
ss.User().PermanentDelete(newUserId)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if _, err = ss.Team().SaveMember(&model.TeamMember{
|
_, err = ss.Team().SaveMember(&model.TeamMember{
|
||||||
TeamId: team.Id,
|
TeamId: team.Id,
|
||||||
UserId: newUserId,
|
UserId: newUserId,
|
||||||
}, maxUsersPerTeam); err == nil {
|
}, maxUsersPerTeam)
|
||||||
t.Fatal("shouldn't be able to save member when at maximum members per team")
|
require.NotNil(t, err, "shouldn't be able to save member when at maximum members per team")
|
||||||
}
|
|
||||||
|
|
||||||
if totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id, nil); teamErr != nil {
|
totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id, nil)
|
||||||
t.Fatal(teamErr)
|
require.Nil(t, teamErr)
|
||||||
} else if int(totalMemberCount) != maxUsersPerTeam {
|
require.Equal(t, maxUsersPerTeam, int(totalMemberCount), "should still have 5 team members, had %v instead", totalMemberCount)
|
||||||
t.Fatalf("should still have 5 team members, had %v instead", totalMemberCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Leaving the team from the UI sets DeleteAt instead of using TeamStore.RemoveMember
|
// Leaving the team from the UI sets DeleteAt instead of using TeamStore.RemoveMember
|
||||||
if _, teamErr := ss.Team().UpdateMember(&model.TeamMember{
|
_, teamErr = ss.Team().UpdateMember(&model.TeamMember{
|
||||||
TeamId: team.Id,
|
TeamId: team.Id,
|
||||||
UserId: userIds[0],
|
UserId: userIds[0],
|
||||||
DeleteAt: 1234,
|
DeleteAt: 1234,
|
||||||
}); teamErr != nil {
|
})
|
||||||
panic(teamErr)
|
require.Nil(t, teamErr)
|
||||||
}
|
|
||||||
|
|
||||||
if totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id, nil); teamErr != nil {
|
totalMemberCount, teamErr = ss.Team().GetTotalMemberCount(team.Id, nil)
|
||||||
t.Fatal(teamErr)
|
require.Nil(t, teamErr)
|
||||||
} else if int(totalMemberCount) != maxUsersPerTeam-1 {
|
require.Equal(t, maxUsersPerTeam-1, int(totalMemberCount), "should now only have 4 team members, had %v instead", totalMemberCount)
|
||||||
t.Fatalf("should now only have 4 team members, had %v instead", totalMemberCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = ss.Team().SaveMember(&model.TeamMember{TeamId: team.Id, UserId: newUserId}, maxUsersPerTeam); err != nil {
|
_, err = ss.Team().SaveMember(&model.TeamMember{TeamId: team.Id, UserId: newUserId}, maxUsersPerTeam)
|
||||||
t.Fatal("should've been able to save new member after deleting one", err)
|
require.Nil(t, err, "should've been able to save new member after deleting one")
|
||||||
} else {
|
|
||||||
defer func(userId string) {
|
|
||||||
ss.Team().RemoveMember(team.Id, userId)
|
|
||||||
}(newUserId)
|
|
||||||
}
|
|
||||||
|
|
||||||
if totalMemberCount, teamErr := ss.Team().GetTotalMemberCount(team.Id, nil); teamErr != nil {
|
defer ss.Team().RemoveMember(team.Id, newUserId)
|
||||||
t.Fatal(teamErr)
|
|
||||||
} else if int(totalMemberCount) != maxUsersPerTeam {
|
totalMemberCount, teamErr = ss.Team().GetTotalMemberCount(team.Id, nil)
|
||||||
t.Fatalf("should have 5 team members again, had %v instead", totalMemberCount)
|
require.Nil(t, teamErr)
|
||||||
}
|
require.Equal(t, maxUsersPerTeam, int(totalMemberCount), "should have 5 team members again, had %v instead", totalMemberCount)
|
||||||
|
|
||||||
// Deactivating a user should make them stop counting against max members
|
// Deactivating a user should make them stop counting against max members
|
||||||
user2, err := ss.User().Get(userIds[1])
|
user2, err := ss.User().Get(userIds[1])
|
||||||
@@ -1115,13 +1006,10 @@ func testSaveTeamMemberMaxMembers(t *testing.T, ss store.Store) {
|
|||||||
})
|
})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
newUserId2 := user.Id
|
newUserId2 := user.Id
|
||||||
if _, err := ss.Team().SaveMember(&model.TeamMember{TeamId: team.Id, UserId: newUserId2}, maxUsersPerTeam); err != nil {
|
_, err = ss.Team().SaveMember(&model.TeamMember{TeamId: team.Id, UserId: newUserId2}, maxUsersPerTeam)
|
||||||
t.Fatal("should've been able to save new member after deleting one", err)
|
require.Nil(t, err, "should've been able to save new member after deleting one")
|
||||||
} else {
|
|
||||||
defer func(userId string) {
|
defer ss.Team().RemoveMember(team.Id, newUserId2)
|
||||||
ss.Team().RemoveMember(team.Id, userId)
|
|
||||||
}(newUserId2)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetTeamMember(t *testing.T, ss store.Store) {
|
func testGetTeamMember(t *testing.T, ss store.Store) {
|
||||||
@@ -1132,26 +1020,18 @@ func testGetTeamMember(t *testing.T, ss store.Store) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
var rm1 *model.TeamMember
|
var rm1 *model.TeamMember
|
||||||
if rm1, err = ss.Team().GetMember(m1.TeamId, m1.UserId); err != nil {
|
rm1, err = ss.Team().GetMember(m1.TeamId, m1.UserId)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
|
|
||||||
if rm1.TeamId != m1.TeamId {
|
require.Equal(t, rm1.TeamId, m1.TeamId, "bad team id")
|
||||||
t.Fatal("bad team id")
|
|
||||||
}
|
|
||||||
|
|
||||||
if rm1.UserId != m1.UserId {
|
require.Equal(t, rm1.UserId, m1.UserId, "bad user id")
|
||||||
t.Fatal("bad user id")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = ss.Team().GetMember(m1.TeamId, ""); err == nil {
|
_, err = ss.Team().GetMember(m1.TeamId, "")
|
||||||
t.Fatal("empty user id - should have failed")
|
require.NotNil(t, err, "empty user id - should have failed")
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = ss.Team().GetMember("", m1.UserId); err == nil {
|
_, err = ss.Team().GetMember("", m1.UserId)
|
||||||
t.Fatal("empty team id - should have failed")
|
require.NotNil(t, err, "empty team id - should have failed")
|
||||||
}
|
|
||||||
|
|
||||||
// Test with a custom team scheme.
|
// Test with a custom team scheme.
|
||||||
s2 := &model.Scheme{
|
s2 := &model.Scheme{
|
||||||
@@ -1204,36 +1084,24 @@ func testGetTeamMembersByIds(t *testing.T, ss store.Store) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
var r []*model.TeamMember
|
var r []*model.TeamMember
|
||||||
if r, err = ss.Team().GetMembersByIds(m1.TeamId, []string{m1.UserId}, nil); err != nil {
|
r, err = ss.Team().GetMembersByIds(m1.TeamId, []string{m1.UserId}, nil)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
rm1 := r[0]
|
rm1 := r[0]
|
||||||
|
|
||||||
if rm1.TeamId != m1.TeamId {
|
require.Equal(t, rm1.TeamId, m1.TeamId, "bad team id")
|
||||||
t.Fatal("bad team id")
|
require.Equal(t, rm1.UserId, m1.UserId, "bad user id")
|
||||||
}
|
|
||||||
|
|
||||||
if rm1.UserId != m1.UserId {
|
|
||||||
t.Fatal("bad user id")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m2 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
|
m2 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
|
||||||
_, err = ss.Team().SaveMember(m2, -1)
|
_, err = ss.Team().SaveMember(m2, -1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if rm, err := ss.Team().GetMembersByIds(m1.TeamId, []string{m1.UserId, m2.UserId, model.NewId()}, nil); err != nil {
|
rm, err := ss.Team().GetMembersByIds(m1.TeamId, []string{m1.UserId, m2.UserId, model.NewId()}, nil)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
|
|
||||||
if len(rm) != 2 {
|
require.Len(t, rm, 2, "return wrong number of results")
|
||||||
t.Fatal("return wrong number of results")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Team().GetMembersByIds(m1.TeamId, []string{}, nil); err == nil {
|
_, err = ss.Team().GetMembersByIds(m1.TeamId, []string{}, nil)
|
||||||
t.Fatal("empty user ids - should have failed")
|
require.NotNil(t, err, "empty user ids - should have failed")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTeamStoreMemberCount(t *testing.T, ss store.Store) {
|
func testTeamStoreMemberCount(t *testing.T, ss store.Store) {
|
||||||
@@ -1258,42 +1126,26 @@ func testTeamStoreMemberCount(t *testing.T, ss store.Store) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
var totalMemberCount int64
|
var totalMemberCount int64
|
||||||
if totalMemberCount, err = ss.Team().GetTotalMemberCount(teamId1, nil); err != nil {
|
totalMemberCount, err = ss.Team().GetTotalMemberCount(teamId1, nil)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Equal(t, int(totalMemberCount), 2, "wrong count")
|
||||||
if totalMemberCount != 2 {
|
|
||||||
t.Fatal("wrong count")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var result int64
|
var result int64
|
||||||
if result, err = ss.Team().GetActiveMemberCount(teamId1, nil); err != nil {
|
result, err = ss.Team().GetActiveMemberCount(teamId1, nil)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Equal(t, 1, int(result), "wrong count")
|
||||||
if result != 1 {
|
|
||||||
t.Fatal("wrong count")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m3 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
|
m3 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
|
||||||
_, err = ss.Team().SaveMember(m3, -1)
|
_, err = ss.Team().SaveMember(m3, -1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if totalMemberCount, err := ss.Team().GetTotalMemberCount(teamId1, nil); err != nil {
|
totalMemberCount, err = ss.Team().GetTotalMemberCount(teamId1, nil)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Equal(t, 2, int(totalMemberCount), "wrong count")
|
||||||
if totalMemberCount != 2 {
|
|
||||||
t.Fatal("wrong count")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result, err := ss.Team().GetActiveMemberCount(teamId1, nil); err != nil {
|
result, err = ss.Team().GetActiveMemberCount(teamId1, nil)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Equal(t, 1, int(result), "wrong count")
|
||||||
if result != 1 {
|
|
||||||
t.Fatal("wrong count")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetChannelUnreadsForAllTeams(t *testing.T, ss store.Store) {
|
func testGetChannelUnreadsForAllTeams(t *testing.T, ss store.Store) {
|
||||||
@@ -1323,9 +1175,8 @@ func testGetChannelUnreadsForAllTeams(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Channel().SaveMember(cm2)
|
_, err = ss.Channel().SaveMember(cm2)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if ms1, err := ss.Team().GetChannelUnreadsForAllTeams("", uid); err != nil {
|
ms1, err := ss.Team().GetChannelUnreadsForAllTeams("", uid)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
membersMap := make(map[string]bool)
|
membersMap := make(map[string]bool)
|
||||||
for i := range ms1 {
|
for i := range ms1 {
|
||||||
id := ms1[i].TeamId
|
id := ms1[i].TeamId
|
||||||
@@ -1333,19 +1184,13 @@ func testGetChannelUnreadsForAllTeams(t *testing.T, ss store.Store) {
|
|||||||
membersMap[id] = true
|
membersMap[id] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(membersMap) != 2 {
|
require.Len(t, membersMap, 2, "Should be the unreads for all the teams")
|
||||||
t.Fatal("Should be the unreads for all the teams")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ms1[0].MsgCount != 10 {
|
require.Equal(t, 10, int(ms1[0].MsgCount), "subtraction failed")
|
||||||
t.Fatal("subtraction failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ms2, err := ss.Team().GetChannelUnreadsForAllTeams(teamId1, uid); err != nil {
|
ms2, err := ss.Team().GetChannelUnreadsForAllTeams(teamId1, uid)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
membersMap = make(map[string]bool)
|
||||||
membersMap := make(map[string]bool)
|
|
||||||
for i := range ms2 {
|
for i := range ms2 {
|
||||||
id := ms2[i].TeamId
|
id := ms2[i].TeamId
|
||||||
if _, ok := membersMap[id]; !ok {
|
if _, ok := membersMap[id]; !ok {
|
||||||
@@ -1353,18 +1198,12 @@ func testGetChannelUnreadsForAllTeams(t *testing.T, ss store.Store) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(membersMap) != 1 {
|
require.Len(t, membersMap, 1, "Should be the unreads for just one team")
|
||||||
t.Fatal("Should be the unreads for just one team")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ms2[0].MsgCount != 10 {
|
require.Equal(t, 10, int(ms2[0].MsgCount), "subtraction failed")
|
||||||
t.Fatal("subtraction failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ss.Team().RemoveAllMembersByUser(uid); err != nil {
|
err = ss.Team().RemoveAllMembersByUser(uid)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetChannelUnreadsForTeam(t *testing.T, ss store.Store) {
|
func testGetChannelUnreadsForTeam(t *testing.T, ss store.Store) {
|
||||||
@@ -1390,17 +1229,11 @@ func testGetChannelUnreadsForTeam(t *testing.T, ss store.Store) {
|
|||||||
_, err = ss.Channel().SaveMember(cm2)
|
_, err = ss.Channel().SaveMember(cm2)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if ms, err := ss.Team().GetChannelUnreadsForTeam(m1.TeamId, m1.UserId); err != nil {
|
ms, err := ss.Team().GetChannelUnreadsForTeam(m1.TeamId, m1.UserId)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Len(t, ms, 2, "wrong length")
|
||||||
if len(ms) != 2 {
|
|
||||||
t.Fatal("wrong length")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ms[0].MsgCount != 10 {
|
require.Equal(t, 10, int(ms[0].MsgCount), "subtraction failed")
|
||||||
t.Fatal("subtraction failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testUpdateLastTeamIconUpdate(t *testing.T, ss store.Store) {
|
func testUpdateLastTeamIconUpdate(t *testing.T, ss store.Store) {
|
||||||
@@ -1419,16 +1252,13 @@ func testUpdateLastTeamIconUpdate(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
curTime := model.GetMillis()
|
curTime := model.GetMillis()
|
||||||
|
|
||||||
if err = ss.Team().UpdateLastTeamIconUpdate(o1.Id, curTime); err != nil {
|
err = ss.Team().UpdateLastTeamIconUpdate(o1.Id, curTime)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
ro1, err := ss.Team().Get(o1.Id)
|
ro1, err := ss.Team().Get(o1.Id)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if ro1.LastTeamIconUpdate <= lastTeamIconUpdateInitial {
|
require.Greater(t, ro1.LastTeamIconUpdate, lastTeamIconUpdateInitial, "LastTeamIconUpdate not updated")
|
||||||
t.Fatal("LastTeamIconUpdate not updated")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetTeamsByScheme(t *testing.T, ss store.Store) {
|
func testGetTeamsByScheme(t *testing.T, ss store.Store) {
|
||||||
|
|||||||
@@ -43,13 +43,11 @@ func TestWebhookStore(t *testing.T, ss store.Store) {
|
|||||||
func testWebhookStoreSaveIncoming(t *testing.T, ss store.Store) {
|
func testWebhookStoreSaveIncoming(t *testing.T, ss store.Store) {
|
||||||
o1 := buildIncomingWebhook()
|
o1 := buildIncomingWebhook()
|
||||||
|
|
||||||
if _, err := ss.Webhook().SaveIncoming(o1); err != nil {
|
_, err := ss.Webhook().SaveIncoming(o1)
|
||||||
t.Fatal("couldn't save item", err)
|
require.Nil(t, err, "couldn't save item")
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Webhook().SaveIncoming(o1); err == nil {
|
_, err = ss.Webhook().SaveIncoming(o1)
|
||||||
t.Fatal("shouldn't be able to update from save")
|
require.NotNil(t, err, "shouldn't be able to update from save")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreUpdateIncoming(t *testing.T, ss store.Store) {
|
func testWebhookStoreUpdateIncoming(t *testing.T, ss store.Store) {
|
||||||
@@ -58,9 +56,7 @@ func testWebhookStoreUpdateIncoming(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
o1 := buildIncomingWebhook()
|
o1 := buildIncomingWebhook()
|
||||||
o1, err = ss.Webhook().SaveIncoming(o1)
|
o1, err = ss.Webhook().SaveIncoming(o1)
|
||||||
if err != nil {
|
require.Nil(t, err, "unable to save webhook")
|
||||||
t.Fatal("unable to save webhook", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
previousUpdatedAt := o1.UpdateAt
|
previousUpdatedAt := o1.UpdateAt
|
||||||
|
|
||||||
@@ -70,14 +66,9 @@ func testWebhookStoreUpdateIncoming(t *testing.T, ss store.Store) {
|
|||||||
webhook, err := ss.Webhook().UpdateIncoming(o1)
|
webhook, err := ss.Webhook().UpdateIncoming(o1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if webhook.UpdateAt == previousUpdatedAt {
|
require.NotEqual(t, webhook.UpdateAt, previousUpdatedAt, "should have updated the UpdatedAt of the hook")
|
||||||
t.Fatal("should have updated the UpdatedAt of the hook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if webhook.DisplayName != "TestHook" {
|
|
||||||
t.Fatal("display name is not updated")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
require.Equal(t, "TestHook", webhook.DisplayName, "display name is not updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreGetIncoming(t *testing.T, ss store.Store) {
|
func testWebhookStoreGetIncoming(t *testing.T, ss store.Store) {
|
||||||
@@ -85,33 +76,25 @@ func testWebhookStoreGetIncoming(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
o1 := buildIncomingWebhook()
|
o1 := buildIncomingWebhook()
|
||||||
o1, err = ss.Webhook().SaveIncoming(o1)
|
o1, err = ss.Webhook().SaveIncoming(o1)
|
||||||
if err != nil {
|
require.Nil(t, err, "unable to save webhook")
|
||||||
t.Fatal("unable to save webhook", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
webhook, err := ss.Webhook().GetIncoming(o1.Id, false)
|
webhook, err := ss.Webhook().GetIncoming(o1.Id, false)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhook.CreateAt != o1.CreateAt {
|
require.Equal(t, webhook.CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
webhook, err = ss.Webhook().GetIncoming(o1.Id, true)
|
webhook, err = ss.Webhook().GetIncoming(o1.Id, true)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhook.CreateAt != o1.CreateAt {
|
require.Equal(t, webhook.CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = ss.Webhook().GetIncoming("123", false); err == nil {
|
_, err = ss.Webhook().GetIncoming("123", false)
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = ss.Webhook().GetIncoming("123", true); err == nil {
|
_, err = ss.Webhook().GetIncoming("123", true)
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = ss.Webhook().GetIncoming("123", true); err.StatusCode != http.StatusNotFound {
|
_, err = ss.Webhook().GetIncoming("123", true)
|
||||||
t.Fatal("Should have set the status as not found for missing id")
|
require.NotNil(t, err)
|
||||||
}
|
require.Equal(t, err.StatusCode, http.StatusNotFound, "Should have set the status as not found for missing id")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreGetIncomingList(t *testing.T, ss store.Store) {
|
func testWebhookStoreGetIncomingList(t *testing.T, ss store.Store) {
|
||||||
@@ -122,31 +105,22 @@ func testWebhookStoreGetIncomingList(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
var err *model.AppError
|
var err *model.AppError
|
||||||
o1, err = ss.Webhook().SaveIncoming(o1)
|
o1, err = ss.Webhook().SaveIncoming(o1)
|
||||||
if err != nil {
|
require.Nil(t, err, "unable to save webhook")
|
||||||
t.Fatal("unable to save webhook", err)
|
|
||||||
}
|
hooks, err := ss.Webhook().GetIncomingList(0, 1000)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
if hooks, err := ss.Webhook().GetIncomingList(0, 1000); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else {
|
|
||||||
found := false
|
found := false
|
||||||
for _, hook := range hooks {
|
for _, hook := range hooks {
|
||||||
if hook.Id == o1.Id {
|
if hook.Id == o1.Id {
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
require.True(t, found, "missing webhook")
|
||||||
t.Fatal("missing webhook")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if hooks, err := ss.Webhook().GetIncomingList(0, 1); err != nil {
|
hooks, err = ss.Webhook().GetIncomingList(0, 1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Len(t, hooks, 1, "only 1 should be returned")
|
||||||
if len(hooks) != 1 {
|
|
||||||
t.Fatal("only 1 should be returned")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreGetIncomingListByUser(t *testing.T, ss store.Store) {
|
func testWebhookStoreGetIncomingListByUser(t *testing.T, ss store.Store) {
|
||||||
@@ -179,21 +153,13 @@ func testWebhookStoreGetIncomingByTeam(t *testing.T, ss store.Store) {
|
|||||||
o1, err = ss.Webhook().SaveIncoming(o1)
|
o1, err = ss.Webhook().SaveIncoming(o1)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
if hooks, err := ss.Webhook().GetIncomingByTeam(o1.TeamId, 0, 100); err != nil {
|
hooks, err := ss.Webhook().GetIncomingByTeam(o1.TeamId, 0, 100)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Equal(t, hooks[0].CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
if hooks[0].CreateAt != o1.CreateAt {
|
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if hooks, err := ss.Webhook().GetIncomingByTeam("123", 0, 100); err != nil {
|
hooks, err = ss.Webhook().GetIncomingByTeam("123", 0, 100)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Len(t, hooks, 0, "no webhooks should have returned")
|
||||||
if len(hooks) != 0 {
|
|
||||||
t.Fatal("no webhooks should have returned")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWebhookStoreGetIncomingByTeamByUser(t *testing.T, ss store.Store) {
|
func TestWebhookStoreGetIncomingByTeamByUser(t *testing.T, ss store.Store) {
|
||||||
@@ -232,23 +198,15 @@ func TestWebhookStoreGetIncomingByChannel(t *testing.T, ss store.Store) {
|
|||||||
o1 := buildIncomingWebhook()
|
o1 := buildIncomingWebhook()
|
||||||
|
|
||||||
o1, err := ss.Webhook().SaveIncoming(o1)
|
o1, err := ss.Webhook().SaveIncoming(o1)
|
||||||
if err != nil {
|
require.Nil(t, err, "unable to save webhook")
|
||||||
t.Fatal("unable to save webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
webhooks, err := ss.Webhook().GetIncomingByChannel(o1.ChannelId)
|
webhooks, err := ss.Webhook().GetIncomingByChannel(o1.ChannelId)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhooks[0].CreateAt != o1.CreateAt {
|
require.Equal(t, webhooks[0].CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if webhooks, err = ss.Webhook().GetIncomingByChannel("123"); err != nil {
|
webhooks, err = ss.Webhook().GetIncomingByChannel("123")
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Len(t, webhooks, 0, "no webhooks should have returned")
|
||||||
if len(webhooks) != 0 {
|
|
||||||
t.Fatal("no webhooks should have returned")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreDeleteIncoming(t *testing.T, ss store.Store) {
|
func testWebhookStoreDeleteIncoming(t *testing.T, ss store.Store) {
|
||||||
@@ -256,19 +214,14 @@ func testWebhookStoreDeleteIncoming(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
o1 := buildIncomingWebhook()
|
o1 := buildIncomingWebhook()
|
||||||
o1, err = ss.Webhook().SaveIncoming(o1)
|
o1, err = ss.Webhook().SaveIncoming(o1)
|
||||||
if err != nil {
|
require.Nil(t, err, "unable to save webhook")
|
||||||
t.Fatal("unable to save webhook", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
webhook, err := ss.Webhook().GetIncoming(o1.Id, true)
|
webhook, err := ss.Webhook().GetIncoming(o1.Id, true)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhook.CreateAt != o1.CreateAt {
|
require.Equal(t, webhook.CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = ss.Webhook().DeleteIncoming(o1.Id, model.GetMillis()); err != nil {
|
err = ss.Webhook().DeleteIncoming(o1.Id, model.GetMillis())
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
webhook, err = ss.Webhook().GetIncoming(o1.Id, true)
|
webhook, err = ss.Webhook().GetIncoming(o1.Id, true)
|
||||||
require.NotNil(t, err)
|
require.NotNil(t, err)
|
||||||
@@ -279,23 +232,17 @@ func testWebhookStoreDeleteIncomingByChannel(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
o1 := buildIncomingWebhook()
|
o1 := buildIncomingWebhook()
|
||||||
o1, err = ss.Webhook().SaveIncoming(o1)
|
o1, err = ss.Webhook().SaveIncoming(o1)
|
||||||
if err != nil {
|
require.Nil(t, err, "unable to save webhook")
|
||||||
t.Fatal("unable to save webhook", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
webhook, err := ss.Webhook().GetIncoming(o1.Id, true)
|
webhook, err := ss.Webhook().GetIncoming(o1.Id, true)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhook.CreateAt != o1.CreateAt {
|
require.Equal(t, webhook.CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = ss.Webhook().PermanentDeleteIncomingByChannel(o1.ChannelId); err != nil {
|
err = ss.Webhook().PermanentDeleteIncomingByChannel(o1.ChannelId)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = ss.Webhook().GetIncoming(o1.Id, true); err == nil {
|
_, err = ss.Webhook().GetIncoming(o1.Id, true)
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreDeleteIncomingByUser(t *testing.T, ss store.Store) {
|
func testWebhookStoreDeleteIncomingByUser(t *testing.T, ss store.Store) {
|
||||||
@@ -303,23 +250,17 @@ func testWebhookStoreDeleteIncomingByUser(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
o1 := buildIncomingWebhook()
|
o1 := buildIncomingWebhook()
|
||||||
o1, err = ss.Webhook().SaveIncoming(o1)
|
o1, err = ss.Webhook().SaveIncoming(o1)
|
||||||
if err != nil {
|
require.Nil(t, err, "unable to save webhook")
|
||||||
t.Fatal("unable to save webhook", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
webhook, err := ss.Webhook().GetIncoming(o1.Id, true)
|
webhook, err := ss.Webhook().GetIncoming(o1.Id, true)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhook.CreateAt != o1.CreateAt {
|
require.Equal(t, webhook.CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = ss.Webhook().PermanentDeleteIncomingByUser(o1.UserId); err != nil {
|
err = ss.Webhook().PermanentDeleteIncomingByUser(o1.UserId)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = ss.Webhook().GetIncoming(o1.Id, true); err == nil {
|
_, err = ss.Webhook().GetIncoming(o1.Id, true)
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildIncomingWebhook() *model.IncomingWebhook {
|
func buildIncomingWebhook() *model.IncomingWebhook {
|
||||||
@@ -340,13 +281,11 @@ func testWebhookStoreSaveOutgoing(t *testing.T, ss store.Store) {
|
|||||||
o1.Username = "test-user-name"
|
o1.Username = "test-user-name"
|
||||||
o1.IconURL = "http://nowhere.com/icon"
|
o1.IconURL = "http://nowhere.com/icon"
|
||||||
|
|
||||||
if _, err := ss.Webhook().SaveOutgoing(&o1); err != nil {
|
_, err := ss.Webhook().SaveOutgoing(&o1)
|
||||||
t.Fatal("couldn't save item", err)
|
require.Nil(t, err, "couldn't save item")
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Webhook().SaveOutgoing(&o1); err == nil {
|
_, err = ss.Webhook().SaveOutgoing(&o1)
|
||||||
t.Fatal("shouldn't be able to update from save")
|
require.NotNil(t, err, "shouldn't be able to update from save")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreGetOutgoing(t *testing.T, ss store.Store) {
|
func testWebhookStoreGetOutgoing(t *testing.T, ss store.Store) {
|
||||||
@@ -362,13 +301,10 @@ func testWebhookStoreGetOutgoing(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
webhook, err := ss.Webhook().GetOutgoing(o1.Id)
|
webhook, err := ss.Webhook().GetOutgoing(o1.Id)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhook.CreateAt != o1.CreateAt {
|
require.Equal(t, webhook.CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Webhook().GetOutgoing("123"); err == nil {
|
_, err = ss.Webhook().GetOutgoing("123")
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreGetOutgoingListByUser(t *testing.T, ss store.Store) {
|
func testWebhookStoreGetOutgoingListByUser(t *testing.T, ss store.Store) {
|
||||||
@@ -412,9 +348,8 @@ func testWebhookStoreGetOutgoingList(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
o2, _ = ss.Webhook().SaveOutgoing(o2)
|
o2, _ = ss.Webhook().SaveOutgoing(o2)
|
||||||
|
|
||||||
if r1, err := ss.Webhook().GetOutgoingList(0, 1000); err != nil {
|
r1, err := ss.Webhook().GetOutgoingList(0, 1000)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
|
||||||
hooks := r1
|
hooks := r1
|
||||||
found1 := false
|
found1 := false
|
||||||
found2 := false
|
found2 := false
|
||||||
@@ -429,21 +364,12 @@ func testWebhookStoreGetOutgoingList(t *testing.T, ss store.Store) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found1 {
|
require.True(t, found1, "missing hook1")
|
||||||
t.Fatal("missing hook1")
|
require.True(t, found2, "missing hook2")
|
||||||
}
|
|
||||||
if !found2 {
|
|
||||||
t.Fatal("missing hook2")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result, err := ss.Webhook().GetOutgoingList(0, 2); err != nil {
|
result, err := ss.Webhook().GetOutgoingList(0, 2)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Len(t, result, 2, "wrong number of hooks returned")
|
||||||
if len(result) != 2 {
|
|
||||||
t.Fatal("wrong number of hooks returned")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreGetOutgoingByChannel(t *testing.T, ss store.Store) {
|
func testWebhookStoreGetOutgoingByChannel(t *testing.T, ss store.Store) {
|
||||||
@@ -455,21 +381,13 @@ func testWebhookStoreGetOutgoingByChannel(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
o1, _ = ss.Webhook().SaveOutgoing(o1)
|
o1, _ = ss.Webhook().SaveOutgoing(o1)
|
||||||
|
|
||||||
if r1, err := ss.Webhook().GetOutgoingByChannel(o1.ChannelId, 0, 100); err != nil {
|
r1, err := ss.Webhook().GetOutgoingByChannel(o1.ChannelId, 0, 100)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Equal(t, r1[0].CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
if r1[0].CreateAt != o1.CreateAt {
|
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result, err := ss.Webhook().GetOutgoingByChannel("123", -1, -1); err != nil {
|
result, err := ss.Webhook().GetOutgoingByChannel("123", -1, -1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Len(t, result, 0, "no webhooks should have returned")
|
||||||
if len(result) != 0 {
|
|
||||||
t.Fatal("no webhooks should have returned")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreGetOutgoingByChannelByUser(t *testing.T, ss store.Store) {
|
func testWebhookStoreGetOutgoingByChannelByUser(t *testing.T, ss store.Store) {
|
||||||
@@ -520,21 +438,13 @@ func testWebhookStoreGetOutgoingByTeam(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
o1, _ = ss.Webhook().SaveOutgoing(o1)
|
o1, _ = ss.Webhook().SaveOutgoing(o1)
|
||||||
|
|
||||||
if r1, err := ss.Webhook().GetOutgoingByTeam(o1.TeamId, 0, 100); err != nil {
|
r1, err := ss.Webhook().GetOutgoingByTeam(o1.TeamId, 0, 100)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Equal(t, r1[0].CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
if r1[0].CreateAt != o1.CreateAt {
|
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if result, err := ss.Webhook().GetOutgoingByTeam("123", -1, -1); err != nil {
|
result, err := ss.Webhook().GetOutgoingByTeam("123", -1, -1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.Len(t, result, 0, "no webhooks should have returned")
|
||||||
if len(result) != 0 {
|
|
||||||
t.Fatal("no webhooks should have returned")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreGetOutgoingByTeamByUser(t *testing.T, ss store.Store) {
|
func testWebhookStoreGetOutgoingByTeamByUser(t *testing.T, ss store.Store) {
|
||||||
@@ -589,17 +499,13 @@ func testWebhookStoreDeleteOutgoing(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
webhook, err := ss.Webhook().GetOutgoing(o1.Id)
|
webhook, err := ss.Webhook().GetOutgoing(o1.Id)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhook.CreateAt != o1.CreateAt {
|
require.Equal(t, webhook.CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ss.Webhook().DeleteOutgoing(o1.Id, model.GetMillis()); err != nil {
|
err = ss.Webhook().DeleteOutgoing(o1.Id, model.GetMillis())
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Webhook().GetOutgoing(o1.Id); err == nil {
|
_, err = ss.Webhook().GetOutgoing(o1.Id)
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreDeleteOutgoingByChannel(t *testing.T, ss store.Store) {
|
func testWebhookStoreDeleteOutgoingByChannel(t *testing.T, ss store.Store) {
|
||||||
@@ -613,17 +519,13 @@ func testWebhookStoreDeleteOutgoingByChannel(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
webhook, err := ss.Webhook().GetOutgoing(o1.Id)
|
webhook, err := ss.Webhook().GetOutgoing(o1.Id)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhook.CreateAt != o1.CreateAt {
|
require.Equal(t, webhook.CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ss.Webhook().PermanentDeleteOutgoingByChannel(o1.ChannelId); err != nil {
|
err = ss.Webhook().PermanentDeleteOutgoingByChannel(o1.ChannelId)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Webhook().GetOutgoing(o1.Id); err == nil {
|
_, err = ss.Webhook().GetOutgoing(o1.Id)
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreDeleteOutgoingByUser(t *testing.T, ss store.Store) {
|
func testWebhookStoreDeleteOutgoingByUser(t *testing.T, ss store.Store) {
|
||||||
@@ -637,17 +539,13 @@ func testWebhookStoreDeleteOutgoingByUser(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
webhook, err := ss.Webhook().GetOutgoing(o1.Id)
|
webhook, err := ss.Webhook().GetOutgoing(o1.Id)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
if webhook.CreateAt != o1.CreateAt {
|
require.Equal(t, webhook.CreateAt, o1.CreateAt, "invalid returned webhook")
|
||||||
t.Fatal("invalid returned webhook")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ss.Webhook().PermanentDeleteOutgoingByUser(o1.CreatorId); err != nil {
|
err = ss.Webhook().PermanentDeleteOutgoingByUser(o1.CreatorId)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := ss.Webhook().GetOutgoing(o1.Id); err == nil {
|
_, err = ss.Webhook().GetOutgoing(o1.Id)
|
||||||
t.Fatal("Missing id should have failed")
|
require.NotNil(t, err, "Missing id should have failed")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreUpdateOutgoing(t *testing.T, ss store.Store) {
|
func testWebhookStoreUpdateOutgoing(t *testing.T, ss store.Store) {
|
||||||
@@ -664,9 +562,8 @@ func testWebhookStoreUpdateOutgoing(t *testing.T, ss store.Store) {
|
|||||||
o1.Token = model.NewId()
|
o1.Token = model.NewId()
|
||||||
o1.Username = "another-test-user-name"
|
o1.Username = "another-test-user-name"
|
||||||
|
|
||||||
if _, err := ss.Webhook().UpdateOutgoing(o1); err != nil {
|
_, err := ss.Webhook().UpdateOutgoing(o1)
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreCountIncoming(t *testing.T, ss store.Store) {
|
func testWebhookStoreCountIncoming(t *testing.T, ss store.Store) {
|
||||||
@@ -678,13 +575,9 @@ func testWebhookStoreCountIncoming(t *testing.T, ss store.Store) {
|
|||||||
_, _ = ss.Webhook().SaveIncoming(o1)
|
_, _ = ss.Webhook().SaveIncoming(o1)
|
||||||
|
|
||||||
c, err := ss.Webhook().AnalyticsIncomingCount("")
|
c, err := ss.Webhook().AnalyticsIncomingCount("")
|
||||||
if err != nil {
|
require.Nil(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c == 0 {
|
require.NotEqual(t, 0, c, "should have at least 1 incoming hook")
|
||||||
t.Fatal("should have at least 1 incoming hook")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testWebhookStoreCountOutgoing(t *testing.T, ss store.Store) {
|
func testWebhookStoreCountOutgoing(t *testing.T, ss store.Store) {
|
||||||
@@ -696,11 +589,7 @@ func testWebhookStoreCountOutgoing(t *testing.T, ss store.Store) {
|
|||||||
|
|
||||||
ss.Webhook().SaveOutgoing(o1)
|
ss.Webhook().SaveOutgoing(o1)
|
||||||
|
|
||||||
if r, err := ss.Webhook().AnalyticsOutgoingCount(""); err != nil {
|
r, err := ss.Webhook().AnalyticsOutgoingCount("")
|
||||||
t.Fatal(err)
|
require.Nil(t, err)
|
||||||
} else {
|
require.NotEqual(t, 0, r, "should have at least 1 outgoing hook")
|
||||||
if r == 0 {
|
|
||||||
t.Fatal("should have at least 1 outgoing hook")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ func (h *MainHelper) setupStore() {
|
|||||||
h.ClusterInterface = &FakeClusterInterface{}
|
h.ClusterInterface = &FakeClusterInterface{}
|
||||||
h.SqlSupplier = sqlstore.NewSqlSupplier(*h.Settings, nil)
|
h.SqlSupplier = sqlstore.NewSqlSupplier(*h.Settings, nil)
|
||||||
h.Store = &TestStore{
|
h.Store = &TestStore{
|
||||||
store.NewLayeredStore(h.SqlSupplier, nil, h.ClusterInterface),
|
h.SqlSupplier,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ const (
|
|||||||
actionSymlink
|
actionSymlink
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const root = "___mattermost-server"
|
||||||
|
|
||||||
type testResourceDetails struct {
|
type testResourceDetails struct {
|
||||||
src string
|
src string
|
||||||
dest string
|
dest string
|
||||||
@@ -50,6 +52,15 @@ func findFile(path string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func findDir(dir string) (string, bool) {
|
func findDir(dir string) (string, bool) {
|
||||||
|
if dir == root {
|
||||||
|
srcPath := findFile("go.mod")
|
||||||
|
if srcPath == "" {
|
||||||
|
return "./", false
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.Dir(srcPath), true
|
||||||
|
}
|
||||||
|
|
||||||
found := fileutils.FindPath(dir, commonBaseSearchPaths, func(fileInfo os.FileInfo) bool {
|
found := fileutils.FindPath(dir, commonBaseSearchPaths, func(fileInfo os.FileInfo) bool {
|
||||||
return fileInfo.IsDir()
|
return fileInfo.IsDir()
|
||||||
})
|
})
|
||||||
@@ -65,7 +76,7 @@ func getTestResourcesToSetup() []testResourceDetails {
|
|||||||
var found bool
|
var found bool
|
||||||
|
|
||||||
var testResourcesToSetup = []testResourceDetails{
|
var testResourcesToSetup = []testResourceDetails{
|
||||||
{"mattermost-server", "mattermost-server", resourceTypeFolder, actionSymlink},
|
{root, "mattermost-server", resourceTypeFolder, actionSymlink},
|
||||||
{"i18n", "i18n", resourceTypeFolder, actionSymlink},
|
{"i18n", "i18n", resourceTypeFolder, actionSymlink},
|
||||||
{"templates", "templates", resourceTypeFolder, actionSymlink},
|
{"templates", "templates", resourceTypeFolder, actionSymlink},
|
||||||
{"tests", "tests", resourceTypeFolder, actionSymlink},
|
{"tests", "tests", resourceTypeFolder, actionSymlink},
|
||||||
|
|||||||
15
testlib/resources_test.go
Обычный файл
15
testlib/resources_test.go
Обычный файл
@@ -0,0 +1,15 @@
|
|||||||
|
package testlib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFindDir(t *testing.T) {
|
||||||
|
t.Run("find root", func(t *testing.T) {
|
||||||
|
path, found := findDir(root)
|
||||||
|
assert.True(t, found, "failed to find root")
|
||||||
|
assert.NotEmpty(t, path)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLRU(t *testing.T) {
|
func TestLRU(t *testing.T) {
|
||||||
@@ -20,50 +21,39 @@ func TestLRU(t *testing.T) {
|
|||||||
for i := 0; i < 256; i++ {
|
for i := 0; i < 256; i++ {
|
||||||
l.Add(i, i)
|
l.Add(i, i)
|
||||||
}
|
}
|
||||||
if l.Len() != 128 {
|
require.Equalf(t, l.Len(), 128, "bad len: %v", l.Len())
|
||||||
t.Fatalf("bad len: %v", l.Len())
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, k := range l.Keys() {
|
for i, k := range l.Keys() {
|
||||||
if v, ok := l.Get(k); !ok || v != k || v != i+128 {
|
v, ok := l.Get(k)
|
||||||
t.Fatalf("bad key: %v", k)
|
require.True(t, ok, "bad key: %v", k)
|
||||||
}
|
require.Equalf(t, v, k, "bad key: %v", k)
|
||||||
|
require.Equalf(t, i+128, v, "bad key: %v", k)
|
||||||
}
|
}
|
||||||
for i := 0; i < 128; i++ {
|
for i := 0; i < 128; i++ {
|
||||||
_, ok := l.Get(i)
|
_, ok := l.Get(i)
|
||||||
if ok {
|
require.False(t, ok, "should be evicted")
|
||||||
t.Fatalf("should be evicted")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for i := 128; i < 256; i++ {
|
for i := 128; i < 256; i++ {
|
||||||
_, ok := l.Get(i)
|
_, ok := l.Get(i)
|
||||||
if !ok {
|
require.True(t, ok, "should not be evicted")
|
||||||
t.Fatalf("should not be evicted")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for i := 128; i < 192; i++ {
|
for i := 128; i < 192; i++ {
|
||||||
l.Remove(i)
|
l.Remove(i)
|
||||||
_, ok := l.Get(i)
|
_, ok := l.Get(i)
|
||||||
if ok {
|
require.False(t, ok, "should be deleted")
|
||||||
t.Fatalf("should be deleted")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Get(192) // expect 192 to be last key in l.Keys()
|
l.Get(192) // expect 192 to be last key in l.Keys()
|
||||||
|
|
||||||
for i, k := range l.Keys() {
|
for i, k := range l.Keys() {
|
||||||
if (i < 63 && k != i+193) || (i == 63 && k != 192) {
|
require.Falsef(t, (i < 63 && k != i+193), "out of order key: %v", k)
|
||||||
t.Fatalf("out of order key: %v", k)
|
require.Falsef(t, (i == 63 && k != 192), "out of order key: %v", k)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Purge()
|
l.Purge()
|
||||||
if l.Len() != 0 {
|
require.Equalf(t, l.Len(), 0, "bad len: %v", l.Len())
|
||||||
t.Fatalf("bad len: %v", l.Len())
|
_, ok := l.Get(200)
|
||||||
}
|
require.False(t, ok, "should contain nothing")
|
||||||
if _, ok := l.Get(200); ok {
|
|
||||||
t.Fatalf("should contain nothing")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLRUExpire(t *testing.T) {
|
func TestLRUExpire(t *testing.T) {
|
||||||
@@ -75,13 +65,11 @@ func TestLRUExpire(t *testing.T) {
|
|||||||
|
|
||||||
time.Sleep(time.Millisecond * 2100)
|
time.Sleep(time.Millisecond * 2100)
|
||||||
|
|
||||||
if r1, ok := l.Get(1); ok {
|
r1, ok := l.Get(1)
|
||||||
t.Fatal(r1)
|
require.False(t, ok, r1)
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok2 := l.Get(3); !ok2 {
|
_, ok2 := l.Get(3)
|
||||||
t.Fatal("should exist")
|
require.True(t, ok2, "should exist")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLRUGetOrAdd(t *testing.T) {
|
func TestLRUGetOrAdd(t *testing.T) {
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/testlib"
|
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/app"
|
"github.com/mattermost/mattermost-server/app"
|
||||||
"github.com/mattermost/mattermost-server/config"
|
"github.com/mattermost/mattermost-server/config"
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
@@ -97,11 +95,6 @@ func Setup() *TestHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (th *TestHelper) InitPlugins() *TestHelper {
|
func (th *TestHelper) InitPlugins() *TestHelper {
|
||||||
|
|
||||||
if th.tempWorkspace == "" {
|
|
||||||
th.tempWorkspace, _ = testlib.SetupTestResources()
|
|
||||||
}
|
|
||||||
|
|
||||||
pluginDir := filepath.Join(th.tempWorkspace, "plugins")
|
pluginDir := filepath.Join(th.tempWorkspace, "plugins")
|
||||||
webappDir := filepath.Join(th.tempWorkspace, "webapp")
|
webappDir := filepath.Join(th.tempWorkspace, "webapp")
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user