package actions import ( "fmt" "testing" "github.com/dop251/goja" "github.com/zitadel/zitadel/internal/logstore" "github.com/zitadel/zitadel/internal/logstore/record" ) func TestSetFields(t *testing.T) { SetLogstoreService(logstore.New[*record.ExecutionLog](nil, nil)) primitveFn := func(a string) { fmt.Println(a) } complexFn := func(*FieldConfig) interface{} { return primitveFn } tests := []struct { name string setFields FieldOption want fields shouldPanic bool }{ { name: "field is simple value", setFields: SetFields("value", 5), want: fields{ "value": 5, }, }, { name: "field is method", setFields: SetFields("value", primitveFn), want: fields{ "value": primitveFn, }, }, { name: "field is complex method", setFields: SetFields("value", complexFn), want: fields{ "value": primitveFn, }, }, { name: "field without value", setFields: SetFields("value"), want: fields{}, }, { name: "field with empty value", setFields: SetFields("value", ""), want: fields{ "value": "", }, }, { name: "nested simple value", setFields: SetFields( "field", SetFields("sub", 5), ), want: fields{ "field": fields{ "sub": 5, }, }, }, { name: "nested multiple fields", setFields: SetFields( "field", SetFields("sub1", 5), SetFields("sub2", "asdf"), SetFields("sub3", primitveFn), ), want: fields{ "field": fields{ "sub1": 5, "sub2": "asdf", "sub3": primitveFn, }, }, }, { name: "try to overwrite field primitives", setFields: SetFields( "field", SetFields("sub", 5), SetFields("sub", primitveFn), ), shouldPanic: true, }, { name: "try to overwrite primitives with fields", setFields: SetFields( "field", SetFields("sub", 5), SetFields("sub", SetFields("please", "panic")), ), shouldPanic: true, }, { name: "try to overwrite fields with primitive", setFields: SetFields( "field", SetFields("sub", SetFields("please", "panic")), SetFields("sub", 5), ), shouldPanic: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { panicked := false if tt.shouldPanic { defer func() { if panicked != tt.shouldPanic { t.Errorf("wanted panic: %v got %v", tt.shouldPanic, panicked) } }() defer func() { recover() panicked = true }() } config := &FieldConfig{ Runtime: goja.New(), fields: fields{}, } tt.setFields(config) if !tt.shouldPanic && fmt.Sprint(config.fields) != fmt.Sprint(tt.want) { t.Errorf("SetFields() = %v, want %v", fmt.Sprint(config.fields), fmt.Sprint(tt.want)) } }) } } func TestSetFieldsExecuteMethods(t *testing.T) { primitveFn := func(a string) { fmt.Println(a) } complexFn := func(*FieldConfig) interface{} { return primitveFn } tests := []struct { name string setFields FieldOption want fields shouldPanic bool }{ { name: "field is method", setFields: SetFields("value", primitveFn), want: fields{ "value": primitveFn, }, }, { name: "field is complex method", setFields: SetFields("value", complexFn), want: fields{ "value": primitveFn, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { panicked := false if tt.shouldPanic { defer func() { if panicked != tt.shouldPanic { t.Errorf("wanted panic: %v got %v", tt.shouldPanic, panicked) } }() defer func() { recover() panicked = true }() } config := &FieldConfig{ Runtime: goja.New(), fields: fields{}, } tt.setFields(config) if !tt.shouldPanic && fmt.Sprint(config.fields) != fmt.Sprint(tt.want) { t.Errorf("SetFields() = %v, want %v", fmt.Sprint(config.fields), fmt.Sprint(tt.want)) } }) } }