[MM-34076] Add Plugin API User custom status (#17435)

* add missing client for custom user status

* add custom user status plugin api

* update based on feedback review

* add GetCustomStatus

* update interfaces
Этот коммит содержится в:
Carlos Tadeu Panato Junior
2021-11-10 17:11:20 +01:00
коммит произвёл GitHub
родитель 0a3e7f4d55
Коммит bb5a74a42b
13 изменённых файлов: 290 добавлений и 4 удалений

Просмотреть файл

@@ -587,6 +587,7 @@ type AppIface interface {
GetComplianceReport(reportId string) (*model.Compliance, *model.AppError)
GetComplianceReports(page, perPage int) (model.Compliances, *model.AppError)
GetCookieDomain() string
GetCustomStatus(userID string) (*model.CustomStatus, *model.AppError)
GetDefaultProfileImage(user *model.User) ([]byte, *model.AppError)
GetDeletedChannels(teamID string, offset int, limit int, userID string) (model.ChannelList, *model.AppError)
GetEmoji(emojiId string) (*model.Emoji, *model.AppError)

Просмотреть файл

@@ -5449,6 +5449,28 @@ func (a *OpenTracingAppLayer) GetCookieDomain() string {
return resultVar0
}
func (a *OpenTracingAppLayer) GetCustomStatus(userID string) (*model.CustomStatus, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetCustomStatus")
a.ctx = newCtx
a.app.Srv().Store.SetContext(newCtx)
defer func() {
a.app.Srv().Store.SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0, resultVar1 := a.app.GetCustomStatus(userID)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
ext.Error.Set(span, true)
}
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) GetDefaultProfileImage(user *model.User) ([]byte, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetDefaultProfileImage")

Просмотреть файл

@@ -344,6 +344,18 @@ func (api *PluginAPI) SetUserStatusTimedDND(userID string, endTime int64) (*mode
return api.app.GetStatus(userID)
}
func (api *PluginAPI) UpdateUserCustomStatus(userID string, customStatus *model.CustomStatus) *model.AppError {
return api.app.SetCustomStatus(userID, customStatus)
}
func (api *PluginAPI) RemoveUserCustomStatus(userID string) *model.AppError {
return api.app.RemoveCustomStatus(userID)
}
func (api *PluginAPI) GetUserCustomStatus(userID string) (*model.CustomStatus, *model.AppError) {
return api.app.GetCustomStatus(userID)
}
func (api *PluginAPI) GetUsersInChannel(channelID, sortBy string, page, perPage int) ([]*model.User, *model.AppError) {
switch sortBy {
case model.ChannelSortByUsername:

Просмотреть файл

@@ -494,6 +494,59 @@ func TestPluginAPIGetUsersInTeam(t *testing.T) {
}
}
func TestPluginAPIUserCustomStatus(t *testing.T) {
th := Setup(t)
defer th.TearDown()
api := th.SetupPluginAPI()
user1, err := th.App.CreateUser(th.Context, &model.User{
Email: strings.ToLower(model.NewId()) + "success+test@example.com",
Username: "user_" + model.NewId(),
Password: "password",
})
require.Nil(t, err)
defer th.App.PermanentDeleteUser(th.Context, user1)
custom := &model.CustomStatus{
Emoji: ":tada:",
Text: "honk",
}
err = api.UpdateUserCustomStatus(user1.Id, custom)
assert.Nil(t, err)
userCs, err := th.App.GetCustomStatus(user1.Id)
assert.Nil(t, err)
assert.Equal(t, custom, userCs)
custom.Text = ""
err = api.UpdateUserCustomStatus(user1.Id, custom)
assert.Nil(t, err)
userCs, err = th.App.GetCustomStatus(user1.Id)
assert.Nil(t, err)
assert.Equal(t, custom, userCs)
custom.Text = "honk"
custom.Emoji = ""
err = api.UpdateUserCustomStatus(user1.Id, custom)
assert.Nil(t, err)
userCs, err = th.App.GetCustomStatus(user1.Id)
assert.Nil(t, err)
assert.Equal(t, custom, userCs)
custom.Text = ""
err = api.UpdateUserCustomStatus(user1.Id, custom)
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "SetCustomStatus: Failed to update the custom status. Please add either emoji or custom text status or both., ")
// Remove custom status
err = api.RemoveUserCustomStatus(user1.Id)
assert.Nil(t, err)
var csClear *model.CustomStatus
userCs, err = th.App.GetCustomStatus(user1.Id)
assert.Nil(t, err)
assert.Equal(t, csClear, userCs)
}
func TestPluginAPIGetFile(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
@@ -715,7 +768,6 @@ func TestPluginAPILoadPluginConfiguration(t *testing.T) {
]
}}`)
require.NoError(t, err)
}
func TestPluginAPILoadPluginConfigurationDefaults(t *testing.T) {
@@ -755,7 +807,6 @@ func TestPluginAPILoadPluginConfigurationDefaults(t *testing.T) {
}`)
require.NoError(t, err)
}
func TestPluginAPIGetPlugins(t *testing.T) {
@@ -1084,6 +1135,7 @@ func pluginAPIHookTest(t *testing.T, th *TestHelper, fileName string, id string,
if ret != "OK" {
return errors.New(ret)
}
return nil
}
@@ -1284,7 +1336,6 @@ func TestPluginCreateBot(t *testing.T) {
Description: "bot2",
})
require.NotNil(t, err)
}
func TestPluginCreatePostWithUploadedFile(t *testing.T) {
@@ -1748,6 +1799,7 @@ type MockSlashCommandProvider struct {
func (*MockSlashCommandProvider) GetTrigger() string {
return "mock"
}
func (*MockSlashCommandProvider) GetCommand(a *App, T i18n.TranslateFunc) *model.Command {
return &model.Command{
Trigger: "mock",
@@ -1757,6 +1809,7 @@ func (*MockSlashCommandProvider) GetCommand(a *App, T i18n.TranslateFunc) *model
DisplayName: "mock",
}
}
func (mscp *MockSlashCommandProvider) DoCommand(a *App, c *request.Context, args *model.CommandArgs, message string) *model.CommandResponse {
mscp.Args = args
mscp.Message = message
@@ -1920,7 +1973,6 @@ func TestPluginAPIUpdateCommand(t *testing.T) {
require.NoError(t, appErr)
require.Equal(t, "anothernewtriggeragain", newCmd4.Trigger)
require.Equal(t, team1.Id, newCmd4.TeamId)
}
func TestPluginAPIIsEnterpriseReady(t *testing.T) {

Просмотреть файл

@@ -406,6 +406,10 @@ func (a *App) UpdateDNDStatusOfUsers() {
}
func (a *App) SetCustomStatus(userID string, cs *model.CustomStatus) *model.AppError {
if cs == nil || (cs.Emoji == "" && cs.Text == "") {
return model.NewAppError("SetCustomStatus", "api.custom_status.set_custom_statuses.update.app_error", nil, "", http.StatusBadRequest)
}
user, err := a.GetUser(userID)
if err != nil {
return err
@@ -439,6 +443,15 @@ func (a *App) RemoveCustomStatus(userID string) *model.AppError {
return nil
}
func (a *App) GetCustomStatus(userID string) (*model.CustomStatus, *model.AppError) {
user, err := a.GetUser(userID)
if err != nil {
return &model.CustomStatus{}, err
}
return user.GetCustomStatus(), nil
}
func (a *App) addRecentCustomStatus(userID string, status *model.CustomStatus) *model.AppError {
var newRCS model.RecentCustomStatuses

Просмотреть файл

@@ -37,3 +37,30 @@ func TestSaveStatus(t *testing.T) {
})
}
}
func TestCustomStatus(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
user := th.BasicUser
cs := &model.CustomStatus{
Emoji: ":smile:",
Text: "honk!",
}
err := th.App.SetCustomStatus(user.Id, cs)
require.Nil(t, err, "failed to set custom status %v", err)
csSaved, err := th.App.GetCustomStatus(user.Id)
require.Nil(t, err, "failed to get custom status after save %v", err)
require.Equal(t, cs, csSaved)
err = th.App.RemoveCustomStatus(user.Id)
require.Nil(t, err, "failed to to clear custom status %v", err)
var csClear *model.CustomStatus
csSaved, err = th.App.GetCustomStatus(user.Id)
require.Nil(t, err, "failed to get custom status after clear %v", err)
require.Equal(t, csClear, csSaved)
}