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

Polymorphics #59

Merged
merged 14 commits into from
Oct 6, 2021
Merged

Polymorphics #59

merged 14 commits into from
Oct 6, 2021

Conversation

hotmeteor
Copy link
Owner

@hotmeteor hotmeteor commented Jul 24, 2021

Adds support and tests for oneOf, anyOf, and allOf polymorphics.

Some notes:

@bilfeldt
Copy link
Contributor

bilfeldt commented Aug 13, 2021

@hotmeteor This PR is much appreciated. I have tested this branch on the specs I have found a problem when declaring a property within a allOf as nullable:

Example below causes an issue with the id when this is null.

 ================================================== 
  Request body did not match provided JSON schema.  
 ================================================== 
  ⨯ The data should match all schemas     
  ⨯ The properties must match schema: id          
  ⨯ The data (null) must match the type: string   

The specs have a response defined by:

                "responses": {
                    "401": {
                        "$ref": "#/components/responses/401"
                    }
                }

Which is defined like

        "responses": {
            "401": {
                "description": "Unauthenticated request. Please provide correct authentication.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/DetailedError"
                        }
                    }
                }
            }
        }

And this is the components for

            "Error": {
                "description": "Error response",
                "required": [
                    "message"
                ],
                "properties": {
                    "message": {
                        "description": "Description of the message",
                        "type": "string",
                        "example": "Description of the error will be inserted here."
                    }
                },
                "type": "object"
            },
            "DetailedError": {
                "description": "Detailed Error response",
                "required": [
                    "message",
                    "code"
                ],
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Error"
                    },
                    {
                        "properties": {
                            "id": {
                                "description": "Unique ID of the error",
                                "type": "string",
                                "example": "",
                                "nullable": true
                            },
                            "code": {
                                "description": "Code describing the type of error",
                                "type": "string",
                                "example": "ValidationException"
                            },
                            "errors": {
                                "description": "Object with keys corresponding to the fields and each key containing an array of errors. OpenAPI does not allow for dynamic keys until version 3.1 is released",
                                "type": "object"
                            },
                            "links": {
                                "description": "Object with dynamic keys, each with a URL string value. Dynamic keys are not part of OpenAPI until version 3.1 is released",
                                "type": "object"
                            }
                        },
                        "type": "object"
                    }
                ]
            }

And this is the actual response:

{
    "links":{
        "about":"http:\/\/localhost\/docs\/errors\/UnauthenticatedException",
        "status":"http:\/\/localhost\/status"
    },
    "id":null,
    "code":"UnauthenticatedException",
    "message":"Unauthenticated.",
    "errors":{
        "header.Authorization":[
            "Provide a Bearer Token as Authorization header"
        ]
    }
}

Testing

Does this package have some neat way of manually validating a request and/or a request+response agains a specification?

I mean imagine I could test using something like:

Spectator::using('api-docs.json')->validate($request, $response); // Would throw some sort of exception if it fails I would guess

And perhaps the ability to only check the request:

Spectator::using('api-docs.json')->validate($request); 

@hotmeteor
Copy link
Owner Author

@bilfeldt What version of OpenAPI are you using: 3.0 or 3.1?

Also, that's an awesome idea. It's not currently available but I think it should be doable, I'll see if I can add it.

@jarrodparkes
Copy link
Collaborator

@hotmeteor I added some tests to cover equivalent polymorphic cases on the response-side. The main change was ensuring the json_decode call was also performed for the oneOf and anyOf cases for the response's body. I also took a stab at adding some more error feedback for messages that were purely one-to-one mappings of errors generated by the opis/json-schema validator.

@hotmeteor hotmeteor merged commit 3471fdb into master Oct 6, 2021
@hotmeteor hotmeteor deleted the polymorphics branch October 6, 2021 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants