swagger-api / swagger-api/swagger-parser

OpenAPIV3Parser setting null instead of parsing default enum values

Open
#1,454 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
867
Forks
560
Avg merge
2d 21h
Merged PRs (30d)
7

Description

Hi,

I've discovered what seems to be an issue when OpenAPIV3Parser parses specifications containing default values for enum types.

When io.swagger.v3.parser.OpenAPIV3Parser#read(java.lang.String) parses default values for enums, the returned OpenAPI model schemas contain null instead of default values. This applies for both defaults set in enums themselves or inside schemas referencing the enums. The same specification that exposes this issue is valid and properly shows defaults inside Swagger Editor. This seems to be in line with Schema Object in the OpenAPI specification.

I'm providing a test class with unit tests that confirm my claims alongside an example OpenAPI specification that is used in tests and can be run inside Swagger Editor. The tests should be easy to add to your existing OpenAPIV3ParserTest. This is tested using swagger-parser versions 2.0.14 and 2.0.22.

Can you please look into this and see if my findings are correct?

Test class

The class contains various examples of setting default values for enums that do or do not set the default values themselves. Assertions are based on behavior in Swagger Editor. Ignored tests are the ones exposing the issue.

package io.swagger.v3.parser.test;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.OpenAPIV3Parser;
import org.junit.*;

import java.io.File;

import static org.assertj.core.api.BDDAssertions.then;

public class OpenAPIV3ParserTest {

    private static final String GIVEN_SPEC_PATH = "src/test/resources/openapis/openapi-default-enum-bug.json";
    private static final String GIVEN_LOCATION = new File(GIVEN_SPEC_PATH).getAbsolutePath();

    private OpenAPIV3Parser openAPIV3Parser;

    @Before
    public void setUp() {
        openAPIV3Parser = new OpenAPIV3Parser();
    }

    @Test
    public void shouldParseDefaultForEnumSchema() {
        // when
        OpenAPI openAPI = openAPIV3Parser.read(GIVEN_LOCATION);

        // then
        then(openAPI.getComponents()
                .getSchemas()
                .get("Enum")
                .getDefault()
        ).isNull();
    }

    @Test
    public void shouldParseDefaultForEnumWithDefaultSchema() {
        // when
        OpenAPI openAPI = openAPIV3Parser.read(GIVEN_LOCATION);

        // then
        then(openAPI.getComponents()
                .getSchemas()
                .get("EnumWithDefault")
                .getDefault()
        ).isEqualTo("ENUM_DEFAULT");
    }

    @Test
    public void shouldParseDefaultForSchemaWithEnum() {
        // when
        OpenAPI openAPI = openAPIV3Parser.read(GIVEN_LOCATION);

        // then
        then(openAPI.getComponents()
                .getSchemas()
                .get("SchemaWithEnum")
                .getDefault()
        ).isNull();
    }

    @Ignore("This test fails due to OpenAPIV3Parser bug.")
    @Test
    public void shouldParseDefaultForSchemaWithDefaultAndEnum() {
        // when
        OpenAPI openAPI = openAPIV3Parser.read(GIVEN_LOCATION);

        // then
        then(openAPI.getComponents()
                .getSchemas()
                .get("SchemaWithDefaultAndEnum")
                .getDefault()
        ).isEqualTo("SCHEMA_DEFAULT");
    }

    @Ignore("This test fails due to OpenAPIV3Parser bug.")
    @Test
    public void shouldParseDefaultForSchemaWithEnumWithDefault() {
        // when
        OpenAPI openAPI = openAPIV3Parser.read(GIVEN_LOCATION);

        // then
        then(openAPI.getComponents()
                .getSchemas()
                .get("SchemaWithEnumWithDefault")
                .getDefault()
        ).isEqualTo("ENUM_DEFAULT");
    }

    @Ignore("This test fails due to OpenAPIV3Parser bug.")
    @Test
    public void shouldParseDefaultForSchemaWithDefaultAndEnumWithDefault() {
        // when
        OpenAPI openAPI = openAPIV3Parser.read(GIVEN_LOCATION);

        // then
        then(openAPI.getComponents()
                .getSchemas()
                .get("SchemaWithDefaultAndEnumWithDefault")
                .getDefault()
        ).isEqualTo("SCHEMA_DEFAULT");
    }

}
Example specification

This specification is used in the test above and is named openapi-default-enum-bug.json for testing purposes.

{
  "openapi": "3.0.1",
  "info": {
    "title": "Here be enum bugs",
    "description": "OpenAPI spec to test the enum parsing bugs.",
    "version": "1.0.0"
  },
  "paths": {
    "/enum/parse/bug": {
      "post": {
        "summary": "Test enum parse bug",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestRequest"
              }
            }
          }
        },
        "responses": {
          "default": {
            "description": "Successful response"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "TestRequest": {
        "type": "object",
        "description": "This request body schema depicts various enum and default value combinations inside schemas of the following properties.",
        "properties": {
          "schemaWithEnum": {
            "$ref": "#/components/schemas/SchemaWithEnum"
          },
          "schemaWithDefaultAndEnum": {
            "$ref": "#/components/schemas/SchemaWithDefaultAndEnum"
          },
          "schemaWithEnumWithDefault": {
            "$ref": "#/components/schemas/SchemaWithEnumWithDefault"
          },
          "schemaWithDefaultAndEnumWithDefault": {
            "$ref": "#/components/schemas/SchemaWithDefaultAndEnumWithDefault"
          }
        }
      },
      "SchemaWithEnum": {
        "type": "object",
        "properties": {
          "enumProperty": {
            "description": "This schema with no default values set behaves properly in Swagger Editor and when parsed with OpenAPIV3Parser.",
            "allOf": [
              {
                "$ref": "#/components/schemas/Enum"
              }
            ]
          }
        }
      },
      "SchemaWithDefaultAndEnum": {
        "type": "object",
        "properties": {
          "enumProperty": {
            "description": "This schema with set default enum value and enum ref shows default \"SCHEMA_DEFAULT\" value in Swagger Editor, but is null when parsed with OpenAPIV3Parser.",
            "allOf": [
              {
                "$ref": "#/components/schemas/Enum"
              }
            ],
            "default": "SCHEMA_DEFAULT"
          }
        }
      },
      "SchemaWithEnumWithDefault": {
        "type": "object",
        "properties": {
          "enumProperty": {
            "description": "This schema with ref to enum with set default value shows default \"ENUM_DEFAULT\" value in Swagger Editor, but is null when parsed with OpenAPIV3Parser.",
            "allOf": [
              {
                "$ref": "#/components/schemas/EnumWithDefault"
              }
            ]
          }
        }
      },
      "SchemaWithDefaultAndEnumWithDefault": {
        "type": "object",
        "properties": {
          "enumProperty": {
            "description": "This schema with set default enum value and ref to enum with set default value shows default \"SCHEMA_DEFAULT\" value in Swagger Editor, but is null when parsed with OpenAPIV3Parser.",
            "allOf": [
              {
                "$ref": "#/components/schemas/EnumWithDefault"
              }
            ],
            "default": "SCHEMA_DEFAULT"
          }
        }
      },
      "Enum": {
        "type": "string",
        "enum": [
          "SCHEMA_DEFAULT",
          "NOT_DEFAULT"
        ]
      },
      "EnumWithDefault": {
        "type": "string",
        "enum": [
          "SCHEMA_DEFAULT",
          "ENUM_DEFAULT",
          "NOT_DEFAULT"
        ],
        "default": "ENUM_DEFAULT"
      }
    }
  }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at io.swagger.v3.parser.OpenAPIV3Parser#read(java.lang.String) and the existing OpenAPIV3ParserTest, using src/test/resources/openapis/openapi-default-enum-bug.json as the reproduction. Enable the three ignored tests and trace why defaults are lost through enum references; done means those assertions pass while the existing tests remain green.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.