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

patronus

v1.1.4

Published

Specification-driven REST API testing

Downloads

16

Readme

Patronus

Automated unit testing for your Hapi REST API

npm version Build Status License Dependencies Status bitHound Score

NPM

Patronus is a testing module used along with a testing framework (Mocha, Lab... whatever) so that all you have to do is provide a reference to your Hapi server object and supply a JS object with the values used in your API.

Patronus will generate every combo of params, payloads, and query args (based off of your routes Joi validations) and their values that you can think of and tests them all.

It even uses your route description for test names.

Example of Patronus tests being run

screenshot

Using Patronus

Load the npm module:

var Patronus = require('patronus');

Load value objects on a route:


apiServer.route({
    method: 'POST',
    path: route,
    config: {
        description: 'username is required, password is optional',
        validate: {
            payload: Joi.object({
                username: Joi.string().required().example('matt'),
                password: Joi.string(),
            })
        },
        response: {
            schema: Joi.object({
                username: Joi.string().required(),
                password: Joi.string(),
            })
        },
        plugins:{
            patronus: {
                // Note it is an array, test with multiple value sets
                testValues: [{
                    username: 'user-name',
                    password: 'password',

                    // An example value object looks like this, where keys are param/payload/query names
                    // except for __auth and__responseCode
                    // __auth this is reserved for the params used for authentication
                    __auth: {
                        headers: {
                            authorization: 'Bearer 1234'
                        }
                    },
                    // __responseCode is used to validate the servers response type for this value set
                    __responseCode: 401
                }]
            }
        }
    },
    handler: function(request, reply) {
        reply(request.payload);
    }
});

Get all the tests for a single route from the server

var server = new Hapi.Server().connection({ host: 'test' });
var tests = Patronus.testsFromRoute('GET', '/any/route', server);

Or just test all the endpoints

var server = new Hapi.Server().connection({ host: 'test' });
var tests = Patronus.allTests(server);

The tests array contains a sequence of request/response pairs. Test them against your service:

// This will test every endpoint on your server using every combo of
// optional params you could think of. Multiplied by the number of param combos you
// provided
// The second set of tests will make sure every endpoint is tested using every combo
// that joi would allow a user to enter. If not, it will assert an issue letting you
// know what values are missing from your testValues
describe('specification-driven tests', function () {
    var tests = Patronus.allTests(server);

    tests.user.forEach(function (test) {
        it(test.description, function(done) {
            server.inject(test.request, function(res) {
                Patronus.assert(res, test.response);
                done();
            });
        });
    });

    it('should not have anything that would cause a test to be skipped', function() {
        tests.coverage.forEach(function(test) {

            assert.throws(function() {
                Patronus.assertTestCoverage(test);
            }, Error);

        });
    });
});

#.allTests() options

You can also pass into #.allTests() an options param like so:

var tests = Patronus.allTests(server, {
            select: 'api', // [optional] select a connection by label
            ignore: [{ // [optional] an array of objects defining routes you dont want to test

                pathContains: '/docs' // [optional] does an indexOf on the path, ignoring matches
                path: '/docs' // [optional] does a === on the path, ignoring matches
                method: 'GET' // [optional] does a === on the method, ignoring matches
            }, {
                pathContains: '/debug'
            }, {
                pathContains: '/documentation'
            }]
        });

Note that for each object in the ignore array, all params must match on a route to ignore it.

To-Do

  • [ ] Support deep object randomization (currently deep is all or nothing based on parent)

Contribution Guidelines

We welcome contributions from the community and are pleased to have them. Please follow this guide when logging issues or making code changes.

Logging Issues

All issues should be created using the new issue form. Clearly describe the issue including steps to reproduce if there are any. Just being honest here... issues that do not include a route and values object for testing will most likely not get worked on. Include those and we will do our best to fix it ASAP.

Fixes/New Issues

Code changes are welcome and should follow the guidelines below.

  • All tests must pass using npm test
  • Add tests for your new code ensuring that you have 100% code coverage (we can help you reach 100% but will not merge without it).
  • Run npm run coverage to generate a report of test coverage
  • Pull requests should be made to the master branch.