Skip to content
Draft
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
Expand Up @@ -94,6 +94,100 @@ testRule('xgen-IPA-113-singleton-should-have-update-method', [
},
errors: [],
},
{
name: 'read-only singleton with referenced nested schema does not require update method',
document: {
paths: {
'/resource/{exampleId}/readOnlySingleton': {
get: {
responses: {
200: {
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/ReadOnlySingleton',
},
},
},
},
},
},
},
},
components: {
schemas: {
ReadOnlySingleton: {
type: 'object',
properties: {
status: { type: 'string', readOnly: true },
metadata: {
$ref: '#/components/schemas/ReadOnlyMetadata',
},
},
},
ReadOnlyMetadata: {
type: 'object',
properties: {
createdAt: { type: 'string', readOnly: true },
updatedAt: { type: 'string', readOnly: true },
},
},
},
},
},
errors: [],
},
{
name: 'singleton with writable property in referenced nested schema requires update method',
document: {
paths: {
'/resource/{exampleId}/writableSingleton': {
get: {
responses: {
200: {
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/WritableSingleton',
},
},
},
},
},
},
},
},
components: {
schemas: {
WritableSingleton: {
type: 'object',
properties: {
status: { type: 'string', readOnly: true },
metadata: {
$ref: '#/components/schemas/WritableMetadata',
},
},
},
WritableMetadata: {
type: 'object',
properties: {
createdAt: { type: 'string', readOnly: true },
displayName: { type: 'string' },
},
},
},
},
},
errors: [
{
code: 'xgen-IPA-113-singleton-should-have-update-method',
message:
'Singleton resources should define the Update method. If this is not a singleton resource, please implement all CRUDL methods.',
path: ['paths', '/resource/{exampleId}/writableSingleton'],
severity: DiagnosticSeverity.Error,
},
],
},
{
name: 'read-only singleton with List response',
document: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import testRule from './__helpers__/testRule';
import { DiagnosticSeverity } from '@stoplight/types';

const READ_ONLY_SCHEMA_ERROR_MESSAGE =
'The Operation resource must be read-only. All properties of the GET response schema must be marked as readOnly: true.';
'The Operation resource must be read-only. All properties of the GET response schema must be marked as readOnly: true or contain only read-only properties.';

const readOnlyGet = {
responses: {
Expand Down
88 changes: 88 additions & 0 deletions tools/spectral/ipa/__tests__/utils/resourceEvaluation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,82 @@ describe('tools/spectral/ipa/rulesets/functions/utils/resourceEvaluation.js', ()
},
expected: true,
},
{
description: 'schema with unmarked nested object containing only readOnly properties',
schema: {
type: 'object',
properties: {
metadata: {
type: 'object',
properties: {
createdBy: { type: 'string', readOnly: true },
updatedBy: { type: 'string', readOnly: true },
},
},
},
},
expected: true,
},
{
description: 'schema with nested object containing a writable property',
schema: {
type: 'object',
properties: {
metadata: {
type: 'object',
properties: {
createdBy: { type: 'string', readOnly: true },
displayName: { type: 'string' },
},
},
},
},
expected: false,
},
{
description: 'schema with nested array containing only readOnly properties',
schema: {
type: 'object',
properties: {
entries: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string', readOnly: true },
status: { type: 'string', readOnly: true },
},
},
},
},
},
expected: true,
},
{
description: 'schema with nested allOf containing only readOnly properties',
schema: {
type: 'object',
properties: {
metadata: {
allOf: [
{
type: 'object',
properties: {
createdBy: { type: 'string', readOnly: true },
},
},
{
type: 'object',
properties: {
updatedBy: { type: 'string', readOnly: true },
},
},
],
},
},
},
expected: true,
},
{
description: 'schema with array items all readOnly',
schema: {
Expand Down Expand Up @@ -538,6 +614,18 @@ describe('tools/spectral/ipa/rulesets/functions/utils/resourceEvaluation.js', ()
expect(allPropertiesAreReadOnly(testCase.schema)).toEqual(testCase.expected);
});
});

it('returns false for an unmarked circular schema', () => {
const schema = {
type: 'object',
properties: {
id: { type: 'string', readOnly: true },
},
};
schema.properties.parent = schema;

expect(allPropertiesAreReadOnly(schema)).toEqual(false);
});
});

describe('isReadOnlyResource', () => {
Expand Down
2 changes: 1 addition & 1 deletion tools/spectral/ipa/rulesets/IPA-106.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ rules:
##### Implementation details
Rule checks for the following conditions:
- Applies to POST methods on resource collection paths
- Checks if the resource is a read-only resource (all properties in GET response have readOnly:true)
- Checks if the resource is a read-only resource (all properties in the GET response are marked as readOnly or contain only read-only properties)
- If a resource does not have a standard GET method, it is not considered read-only (cannot determine the resource schema)
- Fails if a Create method is defined on a read-only resource
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
Expand Down
2 changes: 1 addition & 1 deletion tools/spectral/ipa/rulesets/IPA-107.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ rules:
##### Implementation details
Rule checks for the following conditions:
- Applies to PUT/PATCH methods on all resource paths
- Checks if the resource is a read-only resource (all properties in GET response have readOnly:true)
- Checks if the resource is a read-only resource (all properties in the GET response are marked as readOnly or contain only read-only properties)
- If a resource does not have a standard GET method, it is not considered read-only (cannot determine the resource schema)
- Fails if an Update method is defined on a read-only resource
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
Expand Down
2 changes: 1 addition & 1 deletion tools/spectral/ipa/rulesets/IPA-108.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ rules:
##### Implementation details
Rule checks for the following conditions:
- Applies to DELETE methods on single resource paths and singleton resources
- Checks if the resource is a read-only resource (all properties in GET response have readOnly:true)
- Checks if the resource is a read-only resource (all properties in the GET response are marked as readOnly or contain only read-only properties)
- If a resource does not have a standard GET method, it is not considered read-only (cannot determine the resource schema)
- Fails if a Delete method is defined on a read-only resource
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
Expand Down
4 changes: 2 additions & 2 deletions tools/spectral/ipa/rulesets/IPA-113.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ rules:
##### Implementation details
Rule checks for the following conditions:
- Applies only to singleton resources
- Excludes read-only singleton resources (where all properties in the GET response schema are marked as readOnly; for List responses, all properties in the items schema must be readOnly)
- Excludes read-only singleton resources (where all properties in the GET response schema are marked as readOnly or contain only read-only properties; for List responses, all properties in the items schema must be readOnly)
- Checks that the resource has the PUT and/or PATCH methods defined
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-113-singleton-should-have-update-method'
severity: error
Expand Down Expand Up @@ -142,7 +142,7 @@ rules:
- Applies only to paths ending with :reset
- Verifies that the parent singleton resource is not read-only
- Uses existing isReadOnlyResource() helper function
- Fails if the singleton resource has all properties marked as readOnly: true
- Fails if all properties of the singleton resource are marked as readOnly or contain only read-only properties
message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-113-reset-method-not-on-readonly-singleton'
severity: error
given: '$.paths[*]'
Expand Down
4 changes: 2 additions & 2 deletions tools/spectral/ipa/rulesets/IPA-132.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ rules:
xgen-IPA-132-operation-must-be-a-read-only-resource:
description: |
Operations endpoints are read-only. They may only define the get method, and all properties
of the Operation resource must be readOnly.
of the Operation resource must be read-only.

##### Implementation details
Rule checks for the following conditions:
Expand All @@ -62,7 +62,7 @@ rules:
- The path item must not define any HTTP method other than `get`
- On the single Operation endpoint (`.../operations/{operationId}`), where the Get method
is defined, all properties of every 2xx response schema of the `get` method must be
marked as `readOnly: true`
marked as `readOnly: true` or contain only read-only properties
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation

message: '{{error}} https://mdb.link/mongodb-atlas-openapi-validation#xgen-IPA-132-operation-must-be-a-read-only-resource'
Expand Down
14 changes: 7 additions & 7 deletions tools/spectral/ipa/rulesets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ Read-only resources must not define the Create method.
##### Implementation details
Rule checks for the following conditions:
- Applies to POST methods on resource collection paths
- Checks if the resource is a read-only resource (all properties in GET response have readOnly:true)
- Checks if the resource is a read-only resource (all properties in the GET response are marked as readOnly or contain only read-only properties)
- If a resource does not have a standard GET method, it is not considered read-only (cannot determine the resource schema)
- Fails if a Create method is defined on a read-only resource
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
Expand Down Expand Up @@ -484,7 +484,7 @@ Read-only resources must not define the Update method.
##### Implementation details
Rule checks for the following conditions:
- Applies to PUT/PATCH methods on all resource paths
- Checks if the resource is a read-only resource (all properties in GET response have readOnly:true)
- Checks if the resource is a read-only resource (all properties in the GET response are marked as readOnly or contain only read-only properties)
- If a resource does not have a standard GET method, it is not considered read-only (cannot determine the resource schema)
- Fails if an Update method is defined on a read-only resource
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
Expand Down Expand Up @@ -577,7 +577,7 @@ Read-only resources must not define the Delete method.
##### Implementation details
Rule checks for the following conditions:
- Applies to DELETE methods on single resource paths and singleton resources
- Checks if the resource is a read-only resource (all properties in GET response have readOnly:true)
- Checks if the resource is a read-only resource (all properties in the GET response are marked as readOnly or contain only read-only properties)
- If a resource does not have a standard GET method, it is not considered read-only (cannot determine the resource schema)
- Fails if a Delete method is defined on a read-only resource
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
Expand Down Expand Up @@ -891,7 +891,7 @@ Singleton resources should define the Update method. Validation for the presence
##### Implementation details
Rule checks for the following conditions:
- Applies only to singleton resources
- Excludes read-only singleton resources (where all properties in the GET response schema are marked as readOnly; for List responses, all properties in the items schema must be readOnly)
- Excludes read-only singleton resources (where all properties in the GET response schema are marked as readOnly or contain only read-only properties; for List responses, all properties in the items schema must be readOnly)
- Checks that the resource has the PUT and/or PATCH methods defined

#### xgen-IPA-113-reset-method-must-use-POST
Expand Down Expand Up @@ -964,7 +964,7 @@ Rule checks for the following conditions:
- Applies only to paths ending with :reset
- Verifies that the parent singleton resource is not read-only
- Uses existing isReadOnlyResource() helper function
- Fails if the singleton resource has all properties marked as readOnly: true
- Fails if all properties of the singleton resource are marked as readOnly or contain only read-only properties

#### xgen-IPA-113-reset-method-valid-operation-id

Expand Down Expand Up @@ -1469,7 +1469,7 @@ Rule checks for the following conditions:

![warn](https://img.shields.io/badge/warning-yellow)
Operations endpoints are read-only. They may only define the get method, and all properties
of the Operation resource must be readOnly.
of the Operation resource must be read-only.

##### Implementation details
Rule checks for the following conditions:
Expand All @@ -1479,7 +1479,7 @@ Rule checks for the following conditions:
- The path item must not define any HTTP method other than `get`
- On the single Operation endpoint (`.../operations/{operationId}`), where the Get method
is defined, all properties of every 2xx response schema of the `get` method must be
marked as `readOnly: true`
marked as `readOnly: true` or contain only read-only properties
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation

#### xgen-IPA-132-operations-endpoint-must-be-a-leaf-resource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { isOperationsPath, isSingleOperationPath } from './utils/longRunningOper
const VALID_METHOD = 'get';
const HTTP_METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'];
const READ_ONLY_SCHEMA_ERROR_MESSAGE =
'The Operation resource must be read-only. All properties of the GET response schema must be marked as readOnly: true.';
'The Operation resource must be read-only. All properties of the GET response schema must be marked as readOnly: true or contain only read-only properties.';

/**
* Checks that an Operations endpoint defined by IPA-132 is a read-only resource: its path items
Expand Down
Loading
Loading