prance icon indicating copy to clipboard operation
prance copied to clipboard

References in discriminator mappings are not being expanded

Open sidekick-eimantas opened this issue 2 years ago • 2 comments

Expected Behaviour

Discriminator mapping references should be expanded https://swagger.io/specification/#discriminator-object

Minimal Example Spec

openapi: 3.0.2
info:
  title: Test
  version: 1.0.1

paths:
  /Test:
    post:
      responses:
        '200':
          description: Successful Response

components:
  schemas:
    UpdateSuitabilityAssessmentRequest:
      properties:
        answers:
          items:
            discriminator:
              propertyName: type
              mapping:
                MULTI_CHOICE: '#/components/schemas/UpdateSuitabilityAssessmentRequestMultiChoiceAnswer'
                SINGLE_CHOICE: '#/components/schemas/UpdateSuitabilityAssessmentRequestSingleChoiceAnswer'
            oneOf:
            - $ref: '#/components/schemas/UpdateSuitabilityAssessmentRequestSingleChoiceAnswer'
            - $ref: '#/components/schemas/UpdateSuitabilityAssessmentRequestMultiChoiceAnswer'

    UpdateSuitabilityAssessmentRequestMultiChoiceAnswer:
      properties:
        type:
          enum:
          - MULTI_CHOICE

    UpdateSuitabilityAssessmentRequestSingleChoiceAnswer:
      properties:
        type:
          enum:
          - SINGLE_CHOICE

Actual Behaviour

Discriminator mapping references (MULTI_CHOICE, SINGLE_CHOICE) are not expanded

{
    "openapi": "3.0.2",
    "info": {
        "title": "Test",
        "version": "1.0.1"
    },
    "paths": {
        "/Test": {
            "post": {
                "responses": {
                    "200": {
                        "description": "Successful Response"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "UpdateSuitabilityAssessmentRequest": {
                "discriminator": {
                    "propertyName": "type",
                    "mapping": {
                        "MULTI_CHOICE": "#/components/schemas/UpdateSuitabilityAssessmentRequestMultiChoiceAnswer",
                        "SINGLE_CHOICE": "#/components/schemas/UpdateSuitabilityAssessmentRequestSingleChoiceAnswer"
                    }
                },
                "oneOf": [
                    {
                        "properties": {
                            "type": {
                                "enum": [
                                    "SINGLE_CHOICE"
                                ]
                            }
                        }
                    },
                    {
                        "properties": {
                            "type": {
                                "enum": [
                                    "MULTI_CHOICE"
                                ]
                            }
                        }
                    }
                ]
            },
            "UpdateSuitabilityAssessmentRequestMultiChoiceAnswer": {
                "properties": {
                    "type": {
                        "enum": [
                            "MULTI_CHOICE"
                        ]
                    }
                }
            },
            "UpdateSuitabilityAssessmentRequestSingleChoiceAnswer": {
                "properties": {
                    "type": {
                        "enum": [
                            "SINGLE_CHOICE"
                        ]
                    }
                }
            }
        }
    }
}

Steps to Reproduce

import prance

resolver = prance.ResolvingParser(
    "openapi.yml",
    spec_string=None,
    backend="openapi-spec-validator",
    strict=False
)

Environment

  • OS: macos 13.4.1
  • Python version: 3.10.7
  • Swagger/OpenAPI version used: 3.0.2
  • Backend: openapi-spec-validator

sidekick-eimantas avatar Aug 03 '23 17:08 sidekick-eimantas

I modified prance/util/iterators.py reference_iterator by appending the following lines of code:

        if len(item_path) >= 3 and item_path[-3] == "discriminator" and item_path[-2] == "mapping":
            yield key, item, item_path

Which has produced a correct expanded schema:

{'openapi': '3.0.2', 'info': {'title': 'Test', 'version': '1.0.1'}, 'paths': {'/Test': {'post': {'responses': {'200': {'description': 'Successful Response'}}}}}, 'components': {'schemas': {'UpdateSuitabilityAssessmentRequest': {'properties': {'answers': {'items': {'discriminator': {'propertyName': 'type', 'mapping': {'MULTI_CHOICE': {'properties': {'type': {'enum': ['MULTI_CHOICE']}}}, 'SINGLE_CHOICE': {'properties': {'type': {'enum': ['SINGLE_CHOICE']}}}}}, 'oneOf': [{'properties': {'type': {'enum': ['SINGLE_CHOICE']}}}, {'properties': {'type': {'enum': ['MULTI_CHOICE']}}}]}}}}, 'UpdateSuitabilityAssessmentRequestMultiChoiceAnswer': {'properties': {'type': {'enum': ['MULTI_CHOICE']}}}, 'UpdateSuitabilityAssessmentRequestSingleChoiceAnswer': {'properties': {'type': {'enum': ['SINGLE_CHOICE']}}}}}}

However, validation is failing:

openapi_spec_validator.validation.exceptions.OpenAPIValidationError: {'properties': {'answers': {'items': {'discriminator': {'propertyName': 'type', 'mapping': {'MULTI_CHOICE': {'properties': {'type': {'enum': ['SINGLE_CHOICE']}}}, 'SINGLE_CHOICE': {'properties': {'type': {'enum': ['MULTI_CHOICE']}}}}}, 'oneOf': [{'properties': {'type': {'enum': ['SINGLE_CHOICE']}}}, {'properties': {'type': {'enum': ['MULTI_CHOICE']}}}]}}}} is not valid under any of the given schemas

Failed validating 'oneOf' in schema['properties']['components']['properties']['schemas']['patternProperties']['^[a-zA-Z0-9\\.\\-_]+$']:
    {'oneOf': [{'$ref': '#/definitions/Schema'},
               {'$ref': '#/definitions/Reference'}]}

On instance['components']['schemas']['UpdateSuitabilityAssessmentRequest']:
    {'properties': {'answers': {'items': {'discriminator': {'mapping': {'MULTI_CHOICE': {'properties': {'type': {'enum': ['SINGLE_CHOICE']}}},
                                                                        'SINGLE_CHOICE': {'properties': {'type': {'enum': ['MULTI_CHOICE']}}}},
                                                            'propertyName': 'type'},
                                          'oneOf': [{'properties': {'type': {'enum': ['SINGLE_CHOICE']}}},
                                                    {'properties': {'type': {'enum': ['MULTI_CHOICE']}}}]}}}}

Sounds like according to the spec, discriminator mapping refs cannot be expanded?

sidekick-eimantas avatar Aug 03 '23 18:08 sidekick-eimantas