focalboard/mattermost-plugin/build/sync/plan/plan_test.go
Jesús Espino f1b8d88d6b
Changing mattermost-auth method to work based on shared database access (#335)
* Improving mattermost auth implementation

* Making mattermost-auth based on shared database access

* Reverting unneeded changes in the config.json file

* Fixing tiny problems

* Removing the need of using the mattermost session token

* Fixing some bugs and allowing to not-bind the server to any port

* Small fix to correctly get the templates

* Adding the mattermost-plugin code inside focalboard repo

* Adding a not working code part of the cluster websocket communication

* Updating the mattermost version

* Adding the cluster messages for the websockets

* Updating to the new node version

* Making it compatible with S3

* Addressing some tiny problems

* Fixing server tests

* Adds support for MySQL migrations and initialization

Co-authored-by: Miguel de la Cruz <miguel@mcrx.me>
2021-05-24 19:06:11 +02:00

253 lines
6.3 KiB
Go

package plan_test
import (
"encoding/json"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/mattermost/mattermost-plugin-starter-template/build/sync/plan"
)
func TestUnmarshalPlan(t *testing.T) {
assert := assert.New(t)
rawJSON := []byte(`
{
"checks": [
{"type": "repo_is_clean", "params": {"repo": "template"}}
],
"actions": [
{
"paths": ["abc"],
"actions": [{
"type": "overwrite_file",
"params": {"create": true},
"conditions": [{
"type": "exists",
"params": {"repo": "plugin"}
}]
}]
}
]
}`)
var p plan.Plan
err := json.Unmarshal(rawJSON, &p)
assert.Nil(err)
expectedCheck := plan.RepoIsCleanChecker{}
expectedCheck.Params.Repo = "template"
expectedAction := plan.OverwriteFileAction{}
expectedAction.Params.Create = true
expectedActionCheck := plan.PathExistsChecker{}
expectedActionCheck.Params.Repo = "plugin"
expectedAction.Conditions = []plan.Check{&expectedActionCheck}
expected := plan.Plan{
Checks: []plan.Check{&expectedCheck},
Actions: []plan.ActionSet{{
Paths: []string{"abc"},
Actions: []plan.Action{
&expectedAction,
},
}},
}
assert.Equal(expected, p)
}
type mockCheck struct {
returnErr error
calledWith string // Path parameter the check was called with.
}
// Check implements the plan.Check interface.
func (m *mockCheck) Check(path string, c plan.Setup) error {
m.calledWith = path
return m.returnErr
}
type mockAction struct {
runErr error // Error to be returned by Run.
checkErr error // Error to be returned by Check.
calledWith string
}
// Check implements plan.Action interface.
func (m *mockAction) Check(path string, c plan.Setup) error {
return m.checkErr
}
// Run implements plan.Action interface.
func (m *mockAction) Run(path string, c plan.Setup) error {
m.calledWith = path
return m.runErr
}
// TestRunPlanSuccessfully tests a successful execution of a sync plan.
func TestRunPlanSuccessfully(t *testing.T) {
assert := assert.New(t)
setup := plan.Setup{} // mocked actions and checks won't be accessing the setup.
preCheck := &mockCheck{}
action1 := &mockAction{}
action2 := &mockAction{}
p := &plan.Plan{
Checks: []plan.Check{preCheck},
Actions: []plan.ActionSet{{
Paths: []string{"somepath"},
Actions: []plan.Action{
action1,
action2,
},
}},
}
err := p.Execute(setup)
assert.Nil(err)
assert.Equal("", preCheck.calledWith)
assert.Equal("somepath", action1.calledWith)
assert.Equal("", action2.calledWith) // second action was not called.
}
// TestRunPlanPreCheckFail checks the scenario where a sync plan precheck
// fails, aborting the whole operation.
func TestRunPlanPreCheckFail(t *testing.T) {
assert := assert.New(t)
setup := plan.Setup{} // mocked actions and checks won't be accessing the setup.
preCheck := &mockCheck{returnErr: plan.CheckFailf("check failed")}
action1 := &mockAction{}
action2 := &mockAction{}
p := &plan.Plan{
Checks: []plan.Check{preCheck},
Actions: []plan.ActionSet{{
Paths: []string{"somepath"},
Actions: []plan.Action{
action1,
action2,
},
}},
}
err := p.Execute(setup)
assert.EqualError(err, "failed check: check failed")
assert.Equal("", preCheck.calledWith)
// None of the actions were executed.
assert.Equal("", action1.calledWith)
assert.Equal("", action2.calledWith)
}
// TestRunPlanActionCheckFails tests the situation where an action's
// check returns a recoverable error, forcing the plan to execute the fallback action.
func TestRunPlanActionCheckFails(t *testing.T) {
assert := assert.New(t)
setup := plan.Setup{} // mocked actions and checks won't be accessing the setup.
action1 := &mockAction{checkErr: plan.CheckFailf("action check failed")}
action2 := &mockAction{}
p := &plan.Plan{
Actions: []plan.ActionSet{{
Paths: []string{"somepath"},
Actions: []plan.Action{
action1,
action2,
},
}},
}
err := p.Execute(setup)
assert.Nil(err)
assert.Equal("", action1.calledWith) // First action was not run.
assert.Equal("somepath", action2.calledWith) // Second action was run.
}
// TestRunPlanNoFallbacks tests the case where an action's check fails,
// but there are not more fallback actions for that path.
func TestRunPlanNoFallbacks(t *testing.T) {
assert := assert.New(t)
setup := plan.Setup{} // mocked actions and checks won't be accessing the setup.
action1 := &mockAction{checkErr: plan.CheckFailf("fail")}
action2 := &mockAction{checkErr: plan.CheckFailf("fail")}
p := &plan.Plan{
Actions: []plan.ActionSet{{
Paths: []string{"somepath"},
Actions: []plan.Action{
action1,
action2,
},
}},
}
err := p.Execute(setup)
assert.Nil(err)
// both actions were not executed.
assert.Equal("", action1.calledWith)
assert.Equal("", action2.calledWith)
}
// TestRunPlanCheckError tests the scenario where a plan check fails with
// an unexpected error. Plan execution is aborted.
func TestRunPlanCheckError(t *testing.T) {
assert := assert.New(t)
setup := plan.Setup{} // mocked actions and checks won't be accessing the setup.
preCheck := &mockCheck{returnErr: fmt.Errorf("fail")}
action1 := &mockAction{}
action2 := &mockAction{}
p := &plan.Plan{
Checks: []plan.Check{preCheck},
Actions: []plan.ActionSet{{
Paths: []string{"somepath"},
Actions: []plan.Action{
action1,
action2,
},
}},
}
err := p.Execute(setup)
assert.EqualError(err, "failed check: fail")
assert.Equal("", preCheck.calledWith)
// Actions were not run.
assert.Equal("", action1.calledWith)
assert.Equal("", action2.calledWith)
}
// TestRunPlanActionError tests the scenario where an action fails,
// aborting the whole sync process.
func TestRunPlanActionError(t *testing.T) {
assert := assert.New(t)
setup := plan.Setup{} // mocked actions and checks won't be accessing the setup.
preCheck := &mockCheck{}
action1 := &mockAction{runErr: fmt.Errorf("fail")}
action2 := &mockAction{}
p := &plan.Plan{
Checks: []plan.Check{preCheck},
Actions: []plan.ActionSet{{
Paths: []string{"somepath"},
Actions: []plan.Action{
action1,
action2,
},
}},
}
err := p.Execute(setup)
assert.EqualError(err, "action failed: fail")
assert.Equal("", preCheck.calledWith)
assert.Equal("somepath", action1.calledWith)
assert.Equal("", action2.calledWith) // second action was not called.
}