@@ -88,6 +88,70 @@ func TestChangesets_WithJSON_EmptyInput(t *testing.T) {
8888 require .Nil (t , configs .InputChainOverrides ) // Chain overrides should be nil when input is missing
8989}
9090
91+ func TestChangesets_WithJSON_StrictPayloadUnmarshaling (t * testing.T ) {
92+ t .Parallel ()
93+
94+ type TestConfig struct {
95+ Value string `json:"value"`
96+ Count int `json:"count"`
97+ }
98+
99+ tests := []struct {
100+ name string
101+ inputJSON string
102+ expectError bool
103+ errorMsg string
104+ }{
105+ {
106+ name : "valid payload with only known fields" ,
107+ inputJSON : `{"payload":{"value":"test","count":42}}` ,
108+ expectError : false ,
109+ },
110+ {
111+ name : "invalid payload with unknown field" ,
112+ inputJSON : `{"payload":{"value":"test","count":42,"unknownField":"value"}}` ,
113+ expectError : true ,
114+ errorMsg : "failed to unmarshal payload: json: unknown field \" unknownField\" " ,
115+ },
116+ {
117+ name : "invalid payload with multiple unknown fields" ,
118+ inputJSON : `{"payload":{"value":"test","count":42,"unknownField1":"value1","unknownField2":"value2"}}` ,
119+ expectError : true ,
120+ errorMsg : "failed to unmarshal payload: json: unknown field \" unknownField1\" " ,
121+ },
122+ {
123+ name : "invalid payload with nested unknown field" ,
124+ inputJSON : `{"payload":{"value":"test","count":42,"nested":{"unknown":"field"}}}` ,
125+ expectError : true ,
126+ errorMsg : "failed to unmarshal payload: json: unknown field \" nested\" " ,
127+ },
128+ }
129+
130+ for _ , tt := range tests {
131+ t .Run (tt .name , func (t * testing.T ) {
132+ t .Parallel ()
133+
134+ cs := deployment .CreateChangeSet (
135+ func (e deployment.Environment , config TestConfig ) (deployment.ChangesetOutput , error ) {
136+ return deployment.ChangesetOutput {}, nil
137+ },
138+ func (e deployment.Environment , config TestConfig ) error { return nil },
139+ )
140+ env := deployment.Environment {Logger : logger .Test (t )}
141+ configured := Configure (cs ).WithJSON (TestConfig {}, tt .inputJSON )
142+
143+ _ , err := configured .Apply (env )
144+
145+ if tt .expectError {
146+ require .Error (t , err , "Expected error for test case: %s" , tt .name )
147+ require .ErrorContains (t , err , tt .errorMsg , "Error message should contain expected text" )
148+ } else {
149+ require .NoError (t , err , "Expected no error for test case: %s" , tt .name )
150+ }
151+ })
152+ }
153+ }
154+
91155func TestChangesets_WithEnvInput (t * testing.T ) {
92156 expectedConfig := "config from env"
93157 t .Setenv ("DURABLE_PIPELINE_INPUT" , `{"payload":"` + expectedConfig + `"}` )
@@ -500,6 +564,138 @@ func TestWithConfigResolver_ChainOverrides(t *testing.T) {
500564 assert .Equal (t , []uint64 {10 , 20 , 30 }, configs .InputChainOverrides )
501565}
502566
567+ func TestWithConfigResolver_StrictPayloadUnmarshaling (t * testing.T ) {
568+ type TestInput struct {
569+ Value string `json:"value"`
570+ Count int `json:"count"`
571+ }
572+
573+ type TestOutput struct {
574+ Result string
575+ }
576+
577+ resolver := func (input TestInput ) (TestOutput , error ) {
578+ return TestOutput {Result : fmt .Sprintf ("%s_%d" , input .Value , input .Count )}, nil
579+ }
580+
581+ tests := []struct {
582+ name string
583+ inputJSON string
584+ expectError bool
585+ errorMsg string
586+ }{
587+ {
588+ name : "valid payload with only known fields" ,
589+ inputJSON : `{"payload":{"value":"test","count":42}}` ,
590+ expectError : false ,
591+ },
592+ {
593+ name : "invalid payload with unknown field" ,
594+ inputJSON : `{"payload":{"value":"test","count":42,"unknownField":"value"}}` ,
595+ expectError : true ,
596+ errorMsg : "config resolver failed: unmarshal payload into changeset.TestInput: json: unknown field \" unknownField\" " ,
597+ },
598+ {
599+ name : "invalid payload with multiple unknown fields" ,
600+ inputJSON : `{"payload":{"value":"test","count":42,"unknownField1":"value1","unknownField2":"value2"}}` ,
601+ expectError : true ,
602+ errorMsg : "config resolver failed: unmarshal payload into changeset.TestInput: json: unknown field \" unknownField1\" " ,
603+ },
604+ {
605+ name : "invalid payload with nested unknown field" ,
606+ inputJSON : `{"payload":{"value":"test","count":42,"nested":{"unknown":"field"}}}` ,
607+ expectError : true ,
608+ errorMsg : "config resolver failed: unmarshal payload into changeset.TestInput: json: unknown field \" nested\" " ,
609+ },
610+ }
611+
612+ for _ , tt := range tests {
613+ t .Run (tt .name , func (t * testing.T ) {
614+ t .Setenv ("DURABLE_PIPELINE_INPUT" , tt .inputJSON )
615+
616+ cs := deployment .CreateChangeSet (
617+ func (e deployment.Environment , config TestOutput ) (deployment.ChangesetOutput , error ) {
618+ return deployment.ChangesetOutput {}, nil
619+ },
620+ func (e deployment.Environment , config TestOutput ) error { return nil },
621+ )
622+ env := deployment.Environment {Logger : logger .Test (t )}
623+ configured := Configure (cs ).WithConfigResolver (resolver )
624+
625+ _ , err := configured .Apply (env )
626+
627+ if tt .expectError {
628+ require .Error (t , err , "Expected error for test case: %s" , tt .name )
629+ require .ErrorContains (t , err , tt .errorMsg , "Error message should contain expected text" )
630+ } else {
631+ require .NoError (t , err , "Expected no error for test case: %s" , tt .name )
632+ }
633+ })
634+ }
635+ }
636+
637+ func TestWithEnvInput_StrictPayloadUnmarshaling (t * testing.T ) {
638+ type TestConfig struct {
639+ Value string `json:"value"`
640+ Count int `json:"count"`
641+ }
642+
643+ tests := []struct {
644+ name string
645+ inputJSON string
646+ expectError bool
647+ errorMsg string
648+ }{
649+ {
650+ name : "valid payload with only known fields" ,
651+ inputJSON : `{"payload":{"value":"test","count":42}}` ,
652+ expectError : false ,
653+ },
654+ {
655+ name : "invalid payload with unknown field" ,
656+ inputJSON : `{"payload":{"value":"test","count":42,"unknownField":"value"}}` ,
657+ expectError : true ,
658+ errorMsg : "failed to unmarshal payload: json: unknown field \" unknownField\" " ,
659+ },
660+ {
661+ name : "invalid payload with multiple unknown fields" ,
662+ inputJSON : `{"payload":{"value":"test","count":42,"unknownField1":"value1","unknownField2":"value2"}}` ,
663+ expectError : true ,
664+ errorMsg : "failed to unmarshal payload: json: unknown field \" unknownField1\" " ,
665+ },
666+ {
667+ name : "invalid payload with nested unknown field" ,
668+ inputJSON : `{"payload":{"value":"test","count":42,"nested":{"unknown":"field"}}}` ,
669+ expectError : true ,
670+ errorMsg : "failed to unmarshal payload: json: unknown field \" nested\" " ,
671+ },
672+ }
673+
674+ for _ , tt := range tests {
675+ t .Run (tt .name , func (t * testing.T ) {
676+ t .Setenv ("DURABLE_PIPELINE_INPUT" , tt .inputJSON )
677+
678+ cs := deployment .CreateChangeSet (
679+ func (e deployment.Environment , config TestConfig ) (deployment.ChangesetOutput , error ) {
680+ return deployment.ChangesetOutput {}, nil
681+ },
682+ func (e deployment.Environment , config TestConfig ) error { return nil },
683+ )
684+ env := deployment.Environment {Logger : logger .Test (t )}
685+ configured := Configure (cs ).WithEnvInput ()
686+
687+ _ , err := configured .Apply (env )
688+
689+ if tt .expectError {
690+ require .Error (t , err , "Expected error for test case: %s" , tt .name )
691+ require .ErrorContains (t , err , tt .errorMsg , "Error message should contain expected text" )
692+ } else {
693+ require .NoError (t , err , "Expected no error for test case: %s" , tt .name )
694+ }
695+ })
696+ }
697+ }
698+
503699func TestConfigurations_ConfigResolverInfo (t * testing.T ) {
504700 t .Parallel ()
505701
0 commit comments