diff --git a/README.md b/README.md index 9acf38b..fa36569 100644 --- a/README.md +++ b/README.md @@ -36,28 +36,6 @@ test('test title', ({ assert }) => { }) ``` -## Register open API schemas -You can register open API schema and then assert HTTP responses against. - -```ts -configure({ - plugins: [assert({ - openApi: { - schemas: [new URL('../api-spec.json', import.meta.url)] - } - })] -}) -``` - -Validate response as follows. - -```ts -test('get users', ({ assert }) => { - const response = await supertest(baseUrl).get('/users') - assert.isValidApiResponse(response) -}) -``` - [github-actions-url]: https://github.com/japa/assert/actions/workflows/checks.yml [github-actions-image]: https://img.shields.io/github/actions/workflow/status/japa/assert/checks.yml?style=for-the-badge "github-actions" diff --git a/api-spec.json b/api-spec.json deleted file mode 100644 index f8f4d85..0000000 --- a/api-spec.json +++ /dev/null @@ -1,898 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", - "version": "1.0.0", - "title": "Swagger Petstore", - "termsOfService": "http://swagger.io/terms/", - "contact": { - "email": "apiteam@swagger.io" - }, - "license": { - "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" - } - }, - "host": "petstore.swagger.io", - "basePath": "/v2", - "tags": [ - { - "name": "pet", - "description": "Everything about your Pets", - "externalDocs": { - "description": "Find out more", - "url": "http://swagger.io" - } - }, - { - "name": "store", - "description": "Access to Petstore orders" - }, - { - "name": "user", - "description": "Operations about user", - "externalDocs": { - "description": "Find out more about our store", - "url": "http://swagger.io" - } - } - ], - "schemes": ["https", "http"], - "paths": { - "/pet": { - "post": { - "tags": ["pet"], - "summary": "Add a new pet to the store", - "description": "", - "operationId": "addPet", - "consumes": ["application/json", "application/xml"], - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "Pet object that needs to be added to the store", - "required": true, - "schema": { - "$ref": "#/definitions/Pet" - } - } - ], - "responses": { - "405": { - "description": "Invalid input" - } - }, - "security": [ - { - "petstore_auth": ["write:pets", "read:pets"] - } - ] - }, - "put": { - "tags": ["pet"], - "summary": "Update an existing pet", - "description": "", - "operationId": "updatePet", - "consumes": ["application/json", "application/xml"], - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "Pet object that needs to be added to the store", - "required": true, - "schema": { - "$ref": "#/definitions/Pet" - } - } - ], - "responses": { - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Pet not found" - }, - "405": { - "description": "Validation exception" - } - }, - "security": [ - { - "petstore_auth": ["write:pets", "read:pets"] - } - ] - } - }, - "/pet/findByStatus": { - "get": { - "tags": ["pet"], - "summary": "Finds Pets by status", - "description": "Multiple status values can be provided with comma separated strings", - "operationId": "findPetsByStatus", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "status", - "in": "query", - "description": "Status values that need to be considered for filter", - "required": true, - "type": "array", - "items": { - "type": "string", - "enum": ["available", "pending", "sold"], - "default": "available" - }, - "collectionFormat": "multi" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Pet" - } - } - }, - "400": { - "description": "Invalid status value" - } - }, - "security": [ - { - "petstore_auth": ["write:pets", "read:pets"] - } - ] - } - }, - "/pet/findByTags": { - "get": { - "tags": ["pet"], - "summary": "Finds Pets by tags", - "description": "Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.", - "operationId": "findPetsByTags", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "tags", - "in": "query", - "description": "Tags to filter by", - "required": true, - "type": "array", - "items": { - "type": "string" - }, - "collectionFormat": "multi" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Pet" - } - } - }, - "400": { - "description": "Invalid tag value" - } - }, - "security": [ - { - "petstore_auth": ["write:pets", "read:pets"] - } - ], - "deprecated": true - } - }, - "/pet/{petId}": { - "get": { - "tags": ["pet"], - "summary": "Find pet by ID", - "description": "Returns a single pet", - "operationId": "getPetById", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet to return", - "required": true, - "type": "integer", - "format": "int64" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/Pet" - } - }, - "400": { - "description": "Invalid ID supplied", - "schema": { - "type": "object", - "required": ["message"], - "properties": { - "message": { - "type": "string" - } - } - } - }, - "404": { - "description": "Pet not found" - } - }, - "security": [ - { - "api_key": [] - } - ] - }, - "post": { - "tags": ["pet"], - "summary": "Updates a pet in the store with form data", - "description": "", - "operationId": "updatePetWithForm", - "consumes": ["application/x-www-form-urlencoded"], - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet that needs to be updated", - "required": true, - "type": "integer", - "format": "int64" - }, - { - "name": "name", - "in": "formData", - "description": "Updated name of the pet", - "required": false, - "type": "string" - }, - { - "name": "status", - "in": "formData", - "description": "Updated status of the pet", - "required": false, - "type": "string" - } - ], - "responses": { - "405": { - "description": "Invalid input" - } - }, - "security": [ - { - "petstore_auth": ["write:pets", "read:pets"] - } - ] - }, - "delete": { - "tags": ["pet"], - "summary": "Deletes a pet", - "description": "", - "operationId": "deletePet", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "api_key", - "in": "header", - "required": false, - "type": "string" - }, - { - "name": "petId", - "in": "path", - "description": "Pet id to delete", - "required": true, - "type": "integer", - "format": "int64" - } - ], - "responses": { - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Pet not found" - } - }, - "security": [ - { - "petstore_auth": ["write:pets", "read:pets"] - } - ] - } - }, - "/pet/{petId}/uploadImage": { - "post": { - "tags": ["pet"], - "summary": "uploads an image", - "description": "", - "operationId": "uploadFile", - "consumes": ["multipart/form-data"], - "produces": ["application/json"], - "parameters": [ - { - "name": "petId", - "in": "path", - "description": "ID of pet to update", - "required": true, - "type": "integer", - "format": "int64" - }, - { - "name": "additionalMetadata", - "in": "formData", - "description": "Additional data to pass to server", - "required": false, - "type": "string" - }, - { - "name": "file", - "in": "formData", - "description": "file to upload", - "required": false, - "type": "file" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/ApiResponse" - } - } - }, - "security": [ - { - "petstore_auth": ["write:pets", "read:pets"] - } - ] - } - }, - "/store/inventory": { - "get": { - "tags": ["store"], - "summary": "Returns pet inventories by status", - "description": "Returns a map of status codes to quantities", - "operationId": "getInventory", - "produces": ["application/json"], - "parameters": [], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "type": "object", - "additionalProperties": { - "type": "integer", - "format": "int32" - } - } - } - }, - "security": [ - { - "api_key": [] - } - ] - } - }, - "/store/order": { - "post": { - "tags": ["store"], - "summary": "Place an order for a pet", - "description": "", - "operationId": "placeOrder", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "order placed for purchasing the pet", - "required": true, - "schema": { - "$ref": "#/definitions/Order" - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/Order" - } - }, - "400": { - "description": "Invalid Order" - } - } - } - }, - "/store/order/{orderId}": { - "get": { - "tags": ["store"], - "summary": "Find purchase order by ID", - "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions", - "operationId": "getOrderById", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "orderId", - "in": "path", - "description": "ID of pet that needs to be fetched", - "required": true, - "type": "integer", - "maximum": 10, - "minimum": 1, - "format": "int64" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/Order" - } - }, - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Order not found" - } - } - }, - "delete": { - "tags": ["store"], - "summary": "Delete purchase order by ID", - "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors", - "operationId": "deleteOrder", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "orderId", - "in": "path", - "description": "ID of the order that needs to be deleted", - "required": true, - "type": "integer", - "minimum": 1, - "format": "int64" - } - ], - "responses": { - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Order not found" - } - } - } - }, - "/user": { - "post": { - "tags": ["user"], - "summary": "Create user", - "description": "This can only be done by the logged in user.", - "operationId": "createUser", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "Created user object", - "required": true, - "schema": { - "$ref": "#/definitions/User" - } - } - ], - "responses": { - "default": { - "description": "successful operation" - } - } - } - }, - "/user/createWithArray": { - "post": { - "tags": ["user"], - "summary": "Creates list of users with given input array", - "description": "", - "operationId": "createUsersWithArrayInput", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "List of user object", - "required": true, - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/User" - } - } - } - ], - "responses": { - "default": { - "description": "successful operation" - } - } - } - }, - "/user/createWithList": { - "post": { - "tags": ["user"], - "summary": "Creates list of users with given input array", - "description": "", - "operationId": "createUsersWithListInput", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "in": "body", - "name": "body", - "description": "List of user object", - "required": true, - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/User" - } - } - } - ], - "responses": { - "default": { - "description": "successful operation" - } - } - } - }, - "/user/login": { - "get": { - "tags": ["user"], - "summary": "Logs user into the system", - "description": "", - "operationId": "loginUser", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "username", - "in": "query", - "description": "The user name for login", - "required": true, - "type": "string" - }, - { - "name": "password", - "in": "query", - "description": "The password for login in clear text", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "type": "string" - }, - "headers": { - "X-Rate-Limit": { - "type": "integer", - "format": "int32", - "description": "calls per hour allowed by the user" - }, - "X-Expires-After": { - "type": "string", - "format": "date-time", - "description": "date in UTC when token expires" - } - } - }, - "400": { - "description": "Invalid username/password supplied" - } - } - } - }, - "/user/logout": { - "get": { - "tags": ["user"], - "summary": "Logs out current logged in user session", - "description": "", - "operationId": "logoutUser", - "produces": ["application/xml", "application/json"], - "parameters": [], - "responses": { - "default": { - "description": "successful operation" - } - } - } - }, - "/user/{username}": { - "get": { - "tags": ["user"], - "summary": "Get user by user name", - "description": "", - "operationId": "getUserByName", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "username", - "in": "path", - "description": "The name that needs to be fetched. Use user1 for testing. ", - "required": true, - "type": "string" - } - ], - "responses": { - "200": { - "description": "successful operation", - "schema": { - "$ref": "#/definitions/User" - } - }, - "400": { - "description": "Invalid username supplied" - }, - "404": { - "description": "User not found" - } - } - }, - "put": { - "tags": ["user"], - "summary": "Updated user", - "description": "This can only be done by the logged in user.", - "operationId": "updateUser", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "username", - "in": "path", - "description": "name that need to be updated", - "required": true, - "type": "string" - }, - { - "in": "body", - "name": "body", - "description": "Updated user object", - "required": true, - "schema": { - "$ref": "#/definitions/User" - } - } - ], - "responses": { - "400": { - "description": "Invalid user supplied" - }, - "404": { - "description": "User not found" - } - } - }, - "delete": { - "tags": ["user"], - "summary": "Delete user", - "description": "This can only be done by the logged in user.", - "operationId": "deleteUser", - "produces": ["application/xml", "application/json"], - "parameters": [ - { - "name": "username", - "in": "path", - "description": "The name that needs to be deleted", - "required": true, - "type": "string" - } - ], - "responses": { - "400": { - "description": "Invalid username supplied" - }, - "404": { - "description": "User not found" - } - } - } - } - }, - "securityDefinitions": { - "petstore_auth": { - "type": "oauth2", - "authorizationUrl": "http://petstore.swagger.io/oauth/dialog", - "flow": "implicit", - "scopes": { - "write:pets": "modify pets in your account", - "read:pets": "read your pets" - } - }, - "api_key": { - "type": "apiKey", - "name": "api_key", - "in": "header" - } - }, - "definitions": { - "Order": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "petId": { - "type": "integer", - "format": "int64" - }, - "quantity": { - "type": "integer", - "format": "int32" - }, - "shipDate": { - "type": "string", - "format": "date-time" - }, - "status": { - "type": "string", - "description": "Order Status", - "enum": ["placed", "approved", "delivered"] - }, - "complete": { - "type": "boolean", - "default": false - } - }, - "xml": { - "name": "Order" - } - }, - "Category": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string" - } - }, - "xml": { - "name": "Category" - } - }, - "User": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "username": { - "type": "string" - }, - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "email": { - "type": "string" - }, - "password": { - "type": "string" - }, - "phone": { - "type": "string" - }, - "userStatus": { - "type": "integer", - "format": "int32", - "description": "User Status" - } - }, - "xml": { - "name": "User" - } - }, - "Tag": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string" - } - }, - "xml": { - "name": "Tag" - } - }, - "Pet": { - "type": "object", - "required": ["name", "photoUrls"], - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - }, - "name": { - "type": "string", - "example": "doggie" - }, - "photoUrls": { - "type": "array", - "xml": { - "name": "photoUrl", - "wrapped": true - }, - "items": { - "type": "string" - } - }, - "tags": { - "type": "array", - "xml": { - "name": "tag", - "wrapped": true - }, - "items": { - "$ref": "#/definitions/Tag" - } - }, - "status": { - "type": "string", - "description": "pet status in the store", - "enum": ["available", "pending", "sold"] - } - }, - "xml": { - "name": "Pet" - } - }, - "ApiResponse": { - "type": "object", - "properties": { - "code": { - "type": "integer", - "format": "int32" - }, - "type": { - "type": "string" - }, - "message": { - "type": "string" - } - } - } - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - } -} diff --git a/index.ts b/index.ts index 4348170..d27e4b1 100644 --- a/index.ts +++ b/index.ts @@ -22,14 +22,7 @@ declare module '@japa/runner/core' { /** * Plugin for "@japa/runner" */ -export function assert(options?: PluginConfig): PluginFn { - if (options?.openApi) { - Assert.registerApiSpecs(options.openApi.schemas, { - exportCoverage: options.openApi.exportCoverage, - reportCoverage: options.openApi.reportCoverage, - }) - } - +export function assert(_options?: PluginConfig): PluginFn { return function () { TestContext.getter('assert', () => new Assert(), true) Test.executed(function (test: Test, hasError) { diff --git a/package.json b/package.json index 1ba0493..ac6b386 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "dependencies": { "@poppinss/macroable": "^1.0.2", "@types/chai": "^4.3.14", - "api-contract-validator": "^2.2.8", "chai": "^5.1.0" }, "peerDependencies": { diff --git a/src/assert.ts b/src/assert.ts index 8d257b7..726fbc6 100644 --- a/src/assert.ts +++ b/src/assert.ts @@ -7,10 +7,8 @@ * file that was distributed with this source code. */ -import { fileURLToPath } from 'node:url' import Macroable from '@poppinss/macroable' -import { chaiPlugin } from 'api-contract-validator' -import { assert, Assertion, AssertionError, use, expect } from 'chai' +import { assert, Assertion, AssertionError } from 'chai' import { subsetCompare } from './utils.js' import type { AssertContract, ChaiAssert } from './types.js' @@ -27,23 +25,6 @@ import type { AssertContract, ChaiAssert } from './types.js' * assert.deepEqual({ id: 1 }, { id: 1 }) */ export class Assert extends Macroable implements AssertContract { - protected static hasInstalledApiValidator = false - - /** - * Register api specs to be used for validating responses - */ - static registerApiSpecs( - schemaPathsOrURLs: (string | URL)[], - options?: { reportCoverage?: boolean; exportCoverage?: boolean } - ) { - this.hasInstalledApiValidator = true - const paths = schemaPathsOrURLs.map((schemaPathsOrURL) => { - return schemaPathsOrURL instanceof URL ? fileURLToPath(schemaPathsOrURL) : schemaPathsOrURL - }) - - use(chaiPlugin({ apiDefinitionsPath: paths, ...options })) - } - /** * Tracking assertions */ @@ -1534,12 +1515,10 @@ export class Assert extends Macroable implements AssertContract { * ) // fails */ notIncludeDeepMembers( - ...args: Parameters - ): ReturnType { + ...args: Parameters + ): ReturnType { this.incrementAssertionsCount() - - // @ts-expect-error not in @types/chai - return assert['notIncludeDeepMembers'](...args) + return assert.notIncludeDeepMembers(...args) } /** @@ -2173,15 +2152,4 @@ export class Assert extends Macroable implements AssertContract { * Use {@link Assert.doesNotReject} without the "s" */ doesNotRejects = this.doesNotReject.bind(this) - - /** - * Assert the response confirms to open API spec - */ - isValidApiResponse(response: any) { - // @ts-ignore - if (!this.constructor['hasInstalledApiValidator']) { - throw new Error('Cannot validate responses without defining api schemas') - } - return expect(response).to.matchApiSchema() - } } diff --git a/src/types.ts b/src/types.ts index f8a1c48..80d18e2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -74,10 +74,4 @@ export type AssertContract = Omit< | 'notDeepOwnInclude' > -export type PluginConfig = { - openApi?: { - schemas: (string | URL)[] - reportCoverage?: boolean - exportCoverage?: boolean - } -} +export type PluginConfig = {} diff --git a/tests/assert/assert.spec.ts b/tests/assert/assert.spec.ts index 7a48438..1b25252 100644 --- a/tests/assert/assert.spec.ts +++ b/tests/assert/assert.spec.ts @@ -2023,19 +2023,19 @@ test.describe('assert', function () { expectError(function () { assert.closeTo([1.5] as any, 1.0, 0.5, 'blah') - }, 'blah: expected [ 1.5 ] to be a number') + }, 'blah: expected [ 1.5 ] to be numeric') expectError(function () { assert.closeTo(1.5, '1.0' as any, 0.5, 'blah') - }, 'blah: the arguments to closeTo or approximately must be numbers') + }, "blah: expected '1.0' to be numeric") expectError(function () { assert.closeTo(1.5, 1.0, true as any, 'blah') - }, 'blah: the arguments to closeTo or approximately must be numbers') + }, 'blah: expected true to be numeric') expectError(function () { assert.closeTo(1.5, 1.0, undefined as any, 'blah') - }, 'blah: the arguments to closeTo or approximately must be numbers, and a delta is required') + }, 'blah: A `delta` value is required for `closeTo`') }) test('approximately', function () { @@ -2055,19 +2055,19 @@ test.describe('assert', function () { expectError(function () { assert.approximately([1.5] as any, 1.0, 0.5) - }, 'expected [ 1.5 ] to be a number') + }, 'expected [ 1.5 ] to be numeric') expectError(function () { assert.approximately(1.5, '1.0' as any, 0.5, 'blah') - }, 'blah: the arguments to closeTo or approximately must be numbers') + }, "blah: expected '1.0' to be numeric") expectError(function () { assert.approximately(1.5, 1.0, true as any, 'blah') - }, 'blah: the arguments to closeTo or approximately must be numbers') + }, 'blah: expected true to be numeric') expectError(function () { assert.approximately(1.5, 1.0, undefined as any, 'blah') - }, 'blah: the arguments to closeTo or approximately must be numbers, and a delta is required') + }, 'blah: A `delta` value is required for `closeTo`') }) test('sameMembers', function () { diff --git a/tests/assert/openapi.spec.ts b/tests/assert/openapi.spec.ts deleted file mode 100644 index 51b8d27..0000000 --- a/tests/assert/openapi.spec.ts +++ /dev/null @@ -1,103 +0,0 @@ -/* - * @japa/assert - * - * (c) Japa.dev - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -import { test } from 'node:test' -import { Assert } from '../../src/assert.js' -import { expectError } from '../../tests_helpers/index.js' - -Assert.registerApiSpecs([new URL('../../api-spec.json', import.meta.url)]) - -test.describe('assert | open api', () => { - test('pass when response confirms to the api spec', () => { - const assert = new Assert() - - assert.isValidApiResponse({ - path: '/v2/pet/1', - method: 'get', - status: 200, - body: { - name: 'Pet 1', - photoUrls: ['/a', 'b'], - }, - headers: {}, - }) - }) - - test('fail when response does not confirms to the api spec', () => { - const assert = new Assert() - - expectError(() => { - assert.isValidApiResponse({ - path: '/v2/pet/1', - method: 'get', - status: 200, - body: {}, - headers: {}, - }) - }, 'expected response to match API schema') - }) - - test('validate error messages response', () => { - const assert = new Assert() - - assert.isValidApiResponse({ - path: '/v2/pet/1', - method: 'get', - status: 400, - body: { - message: 'Invalid id', - }, - headers: {}, - }) - }) - - test('fail when response status code is not in the spec', () => { - const assert = new Assert() - - expectError(() => { - assert.isValidApiResponse({ - path: '/v2/pet/1', - method: 'get', - status: 401, - body: {}, - headers: {}, - }) - }, 'schema not found for {"path":"/v2/pet/1","method":"get","status":401}') - }) - - test('fail when endpoint is not in the spec', () => { - const assert = new Assert() - - expectError(() => { - assert.isValidApiResponse({ - path: '/v2/pets/1', - method: 'get', - status: 200, - body: {}, - headers: {}, - }) - }, 'schema not found for {"path":"/v2/pets/1","method":"get","status":200}') - }) - - test('fail when response headers mis-match', () => { - const assert = new Assert() - - expectError(() => { - assert.isValidApiResponse({ - path: '/v2/user/login', - method: 'get', - status: 200, - body: 'dads', - headers: { - 'x-rate-limit': 'abc', - }, - }) - }, 'expected response to match API schema') - }) -})