kin-openapi icon indicating copy to clipboard operation
kin-openapi copied to clipboard

Response validation fails when using oneOf

Open tjdavis3 opened this issue 2 years ago • 2 comments

I'm trying to run validation tests against a spec that uses oneOf. I was getting this same error on the examples and wasn't sure what was going on, so I removed the examples. Now I'm trying to run tests against my code and am still getting the same error. The value returned in the example below matches the IngressTrunkGroup schema. I don't know if it's it's related, but both IngressTrunkGroup and EgressTrunkgroup use an allOf with properties and a BaseTrunkGroup

Error Received

        testing.go:130: response body doesn't match the schema: Doesn't match schema "oneOf"
            Schema:
              {
                "discriminator": {
                  "mapping": {
                    "egress": "EgressTrunkgroup",
                    "ingress": "IngressTrunkGroup"
                  },
                  "propertyName": "direction"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/IngressTrunkGroup"
                  },
                  {
                    "$ref": "#/components/schemas/EgressTrunkgroup"
                  }
                ],
                "type": "object"
              }
            
            Value:
              {
                "active": true,
                "cps": 6,
                "cpsBurst": 8,
                "direction": "ingress",
                "ip": "192.168.123.121",
                "limit": 300,
                "mask": 32,
                "name": "C_test_100",
                "zone": "TESTING"
              }

Schemas

        EgressTrunkgroup:
            title: Egress Trunkgroup
            description: Represents an egress trunkgroup
            type: object
            allOf:
                -
                    type: object
                    properties:
                        description:
                            description: ''
                            type: string
                        roundrobin:
                            description: Indicates if IPs should be accessed in a round-robin fashion
                            type: boolean
                        IPs:
                            description: 'IP addresses or FQDNs to use for sending calls '
                            type: array
                            items:
                                $ref: '#/components/schemas/IP'
                -
                    $ref: '#/components/schemas/BaseTrunkGroup'

        IngressTrunkGroup:
            title: Ingress Trunkgroup
            type: object
            allOf:
                -
                    required:
                        - ip
                        - mask
                    type: object
                    properties:
                        ip:
                            type: string
                            x-oapi-codegen-extra-tags:
                                validate: ip
                        mask:
                            type: integer
                            x-oapi-codegen-extra-tags:
                                validate: 'gte=1,lte=32'
                        cps:
                            description: >-
                                Maximum calls-per-second for this trunkgroup.  This is calculated based on
                                the 

                                configured call limit
                            type: integer
                            readOnly: true
                        cpsBurst:
                            description: >-
                                This is the maximum burst allowed for call-per-second.  It is calculated
                                based 

                                on the calculated `cps`.
                            type: integer
                            readOnly: true
                -
                    $ref: '#/components/schemas/BaseTrunkGroup'

        BaseTrunkGroup:
            title: Root Type for TrunkGroup
            description: ''
            required:
                - direction
                - zone
            type: object
            properties:
                zone:
                    description: The signaling zone defined in the SBC that is used for this trunkgroup
                    type: string
                name:
                    description: The generated trunkgroup name
                    pattern: '^(?P<typind>[CV])_(?P<slug>[[:alnum:]-]*)_(?P<direction>[1-2])(?P<seq>\d{2})$'
                    type: string
                    readOnly: true
                direction:
                    description: >-
                        Indicates if this trunkgroup is for call coming into the SBC (ingress) or out of the
                        SBC (egress)
                    enum:
                        - ingress
                        - egress
                    type: string
                    x-oapi-codegen-extra-tags:
                        validate: oneof=ingress egress
                limit:
                    format: int32
                    description: The number of simultaneous calls that can be handled by this trunkgroup
                    type: integer
                active:
                    description: Indicates if this trunkgroup is currently active
                    type: boolean
        IP:
            title: Root Type for IP
            description: ''
            required:
                - address
                - port
            type: object
            properties:
                address:
                    description: The IP address or FQDN
                    type: string
                    example: 192.168.1.1
                    x-oapi-codegen-extra-tags:
                        validate: fqdn|ip
                port:
                    format: int32
                    description: The port to signal to
                    minimum: 1
                    type: integer
                enabled:
                    description: Indicates if this IP is in service
                    type: boolean
            example:
                address: 192.168.210.1
                port: 5060
                enabled: true

tjdavis3 avatar Nov 03 '22 20:11 tjdavis3

I'm not sure I understand where the oneOf comes from looking at your code. Could you send a working example, maybe in the form of a test in a pull request? Thanks

fenollp avatar Dec 19 '22 16:12 fenollp

@fenollp I just realized there's another schema object that is missing from the above code, and that is the Trunkgroup, which is where the oneOf occurs:

        Trunkgroup:
            oneOf:
                -
                    $ref: '#/components/schemas/IngressTrunkGroup'
                -
                    $ref: '#/components/schemas/EgressTrunkgroup'
            discriminator:
                propertyName: direction
                mapping:
                    ingress: IngressTrunkGroup
                    egress: EgressTrunkgroup
            description: ''
            type: object

I'll see about getting a test example put together. Essentially, what I have is a Trunkgroup that can be either an IngressTrunkGroup or an EgressTrunkgroup. Both of those are made up of a BaseTrunkgroup plus some additional fields.

tjdavis3 avatar Dec 19 '22 21:12 tjdavis3