ClientApi

Gem Version Build Status

HTTP Rest Api client for RSpec test automation framework that binds within itself

Features

  • [x] Custom Header, URL, and Timeout support
  • [x] Datatype and key-pair value validation
  • [x] Single key-pair response validation
  • [x] Multi key-pair response validation
  • [x] JSON schema validation
  • [x] JSON structure validation
  • [x] JSON template as body and schema
  • [x] Support to store JSON responses of each tests for the current run
  • [x] Logs support for debug
  • [x] Custom logs remover

Installation

Add this line to your application's Gemfile:

gem 'client-api'

And then execute:

$ bundle

Or install it yourself as:

$ gem install client-api

Import the library in your env file

require 'client-api'

Usage

Add this config snippet in the spec_helper.rb file:

ClientApi.configure do |config|
  config.base_url = 'https://reqres.in'
  config.headers = {'Content-Type' => 'application/json', 'Accept' => 'application/json'}
  config.basic_auth = {'Username' => '[email protected]', 'Password' => '[email protected]'}
  config.json_output = {'Dirname' => './output', 'Filename' => 'test'}
  config.time_out = 10  # in secs
  config.logger = {'Dirname' => './logs', 'Filename' => 'test', 'StoreFilesCount' => 2}
end

Create client-api object with custom variable

api = ClientApi::Api.new

RSpec test scenarios look like,

it "GET request" do
  api = ClientApi::Api.new

  api.get('/api/users')
  expect(api.status).to eq(200)
  expect(api.code).to eq(200)
  expect(api.message).to eq('OK')
end

it "POST request" do
  api.post('/api/users', {"name": "prashanth sams"})
  expect(api.status).to eq(201)
end

it "DELETE request" do
  api.delete('/api/users/3')
  expect(api.status).to eq(204)
end

it "PUT request" do
  api.put('/api/users/2', {"data":{"email":"[email protected]","first_name":"Prashanth","last_name":"Sams"}})
  expect(api.status).to eq(200)
end

it "PATCH request" do
  api.patch('/api/users/2', {"data":{"email":"[email protected]","first_name":"Prashanth","last_name":"Sams"}})
  expect(api.status).to eq(200)
end

Using json template as body

it "JSON template as body" do
  api.post('/api/users', payload("./data/request/post.json"))
  expect(api.status).to eq(201)
end

Add custom header

it "GET request with custom header" do
  api.get('/api/users', {'Content-Type' => 'application/json', 'Accept' => 'application/json'})
  expect(api.status).to eq(200)
end

it "PATCH request with custom header" do api.patch('/api/users/2', href="mailto:[email protected]">[email protected]","first_name":"Prashanth","last_name":"Sams"}, => 'application/json', 'Accept' => 'application/json') expect(api.status).to eq(200) end

> Full url support
```ruby
it "full url", :post do
  api.post('https://api.enterprise.apigee.com/v1/organizations/ahamilton-eval',{},{'Authorization' => 'Basic YWhhbWlsdG9uQGFwaWdlZS5jb206bXlwYXNzdzByZAo'})
  expect(api.status).to eq(403)
end

Basic Authentication

ClientApi.configure do |config|
  ...
  config.basic_auth = {'Username' => '[email protected]', 'Password' => '[email protected]'}
end

Custom Timeout in secs

ClientApi.configure do |config|
  ...
  config.time_out = 10 # in secs
end

Output as json template

ClientApi.configure do |config|
  ...
  config.json_output = {'Dirname' => './output', 'Filename' => 'sample'}
end

validation

Validate .json response values and datatype; validates single key-pair values in the response

validate( api.body,
    {
        "key": "name",
        "value": "prashanth sams",
        "operator": "==",
        "type": 'string'
    }
)

Multi key-pair values response validator

validate( api.body,
    {
        "key": "name",
        "value": "prashanth sams",
        "operator": "==",
        "type": 'string'
    },
    {
        "key": "event",
        "operator": "eql?",
        "type": 'boolean'
    },
    {
         "key": "posts->1->enabled",
         "value": false,
         "operator": "!=",
         "type": 'boolean'
    },
    {
        "key": "profile->name->id",
        "value": 2,
        "operator": "==",
        "type": 'integer'
    }
)

Operator
Type options
Equal =, ==, eql?, equal, equal?
Not Equal !, !=, !eql?, not equal, !equal?
Datatype
Type options
String string, str
Integer integer, int
Symbol symbol, sym
Boolean boolean, bool
Array array, arr
Object object, obj
Float float
Hash hash
Complex complex
Rational rational
Fixnum fixnum
Falseclass falseclass
Trueclass trueclass
Bignum bignum

json schema validation

validate_schema(
  schema_from_json('./data/schema/get_user_schema.json'),
  {
    "data":
        {
            "id": 2,
            "email": "[email protected]",
            "firstd_name": "Janet",
            "last_name": "Weaver",
            "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
        }
  }
)
validate_schema(
    {
        "required": [
            "data"
        ],
        "type": "object",
        "properties": {
            "data": {
                "type": "object",
                "required": [
                    "id", "email", "first_name", "last_name", "avatar"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "email": {
                        "type": "string"
                    },
                    "first_name": {
                        "type": "string"
                    },
                    "last_name": {
                        "type": "string"
                    },
                    "avatar": {
                        "type": "string"
                    }
                }
            }
        }
    },
  {
    "data":
        {
            "id": 2,
            "email": "[email protected]",
            "first_name": "Janet",
            "last_name": "Weaver",
            "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
        }
  }
)
validate_schema(
    schema_from_json('./data/schema/get_user_schema.json'),
    api.body
)

json structure validation

json response structure value validation

actual_body = {
    "posts":
        {
            "prashanth": {
                "id": 1,
                "title": "Post 1"
            },
            "sams": {
                "id": 2,
                "title": "Post 2"
            }
        },
    "profile":
        {
            "id": 44,
            "title": "Post 44"
        }
}

validate_json( actual_body, { "posts": { "prashanth": { "id": 1, "title": "Post 1" }, "sams": { "id": 2 } }, "profile": { "title": "Post 44" } })

```ruby
validate_json( api.body,
  {
      "posts": [
          {
              "id": 2,
              "title": "Post 2"
          }
      ],
      "profile": {
          "name": "typicode"
      }
  }
)

logs

Logs are optional in this library; you can do so through config in spec_helper.rb. The param,StoreFilesCount will keep the custom files as logs; you can remove it, if not needed.

ClientApi.configure do |config|
  ...
  config.logger = {'Dirname' => './logs', 'Filename' => 'test', 'StoreFilesCount' => 5}
end

Is there a demo available for this gem?

Yes, you can use this demo as an example, https://github.com/prashanth-sams/client-api

rake spec