diff --git a/plugin/client.go b/plugin/client.go index d74663d1ec..e445f9e1e0 100644 --- a/plugin/client.go +++ b/plugin/client.go @@ -10,7 +10,6 @@ import ( const ( INTERNAL_KEY_PREFIX = "mmi_" BOT_USER_KEY = INTERNAL_KEY_PREFIX + "botid" - CHANNEL_KEY = INTERNAL_KEY_PREFIX + "channelid" ) // Starts the serving of a Mattermost plugin over net/rpc. gRPC is not yet supported. diff --git a/plugin/helpers_channels.go b/plugin/helpers_channels.go deleted file mode 100644 index 710b022303..0000000000 --- a/plugin/helpers_channels.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package plugin - -import ( - "github.com/mattermost/mattermost-server/model" - "github.com/mattermost/mattermost-server/utils" - "github.com/pkg/errors" -) - -func (p *HelpersImpl) EnsureChannel(channel *model.Channel) (retChannelId string, retErr error) { - // Must provide a channel with a name and teadId - if channel == nil || len(channel.Name) < 1 || len(channel.TeamId) < 1 { - return "", errors.New("passed a bad channel, nil or no name or no team id") - } - - // If we fail for any reason, this could be a race between creation of channel and - // retrieval from another EnsureChannel. Just try the basic retrieve existing again. - defer func() { - if retChannelId == "" || retErr != nil { - var err error - var channelIdBytes []byte - - err = utils.ProgressiveRetry(func() error { - channelIdBytes, err = p.API.KVGet(CHANNEL_KEY) - if err != nil { - return err - } - return nil - }) - - if err == nil && channelIdBytes != nil { - retChannelId = string(channelIdBytes) - retErr = nil - } - } - }() - - // Fetch channel ID from key value store - channelIdBytes, kvGetErr := p.API.KVGet(CHANNEL_KEY) - if kvGetErr != nil { - // Failed to retrive the value of channel - return "", errors.Wrap(kvGetErr, "failed to get channel ID") - } - - var existingChannel *model.Channel - var channelGetErr *model.AppError - - // If channel ID exists, get existing channel by ID else get it by Name - if channelIdBytes != nil { - existingChannel, channelGetErr = p.API.GetChannel(string(channelIdBytes)) - if channelGetErr != nil { - return "", errors.Wrap(channelGetErr, "failed to get channel by ID") - } - } else { - existingChannel, channelGetErr = p.API.GetChannelByName(channel.TeamId, channel.Name, false) - if channelGetErr != nil { - return "", errors.Wrap(channelGetErr, "failed to get channel by name") - } - } - - // If channel exists, update the metadata - if existingChannel != nil { - return updateChannel(p, existingChannel, channel) - } - - // Create a new channel - createdChannel, createChannelErr := p.API.CreateChannel(channel) - if createChannelErr != nil { - return "", errors.Wrap(createChannelErr, "failed to create channel") - } - - // Set the new channel id in key value store - if kvSetErr := p.API.KVSet(CHANNEL_KEY, []byte(createdChannel.Id)); kvSetErr != nil { - p.API.LogWarn("Failed to set created channel id.", "channelid", createdChannel.Id, "err", kvSetErr) - } - - return createdChannel.Id, nil -} - -func updateChannel(p *HelpersImpl, existing *model.Channel, new *model.Channel) (string, error) { - // Update metadata of the channel - if updateErr := updateChannelMeta(existing, new); updateErr != nil { - return "", errors.Wrap(updateErr, "Failed to update the metadata of existing channel") - } - - // Send the updates to API - updatedChannel, channelUpdateErr := p.API.UpdateChannel(existing) - if channelUpdateErr != nil { - return "", errors.Wrap(channelUpdateErr, "Failed to update the existing channel") - } - - // Channel exists! - return updatedChannel.Id, nil -} - -func updateChannelMeta(existing *model.Channel, new *model.Channel) error { - // Check if channels are of different types - if existing.Type != new.Type { - return errors.New("Channel type cannot be updated") - } - - // Update metadata of channel - existing.Name = new.Name - existing.DisplayName = new.DisplayName - existing.Purpose = new.Purpose - existing.Header = new.Header - - return nil -} diff --git a/plugin/helpers_channels_test.go b/plugin/helpers_channels_test.go deleted file mode 100644 index 691466ed08..0000000000 --- a/plugin/helpers_channels_test.go +++ /dev/null @@ -1,297 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package plugin_test - -import ( - "testing" - - "github.com/mattermost/mattermost-server/model" - "github.com/mattermost/mattermost-server/plugin" - "github.com/mattermost/mattermost-server/plugin/plugintest" - "github.com/stretchr/testify/assert" -) - -func TestEnsureChannel(t *testing.T) { - setupAPI := func() *plugintest.API { - return &plugintest.API{} - } - - testChannel := &model.Channel{ - Id: model.NewId(), - TeamId: model.NewId(), - Type: "public", - Name: "test_channel", - DisplayName: "Test Channel", - Purpose: "Testing EnsureChannel", - Header: "Testing EnsureChannel", - } - - t.Run("bad parameters", func(t *testing.T) { - t.Run("no channel", func(t *testing.T) { - p := &plugin.HelpersImpl{} - channelId, err := p.EnsureChannel(nil) - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("empty name", func(t *testing.T) { - p := &plugin.HelpersImpl{} - channelId, err := p.EnsureChannel(&model.Channel{ - Name: "", - }) - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("name without teamId", func(t *testing.T) { - p := &plugin.HelpersImpl{} - channelId, err := p.EnsureChannel(&model.Channel{ - Name: "test_channel", - }) - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("teamId without name", func(t *testing.T) { - p := &plugin.HelpersImpl{} - channelId, err := p.EnsureChannel(&model.Channel{ - TeamId: model.NewId(), - }) - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("teamId with empty name", func(t *testing.T) { - p := &plugin.HelpersImpl{} - channelId, err := p.EnsureChannel(&model.Channel{ - TeamId: model.NewId(), - }) - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - }) - - t.Run("if channel already exists in Key Value store", func(t *testing.T) { - t.Run("should return an error if unable to get channel id", func(t *testing.T) { - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return(nil, &model.AppError{}) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("should return an error if unable to get channel", func(t *testing.T) { - expectedChannelId := model.NewId() - - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return([]byte(expectedChannelId), nil) - api.On("GetChannel", expectedChannelId).Return(nil, &model.AppError{}) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("should return an error if unable to update channel", func(t *testing.T) { - expectedChannelId := model.NewId() - - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return([]byte(expectedChannelId), nil) - api.On("GetChannel", expectedChannelId).Return(testChannel, nil) - api.On("UpdateChannel", testChannel).Return(nil, &model.AppError{}) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("should return the Id of existing channel if metadata is same", func(t *testing.T) { - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return([]byte(testChannel.Id), nil) - api.On("GetChannel", testChannel.Id).Return(testChannel, nil) - api.On("UpdateChannel", testChannel).Return(testChannel, nil) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, testChannel.Id, channelId) - assert.Nil(t, err) - }) - t.Run("should return error if channel type is different from existing one", func(t *testing.T) { - privChannel := &model.Channel{ - Id: model.NewId(), - Type: "private", - TeamId: testChannel.TeamId, - Name: testChannel.Name, - } - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return([]byte(testChannel.Id), nil) - api.On("GetChannel", testChannel.Id).Return(privChannel, nil) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("should return the Id of updated channel if metadata is different", func(t *testing.T) { - updatedChannel := &model.Channel{ - Id: model.NewId(), - TeamId: testChannel.TeamId, - Name: testChannel.Name, - } - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return([]byte(testChannel.Id), nil) - api.On("GetChannel", testChannel.Id).Return(testChannel, nil) - api.On("UpdateChannel", testChannel).Return(updatedChannel, nil) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, updatedChannel.Id, channelId) - assert.Nil(t, err) - }) - }) - - t.Run("if channel is not in Key Value store but already exists", func(t *testing.T) { - t.Run("should return an error if unable to get channel", func(t *testing.T) { - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return(nil, nil) - api.On("GetChannelByName", testChannel.TeamId, testChannel.Name, false).Return(nil, &model.AppError{}) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("should return the Id of existing channel if metadata is same", func(t *testing.T) { - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return(nil, nil) - api.On("GetChannelByName", testChannel.TeamId, testChannel.Name, false).Return(testChannel, nil) - api.On("UpdateChannel", testChannel).Return(testChannel, nil) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, testChannel.Id, channelId) - assert.Nil(t, err) - }) - t.Run("should return error if failed to update the channel", func(t *testing.T) { - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return(nil, nil) - api.On("GetChannelByName", testChannel.TeamId, testChannel.Name, false).Return(testChannel, nil) - api.On("UpdateChannel", testChannel).Return(nil, &model.AppError{}) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("should return the Id of updated channel if metadata is different", func(t *testing.T) { - updatedChannel := &model.Channel{ - Id: model.NewId(), - TeamId: testChannel.TeamId, - Name: testChannel.Name, - } - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return(nil, nil) - api.On("GetChannelByName", testChannel.TeamId, testChannel.Name, false).Return(testChannel, nil) - api.On("UpdateChannel", testChannel).Return(updatedChannel, nil) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, updatedChannel.Id, channelId) - assert.Nil(t, err) - }) - t.Run("should return error if channel type is different from existing one", func(t *testing.T) { - privChannel := &model.Channel{ - Id: model.NewId(), - Type: "private", - TeamId: testChannel.TeamId, - Name: testChannel.Name, - } - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return(nil, nil) - api.On("GetChannelByName", testChannel.TeamId, testChannel.Name, false).Return(privChannel, nil) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - }) - - t.Run("if channel does not exist", func(t *testing.T) { - t.Run("should create new channel and return the Id", func(t *testing.T) { - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return(nil, nil) - api.On("GetChannelByName", testChannel.TeamId, testChannel.Name, false).Return(nil, nil) - api.On("CreateChannel", testChannel).Return(testChannel, nil) - api.On("KVSet", plugin.CHANNEL_KEY, []byte(testChannel.Id)).Return(nil) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, testChannel.Id, channelId) - assert.Nil(t, err) - }) - t.Run("should return error if unable to create new channel", func(t *testing.T) { - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return(nil, nil) - api.On("GetChannelByName", testChannel.TeamId, testChannel.Name, false).Return(nil, nil) - api.On("CreateChannel", testChannel).Return(nil, &model.AppError{}) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, "", channelId) - assert.NotNil(t, err) - }) - t.Run("should log and return id if unable to write to Key Value store", func(t *testing.T) { - api := setupAPI() - api.On("KVGet", plugin.CHANNEL_KEY).Return(nil, nil) - api.On("GetChannelByName", testChannel.TeamId, testChannel.Name, false).Return(nil, nil) - api.On("CreateChannel", testChannel).Return(testChannel, nil) - api.On("KVSet", plugin.CHANNEL_KEY, []byte(testChannel.Id)).Return(&model.AppError{}) - api.On("LogWarn", "Failed to set created channel id.", "channelid", testChannel.Id, "err", &model.AppError{}) - defer api.AssertExpectations(t) - - p := &plugin.HelpersImpl{API: api} - - channelId, err := p.EnsureChannel(testChannel) - - assert.Equal(t, testChannel.Id, channelId) - assert.Nil(t, err) - }) - }) -}