You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We have a specification that has a single endpoint for PATCH but allows either standard JSON patch (application/json-patch+json) or JSON merge patch (application/merge-patch+json) as input in the request body.
I find that only the first one ends up generating contract tests.
I did see this issue about different content types (one being non-JSON) having some challenges getting handled, and this issue about handling JSON patch. They seem to slightly overlap with what I'm talking about, so I don't know if it's all connected or what.
Here's an example schema to show what I'm talking about:
schema.json (click to expand)
{
"components": {
"responses": {
"400badrequest": {
"description": "The request could not be processed by the server."
},
"401unauthorized": {
"description": "The client has not authenticated to perform the operation."
},
"403forbidden": {
"description": "The authenticated client is not authorized to perform the operation."
},
"404notfound": {
"description": "The server has not found a resource matching the request URI."
}
},
"schemas": {
"jsonPatchDocument": {
"description": "RFC 6902 JSON Patch document - http://json.schemastore.org/json-patch",
"items": {
"oneOf": [
{
"additionalProperties": false,
"properties": {
"op": {
"description": "The operation to perform.",
"enum": [
"add",
"replace",
"test"
],
"type": "string"
},
"path": {
"$ref": "#/components/schemas/jsonPatchPath"
},
"value": {
"description": "The value to add, replace or test."
}
},
"required": [
"value",
"op",
"path"
]
},
{
"additionalProperties": false,
"properties": {
"op": {
"description": "The operation to perform.",
"enum": [
"remove"
],
"type": "string"
},
"path": {
"$ref": "#/components/schemas/jsonPatchPath"
}
},
"required": [
"op",
"path"
]
},
{
"additionalProperties": false,
"properties": {
"from": {
"$ref": "#/components/schemas/jsonPatchPath"
},
"op": {
"description": "The operation to perform.",
"enum": [
"move",
"copy"
],
"type": "string"
},
"path": {
"$ref": "#/components/schemas/jsonPatchPath"
}
},
"required": [
"from",
"op",
"path"
]
}
]
},
"type": "array"
},
"jsonPatchPath": {
"description": "A JSON Pointer path pointing to the location of the patch operation.",
"type": "string"
},
"user": {
"allOf": [
{
"$ref": "#/components/schemas/userPatch"
},
{
"properties": {
"id": {
"$ref": "#/components/schemas/userId"
}
}
}
],
"description": "The identity for an individual person.",
"required": [
"id",
"familyName",
"givenName"
]
},
"userId": {
"description": "A unique and immutable identifier used to identify a user resource.",
"example": "214d9ca3-3aaf-4312-902d-03818fd0f4e6",
"maxLength": 40,
"minLength": 1,
"type": "string"
},
"userPatch": {
"description": "Base properties for a user.",
"properties": {
"familyName": {
"description": "The family/last name for the user.",
"example": "Smith",
"type": "string"
},
"givenName": {
"description": "The given/first name for the user.",
"example": "Alice",
"type": "string"
}
},
"type": "object"
}
}
},
"info": {
"contact": {
"name": "Demo"
},
"description": "Patch demo API.",
"title": "Patch Demo",
"version": "0.0.1"
},
"openapi": "3.0.3",
"paths": {
"/users/{id}": {
"patch": {
"description": "Makes changes to the profile of a user.",
"operationId": "patch-user",
"parameters": [
{
"description": "The identifier of the user to update.",
"in": "path",
"name": "id",
"required": true,
"schema": {
"$ref": "#/components/schemas/userId"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"example": [
{
"op": "replace",
"path": "/givenName",
"value": "Alison"
}
],
"schema": {
"$ref": "#/components/schemas/jsonPatchDocument"
}
},
"application/merge-patch+json": {
"example": {
"givenName": "Alison"
},
"schema": {
"$ref": "#/components/schemas/userPatch"
}
}
},
"description": "A JSON Patch document with the set of profile element updates.",
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/user"
}
}
},
"description": "All operations in the patch document succeeded. The response will contain the updated user profile."
},
"400": {
"$ref": "#/components/responses/400badrequest"
},
"401": {
"$ref": "#/components/responses/401unauthorized"
},
"403": {
"$ref": "#/components/responses/403forbidden"
},
"404": {
"$ref": "#/components/responses/404notfound"
}
},
"summary": "Update a user profile",
"tags": [
"resource-users"
]
}
}
},
"servers": [
{
"description": "Demo API",
"url": "https://api.demo.com"
}
],
"tags": [
{
"description": "User/identity-related services.",
"name": "resource-users"
}
]
}
As the schema is now, it will generate tests for application/json-patch+json because that's the first one listed in the requestBody.content listing. If you reorder them so application/merge-patch+json is first, those are the tests you'll get.
How do I get both?
The text was updated successfully, but these errors were encountered:
Portman typically looks for the 1st JSON content type it comes across and uses that to generate the schema validation.
In your case, you would want to have tests generated for multiple content-types within a response?
Yeah, because each JSON type has a different schema associated - merge patch looks similar to the document getting patched, while JSON patch has a specific schema that specifies operations using JSONPath. Both are JSON, both have a JSON schema, but different schema per content type.
We have a specification that has a single endpoint for
PATCH
but allows either standard JSON patch (application/json-patch+json
) or JSON merge patch (application/merge-patch+json
) as input in the request body.I find that only the first one ends up generating contract tests.
I did see this issue about different content types (one being non-JSON) having some challenges getting handled, and this issue about handling JSON patch. They seem to slightly overlap with what I'm talking about, so I don't know if it's all connected or what.
Here's an example schema to show what I'm talking about:
schema.json (click to expand)
As the schema is now, it will generate tests for
application/json-patch+json
because that's the first one listed in therequestBody.content
listing. If you reorder them soapplication/merge-patch+json
is first, those are the tests you'll get.How do I get both?
The text was updated successfully, but these errors were encountered: