Skip to content

Commit 3b67e04

Browse files
committed
test: add workflow mutator and SetLayout tests for ako review
Add 48+ workflow mutation operation tests covering InsertAfterActivity, ReplaceActivity, InsertOutcome, DropOutcome, InsertPath, DropPath, InsertBranch, DropBranch, InsertBoundaryEvent, SetActivityProperty (PAGE, DESCRIPTION, TARGETING_MICROFLOW, TARGETING_XPATH), and SetPropertyWithEntity (OVERVIEW_PAGE, PARAMETER). Document dSet silent-failure bug for missing keys. Add 6 SetLayout tests: basic layout change, explicit param mappings, same layout no-op, snippet rejection, missing FormCall, and empty Form field.
1 parent 57261b3 commit 3b67e04

2 files changed

Lines changed: 1011 additions & 0 deletions

File tree

mdl/backend/mpr/page_mutator_test.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package mprbackend
44

55
import (
6+
"strings"
67
"testing"
78

89
"go.mongodb.org/mongo-driver/bson"
@@ -722,3 +723,139 @@ func TestParamScope(t *testing.T) {
722723
t.Error("Expected non-empty ID")
723724
}
724725
}
726+
727+
// ---------------------------------------------------------------------------
728+
// SetLayout tests
729+
// ---------------------------------------------------------------------------
730+
731+
// makePageWithLayout builds a minimal page BSON doc with a FormCall pointing
732+
// to the given layout and argument parameters.
733+
func makePageWithLayout(layoutQN string, params ...string) bson.D {
734+
args := bson.A{int32(3)}
735+
for _, p := range params {
736+
args = append(args, bson.D{
737+
{Key: "$ID", Value: primitive.Binary{Subtype: 0x04, Data: make([]byte, 16)}},
738+
{Key: "$Type", Value: "Pages$FormCallArgument"},
739+
{Key: "Parameter", Value: layoutQN + "." + p},
740+
})
741+
}
742+
return bson.D{
743+
{Key: "$ID", Value: primitive.Binary{Subtype: 0x04, Data: make([]byte, 16)}},
744+
{Key: "$Type", Value: "Pages$FormCall"},
745+
{Key: "FormCall", Value: bson.D{
746+
{Key: "Form", Value: layoutQN},
747+
{Key: "Arguments", Value: args},
748+
}},
749+
}
750+
}
751+
752+
func makePageMutator(rawData bson.D) *mprPageMutator {
753+
return &mprPageMutator{rawData: rawData, containerType: "page", widgetFinder: findBsonWidget}
754+
}
755+
756+
func TestSetLayout_Basic(t *testing.T) {
757+
page := makePageWithLayout("MyModule.OldLayout", "Content", "Header")
758+
m := makePageMutator(page)
759+
760+
if err := m.SetLayout("MyModule.NewLayout", nil); err != nil {
761+
t.Fatalf("SetLayout failed: %v", err)
762+
}
763+
764+
formCall := dGetDoc(m.rawData, "FormCall")
765+
if got := dGetString(formCall, "Form"); got != "MyModule.NewLayout" {
766+
t.Errorf("Form = %q, want MyModule.NewLayout", got)
767+
}
768+
769+
// Verify parameters were remapped
770+
args := dGetArrayElements(dGet(formCall, "Arguments"))
771+
for _, a := range args {
772+
aDoc := a.(bson.D)
773+
param := dGetString(aDoc, "Parameter")
774+
if !strings.HasPrefix(param, "MyModule.NewLayout.") {
775+
t.Errorf("Parameter %q should start with MyModule.NewLayout.", param)
776+
}
777+
}
778+
}
779+
780+
func TestSetLayout_WithParamMappings(t *testing.T) {
781+
page := makePageWithLayout("MyModule.OldLayout", "Content", "Header")
782+
m := makePageMutator(page)
783+
784+
mappings := map[string]string{
785+
"Content": "MainArea",
786+
"Header": "TopBar",
787+
}
788+
if err := m.SetLayout("MyModule.NewLayout", mappings); err != nil {
789+
t.Fatalf("SetLayout with mappings failed: %v", err)
790+
}
791+
792+
formCall := dGetDoc(m.rawData, "FormCall")
793+
args := dGetArrayElements(dGet(formCall, "Arguments"))
794+
paramValues := make(map[string]bool)
795+
for _, a := range args {
796+
aDoc := a.(bson.D)
797+
paramValues[dGetString(aDoc, "Parameter")] = true
798+
}
799+
if !paramValues["MyModule.NewLayout.MainArea"] {
800+
t.Error("Expected MyModule.NewLayout.MainArea in remapped params")
801+
}
802+
if !paramValues["MyModule.NewLayout.TopBar"] {
803+
t.Error("Expected MyModule.NewLayout.TopBar in remapped params")
804+
}
805+
}
806+
807+
func TestSetLayout_SameLayout_Noop(t *testing.T) {
808+
page := makePageWithLayout("MyModule.SameLayout", "Content")
809+
m := makePageMutator(page)
810+
811+
if err := m.SetLayout("MyModule.SameLayout", nil); err != nil {
812+
t.Fatalf("SetLayout same layout failed: %v", err)
813+
}
814+
815+
// Should be a no-op — form unchanged
816+
formCall := dGetDoc(m.rawData, "FormCall")
817+
if got := dGetString(formCall, "Form"); got != "MyModule.SameLayout" {
818+
t.Errorf("Form = %q, want MyModule.SameLayout", got)
819+
}
820+
}
821+
822+
func TestSetLayout_Snippet_Error(t *testing.T) {
823+
page := makePageWithLayout("MyModule.Layout", "Content")
824+
m := &mprPageMutator{rawData: page, containerType: "snippet", widgetFinder: findBsonWidget}
825+
826+
err := m.SetLayout("MyModule.NewLayout", nil)
827+
if err == nil {
828+
t.Fatal("Expected error for snippet")
829+
}
830+
if !strings.Contains(err.Error(), "snippet") {
831+
t.Errorf("Error = %q, want to mention snippet", err.Error())
832+
}
833+
}
834+
835+
func TestSetLayout_NoFormCall_Error(t *testing.T) {
836+
page := bson.D{
837+
{Key: "$ID", Value: primitive.Binary{Subtype: 0x04, Data: make([]byte, 16)}},
838+
{Key: "$Type", Value: "Pages$Page"},
839+
}
840+
m := makePageMutator(page)
841+
842+
err := m.SetLayout("MyModule.NewLayout", nil)
843+
if err == nil {
844+
t.Fatal("Expected error for missing FormCall")
845+
}
846+
}
847+
848+
func TestSetLayout_EmptyForm_Error(t *testing.T) {
849+
page := bson.D{
850+
{Key: "FormCall", Value: bson.D{
851+
{Key: "Form", Value: ""},
852+
{Key: "Arguments", Value: bson.A{int32(3)}},
853+
}},
854+
}
855+
m := makePageMutator(page)
856+
857+
err := m.SetLayout("MyModule.NewLayout", nil)
858+
if err == nil {
859+
t.Fatal("Expected error when current layout cannot be determined")
860+
}
861+
}

0 commit comments

Comments
 (0)