706 lines
21 KiB
Go
706 lines
21 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/go-yaml/yaml"
|
|
|
|
"github.com/gotify/server/v2/mode"
|
|
"github.com/gotify/server/v2/model"
|
|
"github.com/gotify/server/v2/plugin"
|
|
"github.com/gotify/server/v2/plugin/compat"
|
|
"github.com/gotify/server/v2/plugin/testing/mock"
|
|
"github.com/gotify/server/v2/test"
|
|
"github.com/gotify/server/v2/test/testdb"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
func TestPluginSuite(t *testing.T) {
|
|
suite.Run(t, new(PluginSuite))
|
|
}
|
|
|
|
type PluginSuite struct {
|
|
suite.Suite
|
|
db *testdb.Database
|
|
a *PluginAPI
|
|
ctx *gin.Context
|
|
recorder *httptest.ResponseRecorder
|
|
manager *plugin.Manager
|
|
notified bool
|
|
}
|
|
|
|
func (s *PluginSuite) BeforeTest(suiteName, testName string) {
|
|
mode.Set(mode.TestDev)
|
|
s.db = testdb.NewDB(s.T())
|
|
s.resetRecorder()
|
|
manager, err := plugin.NewManager(s.db, "", nil, s)
|
|
assert.Nil(s.T(), err)
|
|
s.manager = manager
|
|
withURL(s.ctx, "http", "example.com")
|
|
s.a = &PluginAPI{DB: s.db, Manager: manager, Notifier: s}
|
|
|
|
mockPluginCompat := new(mock.Plugin)
|
|
assert.Nil(s.T(), s.manager.LoadPlugin(mockPluginCompat))
|
|
|
|
s.db.User(1)
|
|
assert.Nil(s.T(), s.manager.InitializeForUserID(1))
|
|
s.db.User(2)
|
|
assert.Nil(s.T(), s.manager.InitializeForUserID(2))
|
|
|
|
s.db.CreatePluginConf(&model.PluginConf{
|
|
UserID: 1,
|
|
ModulePath: "github.com/gotify/server/v2/plugin/example/removed",
|
|
Token: "P1234",
|
|
Enabled: false,
|
|
})
|
|
}
|
|
|
|
func (s *PluginSuite) getDanglingConf(uid uint) *model.PluginConf {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(uid, "github.com/gotify/server/v2/plugin/example/removed")
|
|
assert.NoError(s.T(), err)
|
|
return conf
|
|
}
|
|
|
|
func (s *PluginSuite) resetRecorder() {
|
|
s.recorder = httptest.NewRecorder()
|
|
s.ctx, _ = gin.CreateTestContext(s.recorder)
|
|
}
|
|
|
|
func (s *PluginSuite) AfterTest(suiteName, testName string) {
|
|
s.db.Close()
|
|
}
|
|
|
|
func (s *PluginSuite) Notify(userID uint, msg *model.MessageExternal) {
|
|
s.notified = true
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetPlugins() {
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", "/plugin", nil)
|
|
s.a.GetPlugins(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
|
|
pluginConfs := make([]model.PluginConfExternal, 0)
|
|
assert.Nil(s.T(), json.Unmarshal(s.recorder.Body.Bytes(), &pluginConfs))
|
|
|
|
assert.Equal(s.T(), mock.Name, pluginConfs[0].Name)
|
|
assert.Equal(s.T(), mock.ModulePath, pluginConfs[0].ModulePath)
|
|
|
|
assert.False(s.T(), pluginConfs[0].Enabled, "Plugins should be disabled by default")
|
|
}
|
|
|
|
func (s *PluginSuite) Test_EnableDisablePlugin() {
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/plugin/1/enable", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "1"}}
|
|
s.a.EnablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
|
|
if pluginConf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath); assert.NoError(s.T(), err) {
|
|
assert.True(s.T(), pluginConf.Enabled)
|
|
}
|
|
s.resetRecorder()
|
|
}
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/plugin/1/enable", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "1"}}
|
|
s.a.EnablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
|
|
if pluginConf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath); assert.NoError(s.T(), err) {
|
|
assert.True(s.T(), pluginConf.Enabled)
|
|
}
|
|
s.resetRecorder()
|
|
}
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/plugin/1/disable", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "1"}}
|
|
s.a.DisablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
|
|
if pluginConf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath); assert.NoError(s.T(), err) {
|
|
assert.False(s.T(), pluginConf.Enabled)
|
|
}
|
|
s.resetRecorder()
|
|
}
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/plugin/1/disable", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "1"}}
|
|
s.a.DisablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
|
|
if pluginConf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath); assert.NoError(s.T(), err) {
|
|
assert.False(s.T(), pluginConf.Enabled)
|
|
}
|
|
s.resetRecorder()
|
|
}
|
|
|
|
}
|
|
|
|
func (s *PluginSuite) Test_EnableDisablePlugin_EnableReturnsError_expect500() {
|
|
s.db.User(16)
|
|
assert.Nil(s.T(), s.manager.InitializeForUserID(16))
|
|
mock.ReturnErrorOnEnableForUser(16, errors.New("test error"))
|
|
conf, err := s.db.GetPluginConfByUserAndPath(16, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 16)
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/enable", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.EnablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 500, s.recorder.Code)
|
|
|
|
if pluginConf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath); assert.NoError(s.T(), err) {
|
|
assert.False(s.T(), pluginConf.Enabled)
|
|
}
|
|
s.resetRecorder()
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_EnableDisablePlugin_DisableReturnsError_expect500() {
|
|
s.db.User(17)
|
|
assert.Nil(s.T(), s.manager.InitializeForUserID(17))
|
|
mock.ReturnErrorOnDisableForUser(17, errors.New("test error"))
|
|
conf, err := s.db.GetPluginConfByUserAndPath(17, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
s.manager.SetPluginEnabled(conf.ID, true)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 17)
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/disable", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.DisablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 500, s.recorder.Code)
|
|
|
|
if pluginConf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath); assert.NoError(s.T(), err) {
|
|
assert.False(s.T(), pluginConf.Enabled)
|
|
}
|
|
s.resetRecorder()
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_EnableDisablePlugin_incorrectUser_expectNotFound() {
|
|
{
|
|
test.WithUser(s.ctx, 2)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/plugin/1/enable", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "1"}}
|
|
s.a.EnablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
|
|
if pluginConf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath); assert.NoError(s.T(), err) {
|
|
assert.False(s.T(), pluginConf.Enabled)
|
|
}
|
|
s.resetRecorder()
|
|
}
|
|
|
|
{
|
|
test.WithUser(s.ctx, 2)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/plugin/1/disable", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "1"}}
|
|
s.a.DisablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
|
|
if pluginConf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath); assert.NoError(s.T(), err) {
|
|
assert.False(s.T(), pluginConf.Enabled)
|
|
}
|
|
s.resetRecorder()
|
|
}
|
|
|
|
}
|
|
|
|
func (s *PluginSuite) Test_EnableDisablePlugin_nonExistPlugin_expectNotFound() {
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/plugin/99/enable", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "99"}}
|
|
s.a.EnablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
s.resetRecorder()
|
|
}
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/plugin/99/disable", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "99"}}
|
|
s.a.DisablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
s.resetRecorder()
|
|
}
|
|
|
|
}
|
|
|
|
func (s *PluginSuite) Test_EnableDisablePlugin_danglingConf_expectNotFound() {
|
|
conf := s.getDanglingConf(1)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/enable", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.EnablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
s.resetRecorder()
|
|
}
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/disable", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.DisablePlugin(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
s.resetRecorder()
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetDisplay() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
|
|
mockInst.DisplayString = "test string"
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", fmt.Sprintf("/plugin/%d/display", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.GetDisplay(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
test.JSONEquals(s.T(), mockInst.DisplayString, s.recorder.Body.String())
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetDisplay_NotImplemented_expectEmptyString() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
|
|
mockInst.SetCapability(compat.Displayer, false)
|
|
defer mockInst.SetCapability(compat.Displayer, true)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", fmt.Sprintf("/plugin/%d/display", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.GetDisplay(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
test.JSONEquals(s.T(), "", s.recorder.Body.String())
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetDisplay_incorrectUser_expectNotFound() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
|
|
mockInst.DisplayString = "test string"
|
|
|
|
{
|
|
test.WithUser(s.ctx, 2)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", fmt.Sprintf("/plugin/%d/display", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.GetDisplay(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetDisplay_danglingConf_expectNotFound() {
|
|
conf := s.getDanglingConf(1)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", fmt.Sprintf("/plugin/%d/display", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.GetDisplay(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetDisplay_nonExistPlugin_expectNotFound() {
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", "/plugin/99/display", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "99"}}
|
|
s.a.GetDisplay(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetConfig() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
|
|
assert.Equal(s.T(), mockInst.DefaultConfig(), mockInst.Config, "Initial config should be default config")
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", fmt.Sprintf("/plugin/%d/config", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.GetConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
returnedConfig := new(mock.PluginConfig)
|
|
assert.Nil(s.T(), yaml.Unmarshal(s.recorder.Body.Bytes(), returnedConfig))
|
|
assert.Equal(s.T(), mockInst.Config, returnedConfig)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetConfg_notImplemeted_expect400() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
|
|
mockInst.SetCapability(compat.Configurer, false)
|
|
defer mockInst.SetCapability(compat.Configurer, true)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", fmt.Sprintf("/plugin/%d/config", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.GetConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetConfig_incorrectUser_expectNotFound() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 2)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", fmt.Sprintf("/plugin/%d/config", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.GetConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetConfig_danglingConf_expectNotFound() {
|
|
conf := s.getDanglingConf(1)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", fmt.Sprintf("/plugin/%d/config", conf.ID), nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.GetConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_GetConfig_nonExistPlugin_expectNotFound() {
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("GET", "/plugin/99/config", nil)
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "99"}}
|
|
s.a.GetConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_UpdateConfig() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
|
|
newConfig := &mock.PluginConfig{
|
|
TestKey: "test__new__config",
|
|
}
|
|
newConfigYAML, err := yaml.Marshal(newConfig)
|
|
assert.Nil(s.T(), err)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/config", conf.ID), bytes.NewReader(newConfigYAML))
|
|
s.ctx.Header("Content-Type", "application/x-yaml")
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.UpdateConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 200, s.recorder.Code)
|
|
assert.Equal(s.T(), newConfig, mockInst.Config, "config should be received by plugin")
|
|
|
|
var pluginFromDBBytes []byte
|
|
if pluginConf, err := s.db.GetPluginConfByID(conf.ID); assert.NoError(s.T(), err) {
|
|
pluginFromDBBytes = pluginConf.Config
|
|
}
|
|
pluginFromDB := new(mock.PluginConfig)
|
|
err := yaml.Unmarshal(pluginFromDBBytes, pluginFromDB)
|
|
assert.Nil(s.T(), err)
|
|
assert.Equal(s.T(), newConfig, pluginFromDB, "config should be updated in database")
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_UpdateConfig_invalidConfig_expect400() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
origConfig := mockInst.Config
|
|
|
|
newConfig := &mock.PluginConfig{
|
|
TestKey: "test__new__config__invalid",
|
|
IsNotValid: true,
|
|
}
|
|
newConfigYAML, err := yaml.Marshal(newConfig)
|
|
assert.Nil(s.T(), err)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/config", conf.ID), bytes.NewReader(newConfigYAML))
|
|
s.ctx.Header("Content-Type", "application/x-yaml")
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.UpdateConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
assert.Equal(s.T(), origConfig, mockInst.Config, "config should not be received by plugin")
|
|
|
|
var pluginFromDBBytes []byte
|
|
if pluginConf, err := s.db.GetPluginConfByID(conf.ID); assert.NoError(s.T(), err) {
|
|
pluginFromDBBytes = pluginConf.Config
|
|
}
|
|
pluginFromDB := new(mock.PluginConfig)
|
|
err := yaml.Unmarshal(pluginFromDBBytes, pluginFromDB)
|
|
assert.Nil(s.T(), err)
|
|
assert.Equal(s.T(), origConfig, pluginFromDB, "config should not be updated in database")
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_UpdateConfig_malformedYAML_expect400() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
origConfig := mockInst.Config
|
|
|
|
newConfigYAML := []byte(`--- "rg e""`)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/config", conf.ID), bytes.NewReader(newConfigYAML))
|
|
s.ctx.Header("Content-Type", "application/x-yaml")
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.UpdateConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
assert.Equal(s.T(), origConfig, mockInst.Config, "config should not be received by plugin")
|
|
|
|
var pluginFromDBBytes []byte
|
|
if pluginConf, err := s.db.GetPluginConfByID(conf.ID); assert.NoError(s.T(), err) {
|
|
pluginFromDBBytes = pluginConf.Config
|
|
}
|
|
pluginFromDB := new(mock.PluginConfig)
|
|
err := yaml.Unmarshal(pluginFromDBBytes, pluginFromDB)
|
|
assert.Nil(s.T(), err)
|
|
assert.Equal(s.T(), origConfig, pluginFromDB, "config should not be updated in database")
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_UpdateConfig_ioError_expect500() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
origConfig := mockInst.Config
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/config", conf.ID), test.UnreadableReader())
|
|
s.ctx.Header("Content-Type", "application/x-yaml")
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.UpdateConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 500, s.recorder.Code)
|
|
assert.Equal(s.T(), origConfig, mockInst.Config, "config should not be received by plugin")
|
|
|
|
var pluginFromDBBytes []byte
|
|
if pluginConf, err := s.db.GetPluginConfByID(conf.ID); assert.NoError(s.T(), err) {
|
|
pluginFromDBBytes = pluginConf.Config
|
|
}
|
|
pluginFromDB := new(mock.PluginConfig)
|
|
err := yaml.Unmarshal(pluginFromDBBytes, pluginFromDB)
|
|
assert.Nil(s.T(), err)
|
|
assert.Equal(s.T(), origConfig, pluginFromDB, "config should not be updated in database")
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_UpdateConfig_notImplemented_expect400() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
|
|
newConfig := &mock.PluginConfig{
|
|
TestKey: "test__new__config",
|
|
}
|
|
newConfigYAML, err := yaml.Marshal(newConfig)
|
|
assert.Nil(s.T(), err)
|
|
|
|
mockInst.SetCapability(compat.Configurer, false)
|
|
defer mockInst.SetCapability(compat.Configurer, true)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/config", conf.ID), bytes.NewReader(newConfigYAML))
|
|
s.ctx.Header("Content-Type", "application/x-yaml")
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.UpdateConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 400, s.recorder.Code)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_UpdateConfig_incorrectUser_expectNotFound() {
|
|
conf, err := s.db.GetPluginConfByUserAndPath(1, mock.ModulePath)
|
|
assert.NoError(s.T(), err)
|
|
inst, err := s.manager.Instance(conf.ID)
|
|
assert.Nil(s.T(), err)
|
|
mockInst := inst.(*mock.PluginInstance)
|
|
origConfig := mockInst.Config
|
|
|
|
newConfig := &mock.PluginConfig{
|
|
TestKey: "test__new__config",
|
|
}
|
|
newConfigYAML, err := yaml.Marshal(newConfig)
|
|
assert.Nil(s.T(), err)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 2)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/config", conf.ID), bytes.NewReader(newConfigYAML))
|
|
s.ctx.Header("Content-Type", "application/x-yaml")
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.UpdateConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
assert.Equal(s.T(), origConfig, mockInst.Config, "config should not be received by plugin")
|
|
|
|
var pluginFromDBBytes []byte
|
|
if pluginConf, err := s.db.GetPluginConfByID(conf.ID); assert.NoError(s.T(), err) {
|
|
pluginFromDBBytes = pluginConf.Config
|
|
}
|
|
pluginFromDB := new(mock.PluginConfig)
|
|
err := yaml.Unmarshal(pluginFromDBBytes, pluginFromDB)
|
|
assert.Nil(s.T(), err)
|
|
assert.Equal(s.T(), origConfig, pluginFromDB, "config should not be updated in database")
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_UpdateConfig_danglingConf_expectNotFound() {
|
|
conf := s.getDanglingConf(1)
|
|
|
|
newConfig := &mock.PluginConfig{
|
|
TestKey: "test__new__config",
|
|
}
|
|
newConfigYAML, err := yaml.Marshal(newConfig)
|
|
assert.Nil(s.T(), err)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", fmt.Sprintf("/plugin/%d/config", conf.ID), bytes.NewReader(newConfigYAML))
|
|
s.ctx.Header("Content-Type", "application/x-yaml")
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: fmt.Sprint(conf.ID)}}
|
|
s.a.UpdateConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
}
|
|
|
|
func (s *PluginSuite) Test_UpdateConfig_nonExistPlugin_expectNotFound() {
|
|
newConfig := &mock.PluginConfig{
|
|
TestKey: "test__new__config",
|
|
}
|
|
newConfigYAML, err := yaml.Marshal(newConfig)
|
|
assert.Nil(s.T(), err)
|
|
|
|
{
|
|
test.WithUser(s.ctx, 1)
|
|
|
|
s.ctx.Request = httptest.NewRequest("POST", "/plugin/99/config", bytes.NewReader(newConfigYAML))
|
|
s.ctx.Header("Content-Type", "application/x-yaml")
|
|
s.ctx.Params = gin.Params{{Key: "id", Value: "99"}}
|
|
s.a.UpdateConfig(s.ctx)
|
|
|
|
assert.Equal(s.T(), 404, s.recorder.Code)
|
|
}
|
|
}
|