Repository: getkin/kin-openapi
Pull request #1067 (2025-04-28 10:49:50)

openapi2conv: fix for refs on items within additional properties
This PR addresses the issue mentioned in #1049


Patch:
diff --git a/openapi2conv/openapi2_conv.go b/openapi2conv/openapi2_conv.go
index 8aa4525..c32d1a6 100644
--- a/openapi2conv/openapi2_conv.go
+++ b/openapi2conv/openapi2_conv.go
@@ -563,6 +563,9 @@ func convertRefsInV3SchemaRef(from *openapi3.SchemaRef) *openapi3.SchemaRef {
 	if to.Value != nil {
 		v := *from.Value
 		to.Value = &v
+		if to.Value.Items != nil {
+			to.Value.Items.Ref = ToV3Ref(to.Value.Items.Ref)
+		}
 		to.Value.AdditionalProperties = toV3AdditionalProperties(to.Value.AdditionalProperties)
 	}
 	return &to


Test patch:
diff --git a/openapi2conv/issue1049_test.go b/openapi2conv/issue1049_test.go
new file mode 100644
index 0000000..04ddf85
--- /dev/null
+++ b/openapi2conv/issue1049_test.go
@@ -0,0 +1,86 @@
+package openapi2conv
+
+import (
+	"context"
+	"encoding/json"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestIssue1049(t *testing.T) {
+	spec := `
+{
+  "swagger": "2.0",
+  "info": {
+    "description": "Test for additionalProperties",
+    "version": "v1",
+    "title": "API Test"
+  },
+  "host": "Test",
+  "paths": {
+    "/map": {
+      "post": {
+        "summary": "api test summary",
+        "description": "api test description",
+        "operationId": "apiTestUsingPOST",
+        "consumes": ["application/json"],
+        "produces": ["*/*"],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "schema": {
+              "$ref": "#/definitions/ResponseOfMap"
+            }
+          }
+        }
+      }
+    }
+  },
+  "definitions": {
+    "BaseDictResp": {
+      "type": "object",
+      "properties": {
+        "key": {
+          "type": "string",
+          "description": "key of map"
+        },
+        "value": {
+          "type": "string",
+          "description": "value of map"
+        }
+      },
+      "title": "BaseDictResp",
+      "description": "BaseDictResp description"
+    },
+
+    "ResponseOfMap": {
+      "type": "object",
+      "properties": {
+        "data": {
+          "type": "object",
+          "description": "response data",
+          "additionalProperties": {
+            "type": "array",
+            "items": {
+              "$ref": "#/definitions/BaseDictResp"
+            }
+          }
+        }
+      },
+      "title": "ResponseOfMap"
+    }
+  }
+}
+`
+	doc3, err := v2v3JSON([]byte(spec))
+	require.NoError(t, err)
+
+	spec3, err := json.Marshal(doc3)
+	require.NoError(t, err)
+	const expected = `{"components":{"schemas":{"BaseDictResp":{"description":"BaseDictResp description","properties":{"key":{"description":"key of map","type":"string"},"value":{"description":"value of map","type":"string"}},"title":"BaseDictResp","type":"object"},"ResponseOfMap":{"properties":{"data":{"additionalProperties":{"items":{"$ref":"#/components/schemas/BaseDictResp"},"type":"array"},"description":"response data","type":"object"}},"title":"ResponseOfMap","type":"object"}}},"info":{"description":"Test for additionalProperties","title":"API Test","version":"v1"},"openapi":"3.0.3","paths":{"/map":{"post":{"description":"api test description","operationId":"apiTestUsingPOST","responses":{"200":{"content":{"*/*":{"schema":{"$ref":"#/components/schemas/ResponseOfMap"}}},"description":"OK"}},"summary":"api test summary"}}},"servers":[{"url":"https://Test/"}]}`
+	require.JSONEq(t, expected, string(spec3))
+
+	err = doc3.Validate(context.Background())
+	require.NoError(t, err)
+}