Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] [ExampleGenerator] Generated examples from Composed schema types are null (allOf, oneOf, anyOf...) #17497

Closed
5 of 6 tasks
acouvreur opened this issue Dec 29, 2023 · 0 comments · Fixed by #17499
Closed
5 of 6 tasks

Comments

@acouvreur
Copy link
Contributor

acouvreur commented Dec 29, 2023

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When generating an example for a model defined as a composite schema, such as:

Current (undesired) behavior:

Consider the following schema:

components:
  schemas:
    ExampleSchema:
      type: object
      properties:
        example_schema_property:
          type: string
          example: example schema property value
    ExampleComposedSchema:
      type: object
      allOf:
        - $ref: '#/components/schemas/ExampleSchema'
        - type: object
          properties:
            example_schema_property_composed:
              type: string
              example: example schema property value composed

I'd expect the generated example to look like:

{
  "example_schema_property": "example schema property value",
  "example_schema_property_composed": "example schema property value composed"
}

However, it currently generates the following:

null

Why is this behavior happening?

It's because only examples and properties are being supported right now:

if (schema.getExample() != null) {
LOGGER.debug("Using example from spec: {}", schema.getExample());
return schema.getExample();
} else if (schema.getProperties() != null) {
LOGGER.debug("Creating example from model values");
for (Object propertyName : schema.getProperties().keySet()) {
Schema property = (Schema) schema.getProperties().get(propertyName.toString());
values.put(propertyName.toString(), resolvePropertyToExample(propertyName.toString(), mediaType, property, processedModels));
}
schema.setExample(values);
return schema.getExample();
} else {
// TODO log an error message as the model does not have any properties
return null;
}

The message

// TODO log an error message as the model does not have any properties 

is wrong because composed schema may exist.

openapi-generator version

master a5d3fb4

OpenAPI declaration file content or url
openapi: 3.0.2
info:
  version: 1.0.0
  title: OpenAPI Petstore
  license:
    name: Apache-2.0
paths:
  /generate_from_response_schema_with_composed_model:
    get:
      operationId: generateFromResponseSchemaWithComposedModel
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExampleComposedSchema'
components:
  schemas:
    ExampleSchema:
      type: object
      properties:
        example_schema_property:
          type: string
          example: example schema property value
    ExampleComposedSchema:
      type: object
      allOf:
        - $ref: '#/components/schemas/ExampleSchema'
        - type: object
          properties:
            example_schema_property_composed:
              type: string
              example: example schema property value composed
Generation Details

Run ExampleGeneratorTest.java

Steps to reproduce

Apply to following patch:

Subject: [PATCH] Add failing test case to ExampleGenerator for composed schema
---
Index: modules/openapi-generator/src/test/resources/3_0/example_generator_test.yaml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/modules/openapi-generator/src/test/resources/3_0/example_generator_test.yaml b/modules/openapi-generator/src/test/resources/3_0/example_generator_test.yaml
--- a/modules/openapi-generator/src/test/resources/3_0/example_generator_test.yaml	(revision a5d3fb4f601e4bced19f39cb6d82799a71531282)
+++ b/modules/openapi-generator/src/test/resources/3_0/example_generator_test.yaml	(date 1703875535793)
@@ -53,7 +53,7 @@
                   example: primitive types example value
   /generate_from_response_schema_with_model:
     get:
-      operationId: generateFromResponseSchemaWithArrayOfPrimitiveTypes
+      operationId: generateFromResponseSchemaWithModel
       responses:
         '200':
           description: successful operation
@@ -61,6 +61,16 @@
             application/json:
               schema:
                 $ref: '#/components/schemas/ExampleSchema'
+  /generate_from_response_schema_with_composed_model:
+    get:
+      operationId: generateFromResponseSchemaWithComposedModel
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ExampleComposedSchema'
 components:
   schemas:
     StringSchema:
@@ -72,3 +82,12 @@
         example_schema_property:
           type: string
           example: example schema property value
+    ExampleComposedSchema:
+      type: object
+      allOf:
+        - $ref: '#/components/schemas/ExampleSchema'
+        - type: object
+          properties:
+            example_schema_property_composed:
+              type: string
+              example: example schema property value composed
Index: modules/openapi-generator/src/test/java/org/openapitools/codegen/ExampleGeneratorTest.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/ExampleGeneratorTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/ExampleGeneratorTest.java
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/ExampleGeneratorTest.java	(revision a5d3fb4f601e4bced19f39cb6d82799a71531282)
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/ExampleGeneratorTest.java	(date 1703875564840)
@@ -146,6 +146,35 @@
                 mediaTypeKeys
         );
 
+        assertEquals(1, examples.size());
+        assertEquals("application/json", examples.get(0).get("contentType"));
+        assertEquals(String.format(Locale.ROOT, "{%n  \"example_schema_property\" : \"example schema property value\"%n}"), examples.get(0).get("example"));
+        assertEquals("200", examples.get(0).get("statusCode"));
+    }
+
+    @Test
+    public void generateFromResponseSchemaWithComposedModel() {
+        OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/example_generator_test.yaml");
+
+        new InlineModelResolver().flatten(openAPI);
+
+        ExampleGenerator exampleGenerator = new ExampleGenerator(openAPI.getComponents().getSchemas(), openAPI);
+        Set<String> mediaTypeKeys = new TreeSet<>();
+        mediaTypeKeys.add("application/json");
+        List<Map<String, String>> examples = exampleGenerator.generateFromResponseSchema(
+                "200",
+                openAPI
+                        .getPaths()
+                        .get("/generate_from_response_schema_with_composed_model")
+                        .getGet()
+                        .getResponses()
+                        .get("200")
+                        .getContent()
+                        .get("application/json")
+                        .getSchema(),
+                mediaTypeKeys
+        );
+
         assertEquals(1, examples.size());
         assertEquals("application/json", examples.get(0).get("contentType"));
         assertEquals(String.format(Locale.ROOT, "{%n  \"example_schema_property\" : \"example schema property value\"%n}"), examples.get(0).get("example"));
Related issues/PRs
Suggest a fix

Will open a PR soon

acouvreur added a commit to acouvreur/openapi-generator that referenced this issue Jan 5, 2024
Changes the previous behavior of generating `null` examples for allOf composed schemas.

Fixes OpenAPITools#17497
acouvreur added a commit to acouvreur/openapi-generator that referenced this issue Jan 5, 2024
…hemas

Changes the previous behavior of generating `null` examples for anyOf and oneOf composed schemas.

To generate a oneOf/anyOf example, we generate the example using the first valid schema available. In case of a $ref, we use the first valid reference.

Fixes OpenAPITools#17497
acouvreur added a commit to acouvreur/openapi-generator that referenced this issue Jan 5, 2024
Changes the previous behavior of generating `null` examples for allOf composed schemas.

Fixes OpenAPITools#17497
acouvreur added a commit to acouvreur/openapi-generator that referenced this issue Jan 6, 2024
…hemas

Changes the previous behavior of generating `null` examples for anyOf and oneOf composed schemas.

To generate a oneOf/anyOf example, we generate the example using the first valid schema available. In case of a $ref, we use the first valid reference.

Fixes OpenAPITools#17497
wing328 pushed a commit that referenced this issue Jan 10, 2024
)

* fix: ExampleGenerator correctly generates allOf composed schemas

Changes the previous behavior of generating `null` examples for allOf composed schemas.

Fixes #17497

* fix: ExampleGenerator correctly generates anyOf and oneOf composed schemas

Changes the previous behavior of generating `null` examples for anyOf and oneOf composed schemas.

To generate a oneOf/anyOf example, we generate the example using the first valid schema available. In case of a $ref, we use the first valid reference.

Fixes #17497
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant