npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

api-contract-validator

v2.2.8

Published

Plugin for validating API schemas from API documentation

Downloads

91,010

Readme

npm npm Build Status Coverage Status Known Vulnerabilities style NPM

api-contract-validator

This plugin for assertion libraries is for validating API response schemas against Swagger/OpenAPI definition.

Using the plugin is easy. Simply point the plugin to your API definitions file path and add one line to your integration test to validate that your application adheres to its design contract.

Highlights

  • Asserts according to API definitions document
  • Descriptive assertion failures
  • Simple and concise usage
  • Coverage report (can be printed to your terminal or exported to a json file)
  • Supports response format from axios, superagent, supertest, request and light-my-request (used by fastify)
  • Supports OpenAPI 3.0
  • Supports multiple definition files

How does it work?

The api-contract-validator transforms your API definition into a json-schema based on the provided API documentation file. Then whenever the matchApiSchema assertion is called, it automatically extracts the method, path and status code from the response object returned by the API request that you invoked and validates the response object. Both the response headers and body are validated.

How to use?

Installation

> npm i --save-dev api-contract-validator

Chai.js

const matchApiSchema = require('api-contract-validator').chaiPlugin;
const path = require('path');
const { expect, use } = require('chai');

// API definitions path
const apiDefinitionsPath = path.join(__dirname, 'myApp.yaml'); 

// add as chai plugin
use(matchApiSchema({ apiDefinitionsPath }));

it('GET /pets/123', async () => {
    const response = await request.get('/pet/123');
    expect(response).to.have.status(200).and.to.matchApiSchema();

    // alternatively pass
    const { statusCode, headers, body } = response
    expect({
        path: '/pet/123',
        method: 'get',
        status: statusCode,
        body: body,
        headers: headers,
    }).to.have.status(200).and.to.matchApiSchema();
})

Should.js

const matchApiSchema = require('api-contract-validator').shouldPlugin;

// API definitions path
const apiDefinitionsPath = path.join(__dirname, 'myApp.yaml');

// add as should plugin
matchApiSchema(should, { apiDefinitionsPath });

it('GET /pets/123', async () => {
    const response = await request.get('/pet/123');
    should(response).have.status(200).and.matchApiSchema();
})

Jest

const matchApiSchema = require('api-contract-validator').jestPlugin;

// API definitions path
const apiDefinitionsPath = path.join(__dirname, 'myApp.yaml');

// add as jest plugin
matchApiSchema({ apiDefinitionsPath });

it('GET /pets/123', async () => {
    const response = await request.get('/pet/123');
    expect(response).toHaveStatus(200);
    expect(response).toMatchApiSchema();
})

Multiple api definitions files

use apiDefinitionsPath option with an array of files paths

const apiDefinitionsPath = [path.join(__dirname, 'myApp.yaml'), path.join(__dirname, 'myApp2.yaml')];

Descriptive assertion failures

AssertionError: expected response to match API schema
+ expected - actual

{
    "body": {
-    "age": -1
+    "age": "should be >= 0"
+    "name": "should have required property"
    }
    "headers": {
-    "x-expires-after": []
-    "x-rate-limit": -5
+    "x-expires-after": "should be string"
+    "x-rate-limit": "should be >= 0"
    }
}

Coverage report

By providing in the plugin options, the flag reportCoverage:true, the plugin generates a report of all uncovered API definitions.

use(matchApiSchema({
    apiDefinitionsPath,
    reportCoverage: true
}));
* API definitions coverage report *

Uncovered API definitions found:
*ROUTE*                    | *METHOD*   | *STATUSES* 
/v2/pet                    | POST       | 405        
/v2/pet                    | PUT        | 400,404,405
/v2/pet/findByStatus       | GET        | 200,400    
/v2/pet/findByTags         | GET        | 200,400    
/v2/pet/:petId             | GET        | 400,404    
/v2/pet/:petId             | POST       | 405        
/v2/pet/:petId             | DELETE     | 400,404    
/v2/pet/:petId/uploadImage | POST       | 200         

Exporting the report:

When providing exportCoverage: true a coverage.json file will be created in your cwd with following structure:

use(matchApiSchema({
    apiDefinitionsPath,
    exportCoverage: true
}));

coverage.json:

[{"route":"/v2/pet","method":"POST","statuses":"405"},
{"route":"/v2/pet","method":"PUT","statuses":"400,404,405"},
{"route":"/v2/pet/:petId","method":"GET","statuses":"200"},
{"route":"/v2/pet/:petId","method":"POST","statuses":"405"},
{"route":"/v2/pet/:petId","method":"DELETE","statuses":"404"}]

Supported request libraries

  • supertest
  • axios
  • request-promise*
  • more to come

* When using request-promise resolveWithFullResponse:true must be added to the request options, in order to properly extract the request details

Supported assertion libraries

  • chai.js
  • should.js
  • jest
  • more to come