diff --git a/.circleci/config.yml b/.circleci/config.yml index af64217c..9a31c4e2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,8 +28,11 @@ jobs: name: Test command: yarn test - run: - name: E2E Test + name: E2E Test - Bulk Compare command: ./end-end-tests/api-standards/test-bulk.bash + - run: + name: E2E Test - Compare + command: ./end-end-tests/api-standards/test.bash npm-release: <<: *defaults diff --git a/end-end-tests/api-standards/context-beta.json b/end-end-tests/api-standards/context-beta.json new file mode 100644 index 00000000..4e63707c --- /dev/null +++ b/end-end-tests/api-standards/context-beta.json @@ -0,0 +1,9 @@ +{ + "changeDate": "2021-11-11", + "changeResource": "thing", + "changeVersion": { + "date": "2021-11-10", + "stability": "beta" + }, + "resourceVersionReleases": {} +} diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/000-baseline-beta.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/000-baseline-beta.yaml new file mode 100644 index 00000000..b51d2e67 --- /dev/null +++ b/end-end-tests/api-standards/resources/thing/2021-11-10/000-baseline-beta.yaml @@ -0,0 +1,296 @@ +openapi: 3.0.3 +x-snyk-api-stability: beta +info: + title: v3 + version: 3.0.0 +servers: + - url: https://api.snyk.io/v3 + description: Public Snyk API +tags: + - name: Thing + description: Short description of what Thing represents +paths: + /orgs/{org_id}/thing: + post: + summary: Create a new thing + description: Create a new thing + operationId: createThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + responses: + "201": + description: Created thing successfully + headers: + snyk-version-requested: + { + $ref: "#/components/x-rest-common/headers/VersionRequestedResponseHeader", + } + snyk-version-served: + { + $ref: "#/components/x-rest-common/headers/VersionServedResponseHeader", + } + snyk-request-id: + { + $ref: "#/components/x-rest-common/headers/RequestIdResponseHeader", + } + snyk-version-lifecycle-stage: + { + $ref: "#/components/x-rest-common/headers/VersionStageResponseHeader", + } + deprecation: + { + $ref: "#/components/x-rest-common/headers/DeprecationHeader", + } + sunset: + { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + location: + { $ref: "#/components/x-rest-common/headers/LocationHeader" } + content: + application/vnd.api+json: + schema: { $ref: "#/components/schemas/ThingResourceResponse" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "409": { $ref: "#/components/x-rest-common/responses/409" } + "500": { $ref: "#/components/x-rest-common/responses/500" } + get: + summary: List instances of thing + description: List instances of thing + operationId: listThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/x-rest-common/parameters/StartingAfter" } + - { $ref: "#/components/x-rest-common/parameters/EndingBefore" } + - { $ref: "#/components/x-rest-common/parameters/Limit" } + responses: + "200": + description: Returns a list of thing instances + headers: + snyk-version-requested: + { + $ref: "#/components/x-rest-common/headers/VersionRequestedResponseHeader", + } + snyk-version-served: + { + $ref: "#/components/x-rest-common/headers/VersionServedResponseHeader", + } + snyk-request-id: + { + $ref: "#/components/x-rest-common/headers/RequestIdResponseHeader", + } + snyk-version-lifecycle-stage: + { + $ref: "#/components/x-rest-common/headers/VersionStageResponseHeader", + } + deprecation: + { + $ref: "#/components/x-rest-common/headers/DeprecationHeader", + } + sunset: + { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + content: + application/vnd.api+json: + schema: { $ref: "#/components/schemas/ThingCollectionResponse" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "500": { $ref: "#/components/x-rest-common/responses/500" } + /orgs/{org_id}/thing/{thing_id}: + get: + summary: Get an instance of thing + description: Get an instance of thing + operationId: getThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/parameters/ThingId" } + responses: + "200": + description: Returns an instance of thing + headers: + snyk-version-requested: + { + $ref: "#/components/x-rest-common/headers/VersionRequestedResponseHeader", + } + snyk-version-served: + { + $ref: "#/components/x-rest-common/headers/VersionServedResponseHeader", + } + snyk-request-id: + { + $ref: "#/components/x-rest-common/headers/RequestIdResponseHeader", + } + snyk-version-lifecycle-stage: + { + $ref: "#/components/x-rest-common/headers/VersionStageResponseHeader", + } + deprecation: + { + $ref: "#/components/x-rest-common/headers/DeprecationHeader", + } + sunset: + { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + content: + application/vnd.api+json: + schema: { $ref: "#/components/schemas/ThingResourceResponse" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "500": { $ref: "#/components/x-rest-common/responses/500" } + patch: + summary: Update an instance of thing + description: Update an instance of thing + operationId: updateThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/parameters/ThingId" } + responses: + "200": + description: Instance of thing is updated. + headers: + snyk-version-requested: + { + $ref: "#/components/x-rest-common/headers/VersionRequestedResponseHeader", + } + snyk-version-served: + { + $ref: "#/components/x-rest-common/headers/VersionServedResponseHeader", + } + snyk-request-id: + { + $ref: "#/components/x-rest-common/headers/RequestIdResponseHeader", + } + snyk-version-lifecycle-stage: + { + $ref: "#/components/x-rest-common/headers/VersionStageResponseHeader", + } + deprecation: + { + $ref: "#/components/x-rest-common/headers/DeprecationHeader", + } + sunset: + { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + content: + application/vnd.api+json: + schema: { $ref: "#/components/schemas/ThingResourceResponse" } + "204": { $ref: "#/components/x-rest-common/responses/204" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "409": { $ref: "#/components/x-rest-common/responses/409" } + "500": { $ref: "#/components/x-rest-common/responses/500" } + delete: + summary: Delete an instance of thing + description: Delete an instance of thing + operationId: deleteThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/parameters/ThingId" } + responses: + "204": { $ref: "#/components/x-rest-common/responses/204" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "409": { $ref: "#/components/x-rest-common/responses/409" } + "500": { $ref: "#/components/x-rest-common/responses/500" } +components: + x-rest-common: + $ref: '../../../../../components/common.yaml' + parameters: + OrgId: + name: org_id + in: path + required: true + description: Org ID + schema: + type: string + format: uuid + ThingId: + name: thing_id + in: path + required: true + description: Unique identifier for thing instances + schema: + type: string + format: uuid + schemas: + ThingResourceResponse: + type: object + description: Response containing a single thing resource object + properties: + jsonapi: { $ref: "#/components/x-rest-common/schemas/JsonApi" } + data: { $ref: "#/components/schemas/ThingResource" } + links: { $ref: "#/components/x-rest-common/schemas/SelfLink" } + + ThingCollectionResponse: + type: object + description: Response containing a collection of thing resource objects + properties: + jsonapi: { $ref: "#/components/x-rest-common/schemas/JsonApi" } + data: { $ref: "#/components/schemas/ThingCollection" } + links: { $ref: "#/components/x-rest-common/schemas/PaginatedLinks" } + + ThingResource: + type: object + description: thing resource object + properties: + id: + type: string + format: uuid + example: d5b640e5-d88c-4c17-9bf0-93597b7a1ce2 + type: { $ref: "#/components/x-rest-common/schemas/Types" } + attributes: { $ref: "#/components/schemas/ThingAttributes" } + relationships: { $ref: "#/components/schemas/ThingRelationships" } + additionalProperties: false + + ThingRelationships: + type: object + properties: + example: { $ref: "#/components/x-rest-common/schemas/Relationship" } + additionalProperties: false + + ThingCollection: + type: array + items: { $ref: "#/components/schemas/ThingResource" } + + ThingAttributes: + type: object + properties: + name: + type: string + description: Name of this instance of thing. + example: thing + created: + type: string + description: Timestamp when this instance of thing was created. + format: date-time + example: "2021-10-05T13:23:17Z" + updated: + type: string + description: Timestamp when this instance of thing was last updated. + format: date-time + example: "2021-10-05T13:25:29Z" + description: + type: string + description: User-friendly description of this instance of thing. + example: "This is a thing named thing." + additionalProperties: false diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/000-baseline-in-reform.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/000-baseline-in-reform.yaml index 915193e4..96164db2 100644 --- a/end-end-tests/api-standards/resources/thing/2021-11-10/000-baseline-in-reform.yaml +++ b/end-end-tests/api-standards/resources/thing/2021-11-10/000-baseline-in-reform.yaml @@ -47,6 +47,8 @@ paths: } sunset: { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + location: + { $ref: "#/components/x-rest-common/headers/LocationHeader" } content: application/vnd.api+json: schema: { $ref: "#/components/schemas/ThingResourceResponse" } @@ -92,6 +94,8 @@ paths: } sunset: { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + location: + { $ref: "#/components/x-rest-common/headers/LocationHeader" } content: application/vnd.api+json: schema: { $ref: "#/components/schemas/ThingResourceResponse" } @@ -110,6 +114,9 @@ paths: parameters: - { $ref: "#/components/x-rest-common/parameters/Version" } - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/x-rest-common/parameters/StartingAfter" } + - { $ref: "#/components/x-rest-common/parameters/EndingBefore" } + - { $ref: "#/components/x-rest-common/parameters/Limit" } responses: "200": description: Returns a list of thing instances diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml new file mode 100644 index 00000000..9b428430 --- /dev/null +++ b/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml @@ -0,0 +1,241 @@ +# 001-fail-breaking-param-change.yaml +# Introducing a new required parameter breaks compatibility and should fail linting. +# +openapi: 3.0.3 +x-snyk-api-stability: beta +info: + title: v3 + version: 3.0.0 +servers: + - url: https://api.snyk.io/v3 + description: Public Snyk API +tags: + - name: Thing + description: Short description of what Thing represents +paths: + /orgs/{org_id}/thing: + post: + summary: Create a new thing + description: Create a new thing + operationId: createThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + responses: + '201': + description: Created thing successfully + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + location: { $ref: '#/components/x-rest-common/headers/LocationHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingResourceResponse' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + get: + summary: List instances of thing + description: List instances of thing + operationId: listThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/x-rest-common/parameters/StartingAfter" } + - { $ref: "#/components/x-rest-common/parameters/EndingBefore" } + - { $ref: "#/components/x-rest-common/parameters/Limit" } + responses: + '200': + description: Returns a list of thing instances + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingCollectionResponse' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + /orgs/{org_id}/thing/{thing_id}: + get: + summary: Get an instance of thing + description: Get an instance of thing + operationId: getThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: '#/components/parameters/ThingId' } + - in: query + description: Org ID + name: org_id + schema: + type: string + format: uuid + required: true + responses: + '200': + description: Returns an instance of thing + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingResourceResponse' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + patch: + summary: Update an instance of thing + description: Update an instance of thing + operationId: updateThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: '#/components/parameters/ThingId' } + responses: + '200': + description: Instance of thing is updated. + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingResourceResponse' } + '204': { $ref: '#/components/x-rest-common/responses/204' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + delete: + summary: Delete an instance of thing + description: Delete an instance of thing + operationId: deleteThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: '#/components/parameters/ThingId' } + responses: + '204': { $ref: '#/components/x-rest-common/responses/204' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } +components: + x-rest-common: + $ref: '../../../../../components/common.yaml' + parameters: + OrgId: + name: org_id + in: path + required: true + description: Org ID + schema: + type: string + format: uuid + ThingId: + name: thing_id + in: path + required: true + description: Unique identifier for thing instances + schema: + type: string + format: uuid + schemas: + ThingResourceResponse: + type: object + description: Response containing a single thing resource object + properties: + jsonapi: { $ref: '#/components/x-rest-common/schemas/JsonApi' } + data: { $ref: '#/components/schemas/ThingResource' } + links: { $ref: '#/components/x-rest-common/schemas/SelfLink' } + + ThingCollectionResponse: + type: object + description: Response containing a collection of thing resource objects + properties: + jsonapi: { $ref: '#/components/x-rest-common/schemas/JsonApi' } + data: { $ref: '#/components/schemas/ThingCollection' } + links: { $ref: '#/components/x-rest-common/schemas/PaginatedLinks' } + + ThingResource: + type: object + description: thing resource object + properties: + id: + type: string + format: uuid + example: d5b640e5-d88c-4c17-9bf0-93597b7a1ce2 + type: { $ref: '#/components/x-rest-common/schemas/Types' } + attributes: { $ref: '#/components/schemas/ThingAttributes' } + relationships: { $ref: '#/components/schemas/ThingRelationships' } + additionalProperties: false + + ThingRelationships: + type: object + properties: + example: { $ref: '#/components/x-rest-common/schemas/Relationship' } + additionalProperties: false + + ThingCollection: + type: array + items: { $ref: '#/components/schemas/ThingResource' } + + ThingAttributes: + type: object + properties: + name: + type: string + description: Name of this instance of thing. + example: thing + created: + type: string + description: Timestamp when this instance of thing was created. + format: date-time + example: '2021-10-05T13:23:17Z' + updated: + type: string + description: Timestamp when this instance of thing was last updated. + format: date-time + example: '2021-10-05T13:25:29Z' + description: + type: string + description: User-friendly description of this instance of thing. + example: "This is a thing named thing." + additionalProperties: false diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-format-change.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-format-change-beta.yaml similarity index 99% rename from end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-format-change.yaml rename to end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-format-change-beta.yaml index bc52e0d9..6bfd15c5 100644 --- a/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-format-change.yaml +++ b/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-format-change-beta.yaml @@ -1,5 +1,5 @@ openapi: 3.0.3 -x-snyk-api-stability: experimental +x-snyk-api-stability: beta info: title: v3 version: 3.0.0 diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml similarity index 99% rename from end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml rename to end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml index 65477f8b..19a2d371 100644 --- a/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml +++ b/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml @@ -1,7 +1,7 @@ # 001-fail-operation-removed.yaml # Removing an operation should fail linting, since this also breaks compatibility. openapi: 3.0.3 -x-snyk-api-stability: experimental +x-snyk-api-stability: beta info: title: v3 version: 3.0.0 diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-type-change-beta.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-type-change-beta.yaml new file mode 100644 index 00000000..e27c30f9 --- /dev/null +++ b/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-type-change-beta.yaml @@ -0,0 +1,296 @@ +openapi: 3.0.3 +x-snyk-api-stability: beta +info: + title: v3 + version: 3.0.0 +servers: + - url: https://api.snyk.io/v3 + description: Public Snyk API +tags: + - name: Thing + description: Short description of what Thing represents +paths: + /orgs/{org_id}/thing: + post: + summary: Create a new thing + description: Create a new thing + operationId: createThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + responses: + "201": + description: Created thing successfully + headers: + snyk-version-requested: + { + $ref: "#/components/x-rest-common/headers/VersionRequestedResponseHeader", + } + snyk-version-served: + { + $ref: "#/components/x-rest-common/headers/VersionServedResponseHeader", + } + snyk-request-id: + { + $ref: "#/components/x-rest-common/headers/RequestIdResponseHeader", + } + snyk-version-lifecycle-stage: + { + $ref: "#/components/x-rest-common/headers/VersionStageResponseHeader", + } + deprecation: + { + $ref: "#/components/x-rest-common/headers/DeprecationHeader", + } + sunset: + { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + location: + { $ref: '#/components/x-rest-common/headers/LocationHeader' } + content: + application/vnd.api+json: + schema: { $ref: "#/components/schemas/ThingResourceResponse" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "409": { $ref: "#/components/x-rest-common/responses/409" } + "500": { $ref: "#/components/x-rest-common/responses/500" } + get: + summary: List instances of thing + description: List instances of thing + operationId: listThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/x-rest-common/parameters/StartingAfter" } + - { $ref: "#/components/x-rest-common/parameters/EndingBefore" } + - { $ref: "#/components/x-rest-common/parameters/Limit" } + responses: + "200": + description: Returns a list of thing instances + headers: + snyk-version-requested: + { + $ref: "#/components/x-rest-common/headers/VersionRequestedResponseHeader", + } + snyk-version-served: + { + $ref: "#/components/x-rest-common/headers/VersionServedResponseHeader", + } + snyk-request-id: + { + $ref: "#/components/x-rest-common/headers/RequestIdResponseHeader", + } + snyk-version-lifecycle-stage: + { + $ref: "#/components/x-rest-common/headers/VersionStageResponseHeader", + } + deprecation: + { + $ref: "#/components/x-rest-common/headers/DeprecationHeader", + } + sunset: + { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + content: + application/vnd.api+json: + schema: { $ref: "#/components/schemas/ThingCollectionResponse" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "500": { $ref: "#/components/x-rest-common/responses/500" } + /orgs/{org_id}/thing/{thing_id}: + get: + summary: Get an instance of thing + description: Get an instance of thing + operationId: getThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/parameters/ThingId" } + responses: + "200": + description: Returns an instance of thing + headers: + snyk-version-requested: + { + $ref: "#/components/x-rest-common/headers/VersionRequestedResponseHeader", + } + snyk-version-served: + { + $ref: "#/components/x-rest-common/headers/VersionServedResponseHeader", + } + snyk-request-id: + { + $ref: "#/components/x-rest-common/headers/RequestIdResponseHeader", + } + snyk-version-lifecycle-stage: + { + $ref: "#/components/x-rest-common/headers/VersionStageResponseHeader", + } + deprecation: + { + $ref: "#/components/x-rest-common/headers/DeprecationHeader", + } + sunset: + { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + content: + application/vnd.api+json: + schema: { $ref: "#/components/schemas/ThingResourceResponse" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "500": { $ref: "#/components/x-rest-common/responses/500" } + patch: + summary: Update an instance of thing + description: Update an instance of thing + operationId: updateThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/parameters/ThingId" } + responses: + "200": + description: Instance of thing is updated. + headers: + snyk-version-requested: + { + $ref: "#/components/x-rest-common/headers/VersionRequestedResponseHeader", + } + snyk-version-served: + { + $ref: "#/components/x-rest-common/headers/VersionServedResponseHeader", + } + snyk-request-id: + { + $ref: "#/components/x-rest-common/headers/RequestIdResponseHeader", + } + snyk-version-lifecycle-stage: + { + $ref: "#/components/x-rest-common/headers/VersionStageResponseHeader", + } + deprecation: + { + $ref: "#/components/x-rest-common/headers/DeprecationHeader", + } + sunset: + { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + content: + application/vnd.api+json: + schema: { $ref: "#/components/schemas/ThingResourceResponse" } + "204": { $ref: "#/components/x-rest-common/responses/204" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "409": { $ref: "#/components/x-rest-common/responses/409" } + "500": { $ref: "#/components/x-rest-common/responses/500" } + delete: + summary: Delete an instance of thing + description: Delete an instance of thing + operationId: deleteThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/parameters/ThingId" } + responses: + "204": { $ref: "#/components/x-rest-common/responses/204" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "409": { $ref: "#/components/x-rest-common/responses/409" } + "500": { $ref: "#/components/x-rest-common/responses/500" } +components: + x-rest-common: + $ref: '../../../../../components/common.yaml' + parameters: + OrgId: + name: org_id + in: path + required: true + description: Org ID + schema: + type: string + format: uuid + ThingId: + name: thing_id + in: path + required: true + description: Unique identifier for thing instances + schema: + # Should fail: changing the type of a parameter is breaking + type: integer + schemas: + ThingResourceResponse: + type: object + description: Response containing a single thing resource object + properties: + jsonapi: { $ref: "#/components/x-rest-common/schemas/JsonApi" } + data: { $ref: "#/components/schemas/ThingResource" } + links: { $ref: "#/components/x-rest-common/schemas/SelfLink" } + + ThingCollectionResponse: + type: object + description: Response containing a collection of thing resource objects + properties: + jsonapi: { $ref: "#/components/x-rest-common/schemas/JsonApi" } + data: { $ref: "#/components/schemas/ThingCollection" } + links: { $ref: "#/components/x-rest-common/schemas/PaginatedLinks" } + + ThingResource: + type: object + description: thing resource object + properties: + id: + type: string + format: uuid + example: d5b640e5-d88c-4c17-9bf0-93597b7a1ce2 + type: { $ref: "#/components/x-rest-common/schemas/Types" } + attributes: { $ref: "#/components/schemas/ThingAttributes" } + relationships: { $ref: "#/components/schemas/ThingRelationships" } + additionalProperties: false + + ThingRelationships: + type: object + properties: + example: { $ref: "#/components/x-rest-common/schemas/Relationship" } + additionalProperties: false + + ThingCollection: + type: array + items: { $ref: "#/components/schemas/ThingResource" } + + ThingAttributes: + type: object + properties: + name: + type: string + description: Name of this instance of thing. + example: thing + # This should fail; changing the type of properties is a breaking change + # But also, these property names are reserved and should be date-time + created: + type: integer + description: Timestamp when this instance of thing was created, in epoch seconds. + example: 1638477545 + updated: + type: integer + description: Timestamp when this instance of thing was last updated, in epoch seconds. + example: 1638477545 + description: + type: integer + description: User-friendly description of this instance of thing, in epoch seconds. + example: 1638477545 + additionalProperties: false diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/001-ok-breaking-param-change.yaml similarity index 100% rename from end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml rename to end-end-tests/api-standards/resources/thing/2021-11-10/001-ok-breaking-param-change.yaml diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-type-change.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/001-ok-type-change.yaml similarity index 100% rename from end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-type-change.yaml rename to end-end-tests/api-standards/resources/thing/2021-11-10/001-ok-type-change.yaml diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/002-fail-batch-post-bad-request.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/002-fail-batch-post-bad-request.yaml new file mode 100644 index 00000000..a6146623 --- /dev/null +++ b/end-end-tests/api-standards/resources/thing/2021-11-10/002-fail-batch-post-bad-request.yaml @@ -0,0 +1,135 @@ +openapi: 3.0.3 +x-snyk-api-stability: experimental +info: + title: v3 + version: 3.0.0 +servers: + - url: https://api.snyk.io/v3 + description: Public Snyk API +tags: + - name: Thing + description: Short description of what Thing represents +paths: + /orgs/{org_id}/thing: + post: + summary: Create a new thing + description: Create a new thing + operationId: createThing + tags: + - Thing + parameters: + - { $ref: "#/components/x-rest-common/parameters/Version" } + - { $ref: '#/components/parameters/OrgId' } + requestBody: + required: true + content: + application/vnd.api+json: + schema: { $ref: "#/components/schemas/ThingResourceRequest" } + + responses: + "204": + description: Created thing successfully + headers: + snyk-version-requested: + { + $ref: "#/components/x-rest-common/headers/VersionRequestedResponseHeader", + } + snyk-version-served: + { + $ref: "#/components/x-rest-common/headers/VersionServedResponseHeader", + } + snyk-request-id: + { + $ref: "#/components/x-rest-common/headers/RequestIdResponseHeader", + } + snyk-version-lifecycle-stage: + { + $ref: "#/components/x-rest-common/headers/VersionStageResponseHeader", + } + deprecation: + { + $ref: "#/components/x-rest-common/headers/DeprecationHeader", + } + sunset: + { $ref: "#/components/x-rest-common/headers/SunsetHeader" } + location: + { $ref: "#/components/x-rest-common/headers/LocationHeader" } + "400": { $ref: "#/components/x-rest-common/responses/400" } + "401": { $ref: "#/components/x-rest-common/responses/401" } + "403": { $ref: "#/components/x-rest-common/responses/403" } + "404": { $ref: "#/components/x-rest-common/responses/404" } + "409": { $ref: "#/components/x-rest-common/responses/409" } + "500": { $ref: "#/components/x-rest-common/responses/500" } +components: + x-rest-common: + $ref: '../../../../../components/common.yaml' + parameters: + OrgId: + name: org_id + in: path + required: true + description: Org ID + schema: + type: string + format: uuid + ThingId: + name: thing_id + in: path + required: true + description: Unique identifier for thing instances + schema: + type: string + format: uuid + schemas: + ThingResourceRequest: + type: object + description: Request containing a single thing resource object + properties: + jsonapi: { $ref: "#/components/x-rest-common/schemas/JsonApi" } + data: { $ref: "#/components/schemas/ThingResource" } + links: { $ref: "#/components/x-rest-common/schemas/SelfLink" } + ThingResource: + type: object + description: thing resource object + properties: + id: + type: string + format: uuid + example: d5b640e5-d88c-4c17-9bf0-93597b7a1ce2 + type: { $ref: "#/components/x-rest-common/schemas/Types" } + attributes: { $ref: "#/components/schemas/ThingAttributes" } + relationships: { $ref: "#/components/schemas/ThingRelationships" } + additionalProperties: false + + ThingRelationships: + type: object + properties: + example: { $ref: "#/components/x-rest-common/schemas/Relationship" } + additionalProperties: false + + ThingCollection: + type: array + items: { $ref: "#/components/schemas/ThingResource" } + + ThingAttributes: + type: object + properties: + name: + type: string + description: Name of this instance of thing. + example: thing + created: + type: string + description: Timestamp when this instance of thing was created. + format: date-time + example: "2021-10-05T13:23:17Z" + updated: + type: string + description: Timestamp when this instance of thing was last updated. + format: date-time + example: "2021-10-05T13:25:29Z" + description: + type: string + description: User-friendly description of this instance of thing. + example: "This is a thing named thing." + additionalProperties: false diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/002-fail-tenancy.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/002-fail-paginated-post.yaml similarity index 100% rename from end-end-tests/api-standards/resources/thing/2021-11-10/002-fail-tenancy.yaml rename to end-end-tests/api-standards/resources/thing/2021-11-10/002-fail-paginated-post.yaml diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/002-ok-add-operation-beta.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/002-ok-add-operation-beta.yaml new file mode 100644 index 00000000..ec87d393 --- /dev/null +++ b/end-end-tests/api-standards/resources/thing/2021-11-10/002-ok-add-operation-beta.yaml @@ -0,0 +1,262 @@ +# 002-ok-add-operation.yaml +# Adding a new operation to an existing release is also allowed. +openapi: 3.0.3 +x-snyk-api-stability: beta +info: + title: v3 + version: 3.0.0 +servers: + - url: https://api.snyk.io/v3 + description: Public Snyk API +tags: + - name: Thing + description: Short description of what Thing represents +paths: + /orgs/{org_id}/thing: + post: + summary: Create a new thing + description: Create a new thing + operationId: createThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + responses: + '201': + description: Created thing successfully + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + location: { $ref: '#/components/x-rest-common/headers/LocationHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingResourceResponse' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + get: + summary: List instances of thing + description: List instances of thing + operationId: listThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/x-rest-common/parameters/StartingAfter" } + - { $ref: "#/components/x-rest-common/parameters/EndingBefore" } + - { $ref: "#/components/x-rest-common/parameters/Limit" } + responses: + '200': + description: Returns a list of thing instances + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingCollectionResponse' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + delete: + summary: Bulk delete a collection of matching things + description: Bulk delete a collection of matching things + operationId: deleteMatchingThings + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - in: query + description: Thing IDs to be deleted + schema: + type: array + items: + type: string + name: thing_ids + required: true + responses: + '204': { $ref: '#/components/x-rest-common/responses/204' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + /orgs/{org_id}/thing/{thing_id}: + get: + summary: Get an instance of thing + description: Get an instance of thing + operationId: getThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: '#/components/parameters/ThingId' } + responses: + '200': + description: Returns an instance of thing + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingResourceResponse' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + patch: + summary: Update an instance of thing + description: Update an instance of thing + operationId: updateThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: '#/components/parameters/ThingId' } + responses: + '200': + description: Instance of thing is updated. + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingResourceResponse' } + '204': { $ref: '#/components/x-rest-common/responses/204' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + delete: + summary: Delete an instance of thing + description: Delete an instance of thing + operationId: deleteThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: '#/components/parameters/ThingId' } + responses: + '204': { $ref: '#/components/x-rest-common/responses/204' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } +components: + x-rest-common: + $ref: '../../../../../components/common.yaml' + parameters: + OrgId: + name: org_id + in: path + required: true + description: Org ID + schema: + type: string + format: uuid + ThingId: + name: thing_id + in: path + required: true + description: Unique identifier for thing instances + schema: + type: string + format: uuid + schemas: + ThingResourceResponse: + type: object + description: Response containing a single thing resource object + properties: + jsonapi: { $ref: '#/components/x-rest-common/schemas/JsonApi' } + data: { $ref: '#/components/schemas/ThingResource' } + links: { $ref: '#/components/x-rest-common/schemas/SelfLink' } + + ThingCollectionResponse: + type: object + description: Response containing a collection of thing resource objects + properties: + jsonapi: { $ref: '#/components/x-rest-common/schemas/JsonApi' } + data: { $ref: '#/components/schemas/ThingCollection' } + links: { $ref: '#/components/x-rest-common/schemas/PaginatedLinks' } + + ThingResource: + type: object + description: thing resource object + properties: + id: + type: string + format: uuid + example: d5b640e5-d88c-4c17-9bf0-93597b7a1ce2 + type: { $ref: '#/components/x-rest-common/schemas/Types' } + attributes: { $ref: '#/components/schemas/ThingAttributes' } + relationships: { $ref: '#/components/schemas/ThingRelationships' } + additionalProperties: false + + ThingRelationships: + type: object + properties: + example: { $ref: '#/components/x-rest-common/schemas/Relationship' } + additionalProperties: false + + ThingCollection: + type: array + items: { $ref: '#/components/schemas/ThingResource' } + + ThingAttributes: + type: object + properties: + name: + type: string + description: Name of this instance of thing. + example: thing + created: + type: string + description: Timestamp when this instance of thing was created. + format: date-time + example: '2021-10-05T13:23:17Z' + updated: + type: string + description: Timestamp when this instance of thing was last updated. + format: date-time + example: '2021-10-05T13:25:29Z' + description: + type: string + description: User-friendly description of this instance of thing. + example: "This is a thing named thing." + strangeness: + type: number + description: The amount of strangeness this thing adds or removes from the situation. + example: 42 + additionalProperties: false diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/003-fail-type-change-beta.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/003-fail-type-change-beta.yaml new file mode 100644 index 00000000..373d9eb5 --- /dev/null +++ b/end-end-tests/api-standards/resources/thing/2021-11-10/003-fail-type-change-beta.yaml @@ -0,0 +1,263 @@ +# 002-ok-add-operation.yaml +# Adding a new operation to an existing release is also allowed. +openapi: 3.0.3 +x-snyk-api-stability: beta +info: + title: v3 + version: 3.0.0 +servers: + - url: https://api.snyk.io/v3 + description: Public Snyk API +tags: + - name: Thing + description: Short description of what Thing represents +paths: + /orgs/{org_id}/thing: + post: + summary: Create a new thing + description: Create a new thing + operationId: createThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + responses: + '201': + description: Created thing successfully + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + location: { $ref: '#/components/x-rest-common/headers/LocationHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingResourceResponse' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + get: + summary: List instances of thing + description: List instances of thing + operationId: listThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: "#/components/x-rest-common/parameters/StartingAfter" } + - { $ref: "#/components/x-rest-common/parameters/EndingBefore" } + - { $ref: "#/components/x-rest-common/parameters/Limit" } + responses: + '200': + description: Returns a list of thing instances + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingCollectionResponse' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + delete: + summary: Bulk delete a collection of matching things + description: Bulk delete a collection of matching things + operationId: deleteMatchingThings + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - in: query + description: Thing IDs to be deleted + schema: + type: array + items: + type: string + name: thing_ids + required: true + responses: + '204': { $ref: '#/components/x-rest-common/responses/204' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + /orgs/{org_id}/thing/{thing_id}: + get: + summary: Get an instance of thing + description: Get an instance of thing + operationId: getThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: '#/components/parameters/ThingId' } + responses: + '200': + description: Returns an instance of thing + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingResourceResponse' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + patch: + summary: Update an instance of thing + description: Update an instance of thing + operationId: updateThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: '#/components/parameters/ThingId' } + responses: + '200': + description: Instance of thing is updated. + headers: + snyk-version-requested: { $ref: '#/components/x-rest-common/headers/VersionRequestedResponseHeader' } + snyk-version-served: { $ref: '#/components/x-rest-common/headers/VersionServedResponseHeader' } + snyk-request-id: { $ref: '#/components/x-rest-common/headers/RequestIdResponseHeader' } + snyk-version-lifecycle-stage: { $ref: '#/components/x-rest-common/headers/VersionStageResponseHeader' } + deprecation: { $ref: '#/components/x-rest-common/headers/DeprecationHeader' } + sunset: { $ref: '#/components/x-rest-common/headers/SunsetHeader' } + content: + application/vnd.api+json: + schema: { $ref: '#/components/schemas/ThingResourceResponse' } + '204': { $ref: '#/components/x-rest-common/responses/204' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } + delete: + summary: Delete an instance of thing + description: Delete an instance of thing + operationId: deleteThing + tags: + - Thing + parameters: + - { $ref: '#/components/x-rest-common/parameters/Version' } + - { $ref: '#/components/parameters/OrgId' } + - { $ref: '#/components/parameters/ThingId' } + responses: + '204': { $ref: '#/components/x-rest-common/responses/204' } + '400': { $ref: '#/components/x-rest-common/responses/400' } + '401': { $ref: '#/components/x-rest-common/responses/401' } + '403': { $ref: '#/components/x-rest-common/responses/403' } + '404': { $ref: '#/components/x-rest-common/responses/404' } + '409': { $ref: '#/components/x-rest-common/responses/409' } + '500': { $ref: '#/components/x-rest-common/responses/500' } +components: + x-rest-common: + $ref: '../../../../../components/common.yaml' + parameters: + OrgId: + name: org_id + in: path + required: true + description: Org ID + schema: + type: string + format: uuid + ThingId: + name: thing_id + in: path + required: true + description: Unique identifier for thing instances + schema: + type: string + format: uuid + schemas: + ThingResourceResponse: + type: object + description: Response containing a single thing resource object + properties: + jsonapi: { $ref: '#/components/x-rest-common/schemas/JsonApi' } + data: { $ref: '#/components/schemas/ThingResource' } + links: { $ref: '#/components/x-rest-common/schemas/SelfLink' } + + ThingCollectionResponse: + type: object + description: Response containing a collection of thing resource objects + properties: + jsonapi: { $ref: '#/components/x-rest-common/schemas/JsonApi' } + data: { $ref: '#/components/schemas/ThingCollection' } + links: { $ref: '#/components/x-rest-common/schemas/PaginatedLinks' } + + ThingResource: + type: object + description: thing resource object + properties: + id: + type: string + format: uuid + example: d5b640e5-d88c-4c17-9bf0-93597b7a1ce2 + type: { $ref: '#/components/x-rest-common/schemas/Types' } + attributes: { $ref: '#/components/schemas/ThingAttributes' } + relationships: { $ref: '#/components/schemas/ThingRelationships' } + additionalProperties: false + + ThingRelationships: + type: object + properties: + example: { $ref: '#/components/x-rest-common/schemas/Relationship' } + additionalProperties: false + + ThingCollection: + type: array + items: { $ref: '#/components/schemas/ThingResource' } + + ThingAttributes: + type: object + properties: + name: + type: string + description: Name of this instance of thing. + example: thing + created: + type: string + description: Timestamp when this instance of thing was created. + format: date-time + example: '2021-10-05T13:23:17Z' + updated: + type: string + description: Timestamp when this instance of thing was last updated. + format: date-time + example: '2021-10-05T13:25:29Z' + description: + type: string + description: User-friendly description of this instance of thing. + example: "This is a thing named thing." + strangeness: + # Should fail: changing the type of a property is a breaking change + type: string + description: The amount of strangeness this thing adds or removes from the situation. + example: "42" + additionalProperties: false diff --git a/end-end-tests/api-standards/resources/thing/2021-11-10/003-fail-type-change.yaml b/end-end-tests/api-standards/resources/thing/2021-11-10/003-ok-type-change.yaml similarity index 100% rename from end-end-tests/api-standards/resources/thing/2021-11-10/003-fail-type-change.yaml rename to end-end-tests/api-standards/resources/thing/2021-11-10/003-ok-type-change.yaml diff --git a/end-end-tests/api-standards/test-bulk.bash b/end-end-tests/api-standards/test-bulk.bash index f94365c4..302ca24e 100755 --- a/end-end-tests/api-standards/test-bulk.bash +++ b/end-end-tests/api-standards/test-bulk.bash @@ -6,11 +6,27 @@ cd $HERE/../.. CONTEXT=$(awk NF=NF RS= OFS= <$HERE/context.json) -COMPARE=${COMPARE:-yarn run bulk-compare} +COMPARE=${COMPARE:-./node_modules/.bin/ts-node src/index.ts bulk-compare} tempdir=$(mktemp -d) trap "rm -rf $tempdir" EXIT +set +e + +function assert_ok { + if [ "$?" != "0" ]; then + echo "unexpected rc=$?" + exit 1 + fi +} + +function assert_err { + if [ "$?" == "0" ]; then + echo "unexpected rc=$?" + exit 1 + fi +} + echo "*** TEST: 'from scratch' comparisons of well-formed OpenAPI ***" cat >$tempdir/from_scratch <$tempdir/from_scratch <$tempdir/passes <$tempdir/passes <$tempdir/invalid_input <$tempdir/invalid_input <$tempdir/failures <$tempdir/failures <$tempdir/failures < { + return stability === "wip" || stability === "experimental"; +}; + export interface SynkApiCheckContext { // Vervet provides context about the change itself. Since // Optic is analyzing two OpenAPI spec files, we need to tell it diff --git a/src/rulesets/api-lifeycle.ts b/src/rulesets/api-lifeycle.ts index 0e632b3f..f836df43 100644 --- a/src/rulesets/api-lifeycle.ts +++ b/src/rulesets/api-lifeycle.ts @@ -38,6 +38,7 @@ export const rules = { followSunsetRules: ({ checkApiContext }: SnykApiCheckDsl) => { checkApiContext.must("follow sunset rules", (context) => { if (context.changeVersion.stability === "wip") return; + if (context.changeVersion.stability === "experimental") return; if (!context.wasDeleted) return; const deprecatedBy = context.resourceVersions?.[context.changeResource]?.[ @@ -64,11 +65,13 @@ export const rules = { // Number of days required before a resource can be removed const sunsetSchedule = { - experimental: 30, beta: 90, ga: 180, }; const requiredDays = sunsetSchedule[stability]; + if (!requiredDays) { + expect.fail(`unexpected stability ${stability} in ${resourceName}`); + } if (diffDays < requiredDays) { expect.fail( `expected ${stability} resource ${resourceName} to be deprecated ${requiredDays} days`, diff --git a/src/rulesets/operations.ts b/src/rulesets/operations.ts index 8cd76829..8e42fe09 100644 --- a/src/rulesets/operations.ts +++ b/src/rulesets/operations.ts @@ -1,4 +1,8 @@ -import { SnykApiCheckDsl } from "../dsl"; +import { + isBreakingChangeAllowed, + SnykApiCheckDsl, + SynkApiCheckContext, +} from "../dsl"; import { camelCase, snakeCase } from "change-case"; import { OpenAPIV3 } from "@useoptic/api-checks"; import { expect } from "chai"; @@ -18,7 +22,11 @@ const preventParameterChange = (schemaProperty: string) => { return ( parameterBefore: OpenApiRequestParameterFact, parameterAfter: OpenApiRequestParameterFact, + context: SynkApiCheckContext, ) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } const beforeSchema = (parameterBefore.schema || {}) as OpenAPIV3.SchemaObject; const afterSchema = (parameterAfter.schema || {}) as OpenAPIV3.SchemaObject; @@ -37,6 +45,9 @@ export const rules = { .must( "have the correct operationId format", (operation, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.standards.operationIds); docs.becomesEffectiveOn(new Date("2021-07-01")); expect(operation.operationId).to.be.ok; @@ -62,6 +73,9 @@ export const rules = { }, tags: ({ operations }: SnykApiCheckDsl) => { operations.requirement.must("have tags", (operation, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.standards.tags); expect(operation.tags).to.exist; if (!operation.tags) expect.fail("tags must exist"); @@ -72,6 +86,9 @@ export const rules = { operations.requirement.must( "have a summary", (operation, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.standards.operationSummary); if (!operation.summary) expect.fail("must have a summary"); }, @@ -89,6 +106,9 @@ export const rules = { operations.requirementOnChange .attributes("name") .must("use the correct case", (operation, context, docs, specItem) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.standards.parameterNamesPathComponents); for (const p of specItem.parameters || []) { const parameter = p as OpenAPIV3.ParameterObject; @@ -111,6 +131,9 @@ export const rules = { }, preventRemovingOperation: ({ operations }: SnykApiCheckDsl) => { operations.removed.must("not be allowed", (operation, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.versioning.breakingChanges); expect.fail("expected operation to be present"); }); @@ -119,6 +142,9 @@ export const rules = { operations.requirement.must( "include a version parameter", (operation, context, docs, specItem) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.versioning.versionParameter); const parameters = (specItem.parameters || []) as OpenAPIV3.ParameterObject[]; @@ -135,6 +161,9 @@ export const rules = { operations.requirement.must( "use UUID for org_id or group_id", (operation, context, docs, specItem) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.standards.orgAndGroupTenantResources); for (const parameter of specItem.parameters || []) { if ("$ref" in parameter) continue; @@ -160,6 +189,9 @@ export const rules = { specification.requirement.must( "use the right casing for path elements", (spec, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.standards.parameterNamesPathComponents); const pathUrls = Object.keys(spec.paths); for (const pathUrl of pathUrls) { @@ -178,6 +210,9 @@ export const rules = { request.queryParameter.added.must( "not be required", (queryParameter, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } if (context.operationAdded) return; docs.includeDocsLink(links.versioning.breakingChanges); if (queryParameter.required) { @@ -194,6 +229,9 @@ export const rules = { request.queryParameter.changed.must( "not be optional then required", (queryParameterBefore, queryParameterAfter, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.versioning.breakingChanges); if (!queryParameterBefore.required && queryParameterAfter.required) { expect.fail( @@ -205,6 +243,9 @@ export const rules = { }, preventRemovingStatusCodes: ({ responses }: SnykApiCheckDsl) => { responses.removed.must("not be removed", (response, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.versioning.breakingChanges); if (!("inResponse" in context)) return; expect.fail( @@ -216,6 +257,9 @@ export const rules = { request.queryParameter.changed.must( "not change the default value", (parameterBefore, parameterAfter, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.versioning.breakingChanges); const beforeSchema = (parameterBefore.schema || {}) as OpenAPIV3.SchemaObject; diff --git a/src/rulesets/properties.ts b/src/rulesets/properties.ts index 25c5f81e..35af59e7 100644 --- a/src/rulesets/properties.ts +++ b/src/rulesets/properties.ts @@ -1,4 +1,8 @@ -import { SnykApiCheckDsl } from "../dsl"; +import { + isBreakingChangeAllowed, + SnykApiCheckDsl, + SynkApiCheckContext, +} from "../dsl"; import { expect } from "chai"; import { OpenAPIV3 } from "@useoptic/api-checks"; import { links } from "../docs"; @@ -37,7 +41,10 @@ function withinAttributes(context) { * preventChange("format") * */ const preventChange = (schemaProperty: string) => { - return (parameterBefore, parameterAfter, context) => { + return (parameterBefore, parameterAfter, context: SynkApiCheckContext) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } const beforeSchema = (parameterBefore.flatSchema || {}) as OpenAPIV3.SchemaObject; const afterSchema = (parameterAfter.flatSchema || @@ -65,6 +72,9 @@ export const rules = { }, preventRemoval: ({ bodyProperties }: SnykApiCheckDsl) => { bodyProperties.removed.must("not be removed", (property, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } docs.includeDocsLink(links.versioning.breakingChanges); if ("inResponse" in context && "jsonSchemaTrail" in context) { const propertyPath = `response body ${ @@ -93,6 +103,9 @@ export const rules = { bodyProperties, }: SnykApiCheckDsl) => { bodyProperties.added.must("not be required", (property, context, docs) => { + if (isBreakingChangeAllowed(context.changeVersion.stability)) { + return; + } if (context.bodyAdded) return; docs.includeDocsLink(links.versioning.breakingChanges); if (!("inRequest" in context)) return; diff --git a/src/rulesets/tests/__snapshots__/end-end.test.ts.snap b/src/rulesets/tests/__snapshots__/end-end.test.ts.snap index 5d2e6719..58a2c930 100644 --- a/src/rulesets/tests/__snapshots__/end-end.test.ts.snap +++ b/src/rulesets/tests/__snapshots__/end-end.test.ts.snap @@ -12,11 +12,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 75, - "endPosition": 3701, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 3693, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 46, - "startPosition": 2015, + "startPosition": 2007, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -30,11 +30,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 45, - "endPosition": 2010, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 2002, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 17, - "startPosition": 401, + "startPosition": 393, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -48,11 +48,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 111, - "endPosition": 5428, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 5420, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 77, - "startPosition": 3741, + "startPosition": 3733, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -66,11 +66,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 141, - "endPosition": 7102, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7094, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 112, - "startPosition": 5433, + "startPosition": 5425, }, "where": "requirement for operation: PATCH /orgs/{org_id}/thing/{thing_id}", }, @@ -84,11 +84,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 159, - "endPosition": 7948, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7940, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 142, - "startPosition": 7107, + "startPosition": 7099, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -102,11 +102,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 75, - "endPosition": 3701, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 3693, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 46, - "startPosition": 2015, + "startPosition": 2007, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -120,11 +120,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 45, - "endPosition": 2010, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 2002, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 17, - "startPosition": 401, + "startPosition": 393, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -138,11 +138,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 111, - "endPosition": 5428, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 5420, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 77, - "startPosition": 3741, + "startPosition": 3733, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -156,11 +156,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 141, - "endPosition": 7102, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7094, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 112, - "startPosition": 5433, + "startPosition": 5425, }, "where": "requirement for operation: PATCH /orgs/{org_id}/thing/{thing_id}", }, @@ -174,11 +174,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 159, - "endPosition": 7948, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7940, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 142, - "startPosition": 7107, + "startPosition": 7099, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -192,11 +192,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 75, - "endPosition": 3701, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 3693, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 46, - "startPosition": 2015, + "startPosition": 2007, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -210,11 +210,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 45, - "endPosition": 2010, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 2002, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 17, - "startPosition": 401, + "startPosition": 393, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -228,11 +228,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 111, - "endPosition": 5428, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 5420, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 77, - "startPosition": 3741, + "startPosition": 3733, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -246,11 +246,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 141, - "endPosition": 7102, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7094, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 112, - "startPosition": 5433, + "startPosition": 5425, }, "where": "requirement for operation: PATCH /orgs/{org_id}/thing/{thing_id}", }, @@ -264,11 +264,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 159, - "endPosition": 7948, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7940, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 142, - "startPosition": 7107, + "startPosition": 7099, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -282,11 +282,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 75, - "endPosition": 3701, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 3693, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 46, - "startPosition": 2015, + "startPosition": 2007, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -300,11 +300,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 45, - "endPosition": 2010, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 2002, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 17, - "startPosition": 401, + "startPosition": 393, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -318,11 +318,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 111, - "endPosition": 5428, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 5420, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 77, - "startPosition": 3741, + "startPosition": 3733, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -336,11 +336,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 141, - "endPosition": 7102, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7094, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 112, - "startPosition": 5433, + "startPosition": 5425, }, "where": "requirement for operation: PATCH /orgs/{org_id}/thing/{thing_id}", }, @@ -354,11 +354,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 159, - "endPosition": 7948, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7940, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 142, - "startPosition": 7107, + "startPosition": 7099, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -372,11 +372,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 75, - "endPosition": 3701, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 3693, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 46, - "startPosition": 2015, + "startPosition": 2007, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -390,11 +390,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 45, - "endPosition": 2010, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 2002, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 17, - "startPosition": 401, + "startPosition": 393, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -408,11 +408,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 111, - "endPosition": 5428, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 5420, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 77, - "startPosition": 3741, + "startPosition": 3733, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -426,11 +426,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 141, - "endPosition": 7102, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7094, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 112, - "startPosition": 5433, + "startPosition": 5425, }, "where": "requirement for operation: PATCH /orgs/{org_id}/thing/{thing_id}", }, @@ -444,11 +444,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 159, - "endPosition": 7948, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7940, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 142, - "startPosition": 7107, + "startPosition": 7099, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -462,8 +462,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 242, - "endPosition": 10562, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10554, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 4, "startPosition": 125, @@ -481,11 +481,11 @@ Array [ "passed": false, "sourcemap": Object { "endLine": 93, - "endPosition": 4243, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 4235, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 87, - "startPosition": 4088, + "startPosition": 4080, }, "where": "added query-parameter: org_id", }, @@ -499,11 +499,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 70, - "endPosition": 3361, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 3353, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 59, - "startPosition": 2535, + "startPosition": 2527, }, "where": "requirement for response: 200", }, @@ -587,11 +587,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 39, - "endPosition": 1602, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 1594, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 27, - "startPosition": 701, + "startPosition": 693, }, "where": "requirement for response: 201", }, @@ -689,11 +689,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 106, - "endPosition": 5088, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 5080, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 95, - "startPosition": 4269, + "startPosition": 4261, }, "where": "requirement for response: 200", }, @@ -777,11 +777,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 134, - "endPosition": 6626, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 6618, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 123, - "startPosition": 5806, + "startPosition": 5798, }, "where": "requirement for response: 200", }, @@ -1019,11 +1019,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 218, - "endPosition": 9808, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9800, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 216, - "startPosition": 9714, + "startPosition": 9706, }, "where": "requirement for field: data", }, @@ -1037,11 +1037,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 9290, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9282, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 201, - "startPosition": 9185, + "startPosition": 9177, }, "where": "requirement for field: id", }, @@ -1069,11 +1069,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 241, - "endPosition": 10561, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10553, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 220, - "startPosition": 9814, + "startPosition": 9806, }, "where": "requirement for field: attributes", }, @@ -1087,11 +1087,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 226, - "endPosition": 9984, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9976, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 223, - "startPosition": 9876, + "startPosition": 9868, }, "where": "requirement for field: name", }, @@ -1105,11 +1105,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 231, - "endPosition": 10168, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10160, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 227, - "startPosition": 9993, + "startPosition": 9985, }, "where": "requirement for field: created", }, @@ -1123,11 +1123,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 236, - "endPosition": 10357, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10349, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 232, - "startPosition": 10177, + "startPosition": 10169, }, "where": "requirement for field: updated", }, @@ -1141,11 +1141,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 240, - "endPosition": 10527, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10519, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 237, - "startPosition": 10366, + "startPosition": 10358, }, "where": "requirement for field: description", }, @@ -1159,11 +1159,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 214, - "endPosition": 9708, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9700, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 210, - "startPosition": 9541, + "startPosition": 9533, }, "where": "requirement for field: relationships", }, @@ -2395,11 +2395,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 208, - "endPosition": 9535, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9527, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 197, - "startPosition": 9084, + "startPosition": 9076, }, "where": "requirement for field: data", }, @@ -2413,11 +2413,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 9290, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9282, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 201, - "startPosition": 9185, + "startPosition": 9177, }, "where": "requirement for field: id", }, @@ -2445,11 +2445,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 241, - "endPosition": 10561, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10553, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 220, - "startPosition": 9814, + "startPosition": 9806, }, "where": "requirement for field: attributes", }, @@ -2463,11 +2463,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 226, - "endPosition": 9984, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9976, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 223, - "startPosition": 9876, + "startPosition": 9868, }, "where": "requirement for field: name", }, @@ -2481,11 +2481,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 231, - "endPosition": 10168, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10160, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 227, - "startPosition": 9993, + "startPosition": 9985, }, "where": "requirement for field: created", }, @@ -2499,11 +2499,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 236, - "endPosition": 10357, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10349, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 232, - "startPosition": 10177, + "startPosition": 10169, }, "where": "requirement for field: updated", }, @@ -2517,11 +2517,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 240, - "endPosition": 10527, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10519, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 237, - "startPosition": 10366, + "startPosition": 10358, }, "where": "requirement for field: description", }, @@ -2535,11 +2535,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 214, - "endPosition": 9708, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9700, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 210, - "startPosition": 9541, + "startPosition": 9533, }, "where": "requirement for field: relationships", }, @@ -3771,11 +3771,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 208, - "endPosition": 9535, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9527, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 197, - "startPosition": 9084, + "startPosition": 9076, }, "where": "requirement for field: data", }, @@ -3789,11 +3789,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 9290, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9282, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 201, - "startPosition": 9185, + "startPosition": 9177, }, "where": "requirement for field: id", }, @@ -3821,11 +3821,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 241, - "endPosition": 10561, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10553, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 220, - "startPosition": 9814, + "startPosition": 9806, }, "where": "requirement for field: attributes", }, @@ -3839,11 +3839,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 226, - "endPosition": 9984, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9976, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 223, - "startPosition": 9876, + "startPosition": 9868, }, "where": "requirement for field: name", }, @@ -3857,11 +3857,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 231, - "endPosition": 10168, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10160, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 227, - "startPosition": 9993, + "startPosition": 9985, }, "where": "requirement for field: created", }, @@ -3875,11 +3875,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 236, - "endPosition": 10357, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10349, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 232, - "startPosition": 10177, + "startPosition": 10169, }, "where": "requirement for field: updated", }, @@ -3893,11 +3893,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 240, - "endPosition": 10527, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10519, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 237, - "startPosition": 10366, + "startPosition": 10358, }, "where": "requirement for field: description", }, @@ -3911,11 +3911,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 214, - "endPosition": 9708, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9700, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 210, - "startPosition": 9541, + "startPosition": 9533, }, "where": "requirement for field: relationships", }, @@ -4979,11 +4979,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 208, - "endPosition": 9535, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9527, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 197, - "startPosition": 9084, + "startPosition": 9076, }, "where": "requirement for field: data", }, @@ -4997,11 +4997,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 9290, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9282, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 201, - "startPosition": 9185, + "startPosition": 9177, }, "where": "requirement for field: id", }, @@ -5029,11 +5029,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 241, - "endPosition": 10561, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10553, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 220, - "startPosition": 9814, + "startPosition": 9806, }, "where": "requirement for field: attributes", }, @@ -5047,11 +5047,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 226, - "endPosition": 9984, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9976, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 223, - "startPosition": 9876, + "startPosition": 9868, }, "where": "requirement for field: name", }, @@ -5065,11 +5065,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 231, - "endPosition": 10168, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10160, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 227, - "startPosition": 9993, + "startPosition": 9985, }, "where": "requirement for field: created", }, @@ -5083,11 +5083,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 236, - "endPosition": 10357, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10349, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 232, - "startPosition": 10177, + "startPosition": 10169, }, "where": "requirement for field: updated", }, @@ -5101,11 +5101,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 240, - "endPosition": 10527, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10519, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 237, - "startPosition": 10366, + "startPosition": 10358, }, "where": "requirement for field: description", }, @@ -5119,11 +5119,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 214, - "endPosition": 9708, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 9700, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 210, - "startPosition": 9541, + "startPosition": 9533, }, "where": "requirement for field: relationships", }, @@ -7335,8 +7335,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 5, - "endPosition": 174, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 166, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 5, "startPosition": 140, @@ -7353,8 +7353,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 5, - "endPosition": 174, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 166, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 5, "startPosition": 140, @@ -7371,8 +7371,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 242, - "endPosition": 10562, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10554, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 4, "startPosition": 125, @@ -7389,8 +7389,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 242, - "endPosition": 10562, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10554, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 4, "startPosition": 125, @@ -7407,8 +7407,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 242, - "endPosition": 10562, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10554, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 4, "startPosition": 125, @@ -7425,8 +7425,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 242, - "endPosition": 10562, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10554, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 4, "startPosition": 125, @@ -7443,8 +7443,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 242, - "endPosition": 10562, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 10554, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 4, "startPosition": 125, @@ -7461,11 +7461,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 75, - "endPosition": 3701, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 3693, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 46, - "startPosition": 2015, + "startPosition": 2007, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -7479,11 +7479,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 45, - "endPosition": 2010, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 2002, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 17, - "startPosition": 401, + "startPosition": 393, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -7497,11 +7497,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 111, - "endPosition": 5428, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 5420, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 77, - "startPosition": 3741, + "startPosition": 3733, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -7515,11 +7515,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 141, - "endPosition": 7102, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7094, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 112, - "startPosition": 5433, + "startPosition": 5425, }, "where": "requirement for operation: PATCH /orgs/{org_id}/thing/{thing_id}", }, @@ -7533,11 +7533,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 159, - "endPosition": 7948, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change.yaml", + "endPosition": 7940, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-breaking-param-change-beta.yaml", "preview": "", "startLine": 142, - "startPosition": 7107, + "startPosition": 7099, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -65647,11 +65647,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 74, - "endPosition": 3693, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 3685, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 45, - "startPosition": 2007, + "startPosition": 1999, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -65665,11 +65665,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 44, - "endPosition": 2002, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 1994, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 16, - "startPosition": 393, + "startPosition": 385, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -65683,11 +65683,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 103, - "endPosition": 5254, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 5246, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 76, - "startPosition": 3733, + "startPosition": 3725, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -65701,11 +65701,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 121, - "endPosition": 6100, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 6092, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 104, - "startPosition": 5259, + "startPosition": 5251, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -65719,11 +65719,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 74, - "endPosition": 3693, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 3685, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 45, - "startPosition": 2007, + "startPosition": 1999, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -65737,11 +65737,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 44, - "endPosition": 2002, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 1994, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 16, - "startPosition": 393, + "startPosition": 385, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -65755,11 +65755,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 103, - "endPosition": 5254, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 5246, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 76, - "startPosition": 3733, + "startPosition": 3725, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -65773,11 +65773,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 121, - "endPosition": 6100, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 6092, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 104, - "startPosition": 5259, + "startPosition": 5251, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -65791,11 +65791,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 74, - "endPosition": 3693, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 3685, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 45, - "startPosition": 2007, + "startPosition": 1999, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -65809,11 +65809,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 44, - "endPosition": 2002, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 1994, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 16, - "startPosition": 393, + "startPosition": 385, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -65827,11 +65827,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 103, - "endPosition": 5254, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 5246, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 76, - "startPosition": 3733, + "startPosition": 3725, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -65845,11 +65845,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 121, - "endPosition": 6100, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 6092, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 104, - "startPosition": 5259, + "startPosition": 5251, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -65878,11 +65878,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 74, - "endPosition": 3693, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 3685, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 45, - "startPosition": 2007, + "startPosition": 1999, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -65896,11 +65896,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 44, - "endPosition": 2002, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 1994, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 16, - "startPosition": 393, + "startPosition": 385, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -65914,11 +65914,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 103, - "endPosition": 5254, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 5246, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 76, - "startPosition": 3733, + "startPosition": 3725, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -65932,11 +65932,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 121, - "endPosition": 6100, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 6092, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 104, - "startPosition": 5259, + "startPosition": 5251, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -65950,11 +65950,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 74, - "endPosition": 3693, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 3685, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 45, - "startPosition": 2007, + "startPosition": 1999, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -65968,11 +65968,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 44, - "endPosition": 2002, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 1994, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 16, - "startPosition": 393, + "startPosition": 385, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -65986,11 +65986,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 103, - "endPosition": 5254, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 5246, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 76, - "startPosition": 3733, + "startPosition": 3725, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -66004,11 +66004,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 121, - "endPosition": 6100, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 6092, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 104, - "startPosition": 5259, + "startPosition": 5251, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, @@ -66022,8 +66022,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 8714, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8706, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 3, "startPosition": 117, @@ -66040,11 +66040,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 69, - "endPosition": 3353, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 3345, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 58, - "startPosition": 2527, + "startPosition": 2519, }, "where": "requirement for response: 200", }, @@ -66128,11 +66128,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 38, - "endPosition": 1594, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 1586, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 26, - "startPosition": 693, + "startPosition": 685, }, "where": "requirement for response: 201", }, @@ -66230,11 +66230,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 98, - "endPosition": 4914, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 4906, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 87, - "startPosition": 4095, + "startPosition": 4087, }, "where": "requirement for response: 200", }, @@ -66444,11 +66444,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 180, - "endPosition": 7960, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 7952, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 178, - "startPosition": 7866, + "startPosition": 7858, }, "where": "requirement for field: data", }, @@ -66462,11 +66462,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 166, - "endPosition": 7442, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 7434, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 163, - "startPosition": 7337, + "startPosition": 7329, }, "where": "requirement for field: id", }, @@ -66494,11 +66494,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 203, - "endPosition": 8713, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8705, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 182, - "startPosition": 7966, + "startPosition": 7958, }, "where": "requirement for field: attributes", }, @@ -66512,11 +66512,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 188, - "endPosition": 8136, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8128, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 185, - "startPosition": 8028, + "startPosition": 8020, }, "where": "requirement for field: name", }, @@ -66530,11 +66530,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 193, - "endPosition": 8320, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8312, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 189, - "startPosition": 8145, + "startPosition": 8137, }, "where": "requirement for field: created", }, @@ -66548,11 +66548,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 198, - "endPosition": 8509, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8501, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 194, - "startPosition": 8329, + "startPosition": 8321, }, "where": "requirement for field: updated", }, @@ -66566,11 +66566,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 202, - "endPosition": 8679, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8671, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 199, - "startPosition": 8518, + "startPosition": 8510, }, "where": "requirement for field: description", }, @@ -66584,11 +66584,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 176, - "endPosition": 7860, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 7852, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 172, - "startPosition": 7693, + "startPosition": 7685, }, "where": "requirement for field: relationships", }, @@ -67820,11 +67820,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 170, - "endPosition": 7687, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 7679, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 159, - "startPosition": 7236, + "startPosition": 7228, }, "where": "requirement for field: data", }, @@ -67838,11 +67838,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 166, - "endPosition": 7442, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 7434, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 163, - "startPosition": 7337, + "startPosition": 7329, }, "where": "requirement for field: id", }, @@ -67870,11 +67870,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 203, - "endPosition": 8713, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8705, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 182, - "startPosition": 7966, + "startPosition": 7958, }, "where": "requirement for field: attributes", }, @@ -67888,11 +67888,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 188, - "endPosition": 8136, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8128, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 185, - "startPosition": 8028, + "startPosition": 8020, }, "where": "requirement for field: name", }, @@ -67906,11 +67906,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 193, - "endPosition": 8320, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8312, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 189, - "startPosition": 8145, + "startPosition": 8137, }, "where": "requirement for field: created", }, @@ -67924,11 +67924,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 198, - "endPosition": 8509, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8501, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 194, - "startPosition": 8329, + "startPosition": 8321, }, "where": "requirement for field: updated", }, @@ -67942,11 +67942,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 202, - "endPosition": 8679, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8671, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 199, - "startPosition": 8518, + "startPosition": 8510, }, "where": "requirement for field: description", }, @@ -67960,11 +67960,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 176, - "endPosition": 7860, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 7852, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 172, - "startPosition": 7693, + "startPosition": 7685, }, "where": "requirement for field: relationships", }, @@ -69196,11 +69196,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 170, - "endPosition": 7687, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 7679, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 159, - "startPosition": 7236, + "startPosition": 7228, }, "where": "requirement for field: data", }, @@ -69214,11 +69214,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 166, - "endPosition": 7442, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 7434, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 163, - "startPosition": 7337, + "startPosition": 7329, }, "where": "requirement for field: id", }, @@ -69246,11 +69246,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 203, - "endPosition": 8713, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8705, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 182, - "startPosition": 7966, + "startPosition": 7958, }, "where": "requirement for field: attributes", }, @@ -69264,11 +69264,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 188, - "endPosition": 8136, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8128, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 185, - "startPosition": 8028, + "startPosition": 8020, }, "where": "requirement for field: name", }, @@ -69282,11 +69282,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 193, - "endPosition": 8320, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8312, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 189, - "startPosition": 8145, + "startPosition": 8137, }, "where": "requirement for field: created", }, @@ -69300,11 +69300,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 198, - "endPosition": 8509, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8501, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 194, - "startPosition": 8329, + "startPosition": 8321, }, "where": "requirement for field: updated", }, @@ -69318,11 +69318,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 202, - "endPosition": 8679, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8671, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 199, - "startPosition": 8518, + "startPosition": 8510, }, "where": "requirement for field: description", }, @@ -69336,11 +69336,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 176, - "endPosition": 7860, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 7852, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 172, - "startPosition": 7693, + "startPosition": 7685, }, "where": "requirement for field: relationships", }, @@ -71384,8 +71384,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 4, - "endPosition": 166, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 158, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 4, "startPosition": 132, @@ -71402,8 +71402,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 4, - "endPosition": 166, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 158, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 4, "startPosition": 132, @@ -71420,8 +71420,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 8714, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8706, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 3, "startPosition": 117, @@ -71438,8 +71438,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 8714, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8706, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 3, "startPosition": 117, @@ -71456,8 +71456,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 8714, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8706, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 3, "startPosition": 117, @@ -71474,8 +71474,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 8714, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8706, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 3, "startPosition": 117, @@ -71492,8 +71492,8 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 204, - "endPosition": 8714, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 8706, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 3, "startPosition": 117, @@ -71510,11 +71510,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 74, - "endPosition": 3693, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 3685, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 45, - "startPosition": 2007, + "startPosition": 1999, }, "where": "requirement for operation: GET /orgs/{org_id}/thing", }, @@ -71528,11 +71528,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 44, - "endPosition": 2002, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 1994, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 16, - "startPosition": 393, + "startPosition": 385, }, "where": "requirement for operation: POST /orgs/{org_id}/thing", }, @@ -71546,11 +71546,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 103, - "endPosition": 5254, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 5246, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 76, - "startPosition": 3733, + "startPosition": 3725, }, "where": "requirement for operation: GET /orgs/{org_id}/thing/{thing_id}", }, @@ -71564,11 +71564,11 @@ Array [ "passed": true, "sourcemap": Object { "endLine": 121, - "endPosition": 6100, - "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed.yaml", + "endPosition": 6092, + "filePath": "/end-end-tests/api-standards/resources/thing/2021-11-10/001-fail-operation-removed-beta.yaml", "preview": "", "startLine": 104, - "startPosition": 5259, + "startPosition": 5251, }, "where": "requirement for operation: DELETE /orgs/{org_id}/thing/{thing_id}", }, diff --git a/src/rulesets/tests/__snapshots__/lifecycle.test.ts.snap b/src/rulesets/tests/__snapshots__/lifecycle.test.ts.snap index ce83aa7d..9ee0528d 100644 --- a/src/rulesets/tests/__snapshots__/lifecycle.test.ts.snap +++ b/src/rulesets/tests/__snapshots__/lifecycle.test.ts.snap @@ -1372,12 +1372,12 @@ Object { "changeResource": "Example", "changeVersion": Object { "date": "2021-10-10", - "stability": "experimental", + "stability": "beta", }, "resourceVersions": Object { "Example": Object { "2021-10-10": Object { - "experimental": Object { + "beta": Object { "deprecatedBy": Object { "date": "2021-10-20", "stability": "ga", @@ -1401,7 +1401,7 @@ Object { "condition": "follow sunset rules", "docsLink": undefined, "effectiveOnDate": undefined, - "error": "expected experimental resource Example to be deprecated 30 days", + "error": "expected beta resource Example to be deprecated 90 days", "isMust": true, "isShould": false, "passed": false, @@ -1474,16 +1474,16 @@ Object { Object { "change": Object { "added": Object { - "changeDate": "2021-12-01", + "changeDate": "2022-02-01", "changeResource": "Example", "changeVersion": Object { "date": "2021-10-10", - "stability": "experimental", + "stability": "beta", }, "resourceVersions": Object { "Example": Object { "2021-10-10": Object { - "experimental": Object { + "beta": Object { "deprecatedBy": Object { "date": "2021-10-20", "stability": "ga", diff --git a/src/rulesets/tests/__snapshots__/operations.test.ts.snap b/src/rulesets/tests/__snapshots__/operations.test.ts.snap index 6e7a5193..c8f12971 100644 --- a/src/rulesets/tests/__snapshots__/operations.test.ts.snap +++ b/src/rulesets/tests/__snapshots__/operations.test.ts.snap @@ -1288,60 +1288,76 @@ Object { } `; -exports[`operation parameters fails adding put method 1`] = ` +exports[`operation parameters fails if the default value is changed 1`] = ` Object { "base": Object { "info": Object { - "title": "Empty", + "title": "OpenAPI", "version": "0.0.0", }, - "openapi": "3.1.3", - "paths": Object {}, - }, - "changelog": Array [ - Object { - "added": Object { - "method": "put", - "pathPattern": "/example", - }, - "changeType": "added", - "location": Object { - "conceptualLocation": Object { - "method": "put", - "path": "/example", + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "operationId": "getExample", + "parameters": Array [ + Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "before", + "type": "string", + }, + }, + ], + "responses": Object {}, + "summary": "Retrieve example", + "tags": Array [ + "Example", + ], }, - "conceptualPath": Array [ - "operations", - "/example", - "put", - ], - "jsonPath": "/paths/~1example/put", - "kind": "operation", }, }, + }, + "changelog": Array [ Object { "changeType": "changed", "changed": Object { "after": Object { - "info": Object { - "title": "OpenAPI", - "version": "0.0.0", + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "after", + "type": "string", }, - "openapi": "3.0.1", }, "before": Object { - "info": Object { - "title": "Empty", - "version": "0.0.0", + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "before", + "type": "string", }, - "openapi": "3.1.3", }, }, "location": Object { - "conceptualLocation": Object {}, - "conceptualPath": Array [], - "jsonPath": "", - "kind": "specification", + "conceptualLocation": Object { + "inRequest": Object { + "query": "query_parameter", + }, + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "parameters", + "query", + "query_parameter", + ], + "jsonPath": "/paths/~1example/get/parameters/0", + "kind": "query-parameter", }, }, ], @@ -1353,8 +1369,23 @@ Object { "openapi": "3.0.1", "paths": Object { "/example": Object { - "put": Object { + "get": Object { + "operationId": "getExample", + "parameters": Array [ + Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "after", + "type": "string", + }, + }, + ], "responses": Object {}, + "summary": "Retrieve example", + "tags": Array [ + "Example", + ], }, }, }, @@ -1362,33 +1393,53 @@ Object { "results": Array [ Object { "change": Object { - "added": Object { - "method": "put", - "pathPattern": "/example", + "changeType": "changed", + "changed": Object { + "after": Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "after", + "type": "string", + }, + }, + "before": Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "before", + "type": "string", + }, + }, }, - "changeType": "added", "location": Object { "conceptualLocation": Object { - "method": "put", + "inRequest": Object { + "query": "query_parameter", + }, + "method": "get", "path": "/example", }, "conceptualPath": Array [ "operations", "/example", - "put", + "get", + "parameters", + "query", + "query_parameter", ], - "jsonPath": "/paths/~1example/put", - "kind": "operation", + "jsonPath": "/paths/~1example/get/parameters/0", + "kind": "query-parameter", }, }, - "condition": "not use put method", - "docsLink": undefined, + "condition": "not change the default value", + "docsLink": "https://github.com/snyk/sweater-comb/blob/main/docs/version.md#breaking-changes", "effectiveOnDate": undefined, - "error": "put is not allowed in JSON:API", + "error": "expected 'before' to equal 'after'", "isMust": true, "isShould": false, "passed": false, - "where": "added operation: PUT /example", + "where": "updated query-parameter: query_parameter", }, ], } @@ -1666,7 +1717,7 @@ Object { } `; -exports[`operation parameters names fails if the default value is changed 1`] = ` +exports[`operation parameters names fails when adding a required query parameter 1`] = ` Object { "base": Object { "info": Object { @@ -1678,16 +1729,6 @@ Object { "/example": Object { "get": Object { "operationId": "getExample", - "parameters": Array [ - Object { - "in": "query", - "name": "query_parameter", - "schema": Object { - "default": "before", - "type": "string", - }, - }, - ], "responses": Object {}, "summary": "Retrieve example", "tags": Array [ @@ -1699,25 +1740,12 @@ Object { }, "changelog": Array [ Object { - "changeType": "changed", - "changed": Object { - "after": Object { - "in": "query", - "name": "query_parameter", - "schema": Object { - "default": "after", - "type": "string", - }, - }, - "before": Object { - "in": "query", - "name": "query_parameter", - "schema": Object { - "default": "before", - "type": "string", - }, - }, + "added": Object { + "in": "query", + "name": "query_parameter", + "required": true, }, + "changeType": "added", "location": Object { "conceptualLocation": Object { "inRequest": Object { @@ -1753,10 +1781,7 @@ Object { Object { "in": "query", "name": "query_parameter", - "schema": Object { - "default": "after", - "type": "string", - }, + "required": true, }, ], "responses": Object {}, @@ -1771,25 +1796,12 @@ Object { "results": Array [ Object { "change": Object { - "changeType": "changed", - "changed": Object { - "after": Object { - "in": "query", - "name": "query_parameter", - "schema": Object { - "default": "after", - "type": "string", - }, - }, - "before": Object { - "in": "query", - "name": "query_parameter", - "schema": Object { - "default": "before", - "type": "string", - }, - }, + "added": Object { + "in": "query", + "name": "query_parameter", + "required": true, }, + "changeType": "added", "location": Object { "conceptualLocation": Object { "inRequest": Object { @@ -1810,20 +1822,20 @@ Object { "kind": "query-parameter", }, }, - "condition": "not change the default value", + "condition": "not be required", "docsLink": "https://github.com/snyk/sweater-comb/blob/main/docs/version.md#breaking-changes", "effectiveOnDate": undefined, - "error": "expected 'before' to equal 'after'", + "error": "expected request query parameter query_parameter to not be required", "isMust": true, "isShould": false, "passed": false, - "where": "updated query-parameter: query_parameter", + "where": "added query-parameter: query_parameter", }, ], } `; -exports[`operation parameters names fails when adding a required query parameter 1`] = ` +exports[`operation parameters names fails when changing optional to required query parameter 1`] = ` Object { "base": Object { "info": Object { @@ -1835,6 +1847,12 @@ Object { "/example": Object { "get": Object { "operationId": "getExample", + "parameters": Array [ + Object { + "in": "query", + "name": "query_parameter", + }, + ], "responses": Object {}, "summary": "Retrieve example", "tags": Array [ @@ -1846,12 +1864,18 @@ Object { }, "changelog": Array [ Object { - "added": Object { - "in": "query", - "name": "query_parameter", - "required": true, + "changeType": "changed", + "changed": Object { + "after": Object { + "in": "query", + "name": "query_parameter", + "required": true, + }, + "before": Object { + "in": "query", + "name": "query_parameter", + }, }, - "changeType": "added", "location": Object { "conceptualLocation": Object { "inRequest": Object { @@ -1902,12 +1926,18 @@ Object { "results": Array [ Object { "change": Object { - "added": Object { - "in": "query", - "name": "query_parameter", - "required": true, + "changeType": "changed", + "changed": Object { + "after": Object { + "in": "query", + "name": "query_parameter", + "required": true, + }, + "before": Object { + "in": "query", + "name": "query_parameter", + }, }, - "changeType": "added", "location": Object { "conceptualLocation": Object { "inRequest": Object { @@ -1928,143 +1958,7 @@ Object { "kind": "query-parameter", }, }, - "condition": "not be required", - "docsLink": "https://github.com/snyk/sweater-comb/blob/main/docs/version.md#breaking-changes", - "effectiveOnDate": undefined, - "error": "expected request query parameter query_parameter to not be required", - "isMust": true, - "isShould": false, - "passed": false, - "where": "added query-parameter: query_parameter", - }, - ], -} -`; - -exports[`operation parameters names fails when changing optional to required query parameter 1`] = ` -Object { - "base": Object { - "info": Object { - "title": "OpenAPI", - "version": "0.0.0", - }, - "openapi": "3.0.1", - "paths": Object { - "/example": Object { - "get": Object { - "operationId": "getExample", - "parameters": Array [ - Object { - "in": "query", - "name": "query_parameter", - }, - ], - "responses": Object {}, - "summary": "Retrieve example", - "tags": Array [ - "Example", - ], - }, - }, - }, - }, - "changelog": Array [ - Object { - "changeType": "changed", - "changed": Object { - "after": Object { - "in": "query", - "name": "query_parameter", - "required": true, - }, - "before": Object { - "in": "query", - "name": "query_parameter", - }, - }, - "location": Object { - "conceptualLocation": Object { - "inRequest": Object { - "query": "query_parameter", - }, - "method": "get", - "path": "/example", - }, - "conceptualPath": Array [ - "operations", - "/example", - "get", - "parameters", - "query", - "query_parameter", - ], - "jsonPath": "/paths/~1example/get/parameters/0", - "kind": "query-parameter", - }, - }, - ], - "next": Object { - "info": Object { - "title": "OpenAPI", - "version": "0.0.0", - }, - "openapi": "3.0.1", - "paths": Object { - "/example": Object { - "get": Object { - "operationId": "getExample", - "parameters": Array [ - Object { - "in": "query", - "name": "query_parameter", - "required": true, - }, - ], - "responses": Object {}, - "summary": "Retrieve example", - "tags": Array [ - "Example", - ], - }, - }, - }, - }, - "results": Array [ - Object { - "change": Object { - "changeType": "changed", - "changed": Object { - "after": Object { - "in": "query", - "name": "query_parameter", - "required": true, - }, - "before": Object { - "in": "query", - "name": "query_parameter", - }, - }, - "location": Object { - "conceptualLocation": Object { - "inRequest": Object { - "query": "query_parameter", - }, - "method": "get", - "path": "/example", - }, - "conceptualPath": Array [ - "operations", - "/example", - "get", - "parameters", - "query", - "query_parameter", - ], - "jsonPath": "/paths/~1example/get/parameters/0", - "kind": "query-parameter", - }, - }, - "condition": "not be optional then required", + "condition": "not be optional then required", "docsLink": "https://github.com/snyk/sweater-comb/blob/main/docs/version.md#breaking-changes", "effectiveOnDate": undefined, "error": "expected request query parameter query_parameter to not change from optional to required", @@ -2227,7 +2121,7 @@ Object { } `; -exports[`operation parameters status codes fails when a status codes is removed 1`] = ` +exports[`operation parameters names passes if the default value is changed in experimental 1`] = ` Object { "base": Object { "info": Object { @@ -2239,11 +2133,17 @@ Object { "/example": Object { "get": Object { "operationId": "getExample", - "responses": Object { - "200": Object { - "description": "Example response", + "parameters": Array [ + Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "before", + "type": "string", + }, }, - }, + ], + "responses": Object {}, "summary": "Retrieve example", "tags": Array [ "Example", @@ -2254,11 +2154,29 @@ Object { }, "changelog": Array [ Object { - "changeType": "removed", + "changeType": "changed", + "changed": Object { + "after": Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "after", + "type": "string", + }, + }, + "before": Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "before", + "type": "string", + }, + }, + }, "location": Object { "conceptualLocation": Object { - "inResponse": Object { - "statusCode": "200", + "inRequest": Object { + "query": "query_parameter", }, "method": "get", "path": "/example", @@ -2267,17 +2185,12 @@ Object { "operations", "/example", "get", - "responses", - "200", + "parameters", + "query", + "query_parameter", ], - "jsonPath": "/paths/~1example/get/responses/200", - "kind": "response", - }, - "removed": Object { - "before": Object { - "description": "Example response", - "statusCode": "200", - }, + "jsonPath": "/paths/~1example/get/parameters/0", + "kind": "query-parameter", }, }, ], @@ -2291,6 +2204,16 @@ Object { "/example": Object { "get": Object { "operationId": "getExample", + "parameters": Array [ + Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "after", + "type": "string", + }, + }, + ], "responses": Object {}, "summary": "Retrieve example", "tags": Array [ @@ -2303,11 +2226,29 @@ Object { "results": Array [ Object { "change": Object { - "changeType": "removed", + "changeType": "changed", + "changed": Object { + "after": Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "after", + "type": "string", + }, + }, + "before": Object { + "in": "query", + "name": "query_parameter", + "schema": Object { + "default": "before", + "type": "string", + }, + }, + }, "location": Object { "conceptualLocation": Object { - "inResponse": Object { - "statusCode": "200", + "inRequest": Object { + "query": "query_parameter", }, "method": "get", "path": "/example", @@ -2316,33 +2257,27 @@ Object { "operations", "/example", "get", - "responses", - "200", + "parameters", + "query", + "query_parameter", ], - "jsonPath": "/paths/~1example/get/responses/200", - "kind": "response", - }, - "removed": Object { - "before": Object { - "description": "Example response", - "statusCode": "200", - }, + "jsonPath": "/paths/~1example/get/parameters/0", + "kind": "query-parameter", }, }, - "condition": "not be removed", - "docsLink": "https://github.com/snyk/sweater-comb/blob/main/docs/version.md#breaking-changes", + "condition": "not change the default value", + "docsLink": undefined, "effectiveOnDate": undefined, - "error": "expected get /example 200 to be present", "isMust": true, "isShould": false, - "passed": false, - "where": "removed response: 200", + "passed": true, + "where": "updated query-parameter: query_parameter", }, ], } `; -exports[`operation parameters version parameter fails when there is no version parameter 1`] = ` +exports[`operation parameters names passes when changing optional to required query parameter in experimental 1`] = ` Object { "base": Object { "info": Object { @@ -2354,6 +2289,12 @@ Object { "/example": Object { "get": Object { "operationId": "getExample", + "parameters": Array [ + Object { + "in": "query", + "name": "query_parameter", + }, + ], "responses": Object {}, "summary": "Retrieve example", "tags": Array [ @@ -2363,10 +2304,44 @@ Object { }, }, }, - "changelog": Array [], - "next": Object { - "info": Object { - "title": "OpenAPI", + "changelog": Array [ + Object { + "changeType": "changed", + "changed": Object { + "after": Object { + "in": "query", + "name": "query_parameter", + "required": true, + }, + "before": Object { + "in": "query", + "name": "query_parameter", + }, + }, + "location": Object { + "conceptualLocation": Object { + "inRequest": Object { + "query": "query_parameter", + }, + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "parameters", + "query", + "query_parameter", + ], + "jsonPath": "/paths/~1example/get/parameters/0", + "kind": "query-parameter", + }, + }, + ], + "next": Object { + "info": Object { + "title": "OpenAPI", "version": "0.0.0", }, "openapi": "3.0.1", @@ -2374,6 +2349,13 @@ Object { "/example": Object { "get": Object { "operationId": "getExample", + "parameters": Array [ + Object { + "in": "query", + "name": "query_parameter", + "required": true, + }, + ], "responses": Object {}, "summary": "Retrieve example", "tags": Array [ @@ -2386,8 +2368,23 @@ Object { "results": Array [ Object { "change": Object { + "changeType": "changed", + "changed": Object { + "after": Object { + "in": "query", + "name": "query_parameter", + "required": true, + }, + "before": Object { + "in": "query", + "name": "query_parameter", + }, + }, "location": Object { "conceptualLocation": Object { + "inRequest": Object { + "query": "query_parameter", + }, "method": "get", "path": "/example", }, @@ -2395,28 +2392,21 @@ Object { "operations", "/example", "get", + "parameters", + "query", + "query_parameter", ], - "jsonPath": "/paths/~1example/get", - "kind": "operation", - }, - "value": Object { - "method": "get", - "operationId": "getExample", - "pathPattern": "/example", - "summary": "Retrieve example", - "tags": Array [ - "Example", - ], + "jsonPath": "/paths/~1example/get/parameters/0", + "kind": "query-parameter", }, }, - "condition": "include a version parameter", - "docsLink": "https://github.com/snyk/sweater-comb/blob/main/docs/version.md#how-are-versions-accessed-and-resolved-by-consumers", + "condition": "not be optional then required", + "docsLink": undefined, "effectiveOnDate": undefined, - "error": "expected [] to include 'version'", "isMust": true, "isShould": false, - "passed": false, - "where": "requirement for operation: GET /example", + "passed": true, + "where": "updated query-parameter: query_parameter", }, ], } @@ -3202,3 +3192,304 @@ Object { ], } `; + +exports[`put method fails adding put method 1`] = ` +Object { + "base": Object { + "info": Object { + "title": "Empty", + "version": "0.0.0", + }, + "openapi": "3.1.3", + "paths": Object {}, + }, + "changelog": Array [ + Object { + "added": Object { + "method": "put", + "pathPattern": "/example", + }, + "changeType": "added", + "location": Object { + "conceptualLocation": Object { + "method": "put", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "put", + ], + "jsonPath": "/paths/~1example/put", + "kind": "operation", + }, + }, + Object { + "changeType": "changed", + "changed": Object { + "after": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + }, + "before": Object { + "info": Object { + "title": "Empty", + "version": "0.0.0", + }, + "openapi": "3.1.3", + }, + }, + "location": Object { + "conceptualLocation": Object {}, + "conceptualPath": Array [], + "jsonPath": "", + "kind": "specification", + }, + }, + ], + "next": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "put": Object { + "responses": Object {}, + }, + }, + }, + }, + "results": Array [ + Object { + "change": Object { + "added": Object { + "method": "put", + "pathPattern": "/example", + }, + "changeType": "added", + "location": Object { + "conceptualLocation": Object { + "method": "put", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "put", + ], + "jsonPath": "/paths/~1example/put", + "kind": "operation", + }, + }, + "condition": "not use put method", + "docsLink": undefined, + "effectiveOnDate": undefined, + "error": "put is not allowed in JSON:API", + "isMust": true, + "isShould": false, + "passed": false, + "where": "added operation: PUT /example", + }, + ], +} +`; + +exports[`status codes fails when a status codes is removed 1`] = ` +Object { + "base": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "operationId": "getExample", + "responses": Object { + "200": Object { + "description": "Example response", + }, + }, + "summary": "Retrieve example", + "tags": Array [ + "Example", + ], + }, + }, + }, + }, + "changelog": Array [ + Object { + "changeType": "removed", + "location": Object { + "conceptualLocation": Object { + "inResponse": Object { + "statusCode": "200", + }, + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "responses", + "200", + ], + "jsonPath": "/paths/~1example/get/responses/200", + "kind": "response", + }, + "removed": Object { + "before": Object { + "description": "Example response", + "statusCode": "200", + }, + }, + }, + ], + "next": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "operationId": "getExample", + "responses": Object {}, + "summary": "Retrieve example", + "tags": Array [ + "Example", + ], + }, + }, + }, + }, + "results": Array [ + Object { + "change": Object { + "changeType": "removed", + "location": Object { + "conceptualLocation": Object { + "inResponse": Object { + "statusCode": "200", + }, + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "responses", + "200", + ], + "jsonPath": "/paths/~1example/get/responses/200", + "kind": "response", + }, + "removed": Object { + "before": Object { + "description": "Example response", + "statusCode": "200", + }, + }, + }, + "condition": "not be removed", + "docsLink": "https://github.com/snyk/sweater-comb/blob/main/docs/version.md#breaking-changes", + "effectiveOnDate": undefined, + "error": "expected get /example 200 to be present", + "isMust": true, + "isShould": false, + "passed": false, + "where": "removed response: 200", + }, + ], +} +`; + +exports[`version parameter fails when there is no version parameter 1`] = ` +Object { + "base": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "operationId": "getExample", + "responses": Object {}, + "summary": "Retrieve example", + "tags": Array [ + "Example", + ], + }, + }, + }, + }, + "changelog": Array [], + "next": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "operationId": "getExample", + "responses": Object {}, + "summary": "Retrieve example", + "tags": Array [ + "Example", + ], + }, + }, + }, + }, + "results": Array [ + Object { + "change": Object { + "location": Object { + "conceptualLocation": Object { + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + ], + "jsonPath": "/paths/~1example/get", + "kind": "operation", + }, + "value": Object { + "method": "get", + "operationId": "getExample", + "pathPattern": "/example", + "summary": "Retrieve example", + "tags": Array [ + "Example", + ], + }, + }, + "condition": "include a version parameter", + "docsLink": "https://github.com/snyk/sweater-comb/blob/main/docs/version.md#how-are-versions-accessed-and-resolved-by-consumers", + "effectiveOnDate": undefined, + "error": "expected [] to include 'version'", + "isMust": true, + "isShould": false, + "passed": false, + "where": "requirement for operation: GET /example", + }, + ], +} +`; diff --git a/src/rulesets/tests/__snapshots__/properties.test.ts.snap b/src/rulesets/tests/__snapshots__/properties.test.ts.snap index ec974a6e..838cdb21 100644 --- a/src/rulesets/tests/__snapshots__/properties.test.ts.snap +++ b/src/rulesets/tests/__snapshots__/properties.test.ts.snap @@ -358,6 +358,295 @@ Object { } `; +exports[`body properties breaking changes passes if a property is removed in experimental 1`] = ` +Object { + "base": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "responses": Object { + "200": Object { + "content": Object { + "application/json": Object { + "schema": Object { + "properties": Object { + "count": Object { + "type": "number", + }, + }, + "type": "object", + }, + }, + }, + "description": "", + }, + }, + }, + }, + }, + }, + "changelog": Array [ + Object { + "changeType": "removed", + "location": Object { + "conceptualLocation": Object { + "inResponse": Object { + "body": Object { + "contentType": "application/json", + }, + "statusCode": "200", + }, + "jsonSchemaTrail": Array [ + "count", + ], + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "responses", + "200", + "application/json", + "count", + ], + "jsonPath": "/paths/~1example/get/responses/200/content/application~1json/schema/properties/count", + "kind": "field", + }, + "removed": Object { + "before": Object { + "flatSchema": Object { + "type": "number", + }, + "key": "count", + "required": false, + }, + }, + }, + ], + "next": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "responses": Object { + "200": Object { + "content": Object { + "application/json": Object { + "schema": Object { + "properties": Object {}, + "type": "object", + }, + }, + }, + "description": "", + }, + }, + }, + }, + }, + }, + "results": Array [ + Object { + "change": Object { + "changeType": "removed", + "location": Object { + "conceptualLocation": Object { + "inResponse": Object { + "body": Object { + "contentType": "application/json", + }, + "statusCode": "200", + }, + "jsonSchemaTrail": Array [ + "count", + ], + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "responses", + "200", + "application/json", + "count", + ], + "jsonPath": "/paths/~1example/get/responses/200/content/application~1json/schema/properties/count", + "kind": "field", + }, + "removed": Object { + "before": Object { + "flatSchema": Object { + "type": "number", + }, + "key": "count", + "required": false, + }, + }, + }, + "condition": "not be removed", + "docsLink": undefined, + "effectiveOnDate": undefined, + "isMust": true, + "isShould": false, + "passed": true, + "where": "removed field: count", + }, + ], +} +`; + +exports[`body properties breaking changes passes if a required property is added in experimental 1`] = ` +Object { + "base": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "requestBody": Object { + "content": Object { + "application/json": Object { + "schema": Object { + "properties": Object {}, + "type": "object", + }, + }, + }, + }, + "responses": Object {}, + }, + }, + }, + }, + "changelog": Array [ + Object { + "added": Object { + "flatSchema": Object { + "type": "number", + }, + "key": "count", + "required": true, + }, + "changeType": "added", + "location": Object { + "conceptualLocation": Object { + "inRequest": Object { + "body": Object { + "contentType": "application/json", + }, + }, + "jsonSchemaTrail": Array [ + "count", + ], + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "application/json", + "count", + ], + "jsonPath": "/paths/~1example/get/requestBody/content/application~1json/schema/properties/count", + "kind": "field", + }, + }, + ], + "next": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "requestBody": Object { + "content": Object { + "application/json": Object { + "schema": Object { + "properties": Object { + "count": Object { + "type": "number", + }, + }, + "required": Array [ + "count", + ], + "type": "object", + }, + }, + }, + }, + "responses": Object {}, + }, + }, + }, + }, + "results": Array [ + Object { + "change": Object { + "added": Object { + "flatSchema": Object { + "type": "number", + }, + "key": "count", + "required": true, + }, + "changeType": "added", + "location": Object { + "conceptualLocation": Object { + "inRequest": Object { + "body": Object { + "contentType": "application/json", + }, + }, + "jsonSchemaTrail": Array [ + "count", + ], + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "application/json", + "count", + ], + "jsonPath": "/paths/~1example/get/requestBody/content/application~1json/schema/properties/count", + "kind": "field", + }, + }, + "condition": "not be required", + "docsLink": undefined, + "effectiveOnDate": undefined, + "isMust": true, + "isShould": false, + "passed": true, + "where": "added field: count", + }, + ], +} +`; + exports[`body properties key fails when not snake case 1`] = ` Object { "base": Object { @@ -549,6 +838,197 @@ Object { } `; +exports[`body properties key fails when not snake case in experimental 1`] = ` +Object { + "base": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "responses": Object {}, + }, + }, + }, + }, + "changelog": Array [ + Object { + "added": Object { + "contentType": "application/json", + "flatSchema": Object { + "type": "object", + }, + }, + "changeType": "added", + "location": Object { + "conceptualLocation": Object { + "inResponse": Object { + "body": Object { + "contentType": "application/json", + }, + "statusCode": "200", + }, + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "responses", + "200", + "application/json", + ], + "jsonPath": "/paths/~1example/get/responses/200/content/application~1json", + "kind": "body", + }, + }, + Object { + "added": Object { + "flatSchema": Object { + "type": "string", + }, + "key": "not-snake-case", + "required": false, + }, + "changeType": "added", + "location": Object { + "conceptualLocation": Object { + "inResponse": Object { + "body": Object { + "contentType": "application/json", + }, + "statusCode": "200", + }, + "jsonSchemaTrail": Array [ + "not-snake-case", + ], + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "responses", + "200", + "application/json", + "not-snake-case", + ], + "jsonPath": "/paths/~1example/get/responses/200/content/application~1json/schema/properties/not-snake-case", + "kind": "field", + }, + }, + Object { + "added": Object { + "description": "", + "statusCode": "200", + }, + "changeType": "added", + "location": Object { + "conceptualLocation": Object { + "inResponse": Object { + "statusCode": "200", + }, + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "responses", + "200", + ], + "jsonPath": "/paths/~1example/get/responses/200", + "kind": "response", + }, + }, + ], + "next": Object { + "info": Object { + "title": "OpenAPI", + "version": "0.0.0", + }, + "openapi": "3.0.1", + "paths": Object { + "/example": Object { + "get": Object { + "responses": Object { + "200": Object { + "content": Object { + "application/json": Object { + "schema": Object { + "properties": Object { + "not-snake-case": Object { + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "", + }, + }, + }, + }, + }, + }, + "results": Array [ + Object { + "change": Object { + "added": Object { + "flatSchema": Object { + "type": "string", + }, + "key": "not-snake-case", + "required": false, + }, + "changeType": "added", + "location": Object { + "conceptualLocation": Object { + "inResponse": Object { + "body": Object { + "contentType": "application/json", + }, + "statusCode": "200", + }, + "jsonSchemaTrail": Array [ + "not-snake-case", + ], + "method": "get", + "path": "/example", + }, + "conceptualPath": Array [ + "operations", + "/example", + "get", + "responses", + "200", + "application/json", + "not-snake-case", + ], + "jsonPath": "/paths/~1example/get/responses/200/content/application~1json/schema/properties/not-snake-case", + "kind": "field", + }, + }, + "condition": "have snake case keys", + "docsLink": undefined, + "effectiveOnDate": undefined, + "error": "expected response property not-snake-case is be snake case", + "isMust": true, + "isShould": false, + "passed": false, + "where": "added field: not-snake-case", + }, + ], +} +`; + exports[`body properties key fails when not snake case in nested field 1`] = ` Object { "base": Object { diff --git a/src/rulesets/tests/end-end.test.ts b/src/rulesets/tests/end-end.test.ts index e4090a38..c3212d28 100644 --- a/src/rulesets/tests/end-end.test.ts +++ b/src/rulesets/tests/end-end.test.ts @@ -23,8 +23,8 @@ describe("end-end-tests", () => { it("fails when operation is removed", async () => { expect( await snapshotScenario( - "000-baseline.yaml", - "001-fail-operation-removed.yaml", + "000-baseline-beta.yaml", + "001-fail-operation-removed-beta.yaml", resourceDate("thing", "2021-11-10"), { changeDate: "2021-11-11", @@ -42,8 +42,8 @@ describe("end-end-tests", () => { it("fails when breaking param change", async () => { expect( await snapshotScenario( - "000-baseline.yaml", - "001-fail-breaking-param-change.yaml", + "000-baseline-beta.yaml", + "001-fail-breaking-param-change-beta.yaml", resourceDate("thing", "2021-11-10"), { changeDate: "2021-11-11", diff --git a/src/rulesets/tests/lifecycle.test.ts b/src/rulesets/tests/lifecycle.test.ts index e042c2b0..0dc3c416 100644 --- a/src/rulesets/tests/lifecycle.test.ts +++ b/src/rulesets/tests/lifecycle.test.ts @@ -120,12 +120,12 @@ describe("lifecycle", () => { changeResource: "Example", changeVersion: { date: "2021-10-10", - stability: "experimental", + stability: "beta", }, resourceVersions: { Example: { "2021-10-10": { - experimental: { + beta: { deprecatedBy: { date: "2021-10-20", stability: "ga", @@ -155,7 +155,7 @@ describe("lifecycle", () => { }) .withRule(rules.followSunsetRules, { ...context, - changeDate: "2021-12-01", + changeDate: "2022-02-01", }); expect(result.results[0].passed).toBeTruthy(); expect(result).toMatchSnapshot(); diff --git a/src/rulesets/tests/operations.test.ts b/src/rulesets/tests/operations.test.ts index a06f44ea..87a5655c 100644 --- a/src/rulesets/tests/operations.test.ts +++ b/src/rulesets/tests/operations.test.ts @@ -293,6 +293,37 @@ describe("operation parameters", () => { expect(result).toMatchSnapshot(); }); + it("passes when changing optional to required query parameter in experimental", async () => { + const base = JSON.parse(JSON.stringify(baseForOperationMetadataTests)); + base.paths!["/example"]!.get!.parameters = [ + { + in: "query", + name: "query_parameter", + }, + ]; + const result = await compare(base) + .to((spec) => { + spec.paths!["/example"]!.get!.parameters = [ + { + in: "query", + name: "query_parameter", + required: true, + }, + ]; + return spec; + }) + .withRule(rules.preventChangingOptionalToRequiredQueryParameters, { + ...emptyContext, + changeVersion: { + date: "2021-10-10", + stability: "experimental", + }, + }); + + expect(result.results[0].passed).toBeTruthy(); + expect(result).toMatchSnapshot(); + }); + it("fails when changing optional to required query parameter", async () => { const base = JSON.parse(JSON.stringify(baseForOperationMetadataTests)); base.paths!["/example"]!.get!.parameters = [ @@ -321,7 +352,7 @@ describe("operation parameters", () => { expect(result).toMatchSnapshot(); }); - it("fails if the default value is changed", async () => { + it("passes if the default value is changed in experimental", async () => { const base = JSON.parse(JSON.stringify(baseForOperationMetadataTests)); base.paths!["/example"]!.get!.parameters = [ { @@ -347,44 +378,84 @@ describe("operation parameters", () => { ]; return spec; }) - .withRule(rules.preventChangingParameterDefaultValue, emptyContext); + .withRule(rules.preventChangingParameterDefaultValue, { + ...emptyContext, + changeVersion: { + date: "2021-10-10", + stability: "experimental", + }, + }); - expect(result.results[0].passed).toBeFalsy(); + expect(result.results[0].passed).toBeTruthy(); expect(result).toMatchSnapshot(); }); }); - describe("status codes", () => { - it("fails when a status codes is removed", async () => { - const base = JSON.parse(JSON.stringify(baseForOperationMetadataTests)); - base.paths["/example"].get.responses = { - "200": { - description: "Example response", + it("fails if the default value is changed", async () => { + const base = JSON.parse(JSON.stringify(baseForOperationMetadataTests)); + base.paths!["/example"]!.get!.parameters = [ + { + in: "query", + name: "query_parameter", + schema: { + type: "string", + default: "before", }, - }; - const result = await compare(base) - .to((spec) => { - delete spec.paths!["/example"]!.get!.responses!["200"]; - return spec; - }) - .withRule(rules.preventRemovingStatusCodes, emptyContext); + }, + ]; + const result = await compare(base) + .to((spec) => { + spec.paths!["/example"]!.get!.parameters = [ + { + in: "query", + name: "query_parameter", + schema: { + type: "string", + default: "after", + }, + }, + ]; + return spec; + }) + .withRule(rules.preventChangingParameterDefaultValue, emptyContext); - expect(result.results[0].passed).toBeFalsy(); - expect(result).toMatchSnapshot(); - }); + expect(result.results[0].passed).toBeFalsy(); + expect(result).toMatchSnapshot(); }); +}); - describe("version parameter", () => { - it("fails when there is no version parameter", async () => { - const result = await compare(baseForOperationMetadataTests) - .to((spec) => spec) - .withRule(rules.versionParameter, emptyContext); +describe("status codes", () => { + it("fails when a status codes is removed", async () => { + const base = JSON.parse(JSON.stringify(baseForOperationMetadataTests)); + base.paths["/example"].get.responses = { + "200": { + description: "Example response", + }, + }; + const result = await compare(base) + .to((spec) => { + delete spec.paths!["/example"]!.get!.responses!["200"]; + return spec; + }) + .withRule(rules.preventRemovingStatusCodes, emptyContext); - expect(result.results[0].passed).toBeFalsy(); - expect(result).toMatchSnapshot(); - }); + expect(result.results[0].passed).toBeFalsy(); + expect(result).toMatchSnapshot(); }); +}); + +describe("version parameter", () => { + it("fails when there is no version parameter", async () => { + const result = await compare(baseForOperationMetadataTests) + .to((spec) => spec) + .withRule(rules.versionParameter, emptyContext); + + expect(result.results[0].passed).toBeFalsy(); + expect(result).toMatchSnapshot(); + }); +}); +describe("put method", () => { it("fails adding put method", async () => { const result = await compare(defaultEmptySpec) .to({ diff --git a/src/rulesets/tests/properties.test.ts b/src/rulesets/tests/properties.test.ts index 1fc54e5f..13b71865 100644 --- a/src/rulesets/tests/properties.test.ts +++ b/src/rulesets/tests/properties.test.ts @@ -108,6 +108,38 @@ describe("body properties", () => { expect(result).toMatchSnapshot(); }); + it("fails when not snake case in experimental", async () => { + const result = await compare(baseOpenAPI) + .to((spec) => { + spec.paths!["/example"]!.get!.responses = { + "200": { + description: "", + content: { + "application/json": { + schema: { + type: "object", + properties: { + "not-snake-case": { type: "string" }, + }, + }, + }, + }, + }, + }; + return spec; + }) + .withRule(rules.propertyKey, { + ...emptyContext, + changeVersion: { + date: "2021-10-10", + stability: "experimental", + }, + }); + + expect(result.results[0].passed).toBeFalsy(); + expect(result).toMatchSnapshot(); + }); + it("fails when not snake case in nested field", async () => { const result = await compare(baseOpenAPI) .to((spec) => { @@ -251,5 +283,90 @@ describe("body properties", () => { expect(result.results[0].passed).toBeFalsy(); expect(result).toMatchSnapshot(); }); + it("passes if a property is removed in experimental", async () => { + const base = JSON.parse(JSON.stringify(baseOpenAPI)); + base.paths!["/example"]!.get!.responses = { + "200": { + description: "", + content: { + "application/json": { + schema: { + type: "object", + properties: { + count: { type: "number" }, + }, + }, + }, + }, + }, + }; + const result = await compare(base) + .to((spec) => { + spec.paths!["/example"]!.get!.responses = { + "200": { + description: "", + content: { + "application/json": { + schema: { + type: "object", + properties: {}, + }, + }, + }, + }, + }; + return spec; + }) + .withRule(rules.preventRemoval, { + ...emptyContext, + changeVersion: { + date: "2021-10-10", + stability: "experimental", + }, + }); + + expect(result.results[0].passed).toBeTruthy(); + expect(result).toMatchSnapshot(); + }); + it("passes if a required property is added in experimental", async () => { + const base = JSON.parse(JSON.stringify(baseOpenAPI)); + base.paths!["/example"]!.get!.requestBody = { + content: { + "application/json": { + schema: { + type: "object", + properties: {}, + }, + }, + }, + }; + const result = await compare(base) + .to((spec) => { + spec.paths!["/example"]!.get!.requestBody = { + content: { + "application/json": { + schema: { + type: "object", + properties: { + count: { type: "number" }, + }, + required: ["count"], + }, + }, + }, + }; + return spec; + }) + .withRule(rules.preventAddingRequiredRequestProperties, { + ...emptyContext, + changeVersion: { + date: "2021-10-10", + stability: "experimental", + }, + }); + + expect(result.results[0].passed).toBeTruthy(); + expect(result).toMatchSnapshot(); + }); }); });