diff --git a/templates/go/custom/model_oneof_test.mustache b/templates/go/custom/model_oneof_test.mustache new file mode 100644 index 0000000..068d98e --- /dev/null +++ b/templates/go/custom/model_oneof_test.mustache @@ -0,0 +1,61 @@ +{{! NOTE: This is a custom STACKIT template which is not present in upsteam to support testing of oneOf models}} + + +{{! tests only the adjusted cases in the Generator of UnmarshalJSON}} +{{#useOneOfDiscriminatorLookup}} +{{^discriminator}} +// isOneOf + +{{#composedSchemas.oneOf}} +{{#-first}} +func Test{{{classname}}}_UnmarshalJSON(t *testing.T) { + type args struct { + src []byte + } + tests := []struct { + name string + args args + wantErr bool + }{ +{{/-first}} + {{#allowableValues.values}} + { + name: "success - {{dataType}} {{.}}", + args: args{ + src: []byte(`"{{.}}"`), + }, + wantErr: false, + }, + {{/allowableValues.values}} + {{^allowableValues.values}}{{^isModel}} + { + name: "success - {{dataType}} {{example}}", + args: args{ + src: []byte(`"{{example}}"`), + }, + wantErr: false, + }, + {{/isModel}}{{/allowableValues.values}} +{{#-last}} + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + v := &{{{classname}}}{} + if err := v.UnmarshalJSON(tt.args.src); (err != nil) != tt.wantErr { + t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr) + } + marshalJson, err := v.MarshalJSON() + if err != nil { + t.Fatalf("failed marshalling {{classname}}: %v", err) + } + if string(marshalJson) != string(tt.args.src) { + t.Fatalf("wanted %s, get %s", tt.args.src, marshalJson) + } + }) + } +} +{{/-last}} +{{/composedSchemas.oneOf}} + +{{/discriminator}} +{{/useOneOfDiscriminatorLookup}} \ No newline at end of file diff --git a/templates/go/custom/model_test.mustache b/templates/go/custom/model_test.mustache index 65e6577..7a4ee37 100644 --- a/templates/go/custom/model_test.mustache +++ b/templates/go/custom/model_test.mustache @@ -12,6 +12,9 @@ import ( {{#model}} {{^isEnum}} +{{#oneOf}} +{{#-first}}{{>custom/model_oneof_test}}{{/-first}} +{{/oneOf}} {{^oneOf}}{{^anyOf}} {{>custom/model_simple_test}} {{/anyOf}}{{/oneOf}} diff --git a/templates/go/model_oneof.mustache b/templates/go/model_oneof.mustache index 649b03d..a3474f9 100644 --- a/templates/go/model_oneof.mustache +++ b/templates/go/model_oneof.mustache @@ -54,21 +54,34 @@ func (dst *{{classname}}) UnmarshalJSON(data []byte) error { {{/discriminator}} {{^discriminator}} match := 0 - {{#oneOf}} + {{! BEGIN - Workaround in case oneOf contains enums and strings. The enum value would match with both. }} + {{! This workaround adds a regex check for the string (in case the api spec provides a regex) }} + // Workaround until upstream issue is fixed: + // https://github.com/OpenAPITools/openapi-generator/issues/21751 + // Tracking issue on our side: https://jira.schwarz/browse/STACKITSDK-226 + {{#composedSchemas.oneOf}} + {{#dataType}} // try to unmarshal data into {{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} - err = json.Unmarshal(data, &dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) + dst{{classname}}{{-index}} := &{{classname}}{} + err = json.Unmarshal(data, &dst{{classname}}{{-index}}.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) if err == nil { - json{{{.}}}, _ := json.Marshal(dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) - if string(json{{{.}}}) == "{}" { // empty struct - dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil - } else { + json{{{.}}}, _ := json.Marshal(&dst{{classname}}{{-index}}.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}}) + {{#pattern}} + regex := `{{.}}` + regex = regexp.MustCompile("^\\/|\\/$").ReplaceAllString(regex, "$1") // Remove beginning slash and ending slash + regex = regexp.MustCompile("\\\\(.)").ReplaceAllString(regex, "$1") // Remove duplicate escaping char for dots + rawString := regexp.MustCompile(`^"|"$`).ReplaceAllString(*dst{{classname}}{{-index}}.{{#lambda.type-to-name}}{{dataType}}{{/lambda.type-to-name}}, "$1") // Remove quotes + isMatched, _ := regexp.MatchString(regex, rawString) + {{/pattern}} + if string(json{{{.}}}) != "{}" {{#pattern}}&& isMatched {{/pattern}} { // empty struct + dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = dst{{classname}}{{-index}}.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} match++ } - } else { - dst.{{#lambda.type-to-name}}{{{.}}}{{/lambda.type-to-name}} = nil } - {{/oneOf}} + {{/dataType}} + {{/composedSchemas.oneOf}} + {{! END - Workaround in case oneOf contains enums and strings. The enum value would match with both. }} if match > 1 { // more than 1 match // reset to nil {{#oneOf}}