rspec-api/rspec-api-expectations

View on GitHub
README.md

Summary

Maintainability
Test Coverage
RSpec API Expectations
======================

RSpecApi::Expectations lets you express expectations on the response of web APIs:

    expect_response response, status: :ok, type: :json, collection: true

More documentation and examples about RSpecApi are available at [http://rspec-api.github.io](http://rspec-api.github.io)

[![Build Status](https://travis-ci.org/rspec-api/rspec-api-expectations.png?branch=master)](https://travis-ci.org/rspec-api/rspec-api-expectations)
[![Code Climate](https://codeclimate.com/github/rspec-api/rspec-api-expectations.png)](https://codeclimate.com/github/rspec-api/rspec-api-expectations)
[![Coverage Status](https://coveralls.io/repos/rspec-api/rspec-api-expectations/badge.png)](https://coveralls.io/r/rspec-api/rspec-api-expectations)
[![Dependency Status](https://gemnasium.com/rspec-api/rspec-api-expectations.png)](https://gemnasium.com/rspec-api/rspec-api-expectations)

Basic example
-------------

    # 1. Make a request to the GitHub API:

    require 'faraday'
    conn = Faraday.new 'https://api.github.com/' do |c|
      c.use Faraday::Adapter::NetHttp
    end
    conn.headers[:user_agent] = 'RSpec API'
    conn.authorization :token, ENV['RSPEC_API_GITHUB_TOKEN']
    response = conn.get '/repositories'

    # 2. Expect the response to be successful and to return a JSON collection,
    #    where each object has an ID key/value (number), a name key/value
    #    (string) and a url key/value (string in URL format)

    require 'rspec-api/expectations'

    describe 'List all public repositories', rspec_api: true do
      expect_response response, status: :ok, type: :json, collection: true,
        attributes: {id: {type: :number}, name: {type: :string},
                     url: {type: {string: :url}}}

Running the example above returns the following successful output:

    GET https://api.github.com/repositories
      responds with a status code that
        should be 200
      responds with headers that
        should include 'Content-Type': 'application/json; charset=utf-8'
      responds with a body that
        should be a collection
        should have attributes {:id=>{:type=>:number}, :name=>{:type=>:string}, :url=>{:type=>{:string=>:url}}}

    Finished in 0.13086 seconds
    4 examples, 0 failures

Note that, in order run the example, above, you need to get a GitHub Personal Access Token:

* Browse to your [GitHub settings](https://github.com/settings/applications)
* Click on 'Create new token' under 'Personal Access Token' (name it as you want)
* Copy the generated token and store it on your machine as the environment variable called `RSPEC_API_GITHUB_TOKEN`:
* On OSX and bash, accomplish this by running the command `export RSPEC_API_GITHUB_TOKEN=` followed by your pasted key (no spaces after `=`)


Available expectations
======================

The purpose of RSpecApi::Expectations is to give developers a tool to quickly
test that API endpoints respect some [best practices](http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api)
that are common to RESTful resourceful web APIs.

Status
------

    expect_response response, status: :ok

Expects a specific HTTP status code in the response.
The status can be specified either as a number (200) or as a symbol (:ok).

Content Type
------------

    expect_response response, type: :json

Expects a specific 'Content-Type' header in the response.
The status can be specified either as a string or as a symbol.
The expectation always passes when the response does not have a content
(e.g. if the status is '204 No Content').


Page Links
----------

    expect_response response, page_links: true

Expects a 'Link' header in the response to denote pagination, in accordance to [RFC 5988](http://tools.ietf.org/html/rfc5988#page-6).
The expectation passes if a link with rel="prev" is found.

Collection
----------

    expect_response response, collection: true

Expects a collection of JSON objects in the response body.
For example, the expectation above passes if the body is
`[{"name":"foo"},{"name":"bar"}]`.

JSONP Callback
--------------

    expect_response response, callback: 'alert'

Expects a response body with a JSON wrapped in the given JSONP callback.
For example, the expectation above passes if the body is
`alert({"name": "foo"})`.

Sort
----

    expect_response response, sort: {by: :id, verse: :desc}

Expects a response body with a JSON collection sorted by the given option.
For example, the expectation above passes if the body is
`[{"id": 2, "foo"},{"id": 1, "bar"}]`.

Filter
------

    expect_response response, filter: {by: :name, value: "foo"}

Expects a response body with a JSON collection filtered by the given option.
For example, the expectation above passes if the body is
`[{"id": 1, "foo"},{"id": 2, "foo"}]`.

Filter
------

    expect_response response, attributes: [:id, name: {type: :string}]

Expects a response body that includes the given attributes.
For example, the expectation above passes if the body is
`[{"id": 1, "foo"},{"id": 2, "bar"}]`.


How to install
==============

To install on your system, run `gem install rspec-api-expectations`.
To use inside a bundled Ruby project, add this line to the Gemfile:

    gem 'rspec-api-expectations', '~> 0.6.0'

The rspec-api-expectations gem follows [Semantic Versioning](http://semver.org).
Any new release that is fully backward-compatible bumps the *patch* version (0.0.x).
Any new version that breaks compatibility bumps the *minor* version (0.x.0)

Indicating the full version in your Gemfile (*major*.*minor*.*patch*) guarantees
that your project won’t occur in any error when you `bundle update` and a new
version of RSpecApi::Expectations is released.


How to contribute
=================

Don’t hesitate to send me code comments, issues or pull requests through GitHub!

All feedback is appreciated. Thanks :)