diff --git a/internal/osbuild2/result.go b/internal/osbuild2/result.go index ba95055f7..c9926f08c 100644 --- a/internal/osbuild2/result.go +++ b/internal/osbuild2/result.go @@ -14,6 +14,32 @@ type StageResult struct { Error string `json:"string,omitempty"` } +// UnmarshalJSON decodes json-encoded StageResult. +// +// This method is here only as a workaround for the default value of the +// success field, see the comment inside the method. +func (sr *StageResult) UnmarshalJSON(data []byte) error { + // Create a StageResult-like object with the Success value set to true + // before json.Unmarshal is called. If the success field isn't in the + // input JSON, the json decoder will not touch it and thus it will still + // be true. + // + // The type alias is needed to prevent recursive calls of this method. + type stageResultAlias StageResult + stageResultDefault := stageResultAlias{ + Success: true, + } + + err := json.Unmarshal(data, &stageResultDefault) + if err != nil { + return err + } + + *sr = StageResult(stageResultDefault) + + return nil +} + type Result struct { Type string `json:"type"` Success bool `json:"success"` diff --git a/internal/osbuild2/result_test.go b/internal/osbuild2/result_test.go index d0a454639..c49fde8bb 100644 --- a/internal/osbuild2/result_test.go +++ b/internal/osbuild2/result_test.go @@ -1 +1,28 @@ package osbuild2 + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStageResult_UnmarshalJSON(t *testing.T) { + cases := []struct { + input string + success bool + }{ + {input: `{}`, success: true}, + {input: `{"success": true}`, success: true}, + {input: `{"success": false}`, success: false}, + } + + for _, c := range cases { + t.Run(c.input, func(t *testing.T) { + var result StageResult + err := json.Unmarshal([]byte(c.input), &result) + assert.NoError(t, err) + assert.Equal(t, c.success, result.Success) + }) + } +}