Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,350 @@
import testRule from './__helpers__/testRule';
import { DiagnosticSeverity } from '@stoplight/types';

const componentSchemas = {
schemas: {
ResourceSchema: {
type: 'object',
properties: {
id: { type: 'string', readOnly: true },
name: { type: 'string' },
description: { type: 'string' },
createdAt: { type: 'string', readOnly: true },
},
},
OtherSchema: {
type: 'object',
properties: {
id: { type: 'string' },
name: { type: 'string' },
},
},
},
};

testRule('xgen-IPA-106-create-method-response-is-get-method-response', [
{
name: 'valid create requests',
document: {
paths: {
'/resources': {
post: {
responses: {
201: {
content: {
'application/vnd.atlas.2024-08-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
},
'/resources/{id}': {
get: {
responses: {
200: {
content: {
'application/vnd.atlas.2024-08-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
},
// Multiple versions
'/versionedResources': {
post: {
responses: {
201: {
content: {
'application/vnd.atlas.2024-08-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
'application/vnd.atlas.2024-01-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
},
'/versionedResources/{id}': {
get: {
responses: {
200: {
content: {
'application/vnd.atlas.2024-08-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
'application/vnd.atlas.2024-01-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
},
},
components: componentSchemas,
},
errors: [],
},
{
name: 'rule ignores inapplicable cases',
document: {
paths: {
// Path not ending in collection
'/not/a/collection/resource': {
post: {
requestBody: {
content: {
'application/vnd.atlas.2024-08-05+json': {
schema: {
type: 'object',
properties: {
name: { type: 'string' },
},
},
},
},
},
},
},
// Version mismatch but will be ignored
'/versionMismatchResources': {
post: {
requestBody: {
content: {
'application/vnd.atlas.2024-01-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
'/versionMismatchResources/{id}': {
get: {
responses: {
200: {
content: {
'application/vnd.atlas.2024-08-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
},
},
components: componentSchemas,
},
errors: [],
},
{
name: 'invalid create requests',
document: {
paths: {
// Get without schema
'/resourcesOne': {
post: {
responses: {
201: {
content: {
'application/vnd.atlas.2024-01-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
},
'/resourcesOne/{id}': {
get: {
responses: {
200: {
content: {
'application/vnd.atlas.2024-01-05+json': {},
},
},
},
},
},
// Get without schema ref
'/resourcesTwo': {
post: {
responses: {
201: {
content: {
'application/vnd.atlas.2024-01-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
},
'/resourcesTwo/{id}': {
get: {
responses: {
200: {
content: {
'application/vnd.atlas.2024-01-05+json': {
schema: {
type: 'string',
},
},
},
},
},
},
},
},
components: componentSchemas,
},
errors: [
{
code: 'xgen-IPA-106-create-method-response-is-get-method-response',
message:
'Could not validate that the Create method returns the same resource object as the Get method. The Get method does not have a schema.',
path: [
'paths',
'/resourcesOne',
'post',
'responses',
'201',
'content',
'application/vnd.atlas.2024-01-05+json',
],
severity: DiagnosticSeverity.Warning,
},
{
code: 'xgen-IPA-106-create-method-response-is-get-method-response',
message:
'Could not validate that the Create method returns the same resource object as the Get method. The Get method does not have a schema reference.',
path: [
'paths',
'/resourcesTwo',
'post',
'responses',
'201',
'content',
'application/vnd.atlas.2024-01-05+json',
],
severity: DiagnosticSeverity.Warning,
},
],
},
{
name: 'invalid with version mismatch',
document: {
paths: {
'/resources': {
post: {
responses: {
201: {
content: {
'application/vnd.atlas.2024-08-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
},
'/resources/{id}': {
get: {
responses: {
200: {
content: {
'application/vnd.atlas.2024-01-05+json': {
schema: {
$ref: '#/components/schemas/OtherSchema',
},
},
},
},
},
},
},
},
components: componentSchemas,
},
errors: [
{
code: 'xgen-IPA-106-create-method-response-is-get-method-response',
message: 'The schema in the Create method response must be the same schema as the response of the Get method.',
path: ['paths', '/resources', 'post', 'responses', '201', 'content', 'application/vnd.atlas.2024-08-05+json'],
severity: DiagnosticSeverity.Warning,
},
],
},
{
name: 'invalid with exception',
document: {
paths: {
'/resources': {
post: {
responses: {
201: {
content: {
'application/vnd.atlas.2024-08-05+json': {
'x-xgen-IPA-exception': {
'xgen-IPA-106-create-method-response-is-get-method-response': 'Exception reason',
},
schema: {
type: 'object',
properties: {
completelyDifferent: { type: 'boolean' },
},
},
},
},
},
},
},
},
'/resources/{id}': {
get: {
responses: {
200: {
content: {
'application/vnd.atlas.2024-08-05+json': {
schema: {
$ref: '#/components/schemas/ResourceSchema',
},
},
},
},
},
},
},
},
components: componentSchemas,
},
errors: [],
},
]);
4 changes: 2 additions & 2 deletions tools/spectral/ipa/rulesets/IPA-105.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ rules:

##### Implementation details

Validation checks that the List method response contains items property with reference to the same schema as the Get method response.
Validation checks that the List method 200 OK response contains items property with reference to the same schema as the Get method response.

- Validation applies to List methods for resource collections only
- Validation applies to json response content only
Expand All @@ -46,7 +46,7 @@ rules:
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-105-list-method-response-is-get-method-response'
severity: warn
given: '$.paths[*].get.responses[*].content'
given: '$.paths[*].get.responses.200.content'
then:
field: '@key'
function: 'listMethodResponseIsGetMethodResponse'
20 changes: 20 additions & 0 deletions tools/spectral/ipa/rulesets/IPA-106.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ functions:
- createMethodRequestBodyIsGetResponse
- createMethodRequestHasNoReadonlyFields
- createMethodResponseCodeIs201Created
- createMethodResponseIsGetMethodResponse

rules:
xgen-IPA-106-create-method-request-body-is-request-suffixed-object:
Expand Down Expand Up @@ -76,3 +77,22 @@ rules:
given: '$.paths[*].post'
then:
function: 'createMethodResponseCodeIs201Created'
xgen-IPA-106-create-method-response-is-get-method-response:
description: >-
The response body of the Create method should consist of the same resource object returned by the Get method.

##### Implementation details

Validation checks that the Create method 201 Created response contains reference to the same schema as the Get method response.

- Validation applies to Create methods for resource collections only
- Validation applies to json response content only
- Validation ignores responses without schema
- Validation ignores resources without a Get method
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-106-create-method-response-is-get-method-response'
severity: warn
given: '$.paths[*].post.responses.201.content'
then:
field: '@key'
function: 'createMethodResponseIsGetMethodResponse'
Loading
Loading