diff --git a/src/Examples/JsonApiDotNetCoreExample/GeneratedSwagger/JsonApiDotNetCoreExample.json b/src/Examples/JsonApiDotNetCoreExample/GeneratedSwagger/JsonApiDotNetCoreExample.json index d5c1ef9db1..40ace7117f 100644 --- a/src/Examples/JsonApiDotNetCoreExample/GeneratedSwagger/JsonApiDotNetCoreExample.json +++ b/src/Examples/JsonApiDotNetCoreExample/GeneratedSwagger/JsonApiDotNetCoreExample.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The person was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The person was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person or a related resource does not exist." + "description": "The person or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The person was successfully deleted." }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -378,10 +462,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -472,10 +570,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -558,13 +670,34 @@ "description": "The todoItems were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -604,13 +737,34 @@ "description": "The assignedTodoItems relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -650,13 +804,34 @@ "description": "The todoItems were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -704,10 +879,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -798,10 +987,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -884,13 +1087,34 @@ "description": "The todoItems were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -930,13 +1154,34 @@ "description": "The ownedTodoItems relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -976,13 +1221,34 @@ "description": "The todoItems were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The person does not exist." + "description": "The person does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1021,7 +1287,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1106,16 +1379,44 @@ "description": "The tag was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." - }, - "403": { - "description": "Client-generated IDs cannot be used at this endpoint." - }, + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } + }, + "403": { + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } + }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1163,10 +1464,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The tag does not exist." + "description": "The tag does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1272,16 +1587,44 @@ "description": "The tag was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The tag or a related resource does not exist." + "description": "The tag or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1307,7 +1650,14 @@ "description": "The tag was successfully deleted." }, "404": { - "description": "The tag does not exist." + "description": "The tag does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1355,10 +1705,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The tag does not exist." + "description": "The tag does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1449,10 +1813,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The tag does not exist." + "description": "The tag does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1535,13 +1913,34 @@ "description": "The todoItems were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The tag does not exist." + "description": "The tag does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1581,13 +1980,34 @@ "description": "The todoItems relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The tag does not exist." + "description": "The tag does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1627,13 +2047,34 @@ "description": "The todoItems were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The tag does not exist." + "description": "The tag does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1672,7 +2113,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1757,16 +2205,44 @@ "description": "The todoItem was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1814,10 +2290,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1923,16 +2413,44 @@ "description": "The todoItem was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem or a related resource does not exist." + "description": "The todoItem or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1958,7 +2476,14 @@ "description": "The todoItem was successfully deleted." }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -2006,10 +2531,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -2100,10 +2639,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -2186,13 +2739,34 @@ "description": "The assignee relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -2240,10 +2814,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -2334,10 +2922,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -2420,13 +3022,34 @@ "description": "The owner relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -2474,10 +3097,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -2568,10 +3205,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -2654,13 +3305,34 @@ "description": "The tags were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -2700,13 +3372,34 @@ "description": "The tags relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -2746,13 +3439,34 @@ "description": "The tags were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The todoItem does not exist." + "description": "The todoItem does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -2787,6 +3501,99 @@ }, "x-abstract": true }, + "errorLinks": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "errorObject": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/errorLinks" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/errorSource" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "errorResponseDocument": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/errorObject" + } + } + }, + "additionalProperties": false + }, + "errorSource": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "linksInRelationship": { "required": [ "related", diff --git a/src/JsonApiDotNetCore.OpenApi.Client/ApiResponse.cs b/src/JsonApiDotNetCore.OpenApi.Client/ApiResponse.cs index 0c99f88209..c144177d22 100644 --- a/src/JsonApiDotNetCore.OpenApi.Client/ApiResponse.cs +++ b/src/JsonApiDotNetCore.OpenApi.Client/ApiResponse.cs @@ -15,7 +15,7 @@ public static class ApiResponse try { - return await operation(); + return await operation().ConfigureAwait(false); } catch (ApiException exception) when (exception.StatusCode == 204) { @@ -30,7 +30,7 @@ public static async Task TranslateAsync(Func operation) try { - await operation(); + await operation().ConfigureAwait(false); } catch (ApiException exception) when (exception.StatusCode == 204) { diff --git a/src/JsonApiDotNetCore.OpenApi.Client/Exceptions/ApiException.cs b/src/JsonApiDotNetCore.OpenApi.Client/Exceptions/ApiException.cs index 0cc30212a5..7b89e5cc6a 100644 --- a/src/JsonApiDotNetCore.OpenApi.Client/Exceptions/ApiException.cs +++ b/src/JsonApiDotNetCore.OpenApi.Client/Exceptions/ApiException.cs @@ -6,11 +6,19 @@ namespace JsonApiDotNetCore.OpenApi.Client.Exceptions; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ApiException( - string message, int statusCode, string? response, IReadOnlyDictionary> headers, Exception? innerException) - : Exception($"{message}\n\nStatus: {statusCode}\nResponse: \n{response ?? "(null)"}", innerException) +public class ApiException(string message, int statusCode, string? response, IReadOnlyDictionary> headers, Exception? innerException) + : Exception($"HTTP {statusCode}: {message}", innerException) { public int StatusCode { get; } = statusCode; - public string? Response { get; } = response; + public virtual string? Response { get; } = string.IsNullOrEmpty(response) ? null : response; public IReadOnlyDictionary> Headers { get; } = headers; } + +[UsedImplicitly(ImplicitUseTargetFlags.Members)] +public sealed class ApiException( + string message, int statusCode, string? response, IReadOnlyDictionary> headers, TResult result, Exception? innerException) + : ApiException(message, statusCode, response, headers, innerException) +{ + public TResult Result { get; } = result; + public override string Response => $"The response body is unavailable. Use the {nameof(Result)} property instead."; +} diff --git a/src/JsonApiDotNetCore.OpenApi/ConfigureMvcOptions.cs b/src/JsonApiDotNetCore.OpenApi/ConfigureMvcOptions.cs index 3bcc23587e..665432e6dd 100644 --- a/src/JsonApiDotNetCore.OpenApi/ConfigureMvcOptions.cs +++ b/src/JsonApiDotNetCore.OpenApi/ConfigureMvcOptions.cs @@ -7,22 +7,28 @@ namespace JsonApiDotNetCore.OpenApi; internal sealed class ConfigureMvcOptions : IConfigureOptions { - private readonly IControllerResourceMapping _controllerResourceMapping; private readonly IJsonApiRoutingConvention _jsonApiRoutingConvention; + private readonly OpenApiEndpointConvention _openApiEndpointConvention; + private readonly JsonApiRequestFormatMetadataProvider _jsonApiRequestFormatMetadataProvider; - public ConfigureMvcOptions(IControllerResourceMapping controllerResourceMapping, IJsonApiRoutingConvention jsonApiRoutingConvention) + public ConfigureMvcOptions(IJsonApiRoutingConvention jsonApiRoutingConvention, OpenApiEndpointConvention openApiEndpointConvention, + JsonApiRequestFormatMetadataProvider jsonApiRequestFormatMetadataProvider) { - ArgumentGuard.NotNull(controllerResourceMapping); ArgumentGuard.NotNull(jsonApiRoutingConvention); + ArgumentGuard.NotNull(openApiEndpointConvention); + ArgumentGuard.NotNull(jsonApiRequestFormatMetadataProvider); - _controllerResourceMapping = controllerResourceMapping; _jsonApiRoutingConvention = jsonApiRoutingConvention; + _openApiEndpointConvention = openApiEndpointConvention; + _jsonApiRequestFormatMetadataProvider = jsonApiRequestFormatMetadataProvider; } public void Configure(MvcOptions options) { AddSwashbuckleCliCompatibility(options); - AddOpenApiEndpointConvention(options); + + options.InputFormatters.Add(_jsonApiRequestFormatMetadataProvider); + options.Conventions.Add(_openApiEndpointConvention); } private void AddSwashbuckleCliCompatibility(MvcOptions options) @@ -33,10 +39,4 @@ private void AddSwashbuckleCliCompatibility(MvcOptions options) options.Conventions.Insert(0, _jsonApiRoutingConvention); } } - - private void AddOpenApiEndpointConvention(MvcOptions options) - { - var convention = new OpenApiEndpointConvention(_controllerResourceMapping); - options.Conventions.Add(convention); - } } diff --git a/src/JsonApiDotNetCore.OpenApi/JsonApiActionDescriptorCollectionProvider.cs b/src/JsonApiDotNetCore.OpenApi/JsonApiActionDescriptorCollectionProvider.cs index a34ebd0bf3..39e2c40f4a 100644 --- a/src/JsonApiDotNetCore.OpenApi/JsonApiActionDescriptorCollectionProvider.cs +++ b/src/JsonApiDotNetCore.OpenApi/JsonApiActionDescriptorCollectionProvider.cs @@ -22,15 +22,14 @@ internal sealed class JsonApiActionDescriptorCollectionProvider : IActionDescrip public ActionDescriptorCollection ActionDescriptors => GetActionDescriptors(); - public JsonApiActionDescriptorCollectionProvider(IControllerResourceMapping controllerResourceMapping, IActionDescriptorCollectionProvider defaultProvider, - ResourceFieldValidationMetadataProvider resourceFieldValidationMetadataProvider) + public JsonApiActionDescriptorCollectionProvider(IActionDescriptorCollectionProvider defaultProvider, + JsonApiEndpointMetadataProvider jsonApiEndpointMetadataProvider) { - ArgumentGuard.NotNull(controllerResourceMapping); ArgumentGuard.NotNull(defaultProvider); - ArgumentGuard.NotNull(resourceFieldValidationMetadataProvider); + ArgumentGuard.NotNull(jsonApiEndpointMetadataProvider); _defaultProvider = defaultProvider; - _jsonApiEndpointMetadataProvider = new JsonApiEndpointMetadataProvider(controllerResourceMapping, resourceFieldValidationMetadataProvider); + _jsonApiEndpointMetadataProvider = jsonApiEndpointMetadataProvider; } private ActionDescriptorCollection GetActionDescriptors() @@ -167,32 +166,32 @@ private static void UpdateBodyParameterDescriptor(ActionDescriptor endpoint, Typ private static ActionDescriptor Clone(ActionDescriptor descriptor) { - var clonedDescriptor = (ActionDescriptor)descriptor.MemberwiseClone(); + var clone = (ActionDescriptor)descriptor.MemberwiseClone(); - clonedDescriptor.AttributeRouteInfo = (AttributeRouteInfo)descriptor.AttributeRouteInfo!.MemberwiseClone(); + clone.AttributeRouteInfo = (AttributeRouteInfo)descriptor.AttributeRouteInfo!.MemberwiseClone(); - clonedDescriptor.FilterDescriptors = new List(); + clone.FilterDescriptors = new List(); foreach (FilterDescriptor filter in descriptor.FilterDescriptors) { - clonedDescriptor.FilterDescriptors.Add(Clone(filter)); + clone.FilterDescriptors.Add(Clone(filter)); } - clonedDescriptor.Parameters = new List(); + clone.Parameters = new List(); foreach (ParameterDescriptor parameter in descriptor.Parameters) { - clonedDescriptor.Parameters.Add((ParameterDescriptor)parameter.MemberwiseClone()); + clone.Parameters.Add((ParameterDescriptor)parameter.MemberwiseClone()); } - return clonedDescriptor; + return clone; } private static FilterDescriptor Clone(FilterDescriptor descriptor) { - var clonedFilter = (IFilterMetadata)descriptor.Filter.MemberwiseClone(); + var clone = (IFilterMetadata)descriptor.Filter.MemberwiseClone(); - return new FilterDescriptor(clonedFilter, descriptor.Scope) + return new FilterDescriptor(clone, descriptor.Scope) { Order = descriptor.Order }; diff --git a/src/JsonApiDotNetCore.OpenApi/JsonApiMetadata/JsonApiEndpointMetadataProvider.cs b/src/JsonApiDotNetCore.OpenApi/JsonApiMetadata/JsonApiEndpointMetadataProvider.cs index 3408159fe8..c56b881955 100644 --- a/src/JsonApiDotNetCore.OpenApi/JsonApiMetadata/JsonApiEndpointMetadataProvider.cs +++ b/src/JsonApiDotNetCore.OpenApi/JsonApiMetadata/JsonApiEndpointMetadataProvider.cs @@ -12,18 +12,20 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiMetadata; /// internal sealed class JsonApiEndpointMetadataProvider { + private readonly EndpointResolver _endpointResolver; private readonly IControllerResourceMapping _controllerResourceMapping; - private readonly EndpointResolver _endpointResolver = new(); private readonly NonPrimaryDocumentTypeFactory _nonPrimaryDocumentTypeFactory; - public JsonApiEndpointMetadataProvider(IControllerResourceMapping controllerResourceMapping, - ResourceFieldValidationMetadataProvider resourceFieldValidationMetadataProvider) + public JsonApiEndpointMetadataProvider(EndpointResolver endpointResolver, IControllerResourceMapping controllerResourceMapping, + NonPrimaryDocumentTypeFactory nonPrimaryDocumentTypeFactory) { + ArgumentGuard.NotNull(endpointResolver); ArgumentGuard.NotNull(controllerResourceMapping); - ArgumentGuard.NotNull(resourceFieldValidationMetadataProvider); + ArgumentGuard.NotNull(nonPrimaryDocumentTypeFactory); - _nonPrimaryDocumentTypeFactory = new NonPrimaryDocumentTypeFactory(resourceFieldValidationMetadataProvider); + _endpointResolver = endpointResolver; _controllerResourceMapping = controllerResourceMapping; + _nonPrimaryDocumentTypeFactory = nonPrimaryDocumentTypeFactory; } public JsonApiEndpointMetadataContainer Get(MethodInfo controllerAction) diff --git a/src/JsonApiDotNetCore.OpenApi/JsonApiMetadata/RelationshipTypeFactory.cs b/src/JsonApiDotNetCore.OpenApi/JsonApiMetadata/RelationshipTypeFactory.cs index dbdd8b4a23..a51adfc67e 100644 --- a/src/JsonApiDotNetCore.OpenApi/JsonApiMetadata/RelationshipTypeFactory.cs +++ b/src/JsonApiDotNetCore.OpenApi/JsonApiMetadata/RelationshipTypeFactory.cs @@ -5,14 +5,16 @@ namespace JsonApiDotNetCore.OpenApi.JsonApiMetadata; internal sealed class RelationshipTypeFactory { - private readonly ResourceFieldValidationMetadataProvider _resourceFieldValidationMetadataProvider; private readonly NonPrimaryDocumentTypeFactory _nonPrimaryDocumentTypeFactory; + private readonly ResourceFieldValidationMetadataProvider _resourceFieldValidationMetadataProvider; - public RelationshipTypeFactory(ResourceFieldValidationMetadataProvider resourceFieldValidationMetadataProvider) + public RelationshipTypeFactory(NonPrimaryDocumentTypeFactory nonPrimaryDocumentTypeFactory, + ResourceFieldValidationMetadataProvider resourceFieldValidationMetadataProvider) { + ArgumentGuard.NotNull(nonPrimaryDocumentTypeFactory); ArgumentGuard.NotNull(resourceFieldValidationMetadataProvider); - _nonPrimaryDocumentTypeFactory = new NonPrimaryDocumentTypeFactory(resourceFieldValidationMetadataProvider); + _nonPrimaryDocumentTypeFactory = nonPrimaryDocumentTypeFactory; _resourceFieldValidationMetadataProvider = resourceFieldValidationMetadataProvider; } diff --git a/src/JsonApiDotNetCore.OpenApi/JsonApiObjects/Documents/ErrorResponseDocument.cs b/src/JsonApiDotNetCore.OpenApi/JsonApiObjects/Documents/ErrorResponseDocument.cs new file mode 100644 index 0000000000..4804d95c25 --- /dev/null +++ b/src/JsonApiDotNetCore.OpenApi/JsonApiObjects/Documents/ErrorResponseDocument.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using JetBrains.Annotations; +using JsonApiDotNetCore.Serialization.Objects; + +namespace JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents; + +[UsedImplicitly(ImplicitUseTargetFlags.Members)] +internal sealed class ErrorResponseDocument +{ + [Required] + [JsonPropertyName("errors")] + public IList Errors { get; set; } = new List(); +} diff --git a/src/JsonApiDotNetCore.OpenApi/OpenApiEndpointConvention.cs b/src/JsonApiDotNetCore.OpenApi/OpenApiEndpointConvention.cs index 2d54312acf..bbeb4bbe6b 100644 --- a/src/JsonApiDotNetCore.OpenApi/OpenApiEndpointConvention.cs +++ b/src/JsonApiDotNetCore.OpenApi/OpenApiEndpointConvention.cs @@ -1,10 +1,11 @@ +using System.Net; using System.Reflection; using JsonApiDotNetCore.Configuration; using JsonApiDotNetCore.Controllers; using JsonApiDotNetCore.Middleware; using JsonApiDotNetCore.OpenApi.JsonApiMetadata; +using JsonApiDotNetCore.OpenApi.JsonApiObjects.Documents; using JsonApiDotNetCore.Resources.Annotations; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationModels; @@ -16,13 +17,18 @@ namespace JsonApiDotNetCore.OpenApi; internal sealed class OpenApiEndpointConvention : IActionModelConvention { private readonly IControllerResourceMapping _controllerResourceMapping; - private readonly EndpointResolver _endpointResolver = new(); + private readonly EndpointResolver _endpointResolver; + private readonly IJsonApiOptions _options; - public OpenApiEndpointConvention(IControllerResourceMapping controllerResourceMapping) + public OpenApiEndpointConvention(IControllerResourceMapping controllerResourceMapping, EndpointResolver endpointResolver, IJsonApiOptions options) { ArgumentGuard.NotNull(controllerResourceMapping); + ArgumentGuard.NotNull(endpointResolver); + ArgumentGuard.NotNull(options); _controllerResourceMapping = controllerResourceMapping; + _endpointResolver = endpointResolver; + _options = options; } public void Apply(ActionModel action) @@ -39,25 +45,25 @@ public void Apply(ActionModel action) return; } - if (ShouldSuppressEndpoint(endpoint.Value, action.Controller.ControllerType)) + ResourceType? resourceType = _controllerResourceMapping.GetResourceTypeForController(action.Controller.ControllerType); + + if (resourceType == null) + { + throw new UnreachableCodeException(); + } + + if (ShouldSuppressEndpoint(endpoint.Value, resourceType)) { action.ApiExplorer.IsVisible = false; return; } - SetResponseMetadata(action, endpoint.Value); + SetResponseMetadata(action, endpoint.Value, resourceType); SetRequestMetadata(action, endpoint.Value); } - private bool ShouldSuppressEndpoint(JsonApiEndpoint endpoint, Type controllerType) + private bool ShouldSuppressEndpoint(JsonApiEndpoint endpoint, ResourceType resourceType) { - ResourceType? resourceType = _controllerResourceMapping.GetResourceTypeForController(controllerType); - - if (resourceType == null) - { - throw new UnreachableCodeException(); - } - if (!IsEndpointAvailable(endpoint, resourceType)) { return true; @@ -121,49 +127,84 @@ private static bool IsSecondaryOrRelationshipEndpoint(JsonApiEndpoint endpoint) JsonApiEndpoint.PatchRelationship or JsonApiEndpoint.DeleteRelationship; } - private static void SetResponseMetadata(ActionModel action, JsonApiEndpoint endpoint) + private void SetResponseMetadata(ActionModel action, JsonApiEndpoint endpoint, ResourceType resourceType) { - foreach (int statusCode in GetStatusCodesForEndpoint(endpoint)) + action.Filters.Add(new ProducesAttribute(HeaderConstants.MediaType)); + + foreach (HttpStatusCode statusCode in GetSuccessStatusCodesForEndpoint(endpoint)) { - action.Filters.Add(new ProducesResponseTypeAttribute(statusCode)); + // The return type is set later by JsonApiActionDescriptorCollectionProvider. + action.Filters.Add(new ProducesResponseTypeAttribute((int)statusCode)); + } - switch (endpoint) - { - case JsonApiEndpoint.GetCollection when statusCode == StatusCodes.Status200OK: - case JsonApiEndpoint.Post when statusCode == StatusCodes.Status201Created: - case JsonApiEndpoint.Patch when statusCode == StatusCodes.Status200OK: - case JsonApiEndpoint.GetSingle when statusCode == StatusCodes.Status200OK: - case JsonApiEndpoint.GetSecondary when statusCode == StatusCodes.Status200OK: - case JsonApiEndpoint.GetRelationship when statusCode == StatusCodes.Status200OK: - { - action.Filters.Add(new ProducesAttribute(HeaderConstants.MediaType)); - break; - } - } + foreach (HttpStatusCode statusCode in GetErrorStatusCodesForEndpoint(endpoint, resourceType)) + { + action.Filters.Add(new ProducesResponseTypeAttribute(typeof(ErrorResponseDocument), (int)statusCode)); } } - private static IEnumerable GetStatusCodesForEndpoint(JsonApiEndpoint endpoint) + private static IEnumerable GetSuccessStatusCodesForEndpoint(JsonApiEndpoint endpoint) { return endpoint switch { - JsonApiEndpoint.GetCollection or JsonApiEndpoint.GetSingle or JsonApiEndpoint.GetSecondary or JsonApiEndpoint.GetRelationship => + JsonApiEndpoint.GetCollection or JsonApiEndpoint.GetSingle or JsonApiEndpoint.GetSecondary or JsonApiEndpoint.GetRelationship + => [HttpStatusCode.OK], + JsonApiEndpoint.Post => + [ + HttpStatusCode.Created, + HttpStatusCode.NoContent + ], + JsonApiEndpoint.Patch => + [ + HttpStatusCode.OK, + HttpStatusCode.NoContent + ], + JsonApiEndpoint.Delete or JsonApiEndpoint.PostRelationship or JsonApiEndpoint.PatchRelationship or JsonApiEndpoint.DeleteRelationship => + [ + HttpStatusCode.NoContent + ], + _ => throw new UnreachableCodeException() + }; + } + + private IEnumerable GetErrorStatusCodesForEndpoint(JsonApiEndpoint endpoint, ResourceType resourceType) + { + ClientIdGenerationMode clientIdGeneration = resourceType.ClientIdGeneration ?? _options.ClientIdGeneration; + + return endpoint switch + { + JsonApiEndpoint.GetCollection => [HttpStatusCode.BadRequest], + JsonApiEndpoint.GetSingle or JsonApiEndpoint.GetSecondary or JsonApiEndpoint.GetRelationship => + [ + HttpStatusCode.BadRequest, + HttpStatusCode.NotFound + ], + JsonApiEndpoint.Post when clientIdGeneration == ClientIdGenerationMode.Forbidden => [ - StatusCodes.Status200OK + HttpStatusCode.BadRequest, + HttpStatusCode.Forbidden, + HttpStatusCode.Conflict, + HttpStatusCode.UnprocessableEntity ], JsonApiEndpoint.Post => [ - StatusCodes.Status201Created, - StatusCodes.Status204NoContent + HttpStatusCode.BadRequest, + HttpStatusCode.Conflict, + HttpStatusCode.UnprocessableEntity ], JsonApiEndpoint.Patch => [ - StatusCodes.Status200OK, - StatusCodes.Status204NoContent + HttpStatusCode.BadRequest, + HttpStatusCode.NotFound, + HttpStatusCode.Conflict, + HttpStatusCode.UnprocessableEntity ], - JsonApiEndpoint.Delete or JsonApiEndpoint.PostRelationship or JsonApiEndpoint.PatchRelationship or JsonApiEndpoint.DeleteRelationship => new[] + JsonApiEndpoint.Delete => [HttpStatusCode.NotFound], + JsonApiEndpoint.PostRelationship or JsonApiEndpoint.PatchRelationship or JsonApiEndpoint.DeleteRelationship => new[] { - StatusCodes.Status204NoContent + HttpStatusCode.BadRequest, + HttpStatusCode.NotFound, + HttpStatusCode.Conflict }, _ => throw new UnreachableCodeException() }; diff --git a/src/JsonApiDotNetCore.OpenApi/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore.OpenApi/ServiceCollectionExtensions.cs index 4a4787644e..7cefd50a03 100644 --- a/src/JsonApiDotNetCore.OpenApi/ServiceCollectionExtensions.cs +++ b/src/JsonApiDotNetCore.OpenApi/ServiceCollectionExtensions.cs @@ -1,3 +1,4 @@ +using JsonApiDotNetCore.OpenApi.JsonApiMetadata; using JsonApiDotNetCore.OpenApi.SwaggerComponents; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApiExplorer; @@ -23,8 +24,6 @@ public static void AddOpenApi(this IServiceCollection services, IMvcCoreBuilder AddCustomSwaggerComponents(services); AddSwaggerGenerator(services); - services.AddTransient, ConfigureMvcOptions>(); - if (setupSwaggerGenAction != null) { services.Configure(setupSwaggerGenAction); @@ -33,8 +32,13 @@ public static void AddOpenApi(this IServiceCollection services, IMvcCoreBuilder private static void AddCustomApiExplorer(IServiceCollection services, IMvcCoreBuilder mvcBuilder) { + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); services.TryAddSingleton(); - services.AddSingleton(); services.TryAddSingleton(serviceProvider => { @@ -46,7 +50,7 @@ private static void AddCustomApiExplorer(IServiceCollection services, IMvcCoreBu mvcBuilder.AddApiExplorer(); - mvcBuilder.AddMvcOptions(options => options.InputFormatters.Add(new JsonApiRequestFormatMetadataProvider())); + services.AddSingleton, ConfigureMvcOptions>(); } private static void AddCustomSwaggerComponents(IServiceCollection services) @@ -62,6 +66,8 @@ private static void AddSwaggerGenerator(IServiceCollection services) { AddSchemaGenerators(services); + services.TryAddSingleton(); + services.AddSwaggerGen(); services.AddSingleton, ConfigureSwaggerGenOptions>(); } diff --git a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceDataSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceDataSchemaGenerator.cs index 10c13bcfca..8fd577ab91 100644 --- a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceDataSchemaGenerator.cs +++ b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceDataSchemaGenerator.cs @@ -1,4 +1,5 @@ using JsonApiDotNetCore.Configuration; +using JsonApiDotNetCore.OpenApi.JsonApiMetadata; using JsonApiDotNetCore.OpenApi.JsonApiObjects.ResourceObjects; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; @@ -24,11 +25,13 @@ internal sealed class ResourceDataSchemaGenerator private readonly IResourceGraph _resourceGraph; private readonly IJsonApiOptions _options; private readonly ResourceFieldValidationMetadataProvider _resourceFieldValidationMetadataProvider; + private readonly RelationshipTypeFactory _relationshipTypeFactory; private readonly ResourceDocumentationReader _resourceDocumentationReader; public ResourceDataSchemaGenerator(SchemaGenerator defaultSchemaGenerator, ResourceTypeSchemaGenerator resourceTypeSchemaGenerator, ResourceIdentifierSchemaGenerator resourceIdentifierSchemaGenerator, IResourceGraph resourceGraph, IJsonApiOptions options, - ResourceFieldValidationMetadataProvider resourceFieldValidationMetadataProvider, ResourceDocumentationReader resourceDocumentationReader) + ResourceFieldValidationMetadataProvider resourceFieldValidationMetadataProvider, RelationshipTypeFactory relationshipTypeFactory, + ResourceDocumentationReader resourceDocumentationReader) { ArgumentGuard.NotNull(defaultSchemaGenerator); ArgumentGuard.NotNull(resourceTypeSchemaGenerator); @@ -36,6 +39,7 @@ public ResourceDataSchemaGenerator(SchemaGenerator defaultSchemaGenerator, Resou ArgumentGuard.NotNull(resourceGraph); ArgumentGuard.NotNull(options); ArgumentGuard.NotNull(resourceFieldValidationMetadataProvider); + ArgumentGuard.NotNull(relationshipTypeFactory); ArgumentGuard.NotNull(resourceDocumentationReader); _defaultSchemaGenerator = defaultSchemaGenerator; @@ -44,7 +48,7 @@ public ResourceDataSchemaGenerator(SchemaGenerator defaultSchemaGenerator, Resou _resourceGraph = resourceGraph; _options = options; _resourceFieldValidationMetadataProvider = resourceFieldValidationMetadataProvider; - + _relationshipTypeFactory = relationshipTypeFactory; _resourceDocumentationReader = resourceDocumentationReader; } @@ -65,7 +69,7 @@ public OpenApiSchema GenerateSchema(Type resourceDataConstructedType, SchemaRepo var resourceTypeInfo = ResourceTypeInfo.Create(resourceDataConstructedType, _resourceGraph); var fieldSchemaBuilder = new ResourceFieldSchemaBuilder(_defaultSchemaGenerator, _resourceIdentifierSchemaGenerator, - _resourceFieldValidationMetadataProvider, resourceTypeInfo); + _resourceFieldValidationMetadataProvider, _relationshipTypeFactory, resourceTypeInfo); OpenApiSchema effectiveFullSchemaForResourceData = fullSchemaForResourceData.AllOf.Count == 0 ? fullSchemaForResourceData : fullSchemaForResourceData.AllOf[1]; diff --git a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceFieldSchemaBuilder.cs b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceFieldSchemaBuilder.cs index 0641c19ae0..89936d43d6 100644 --- a/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceFieldSchemaBuilder.cs +++ b/src/JsonApiDotNetCore.OpenApi/SwaggerComponents/ResourceFieldSchemaBuilder.cs @@ -35,27 +35,29 @@ internal sealed class ResourceFieldSchemaBuilder private readonly ResourceIdentifierSchemaGenerator _resourceIdentifierSchemaGenerator; private readonly ResourceTypeInfo _resourceTypeInfo; private readonly ResourceFieldValidationMetadataProvider _resourceFieldValidationMetadataProvider; - private readonly SchemaRepository _resourceSchemaRepository = new(); private readonly RelationshipTypeFactory _relationshipTypeFactory; + + private readonly SchemaRepository _resourceSchemaRepository = new(); + private readonly ResourceDocumentationReader _resourceDocumentationReader = new(); private readonly IDictionary _schemasForResourceFields; - private readonly ResourceDocumentationReader _resourceDocumentationReader; public ResourceFieldSchemaBuilder(SchemaGenerator defaultSchemaGenerator, ResourceIdentifierSchemaGenerator resourceIdentifierSchemaGenerator, - ResourceFieldValidationMetadataProvider resourceFieldValidationMetadataProvider, ResourceTypeInfo resourceTypeInfo) + ResourceFieldValidationMetadataProvider resourceFieldValidationMetadataProvider, RelationshipTypeFactory relationshipTypeFactory, + ResourceTypeInfo resourceTypeInfo) { ArgumentGuard.NotNull(defaultSchemaGenerator); ArgumentGuard.NotNull(resourceIdentifierSchemaGenerator); ArgumentGuard.NotNull(resourceTypeInfo); ArgumentGuard.NotNull(resourceFieldValidationMetadataProvider); + ArgumentGuard.NotNull(relationshipTypeFactory); _defaultSchemaGenerator = defaultSchemaGenerator; _resourceIdentifierSchemaGenerator = resourceIdentifierSchemaGenerator; _resourceTypeInfo = resourceTypeInfo; _resourceFieldValidationMetadataProvider = resourceFieldValidationMetadataProvider; + _relationshipTypeFactory = relationshipTypeFactory; - _relationshipTypeFactory = new RelationshipTypeFactory(resourceFieldValidationMetadataProvider); _schemasForResourceFields = GetFieldSchemas(); - _resourceDocumentationReader = new ResourceDocumentationReader(); } private IDictionary GetFieldSchemas() diff --git a/test/OpenApiClientTests/LegacyClient/ResponseTests.cs b/test/OpenApiClientTests/LegacyClient/ResponseTests.cs index 9a7f6f50ff..99df1935fe 100644 --- a/test/OpenApiClientTests/LegacyClient/ResponseTests.cs +++ b/test/OpenApiClientTests/LegacyClient/ResponseTests.cs @@ -1,10 +1,10 @@ using System.Globalization; using System.Net; using FluentAssertions; -using FluentAssertions.Specialized; using JsonApiDotNetCore.OpenApi.Client; using JsonApiDotNetCore.OpenApi.Client.Exceptions; using OpenApiClientTests.LegacyClient.GeneratedCode; +using TestBuildingBlocks; using Xunit; namespace OpenApiClientTests.LegacyClient; @@ -207,7 +207,7 @@ public async Task Getting_unknown_resource_translates_error_response() { "id": "f1a520ac-02a0-466b-94ea-86cbaa86f02f", "status": "404", - "destination": "The requested resource does not exist.", + "title": "The requested resource does not exist.", "detail": "Resource of type 'flights' with ID '{{flightId}}' does not exist." } ] @@ -221,10 +221,16 @@ public async Task Getting_unknown_resource_translates_error_response() Func> action = () => apiClient.GetFlightAsync(flightId, null); // Assert - ExceptionAssertions assertion = await action.Should().ThrowExactlyAsync(); - - assertion.Which.StatusCode.Should().Be((int)HttpStatusCode.NotFound); - assertion.Which.Response.Should().Be(responseBody); + ApiException exception = (await action.Should().ThrowExactlyAsync>()).Which; + exception.StatusCode.Should().Be((int)HttpStatusCode.NotFound); + exception.Result.Errors.ShouldHaveCount(1); + + ErrorObject? error = exception.Result.Errors.ElementAt(0); + error.Id.Should().Be("f1a520ac-02a0-466b-94ea-86cbaa86f02f"); + error.Status.Should().Be("404"); + error.Title.Should().Be("The requested resource does not exist."); + error.Detail.Should().Be($"Resource of type 'flights' with ID '{flightId}' does not exist."); + error.Source.Should().BeNull(); } [Fact] diff --git a/test/OpenApiClientTests/LegacyClient/swagger.g.json b/test/OpenApiClientTests/LegacyClient/swagger.g.json index 1a86868059..7736381583 100644 --- a/test/OpenApiClientTests/LegacyClient/swagger.g.json +++ b/test/OpenApiClientTests/LegacyClient/swagger.g.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The airplane was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The airplane was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane or a related resource does not exist." + "description": "The airplane or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The airplane was successfully deleted." }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -378,10 +462,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -472,10 +570,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -558,13 +670,34 @@ "description": "The flights were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -604,13 +737,34 @@ "description": "The flights relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -650,13 +804,34 @@ "description": "The flights were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -695,7 +870,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -780,16 +962,44 @@ "description": "The flight-attendant was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -837,10 +1047,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -946,16 +1170,44 @@ "description": "The flight-attendant was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant or a related resource does not exist." + "description": "The flight-attendant or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -981,7 +1233,14 @@ "description": "The flight-attendant was successfully deleted." }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1029,10 +1288,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1123,11 +1396,25 @@ } }, "400": { - "description": "The query string is invalid." - }, - "404": { - "description": "The flight-attendant does not exist." - } + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } + }, + "404": { + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } + } } }, "head": { @@ -1209,13 +1496,34 @@ "description": "The flights were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1255,13 +1563,34 @@ "description": "The purser-on-flights relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1301,13 +1630,34 @@ "description": "The flights were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1355,10 +1705,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1449,10 +1813,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1535,13 +1913,34 @@ "description": "The flights were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1581,13 +1980,34 @@ "description": "The scheduled-for-flights relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1627,13 +2047,34 @@ "description": "The flights were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1672,7 +2113,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1757,16 +2205,44 @@ "description": "The flight was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1814,10 +2290,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1923,16 +2413,44 @@ "description": "The flight was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight or a related resource does not exist." + "description": "The flight or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1958,7 +2476,14 @@ "description": "The flight was successfully deleted." }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -2006,10 +2531,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2100,10 +2639,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2186,13 +2739,34 @@ "description": "The backup-purser relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -2240,10 +2814,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2334,10 +2922,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2420,13 +3022,34 @@ "description": "The flight-attendants were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2466,13 +3089,34 @@ "description": "The cabin-crew-members relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2512,13 +3156,34 @@ "description": "The flight-attendants were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -2566,10 +3231,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2660,10 +3339,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2746,13 +3439,34 @@ "description": "The passengers were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2792,13 +3506,34 @@ "description": "The passengers relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2838,13 +3573,34 @@ "description": "The passengers were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -2892,10 +3648,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2986,10 +3756,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -3072,13 +3856,34 @@ "description": "The purser relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -3117,7 +3922,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -3202,16 +4014,44 @@ "description": "The passenger was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -3259,10 +4099,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The passenger does not exist." + "description": "The passenger does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -3368,16 +4222,44 @@ "description": "The passenger was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The passenger or a related resource does not exist." + "description": "The passenger or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -3403,7 +4285,14 @@ "description": "The passenger was successfully deleted." }, "404": { - "description": "The passenger does not exist." + "description": "The passenger does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -3838,6 +4727,99 @@ }, "x-abstract": true }, + "error-links": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "error-object": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/error-links" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/error-source" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "error-response-document": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/error-object" + } + } + }, + "additionalProperties": false + }, + "error-source": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "flight-attendant-attributes-in-patch-request": { "type": "object", "properties": { diff --git a/test/OpenApiClientTests/NamingConventions/CamelCase/swagger.g.json b/test/OpenApiClientTests/NamingConventions/CamelCase/swagger.g.json index eccc5ec2e3..f67656daec 100644 --- a/test/OpenApiClientTests/NamingConventions/CamelCase/swagger.g.json +++ b/test/OpenApiClientTests/NamingConventions/CamelCase/swagger.g.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The staffMember was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The staffMember does not exist." + "description": "The staffMember does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The staffMember was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The staffMember or a related resource does not exist." + "description": "The staffMember or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The staffMember was successfully deleted." }, "404": { - "description": "The staffMember does not exist." + "description": "The staffMember does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -369,7 +453,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -454,16 +545,44 @@ "description": "The supermarket was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -511,10 +630,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -620,16 +753,44 @@ "description": "The supermarket was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket or a related resource does not exist." + "description": "The supermarket or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -655,7 +816,14 @@ "description": "The supermarket was successfully deleted." }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -703,10 +871,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -797,10 +979,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -883,13 +1079,34 @@ "description": "The backupStoreManager relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -937,10 +1154,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1031,10 +1262,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1117,13 +1362,34 @@ "description": "The staffMembers were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1163,13 +1429,34 @@ "description": "The cashiers relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1209,13 +1496,34 @@ "description": "The staffMembers were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1263,10 +1571,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1357,10 +1679,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1443,13 +1779,34 @@ "description": "The storeManager relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1483,6 +1840,99 @@ }, "x-abstract": true }, + "errorLinks": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "errorObject": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/errorLinks" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/errorSource" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "errorResponseDocument": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/errorObject" + } + } + }, + "additionalProperties": false + }, + "errorSource": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "jsonapi": { "type": "object", "properties": { diff --git a/test/OpenApiClientTests/NamingConventions/KebabCase/swagger.g.json b/test/OpenApiClientTests/NamingConventions/KebabCase/swagger.g.json index ff999f4dd7..88f20b6310 100644 --- a/test/OpenApiClientTests/NamingConventions/KebabCase/swagger.g.json +++ b/test/OpenApiClientTests/NamingConventions/KebabCase/swagger.g.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The staff-member was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The staff-member does not exist." + "description": "The staff-member does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The staff-member was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The staff-member or a related resource does not exist." + "description": "The staff-member or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The staff-member was successfully deleted." }, "404": { - "description": "The staff-member does not exist." + "description": "The staff-member does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -369,7 +453,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -454,16 +545,44 @@ "description": "The supermarket was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -511,10 +630,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -620,16 +753,44 @@ "description": "The supermarket was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket or a related resource does not exist." + "description": "The supermarket or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -655,7 +816,14 @@ "description": "The supermarket was successfully deleted." }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -703,10 +871,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -797,10 +979,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -883,13 +1079,34 @@ "description": "The backup-store-manager relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -937,10 +1154,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1031,10 +1262,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1117,13 +1362,34 @@ "description": "The staff-members were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1163,13 +1429,34 @@ "description": "The cashiers relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1209,13 +1496,34 @@ "description": "The staff-members were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1263,10 +1571,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1357,10 +1679,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1443,13 +1779,34 @@ "description": "The store-manager relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The supermarket does not exist." + "description": "The supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1483,6 +1840,99 @@ }, "x-abstract": true }, + "error-links": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "error-object": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/error-links" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/error-source" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "error-response-document": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/error-object" + } + } + }, + "additionalProperties": false + }, + "error-source": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "jsonapi": { "type": "object", "properties": { diff --git a/test/OpenApiClientTests/NamingConventions/PascalCase/swagger.g.json b/test/OpenApiClientTests/NamingConventions/PascalCase/swagger.g.json index 5e88a84c38..6922cbb387 100644 --- a/test/OpenApiClientTests/NamingConventions/PascalCase/swagger.g.json +++ b/test/OpenApiClientTests/NamingConventions/PascalCase/swagger.g.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The StaffMember was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The StaffMember does not exist." + "description": "The StaffMember does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The StaffMember was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The StaffMember or a related resource does not exist." + "description": "The StaffMember or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The StaffMember was successfully deleted." }, "404": { - "description": "The StaffMember does not exist." + "description": "The StaffMember does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } } @@ -369,7 +453,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -454,16 +545,44 @@ "description": "The Supermarket was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } } @@ -511,10 +630,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -620,16 +753,44 @@ "description": "The Supermarket was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket or a related resource does not exist." + "description": "The Supermarket or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -655,7 +816,14 @@ "description": "The Supermarket was successfully deleted." }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } } @@ -703,10 +871,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -797,10 +979,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -883,13 +1079,34 @@ "description": "The BackupStoreManager relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } } @@ -937,10 +1154,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -1031,10 +1262,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -1117,13 +1362,34 @@ "description": "The StaffMembers were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -1163,13 +1429,34 @@ "description": "The Cashiers relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -1209,13 +1496,34 @@ "description": "The StaffMembers were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } } @@ -1263,10 +1571,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -1357,10 +1679,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } }, @@ -1443,13 +1779,34 @@ "description": "The StoreManager relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "404": { - "description": "The Supermarket does not exist." + "description": "The Supermarket does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponseDocument" + } + } + } } } } @@ -1483,6 +1840,99 @@ }, "x-abstract": true }, + "ErrorLinks": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "ErrorObject": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/ErrorLinks" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/ErrorSource" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "ErrorResponseDocument": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ErrorObject" + } + } + }, + "additionalProperties": false + }, + "ErrorSource": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "Jsonapi": { "type": "object", "properties": { diff --git a/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOff/swagger.g.json b/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOff/swagger.g.json index fd3f337728..eef7a522cd 100644 --- a/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOff/swagger.g.json +++ b/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOff/swagger.g.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The resource was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The resource was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource or a related resource does not exist." + "description": "The resource or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The resource was successfully deleted." }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -378,10 +462,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -472,10 +570,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -558,13 +670,34 @@ "description": "The empties were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -604,13 +737,34 @@ "description": "The requiredToMany relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -650,13 +804,34 @@ "description": "The empties were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -704,10 +879,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -798,10 +987,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -884,13 +1087,34 @@ "description": "The requiredToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -938,10 +1162,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1032,10 +1270,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1118,13 +1370,34 @@ "description": "The empties were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1164,13 +1437,34 @@ "description": "The toMany relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1210,13 +1504,34 @@ "description": "The empties were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1264,10 +1579,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1358,10 +1687,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1444,13 +1787,34 @@ "description": "The toOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1605,6 +1969,99 @@ "type": "string", "additionalProperties": false }, + "errorLinks": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "errorObject": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/errorLinks" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/errorSource" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "errorResponseDocument": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/errorObject" + } + } + }, + "additionalProperties": false + }, + "errorSource": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "linksInRelationship": { "required": [ "related", diff --git a/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOn/swagger.g.json b/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOn/swagger.g.json index c24cae3373..20eb52fdb5 100644 --- a/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOn/swagger.g.json +++ b/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOn/swagger.g.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The resource was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The resource was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource or a related resource does not exist." + "description": "The resource or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The resource was successfully deleted." }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -378,10 +462,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -472,10 +570,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -558,13 +670,34 @@ "description": "The empties were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -604,13 +737,34 @@ "description": "The requiredToMany relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -650,13 +804,34 @@ "description": "The empties were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -704,10 +879,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -798,10 +987,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -884,13 +1087,34 @@ "description": "The requiredToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -938,10 +1162,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1032,10 +1270,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1118,13 +1370,34 @@ "description": "The empties were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1164,13 +1437,34 @@ "description": "The toMany relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1210,13 +1504,34 @@ "description": "The empties were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1264,10 +1579,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1358,10 +1687,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1444,13 +1787,34 @@ "description": "The toOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1673,6 +2037,99 @@ }, "additionalProperties": false }, + "errorLinks": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "errorObject": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/errorLinks" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/errorSource" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "errorResponseDocument": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/errorObject" + } + } + }, + "additionalProperties": false + }, + "errorSource": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "linksInRelationship": { "required": [ "related", diff --git a/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOff/swagger.g.json b/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOff/swagger.g.json index ee74823c55..5b8e57278a 100644 --- a/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOff/swagger.g.json +++ b/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOff/swagger.g.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The resource was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The resource was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource or a related resource does not exist." + "description": "The resource or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The resource was successfully deleted." }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -378,10 +462,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -472,10 +570,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -558,13 +670,34 @@ "description": "The nonNullableToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -612,10 +745,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -706,10 +853,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -792,13 +953,34 @@ "description": "The nullableToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -846,10 +1028,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -940,10 +1136,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1026,13 +1236,34 @@ "description": "The requiredNonNullableToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1080,10 +1311,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1174,10 +1419,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1260,13 +1519,34 @@ "description": "The requiredNullableToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1314,10 +1594,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1408,10 +1702,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1494,13 +1802,34 @@ "description": "The empties were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1540,13 +1869,34 @@ "description": "The requiredToMany relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1586,13 +1936,34 @@ "description": "The empties were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1640,10 +2011,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1734,10 +2119,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1820,13 +2219,34 @@ "description": "The empties were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1866,13 +2286,34 @@ "description": "The toMany relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1912,13 +2353,34 @@ "description": "The empties were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -2141,6 +2603,99 @@ }, "additionalProperties": false }, + "errorLinks": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "errorObject": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/errorLinks" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/errorSource" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "errorResponseDocument": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/errorObject" + } + } + }, + "additionalProperties": false + }, + "errorSource": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "linksInRelationship": { "required": [ "related", diff --git a/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOn/swagger.g.json b/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOn/swagger.g.json index f8b8d264f7..c9984786b3 100644 --- a/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOn/swagger.g.json +++ b/test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOn/ModelStateValidationOn/swagger.g.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The resource was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The resource was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource or a related resource does not exist." + "description": "The resource or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The resource was successfully deleted." }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -378,10 +462,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -472,10 +570,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -558,13 +670,34 @@ "description": "The nonNullableToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -612,10 +745,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -706,10 +853,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -792,13 +953,34 @@ "description": "The nullableToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -846,10 +1028,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -940,10 +1136,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1026,13 +1236,34 @@ "description": "The requiredNonNullableToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1080,10 +1311,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1174,10 +1419,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1260,13 +1519,34 @@ "description": "The requiredNullableToOne relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1314,10 +1594,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1408,10 +1702,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1494,13 +1802,34 @@ "description": "The empties were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1540,13 +1869,34 @@ "description": "The requiredToMany relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1586,13 +1936,34 @@ "description": "The empties were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1640,10 +2011,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1734,10 +2119,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1820,13 +2219,34 @@ "description": "The empties were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1866,13 +2286,34 @@ "description": "The toMany relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1912,13 +2353,34 @@ "description": "The empties were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The resource does not exist." + "description": "The resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -2141,6 +2603,99 @@ }, "additionalProperties": false }, + "errorLinks": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "errorObject": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/errorLinks" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/errorSource" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "errorResponseDocument": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/errorObject" + } + } + }, + "additionalProperties": false + }, + "errorSource": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "linksInRelationship": { "required": [ "related", diff --git a/test/OpenApiEndToEndTests/QueryStrings/FilterTests.cs b/test/OpenApiEndToEndTests/QueryStrings/FilterTests.cs index fe7aefe747..27e0be14fb 100644 --- a/test/OpenApiEndToEndTests/QueryStrings/FilterTests.cs +++ b/test/OpenApiEndToEndTests/QueryStrings/FilterTests.cs @@ -145,9 +145,16 @@ public async Task Cannot_use_empty_filter() Func action = async () => _ = await apiClient.GetNodeAsync(Unknown.StringId.Int64, queryString); // Assert - ApiException exception = (await action.Should().ThrowExactlyAsync()).Which; + ApiException exception = (await action.Should().ThrowExactlyAsync>()).Which; exception.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); - exception.Message.Should().StartWith("The query string is invalid."); - exception.Message.Should().Contain("Missing value for 'filter' query string parameter."); + exception.Message.Should().Be("HTTP 400: The query string is invalid."); + exception.Result.Errors.ShouldHaveCount(1); + + ErrorObject error = exception.Result.Errors.ElementAt(0); + error.Status.Should().Be("400"); + error.Title.Should().Be("Missing query string parameter value."); + error.Detail.Should().Be("Missing value for 'filter' query string parameter."); + error.Source.ShouldNotBeNull(); + error.Source.Parameter.Should().Be("filter"); } } diff --git a/test/OpenApiEndToEndTests/QueryStrings/PaginationTests.cs b/test/OpenApiEndToEndTests/QueryStrings/PaginationTests.cs index f1e2ac9658..dc7c5892b3 100644 --- a/test/OpenApiEndToEndTests/QueryStrings/PaginationTests.cs +++ b/test/OpenApiEndToEndTests/QueryStrings/PaginationTests.cs @@ -139,10 +139,17 @@ public async Task Cannot_use_empty_page_size() Func action = async () => _ = await apiClient.GetNodeAsync(Unknown.StringId.Int64, queryString); // Assert - ApiException exception = (await action.Should().ThrowExactlyAsync()).Which; + ApiException exception = (await action.Should().ThrowExactlyAsync>()).Which; exception.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); - exception.Message.Should().StartWith("The query string is invalid."); - exception.Message.Should().Contain("Missing value for 'page[size]' query string parameter."); + exception.Message.Should().Be("HTTP 400: The query string is invalid."); + exception.Result.Errors.ShouldHaveCount(1); + + ErrorObject error = exception.Result.Errors.ElementAt(0); + error.Status.Should().Be("400"); + error.Title.Should().Be("Missing query string parameter value."); + error.Detail.Should().Be("Missing value for 'page[size]' query string parameter."); + error.Source.ShouldNotBeNull(); + error.Source.Parameter.Should().Be("page[size]"); } [Fact] @@ -161,9 +168,16 @@ public async Task Cannot_use_empty_page_number() Func action = async () => _ = await apiClient.GetNodeAsync(Unknown.StringId.Int64, queryString); // Assert - ApiException exception = (await action.Should().ThrowExactlyAsync()).Which; + ApiException exception = (await action.Should().ThrowExactlyAsync>()).Which; exception.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); - exception.Message.Should().StartWith("The query string is invalid."); - exception.Message.Should().Contain("Missing value for 'page[number]' query string parameter."); + exception.Message.Should().Be("HTTP 400: The query string is invalid."); + exception.Result.Errors.ShouldHaveCount(1); + + ErrorObject error = exception.Result.Errors.ElementAt(0); + error.Status.Should().Be("400"); + error.Title.Should().Be("Missing query string parameter value."); + error.Detail.Should().Be("Missing value for 'page[number]' query string parameter."); + error.Source.ShouldNotBeNull(); + error.Source.Parameter.Should().Be("page[number]"); } } diff --git a/test/OpenApiEndToEndTests/QueryStrings/SortTests.cs b/test/OpenApiEndToEndTests/QueryStrings/SortTests.cs index e229b7859f..b0ee517f3e 100644 --- a/test/OpenApiEndToEndTests/QueryStrings/SortTests.cs +++ b/test/OpenApiEndToEndTests/QueryStrings/SortTests.cs @@ -138,9 +138,16 @@ public async Task Cannot_use_empty_sort() Func action = async () => _ = await apiClient.GetNodeAsync(Unknown.StringId.Int64, queryString); // Assert - ApiException exception = (await action.Should().ThrowExactlyAsync()).Which; + ApiException exception = (await action.Should().ThrowExactlyAsync>()).Which; exception.StatusCode.Should().Be((int)HttpStatusCode.BadRequest); - exception.Message.Should().StartWith("The query string is invalid."); - exception.Message.Should().Contain("Missing value for 'sort' query string parameter."); + exception.Message.Should().Be("HTTP 400: The query string is invalid."); + exception.Result.Errors.ShouldHaveCount(1); + + ErrorObject error = exception.Result.Errors.ElementAt(0); + error.Status.Should().Be("400"); + error.Title.Should().Be("Missing query string parameter value."); + error.Detail.Should().Be("Missing value for 'sort' query string parameter."); + error.Source.ShouldNotBeNull(); + error.Source.Parameter.Should().Be("sort"); } } diff --git a/test/OpenApiEndToEndTests/QueryStrings/swagger.g.json b/test/OpenApiEndToEndTests/QueryStrings/swagger.g.json index 8e3d17aaeb..f9c5132ed0 100644 --- a/test/OpenApiEndToEndTests/QueryStrings/swagger.g.json +++ b/test/OpenApiEndToEndTests/QueryStrings/swagger.g.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The nameValuePair was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The nameValuePair does not exist." + "description": "The nameValuePair does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The nameValuePair was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The nameValuePair or a related resource does not exist." + "description": "The nameValuePair or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The nameValuePair was successfully deleted." }, "404": { - "description": "The nameValuePair does not exist." + "description": "The nameValuePair does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -378,10 +462,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The nameValuePair does not exist." + "description": "The nameValuePair does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -472,10 +570,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The nameValuePair does not exist." + "description": "The nameValuePair does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -558,13 +670,34 @@ "description": "The owner relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The nameValuePair does not exist." + "description": "The nameValuePair does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -603,7 +736,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -688,16 +828,44 @@ "description": "The node was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -745,10 +913,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -854,16 +1036,44 @@ "description": "The node was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node or a related resource does not exist." + "description": "The node or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -889,7 +1099,14 @@ "description": "The node was successfully deleted." }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -937,10 +1154,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1031,10 +1262,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1117,13 +1362,34 @@ "description": "The nodes were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1163,13 +1429,34 @@ "description": "The children relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1209,13 +1496,34 @@ "description": "The nodes were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1263,10 +1571,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1357,10 +1679,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1443,13 +1779,34 @@ "description": "The parent relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1497,10 +1854,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1591,10 +1962,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1677,13 +2062,34 @@ "description": "The nameValuePairs were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1723,13 +2129,34 @@ "description": "The values relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } }, @@ -1769,13 +2196,34 @@ "description": "The nameValuePairs were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "404": { - "description": "The node does not exist." + "description": "The node does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/errorResponseDocument" + } + } + } } } } @@ -1809,6 +2257,99 @@ }, "x-abstract": true }, + "errorLinks": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "errorObject": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/errorLinks" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/errorSource" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "errorResponseDocument": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/errorObject" + } + } + }, + "additionalProperties": false + }, + "errorSource": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "linksInRelationship": { "required": [ "related", diff --git a/test/OpenApiTests/DocComments/DocCommentsTests.cs b/test/OpenApiTests/DocComments/DocCommentsTests.cs index fc31208918..71fbc68404 100644 --- a/test/OpenApiTests/DocComments/DocCommentsTests.cs +++ b/test/OpenApiTests/DocComments/DocCommentsTests.cs @@ -72,11 +72,11 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[0].description", ResourceTextQueryString); }); - getElement.Should().ContainPath("responses").With(responseElement => + getElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(2); - responseElement.Should().HaveProperty("200.description", "Successfully returns the found skyscrapers, or an empty array if none were found."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.EnumerateObject().ShouldHaveCount(2); + responsesElement.Should().HaveProperty("200.description", "Successfully returns the found skyscrapers, or an empty array if none were found."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); }); }); @@ -92,11 +92,11 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[0].description", ResourceTextQueryString); }); - headElement.Should().ContainPath("responses").With(responseElement => + headElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(2); - responseElement.Should().HaveProperty("200.description", "The operation completed successfully."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.EnumerateObject().ShouldHaveCount(2); + responsesElement.Should().HaveProperty("200.description", "The operation completed successfully."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); }); }); @@ -111,21 +111,21 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[0].description", ResourceTextQueryString); }); - postElement.Should().ContainPath("responses").With(responseElement => + postElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(5); - responseElement.Should().HaveProperty("201.description", "The skyscraper was successfully created, which resulted in additional changes. The newly created skyscraper is returned."); - responseElement.Should().HaveProperty("204.description", "The skyscraper was successfully created, which did not result in additional changes."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid or the request body is missing or malformed."); - responseElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); - responseElement.Should().HaveProperty("422.description", "Validation of the request body failed."); + responsesElement.EnumerateObject().ShouldHaveCount(5); + responsesElement.Should().HaveProperty("201.description", "The skyscraper was successfully created, which resulted in additional changes. The newly created skyscraper is returned."); + responsesElement.Should().HaveProperty("204.description", "The skyscraper was successfully created, which did not result in additional changes."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid or the request body is missing or malformed."); + responsesElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); + responsesElement.Should().HaveProperty("422.description", "Validation of the request body failed."); }); }); }); - document.Should().ContainPath("paths./skyscrapers/{id}").With(skyscrapersElement => + document.Should().ContainPath("paths./skyscrapers/{id}").With(idElement => { - skyscrapersElement.Should().ContainPath("get").With(getElement => + idElement.Should().ContainPath("get").With(getElement => { getElement.Should().HaveProperty("summary", "Retrieves an individual skyscraper by its identifier."); @@ -138,16 +138,16 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", ResourceTextQueryString); }); - getElement.Should().ContainPath("responses").With(responseElement => + getElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "Successfully returns the found skyscraper."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "Successfully returns the found skyscraper."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); - skyscrapersElement.Should().ContainPath("head").With(headElement => + idElement.Should().ContainPath("head").With(headElement => { headElement.Should().HaveProperty("summary", "Retrieves an individual skyscraper by its identifier without returning it."); headElement.Should().HaveProperty("description", "Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched."); @@ -161,16 +161,16 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", ResourceTextQueryString); }); - headElement.Should().ContainPath("responses").With(responseElement => + headElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "The operation completed successfully."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "The operation completed successfully."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); - skyscrapersElement.Should().ContainPath("patch").With(patchElement => + idElement.Should().ContainPath("patch").With(patchElement => { patchElement.Should().HaveProperty("summary", "Updates an existing skyscraper."); @@ -185,41 +185,41 @@ public async Task Endpoints_are_documented() patchElement.Should().HaveProperty("requestBody.description", "The attributes and relationships of the skyscraper to update. Omitted fields are left unchanged."); - patchElement.Should().ContainPath("responses").With(responseElement => + patchElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(6); - responseElement.Should().HaveProperty("200.description", "The skyscraper was successfully updated, which resulted in additional changes. The updated skyscraper is returned."); - responseElement.Should().HaveProperty("204.description", "The skyscraper was successfully updated, which did not result in additional changes."); - responseElement.Should().HaveProperty("404.description", "The skyscraper or a related resource does not exist."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid or the request body is missing or malformed."); - responseElement.Should().HaveProperty("409.description", "A resource type or identifier in the request body is incompatible."); - responseElement.Should().HaveProperty("422.description", "Validation of the request body failed."); + responsesElement.EnumerateObject().ShouldHaveCount(6); + responsesElement.Should().HaveProperty("200.description", "The skyscraper was successfully updated, which resulted in additional changes. The updated skyscraper is returned."); + responsesElement.Should().HaveProperty("204.description", "The skyscraper was successfully updated, which did not result in additional changes."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid or the request body is missing or malformed."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper or a related resource does not exist."); + responsesElement.Should().HaveProperty("409.description", "A resource type or identifier in the request body is incompatible."); + responsesElement.Should().HaveProperty("422.description", "Validation of the request body failed."); }); }); - skyscrapersElement.Should().ContainPath("delete").With(patchElement => + idElement.Should().ContainPath("delete").With(deleteElement => { - patchElement.Should().HaveProperty("summary", "Deletes an existing skyscraper by its identifier."); + deleteElement.Should().HaveProperty("summary", "Deletes an existing skyscraper by its identifier."); - patchElement.Should().ContainPath("parameters").With(parametersElement => + deleteElement.Should().ContainPath("parameters").With(parametersElement => { parametersElement.EnumerateArray().ShouldHaveCount(1); parametersElement.Should().HaveProperty("[0].in", "path"); parametersElement.Should().HaveProperty("[0].description", "The identifier of the skyscraper to delete."); }); - patchElement.Should().ContainPath("responses").With(responseElement => + deleteElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(2); - responseElement.Should().HaveProperty("204.description", "The skyscraper was successfully deleted."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(2); + responsesElement.Should().HaveProperty("204.description", "The skyscraper was successfully deleted."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); }); - document.Should().ContainPath("paths./skyscrapers/{id}/elevator").With(skyscrapersElement => + document.Should().ContainPath("paths./skyscrapers/{id}/elevator").With(elevatorElement => { - skyscrapersElement.Should().ContainPath("get").With(getElement => + elevatorElement.Should().ContainPath("get").With(getElement => { getElement.Should().HaveProperty("summary", "Retrieves the related elevator of an individual skyscraper's elevator relationship."); @@ -232,16 +232,16 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", ResourceTextQueryString); }); - getElement.Should().ContainPath("responses").With(responseElement => + getElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "Successfully returns the found elevator, or `null` if it was not found."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "Successfully returns the found elevator, or `null` if it was not found."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); - skyscrapersElement.Should().ContainPath("head").With(headElement => + elevatorElement.Should().ContainPath("head").With(headElement => { headElement.Should().HaveProperty("summary", "Retrieves the related elevator of an individual skyscraper's elevator relationship without returning it."); headElement.Should().HaveProperty("description", "Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched."); @@ -255,19 +255,19 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", ResourceTextQueryString); }); - headElement.Should().ContainPath("responses").With(responseElement => + headElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "The operation completed successfully."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "The operation completed successfully."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); }); - document.Should().ContainPath("paths./skyscrapers/{id}/relationships/elevator").With(skyscrapersElement => + document.Should().ContainPath("paths./skyscrapers/{id}/relationships/elevator").With(elevatorElement => { - skyscrapersElement.Should().ContainPath("get").With(getElement => + elevatorElement.Should().ContainPath("get").With(getElement => { getElement.Should().HaveProperty("summary", "Retrieves the related elevator identity of an individual skyscraper's elevator relationship."); @@ -280,16 +280,16 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", RelationshipTextQueryString); }); - getElement.Should().ContainPath("responses").With(responseElement => + getElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "Successfully returns the found elevator identity, or `null` if it was not found."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "Successfully returns the found elevator identity, or `null` if it was not found."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); - skyscrapersElement.Should().ContainPath("head").With(headElement => + elevatorElement.Should().ContainPath("head").With(headElement => { headElement.Should().HaveProperty("summary", "Retrieves the related elevator identity of an individual skyscraper's elevator relationship without returning it."); headElement.Should().HaveProperty("description", "Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched."); @@ -303,16 +303,16 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", RelationshipTextQueryString); }); - headElement.Should().ContainPath("responses").With(responseElement => + headElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "The operation completed successfully."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "The operation completed successfully."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); - skyscrapersElement.Should().ContainPath("patch").With(patchElement => + elevatorElement.Should().ContainPath("patch").With(patchElement => { patchElement.Should().HaveProperty("summary", "Clears or assigns an existing elevator to the elevator relationship of an individual skyscraper."); @@ -325,20 +325,20 @@ public async Task Endpoints_are_documented() patchElement.Should().HaveProperty("requestBody.description", "The identity of the elevator to assign to the elevator relationship, or `null` to clear the relationship."); - patchElement.Should().ContainPath("responses").With(responseElement => + patchElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(4); - responseElement.Should().HaveProperty("204.description", "The elevator relationship was successfully updated, which did not result in additional changes."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); - responseElement.Should().HaveProperty("400.description", "The request body is missing or malformed."); - responseElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); + responsesElement.EnumerateObject().ShouldHaveCount(4); + responsesElement.Should().HaveProperty("204.description", "The elevator relationship was successfully updated, which did not result in additional changes."); + responsesElement.Should().HaveProperty("400.description", "The request body is missing or malformed."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); }); }); }); - document.Should().ContainPath("paths./skyscrapers/{id}/spaces").With(skyscrapersElement => + document.Should().ContainPath("paths./skyscrapers/{id}/spaces").With(spacesElement => { - skyscrapersElement.Should().ContainPath("get").With(getElement => + spacesElement.Should().ContainPath("get").With(getElement => { getElement.Should().HaveProperty("summary", "Retrieves the related spaces of an individual skyscraper's spaces relationship."); @@ -351,16 +351,16 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", ResourceTextQueryString); }); - getElement.Should().ContainPath("responses").With(responseElement => + getElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "Successfully returns the found spaces, or an empty array if none were found."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "Successfully returns the found spaces, or an empty array if none were found."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); - skyscrapersElement.Should().ContainPath("head").With(headElement => + spacesElement.Should().ContainPath("head").With(headElement => { headElement.Should().HaveProperty("summary", "Retrieves the related spaces of an individual skyscraper's spaces relationship without returning them."); headElement.Should().HaveProperty("description", "Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched."); @@ -374,19 +374,19 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", ResourceTextQueryString); }); - headElement.Should().ContainPath("responses").With(responseElement => + headElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "The operation completed successfully."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "The operation completed successfully."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); }); - document.Should().ContainPath("paths./skyscrapers/{id}/relationships/spaces").With(skyscrapersElement => + document.Should().ContainPath("paths./skyscrapers/{id}/relationships/spaces").With(spacesElement => { - skyscrapersElement.Should().ContainPath("get").With(getElement => + spacesElement.Should().ContainPath("get").With(getElement => { getElement.Should().HaveProperty("summary", "Retrieves the related space identities of an individual skyscraper's spaces relationship."); @@ -399,16 +399,16 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", RelationshipTextQueryString); }); - getElement.Should().ContainPath("responses").With(responseElement => + getElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "Successfully returns the found space identities, or an empty array if none were found."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "Successfully returns the found space identities, or an empty array if none were found."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); - skyscrapersElement.Should().ContainPath("head").With(headElement => + spacesElement.Should().ContainPath("head").With(headElement => { headElement.Should().HaveProperty("summary", "Retrieves the related space identities of an individual skyscraper's spaces relationship without returning them."); headElement.Should().HaveProperty("description", "Compare the returned ETag HTTP header with an earlier one to determine if the response has changed since it was fetched."); @@ -422,39 +422,39 @@ public async Task Endpoints_are_documented() parametersElement.Should().HaveProperty("[1].description", RelationshipTextQueryString); }); - headElement.Should().ContainPath("responses").With(responseElement => + headElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(3); - responseElement.Should().HaveProperty("200.description", "The operation completed successfully."); - responseElement.Should().HaveProperty("400.description", "The query string is invalid."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.EnumerateObject().ShouldHaveCount(3); + responsesElement.Should().HaveProperty("200.description", "The operation completed successfully."); + responsesElement.Should().HaveProperty("400.description", "The query string is invalid."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); }); }); - skyscrapersElement.Should().ContainPath("post").With(patchElement => + spacesElement.Should().ContainPath("post").With(postElement => { - patchElement.Should().HaveProperty("summary", "Adds existing spaces to the spaces relationship of an individual skyscraper."); + postElement.Should().HaveProperty("summary", "Adds existing spaces to the spaces relationship of an individual skyscraper."); - patchElement.Should().ContainPath("parameters").With(parametersElement => + postElement.Should().ContainPath("parameters").With(parametersElement => { parametersElement.EnumerateArray().ShouldHaveCount(1); parametersElement.Should().HaveProperty("[0].in", "path"); parametersElement.Should().HaveProperty("[0].description", "The identifier of the skyscraper to add spaces to."); }); - patchElement.Should().HaveProperty("requestBody.description", "The identities of the spaces to add to the spaces relationship."); + postElement.Should().HaveProperty("requestBody.description", "The identities of the spaces to add to the spaces relationship."); - patchElement.Should().ContainPath("responses").With(responseElement => + postElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(4); - responseElement.Should().HaveProperty("204.description", "The spaces were successfully added, which did not result in additional changes."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); - responseElement.Should().HaveProperty("400.description", "The request body is missing or malformed."); - responseElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); + responsesElement.EnumerateObject().ShouldHaveCount(4); + responsesElement.Should().HaveProperty("204.description", "The spaces were successfully added, which did not result in additional changes."); + responsesElement.Should().HaveProperty("400.description", "The request body is missing or malformed."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); }); }); - skyscrapersElement.Should().ContainPath("patch").With(patchElement => + spacesElement.Should().ContainPath("patch").With(patchElement => { patchElement.Should().HaveProperty("summary", "Assigns existing spaces to the spaces relationship of an individual skyscraper."); @@ -467,36 +467,36 @@ public async Task Endpoints_are_documented() patchElement.Should().HaveProperty("requestBody.description", "The identities of the spaces to assign to the spaces relationship, or an empty array to clear the relationship."); - patchElement.Should().ContainPath("responses").With(responseElement => + patchElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(4); - responseElement.Should().HaveProperty("204.description", "The spaces relationship was successfully updated, which did not result in additional changes."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); - responseElement.Should().HaveProperty("400.description", "The request body is missing or malformed."); - responseElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); + responsesElement.EnumerateObject().ShouldHaveCount(4); + responsesElement.Should().HaveProperty("204.description", "The spaces relationship was successfully updated, which did not result in additional changes."); + responsesElement.Should().HaveProperty("400.description", "The request body is missing or malformed."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); }); }); - skyscrapersElement.Should().ContainPath("delete").With(patchElement => + spacesElement.Should().ContainPath("delete").With(deleteElement => { - patchElement.Should().HaveProperty("summary", "Removes existing spaces from the spaces relationship of an individual skyscraper."); + deleteElement.Should().HaveProperty("summary", "Removes existing spaces from the spaces relationship of an individual skyscraper."); - patchElement.Should().ContainPath("parameters").With(parametersElement => + deleteElement.Should().ContainPath("parameters").With(parametersElement => { parametersElement.EnumerateArray().ShouldHaveCount(1); parametersElement.Should().HaveProperty("[0].in", "path"); parametersElement.Should().HaveProperty("[0].description", "The identifier of the skyscraper to remove spaces from."); }); - patchElement.Should().HaveProperty("requestBody.description", "The identities of the spaces to remove from the spaces relationship."); + deleteElement.Should().HaveProperty("requestBody.description", "The identities of the spaces to remove from the spaces relationship."); - patchElement.Should().ContainPath("responses").With(responseElement => + deleteElement.Should().ContainPath("responses").With(responsesElement => { - responseElement.EnumerateObject().ShouldHaveCount(4); - responseElement.Should().HaveProperty("204.description", "The spaces were successfully removed, which did not result in additional changes."); - responseElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); - responseElement.Should().HaveProperty("400.description", "The request body is missing or malformed."); - responseElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); + responsesElement.EnumerateObject().ShouldHaveCount(4); + responsesElement.Should().HaveProperty("204.description", "The spaces were successfully removed, which did not result in additional changes."); + responsesElement.Should().HaveProperty("400.description", "The request body is missing or malformed."); + responsesElement.Should().HaveProperty("404.description", "The skyscraper does not exist."); + responsesElement.Should().HaveProperty("409.description", "A resource type in the request body is incompatible."); }); }); }); @@ -619,9 +619,9 @@ public async Task Forbidden_status_is_added_when_client_generated_IDs_are_disabl JsonElement document = await _testContext.GetSwaggerDocumentAsync(); // Assert - document.Should().ContainPath("paths./elevators.post.responses").With(responseElement => + document.Should().ContainPath("paths./elevators.post.responses").With(responsesElement => { - responseElement.Should().HaveProperty("403.description", "Client-generated IDs cannot be used at this endpoint."); + responsesElement.Should().HaveProperty("403.description", "Client-generated IDs cannot be used at this endpoint."); }); } } diff --git a/test/OpenApiTests/DocComments/ErrorResponseTests.cs b/test/OpenApiTests/DocComments/ErrorResponseTests.cs new file mode 100644 index 0000000000..951ad58356 --- /dev/null +++ b/test/OpenApiTests/DocComments/ErrorResponseTests.cs @@ -0,0 +1,301 @@ +using System.Text.Json; +using FluentAssertions; +using TestBuildingBlocks; +using Xunit; + +namespace OpenApiTests.DocComments; + +public sealed class ErrorResponseTests : IClassFixture, DocCommentsDbContext>> +{ + private const string EscapedJsonApiMediaType = "['application/vnd.api+json']"; + + private readonly OpenApiTestContext, DocCommentsDbContext> _testContext; + + public ErrorResponseTests(OpenApiTestContext, DocCommentsDbContext> testContext) + { + _testContext = testContext; + + testContext.UseController(); + testContext.UseController(); + testContext.UseController(); + } + + [Fact] + public async Task Applicable_error_status_codes_with_schema_are_provided_on_endpoints() + { + // Act + JsonElement document = await _testContext.GetSwaggerDocumentAsync(); + + // Assert + document.Should().ContainPath("paths./skyscrapers").With(skyscrapersElement => + { + skyscrapersElement.Should().ContainPath("get.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(1); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + + skyscrapersElement.Should().ContainPath("head.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(1); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + + errorStatusCodeProperties.Should().AllSatisfy(property => property.Value.Should().NotContainPath("content")); + }); + + skyscrapersElement.Should().ContainPath("post.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(3); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("409"); + errorStatusCodeProperties[2].Name.Should().Be("422"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + }); + + document.Should().ContainPath("paths./skyscrapers/{id}").With(idElement => + { + idElement.Should().ContainPath("get.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + + idElement.Should().ContainPath("head.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => property.Value.Should().NotContainPath("content")); + }); + + idElement.Should().ContainPath("patch.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(4); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + errorStatusCodeProperties[2].Name.Should().Be("409"); + errorStatusCodeProperties[3].Name.Should().Be("422"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + + idElement.Should().ContainPath("delete.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(1); + + errorStatusCodeProperties[0].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + }); + + document.Should().ContainPath("paths./skyscrapers/{id}/elevator").With(elevatorElement => + { + elevatorElement.Should().ContainPath("get.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + + elevatorElement.Should().ContainPath("head.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => property.Value.Should().NotContainPath("content")); + }); + }); + + document.Should().ContainPath("paths./skyscrapers/{id}/relationships/elevator").With(elevatorElement => + { + elevatorElement.Should().ContainPath("get.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + + elevatorElement.Should().ContainPath("head.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => property.Value.Should().NotContainPath("content")); + }); + + elevatorElement.Should().ContainPath("patch.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(3); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + errorStatusCodeProperties[2].Name.Should().Be("409"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + }); + + document.Should().ContainPath("paths./skyscrapers/{id}/spaces").With(spacesElement => + { + spacesElement.Should().ContainPath("get.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + + spacesElement.Should().ContainPath("head.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => property.Value.Should().NotContainPath("content")); + }); + }); + + document.Should().ContainPath("paths./skyscrapers/{id}/relationships/spaces").With(spacesElement => + { + spacesElement.Should().ContainPath("get.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + + spacesElement.Should().ContainPath("head.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(2); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + + errorStatusCodeProperties.Should().AllSatisfy(property => property.Value.Should().NotContainPath("content")); + }); + + spacesElement.Should().ContainPath("post.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(3); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + errorStatusCodeProperties[2].Name.Should().Be("409"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + + spacesElement.Should().ContainPath("patch.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(3); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + errorStatusCodeProperties[2].Name.Should().Be("409"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + + spacesElement.Should().ContainPath("delete.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(3); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("404"); + errorStatusCodeProperties[2].Name.Should().Be("409"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + }); + } + + [Fact] + public async Task Forbidden_status_is_added_when_client_generated_IDs_are_disabled() + { + // Act + JsonElement document = await _testContext.GetSwaggerDocumentAsync(); + + // Assert + document.Should().ContainPath("paths./elevators.post.responses").With(responsesElement => + { + JsonProperty[] errorStatusCodeProperties = responsesElement.EnumerateObject().Where(IsErrorStatusCode).ToArray(); + errorStatusCodeProperties.ShouldHaveCount(4); + + errorStatusCodeProperties[0].Name.Should().Be("400"); + errorStatusCodeProperties[1].Name.Should().Be("403"); + errorStatusCodeProperties[2].Name.Should().Be("409"); + errorStatusCodeProperties[3].Name.Should().Be("422"); + + errorStatusCodeProperties.Should().AllSatisfy(property => + property.Value.Should().ContainPath($"content.{EscapedJsonApiMediaType}.schema.$ref").ShouldBeSchemaReferenceId("errorResponseDocument")); + }); + } + + private static bool IsErrorStatusCode(JsonProperty statusCodeProperty) + { + return int.TryParse(statusCodeProperty.Name, out int statusCodeValue) && statusCodeValue >= 400; + } +} diff --git a/test/OpenApiTests/LegacyOpenApiIntegration/swagger.json b/test/OpenApiTests/LegacyOpenApiIntegration/swagger.json index 1a86868059..7736381583 100644 --- a/test/OpenApiTests/LegacyOpenApiIntegration/swagger.json +++ b/test/OpenApiTests/LegacyOpenApiIntegration/swagger.json @@ -44,7 +44,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -129,16 +136,44 @@ "description": "The airplane was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -186,10 +221,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -295,16 +344,44 @@ "description": "The airplane was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane or a related resource does not exist." + "description": "The airplane or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -330,7 +407,14 @@ "description": "The airplane was successfully deleted." }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -378,10 +462,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -472,10 +570,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -558,13 +670,34 @@ "description": "The flights were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -604,13 +737,34 @@ "description": "The flights relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -650,13 +804,34 @@ "description": "The flights were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The airplane does not exist." + "description": "The airplane does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -695,7 +870,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -780,16 +962,44 @@ "description": "The flight-attendant was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -837,10 +1047,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -946,16 +1170,44 @@ "description": "The flight-attendant was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant or a related resource does not exist." + "description": "The flight-attendant or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -981,7 +1233,14 @@ "description": "The flight-attendant was successfully deleted." }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1029,10 +1288,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1123,11 +1396,25 @@ } }, "400": { - "description": "The query string is invalid." - }, - "404": { - "description": "The flight-attendant does not exist." - } + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } + }, + "404": { + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } + } } }, "head": { @@ -1209,13 +1496,34 @@ "description": "The flights were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1255,13 +1563,34 @@ "description": "The purser-on-flights relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1301,13 +1630,34 @@ "description": "The flights were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1355,10 +1705,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1449,10 +1813,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1535,13 +1913,34 @@ "description": "The flights were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1581,13 +1980,34 @@ "description": "The scheduled-for-flights relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1627,13 +2047,34 @@ "description": "The flights were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight-attendant does not exist." + "description": "The flight-attendant does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1672,7 +2113,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1757,16 +2205,44 @@ "description": "The flight was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -1814,10 +2290,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1923,16 +2413,44 @@ "description": "The flight was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight or a related resource does not exist." + "description": "The flight or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -1958,7 +2476,14 @@ "description": "The flight was successfully deleted." }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -2006,10 +2531,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2100,10 +2639,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2186,13 +2739,34 @@ "description": "The backup-purser relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -2240,10 +2814,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2334,10 +2922,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2420,13 +3022,34 @@ "description": "The flight-attendants were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2466,13 +3089,34 @@ "description": "The cabin-crew-members relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2512,13 +3156,34 @@ "description": "The flight-attendants were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -2566,10 +3231,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2660,10 +3339,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2746,13 +3439,34 @@ "description": "The passengers were successfully added, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2792,13 +3506,34 @@ "description": "The passengers relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2838,13 +3573,34 @@ "description": "The passengers were successfully removed, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -2892,10 +3648,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -2986,10 +3756,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -3072,13 +3856,34 @@ "description": "The purser relationship was successfully updated, which did not result in additional changes." }, "400": { - "description": "The request body is missing or malformed." + "description": "The request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The flight does not exist." + "description": "The flight does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -3117,7 +3922,14 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -3202,16 +4014,44 @@ "description": "The passenger was successfully created, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "403": { - "description": "Client-generated IDs cannot be used at this endpoint." + "description": "Client-generated IDs cannot be used at this endpoint.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type in the request body is incompatible." + "description": "A resource type in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -3259,10 +4099,24 @@ } }, "400": { - "description": "The query string is invalid." + "description": "The query string is invalid.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The passenger does not exist." + "description": "The passenger does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -3368,16 +4222,44 @@ "description": "The passenger was successfully updated, which did not result in additional changes." }, "400": { - "description": "The query string is invalid or the request body is missing or malformed." + "description": "The query string is invalid or the request body is missing or malformed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "404": { - "description": "The passenger or a related resource does not exist." + "description": "The passenger or a related resource does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "409": { - "description": "A resource type or identifier in the request body is incompatible." + "description": "A resource type or identifier in the request body is incompatible.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } }, "422": { - "description": "Validation of the request body failed." + "description": "Validation of the request body failed.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } }, @@ -3403,7 +4285,14 @@ "description": "The passenger was successfully deleted." }, "404": { - "description": "The passenger does not exist." + "description": "The passenger does not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/error-response-document" + } + } + } } } } @@ -3838,6 +4727,99 @@ }, "x-abstract": true }, + "error-links": { + "type": "object", + "properties": { + "about": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "error-object": { + "type": "object", + "properties": { + "id": { + "type": "string", + "nullable": true + }, + "links": { + "allOf": [ + { + "$ref": "#/components/schemas/error-links" + } + ], + "nullable": true + }, + "status": { + "type": "string" + }, + "code": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "detail": { + "type": "string", + "nullable": true + }, + "source": { + "allOf": [ + { + "$ref": "#/components/schemas/error-source" + } + ], + "nullable": true + }, + "meta": { + "type": "object", + "additionalProperties": { }, + "nullable": true + } + }, + "additionalProperties": false + }, + "error-response-document": { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/error-object" + } + } + }, + "additionalProperties": false + }, + "error-source": { + "type": "object", + "properties": { + "pointer": { + "type": "string", + "nullable": true + }, + "parameter": { + "type": "string", + "nullable": true + }, + "header": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "flight-attendant-attributes-in-patch-request": { "type": "object", "properties": { diff --git a/test/OpenApiTests/NamingConventions/CamelCase/CamelCaseTests.cs b/test/OpenApiTests/NamingConventions/CamelCase/CamelCaseTests.cs index db8744fcbc..ea72e0ba11 100644 --- a/test/OpenApiTests/NamingConventions/CamelCase/CamelCaseTests.cs +++ b/test/OpenApiTests/NamingConventions/CamelCase/CamelCaseTests.cs @@ -550,4 +550,14 @@ public async Task Casing_convention_is_applied_to_DeleteRelationship_endpoint() }); }); } + + [Fact] + public async Task Casing_convention_is_applied_to_error_schema() + { + // Act + JsonElement document = await _testContext.GetSwaggerDocumentAsync(); + + // Assert + document.Should().ContainPath("components.schemas.errorResponseDocument"); + } } diff --git a/test/OpenApiTests/NamingConventions/KebabCase/KebabCaseTests.cs b/test/OpenApiTests/NamingConventions/KebabCase/KebabCaseTests.cs index ef97791ab1..6c170ed024 100644 --- a/test/OpenApiTests/NamingConventions/KebabCase/KebabCaseTests.cs +++ b/test/OpenApiTests/NamingConventions/KebabCase/KebabCaseTests.cs @@ -552,4 +552,14 @@ public async Task Casing_convention_is_applied_to_DeleteRelationship_endpoint() }); }); } + + [Fact] + public async Task Casing_convention_is_applied_to_error_schema() + { + // Act + JsonElement document = await _testContext.GetSwaggerDocumentAsync(); + + // Assert + document.Should().ContainPath("components.schemas.error-response-document"); + } } diff --git a/test/OpenApiTests/NamingConventions/PascalCase/PascalCaseTests.cs b/test/OpenApiTests/NamingConventions/PascalCase/PascalCaseTests.cs index f357e095eb..f501828e36 100644 --- a/test/OpenApiTests/NamingConventions/PascalCase/PascalCaseTests.cs +++ b/test/OpenApiTests/NamingConventions/PascalCase/PascalCaseTests.cs @@ -551,4 +551,14 @@ public async Task Casing_convention_is_applied_to_DeleteRelationship_endpoint() }); }); } + + [Fact] + public async Task Casing_convention_is_applied_to_error_schema() + { + // Act + JsonElement document = await _testContext.GetSwaggerDocumentAsync(); + + // Assert + document.Should().ContainPath("components.schemas.ErrorResponseDocument"); + } }