Add KV helper methods to Helpers interface (#11307)
* Add KV helper methods to Helpers interface * Address code-review comments, add unit tests * Update documentation for KVCompareAndSetJSON. * Update assertions for helpers_bots_test.go * Fix assertion not called name in test.
Этот коммит содержится в:
коммит произвёл
Ali Farooq
родитель
ac4019afe5
Коммит
46f2b18e4f
@@ -6,10 +6,26 @@ package plugin
|
|||||||
import "github.com/mattermost/mattermost-server/model"
|
import "github.com/mattermost/mattermost-server/model"
|
||||||
|
|
||||||
type Helpers interface {
|
type Helpers interface {
|
||||||
// EnsureBot ether returns an existing bot user or creates a bot user with
|
// EnsureBot either returns an existing bot user or creates a bot user with
|
||||||
// the specifications of the passed bot.
|
// the specifications of the passed bot.
|
||||||
// Returns the id of the bot created or existing.
|
// Returns the id of the bot created or existing.
|
||||||
EnsureBot(bot *model.Bot) (string, error)
|
EnsureBot(bot *model.Bot) (string, error)
|
||||||
|
|
||||||
|
// KVGetJSON retrievs a value based on the key.
|
||||||
|
KVGetJSON(key string, value interface{}) error
|
||||||
|
|
||||||
|
// KVSetJSON stores a key-value pair.
|
||||||
|
KVSetJSON(key string, value interface{}) error
|
||||||
|
|
||||||
|
// KVCompareAndSetJSON updates a key-value pair if the current
|
||||||
|
// value is equal to oldValue.
|
||||||
|
// Returns (false, err) if DB/marshal/unmarshal error occurred
|
||||||
|
// Returns (false, nil) if current value != old value
|
||||||
|
// Returns (true, nil) if current value == old value or new key is inserted
|
||||||
|
KVCompareAndSetJSON(key string, oldValue interface{}, newValue interface{}) (bool, error)
|
||||||
|
|
||||||
|
// KVSetWithExpiryJSON stores a key-value pair with an expiry time.
|
||||||
|
KVSetWithExpiryJSON(key string, value interface{}, expireInSeconds int64) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type HelpersImpl struct {
|
type HelpersImpl struct {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
@@ -64,3 +65,42 @@ func (p *HelpersImpl) EnsureBot(bot *model.Bot) (retBotId string, retErr error)
|
|||||||
|
|
||||||
return createdBot.UserId, nil
|
return createdBot.UserId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *HelpersImpl) KVGetJSON(key string, value interface{}) error {
|
||||||
|
data, err := p.API.KVGet(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Unmarshal(data, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *HelpersImpl) KVSetJSON(key string, value interface{}) error {
|
||||||
|
data, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.API.KVSet(key, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *HelpersImpl) KVCompareAndSetJSON(key string, oldValue interface{}, newValue interface{}) (bool, error) {
|
||||||
|
oldData, err := json.Marshal(oldValue)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrap(err, "unable to marshal old value")
|
||||||
|
}
|
||||||
|
|
||||||
|
newData, err := json.Marshal(newValue)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrap(err, "unable to marshal new value")
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.API.KVCompareAndSet(key, oldData, newData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *HelpersImpl) KVSetWithExpiryJSON(key string, value interface{}, expireInSeconds int64) error {
|
||||||
|
data, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.API.KVSetWithExpiry(key, data, expireInSeconds)
|
||||||
|
}
|
||||||
|
|||||||
@@ -153,3 +153,179 @@ func TestEnsureBot(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestKVGetJSON(t *testing.T) {
|
||||||
|
setupAPI := func() *plugintest.API {
|
||||||
|
return &plugintest.API{}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("KVGet error", func(t *testing.T) {
|
||||||
|
p := &plugin.HelpersImpl{}
|
||||||
|
|
||||||
|
api := setupAPI()
|
||||||
|
api.On("KVGet", plugin.BOT_USER_KEY).Return(nil, &model.AppError{})
|
||||||
|
p.API = api
|
||||||
|
|
||||||
|
var dat map[string]interface{}
|
||||||
|
|
||||||
|
err := p.KVGetJSON(plugin.BOT_USER_KEY, dat)
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Nil(t, dat)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Malformed JSON", func(t *testing.T) {
|
||||||
|
key := "test-key"
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{}
|
||||||
|
|
||||||
|
api := setupAPI()
|
||||||
|
api.On("KVGet", key).Return([]byte(`{{:}"val-a": 10}`), nil)
|
||||||
|
p.API = api
|
||||||
|
|
||||||
|
var dat map[string]interface{}
|
||||||
|
|
||||||
|
err := p.KVGetJSON(key, &dat)
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Nil(t, dat)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Valid parameters passed (happy-path)", func(t *testing.T) {
|
||||||
|
key := "test-key"
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{}
|
||||||
|
|
||||||
|
api := setupAPI()
|
||||||
|
api.On("KVGet", key).Return([]byte(`{"val-a": 10}`), nil)
|
||||||
|
p.API = api
|
||||||
|
|
||||||
|
var dat map[string]interface{}
|
||||||
|
|
||||||
|
err := p.KVGetJSON(key, &dat)
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, map[string]interface{}{
|
||||||
|
"val-a": float64(10),
|
||||||
|
}, dat)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKVSetJSON(t *testing.T) {
|
||||||
|
key := "test-key"
|
||||||
|
|
||||||
|
setupAPI := func() *plugintest.API {
|
||||||
|
return &plugintest.API{}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("JSON Marshal error", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.AssertNotCalled(t, "KVSet")
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
err := p.KVSetJSON(key, func() { return })
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Valid parameters passed (Happy-path)", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.On("KVSet", key, []byte(`{"val-a":10}`)).Return(nil)
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
err := p.KVSetJSON(key, map[string]interface{}{
|
||||||
|
"val-a": float64(10),
|
||||||
|
})
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKVCompareAndSetJSON(t *testing.T) {
|
||||||
|
key := "test-key"
|
||||||
|
setupAPI := func() *plugintest.API {
|
||||||
|
return &plugintest.API{}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("old value JSON marshal error", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.AssertNotCalled(t, "KVCompareAndSet")
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
ok, err := p.KVCompareAndSetJSON(key, func() { return }, map[string]interface{}{})
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.Equal(t, false, ok)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("new value JSON marshal error", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.AssertNotCalled(t, "KVCompareAndSet")
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
ok, err := p.KVCompareAndSetJSON(key, map[string]interface{}{}, func() { return })
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.Equal(t, false, ok)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Valid parameters passed (happy-path)", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.On("KVCompareAndSet", key, []byte(`{"val-a":10}`), []byte(`{"val-b":20}`)).Return(false, nil)
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
ok, err := p.KVCompareAndSetJSON(key, map[string]interface{}{
|
||||||
|
"val-a": 10,
|
||||||
|
}, map[string]interface{}{
|
||||||
|
"val-b": 20,
|
||||||
|
})
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.Equal(t, false, ok)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKVSetWithExpiryJSON(t *testing.T) {
|
||||||
|
key := "test-key"
|
||||||
|
|
||||||
|
setupAPI := func() *plugintest.API {
|
||||||
|
return &plugintest.API{}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("JSON Marshal error", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.AssertNotCalled(t, "KVSetWithExpiry")
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
err := p.KVSetWithExpiryJSON(key, func() { return }, 100)
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("valid parameters passed (happy-path)", func(t *testing.T) {
|
||||||
|
api := setupAPI()
|
||||||
|
api.On("KVSetWithExpiry", key, []byte(`{"val-a":10}`), int64(100)).Return(nil)
|
||||||
|
|
||||||
|
p := &plugin.HelpersImpl{API: api}
|
||||||
|
|
||||||
|
err := p.KVSetWithExpiryJSON(key, map[string]interface{}{
|
||||||
|
"val-a": float64(10),
|
||||||
|
}, 100)
|
||||||
|
|
||||||
|
api.AssertExpectations(t)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,3 +32,66 @@ func (_m *Helpers) EnsureBot(bot *model.Bot) (string, error) {
|
|||||||
|
|
||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KVCompareAndSetJSON provides a mock function with given fields: key, oldValue, newValue
|
||||||
|
func (_m *Helpers) KVCompareAndSetJSON(key string, oldValue interface{}, newValue interface{}) (bool, error) {
|
||||||
|
ret := _m.Called(key, oldValue, newValue)
|
||||||
|
|
||||||
|
var r0 bool
|
||||||
|
if rf, ok := ret.Get(0).(func(string, interface{}, interface{}) bool); ok {
|
||||||
|
r0 = rf(key, oldValue, newValue)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Get(0).(bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(string, interface{}, interface{}) error); ok {
|
||||||
|
r1 = rf(key, oldValue, newValue)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// KVGetJSON provides a mock function with given fields: key, value
|
||||||
|
func (_m *Helpers) KVGetJSON(key string, value interface{}) error {
|
||||||
|
ret := _m.Called(key, value)
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, interface{}) error); ok {
|
||||||
|
r0 = rf(key, value)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// KVSetJSON provides a mock function with given fields: key, value
|
||||||
|
func (_m *Helpers) KVSetJSON(key string, value interface{}) error {
|
||||||
|
ret := _m.Called(key, value)
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, interface{}) error); ok {
|
||||||
|
r0 = rf(key, value)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// KVSetWithExpiryJSON provides a mock function with given fields: key, value, expireInSeconds
|
||||||
|
func (_m *Helpers) KVSetWithExpiryJSON(key string, value interface{}, expireInSeconds int64) error {
|
||||||
|
ret := _m.Called(key, value, expireInSeconds)
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, interface{}, int64) error); ok {
|
||||||
|
r0 = rf(key, value, expireInSeconds)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user