Skip to content
HTTP Rest Api client for RSpec test automation framework that binds within itself
Ruby Shell
Branch: master
Clone or download
prashanth-sams Merge pull request #101 from prashanth-sams/method
fixed null issue in validate_json
Latest commit 43a8f7f Oct 21, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
bin initial commit Sep 18, 2019
data json schema validator Sep 30, 2019
lib
spec removed response body for pdf headers and fixed nil issue in validate… Oct 17, 2019
.gitignore
.rspec
.travis.yml
CODE_OF_CONDUCT.md
Gemfile validation fix and added boolean keywords Oct 14, 2019
LICENSE.txt
README.md fixed null issue in validate_json Oct 21, 2019
Rakefile initial commit Sep 18, 2019
client-api.gemspec

README.md

ClientApi

Gem Version Build Status

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

Features

  • Custom Header, URL, and Timeout support
  • Datatype and key-pair value validation
  • Single key-pair response validation
  • Multi key-pair response validation
  • JSON response schema validation
  • JSON response content validation
  • Response headers validation
  • JSON template as body and schema
  • Support to store JSON responses of each tests for the current run
  • Logs support for debug
  • Custom logs remover
  • Auto-handle SSL for http(s) schemes

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 outline

Add this config snippet in the spec_helper.rb file:

ClientApi.configure do |config|
  # all these configs are optional; comment out the config if not required
  config.base_url = 'https://reqres.in'
  config.headers = {'Content-Type' => 'application/json', 'Accept' => 'application/json'}
  config.basic_auth = {'Username' => 'ahamilton@apigee.com', 'Password' => 'myp@ssw0rd'}
  config.json_output = {'Dirname' => './output', 'Filename' => 'test'}
  config.time_out = 10  # in secs
  config.logger = {'Dirname' => './logs', 'Filename' => 'test', 'StoreFilesCount' => 2}
  
  # add this snippet only if the logger is enabled
  config.before(:each) do |scenario|
    ClientApi::Request.new(scenario)
  end
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":"prashanth@mail.com","first_name":"Prashanth","last_name":"Sams"}})
  expect(api.status).to eq(200)
end

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

Validation shortcuts

Default validation

key features

  • datatype validation
  • key-pair value validation
  • single key-pair validation
  • multi key-pair validation
General Syntax Syntax | Model 2 Syntax | Model 3
validate(
    api.body,
    {
        key: '', 
        value: '', 
        operator: '', 
        type: ''
    }
)
            
validate(
    api.body,
    {
        key: '', 
        value: '', 
        operator: '', 
    }
)
            
validate(
    api.body,
    {
        key: '', 
        operator: '', 
        type: ''
    },
    {
        key: '', 
        operator: '', 
        value: ''
    }
)
            

JSON response content validation

key benefits

  • the most recommended validation for fixed / static JSON responses
  • validates each JSON content value

what to know?

  • replace null with nil in the expected json (whenever applicable); cos, ruby don't know what is null
General Syntax Syntax | Model 2
validate_json(
    {
        "data":
            {
                "id": 2,
                "first_name": "Prashanth",
                "last_name": "Sams",
            }
    },
    {
        "data":
            {
                "id": 2,
                "first_name": "Prashanth",
                "last_name": "Sams",
            }
    }
)
            
validate_json(
    api.body,
    {
        "data":
            {
                "id": 2,
                "first_name": "Prashanth",
                "last_name": "Sams",
                "link": nil
            }
    }
)
            

JSON response headers validation

key benefits

  • validates any response headers
General Syntax Syntax | Model 2
validate_headers(
    api.response_headers,
    {
       key: '',
       operator: '',
       value: ''
    }
)
            
validate_headers(
    api.response_headers,
    {
       key: "connection",
       operator: "!=",
       value: "open"
    },{
       key: "vary",
       operator: "==",
       value: "Origin, Accept-Encoding"
    }
)
            

#General usage

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', {"data":{"email":"prashanth@mail.com","first_name":"Prashanth","last_name":"Sams"}}, {'Content-Type' => 'application/json', 'Accept' => 'application/json'})
  expect(api.status).to eq(200)
end

Full url support

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' => 'ahamilton@apigee.com', 'Password' => 'myp@ssw0rd'}
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

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}
  
  config.before(:each) do |scenario|
    ClientApi::Request.new(scenario)
  end
end

#Validation | more info.

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'
    },
    {
        "key": "profile->name->id",
        "value": 2,
        "operator": "<",
        "type": 'integer'
    },
    {
        "key": "profile->name->id",
        "operator": ">=",
        "value": 2,
    },
    {
        "key": "post1->0->name",
        "operator": "contains",
        "value": "Sams"
    },
    {
        "key": "post2->0->id",
        "operator": "include",
        "value": 34,
        "type": 'integer'
    },
    {
        "key": "post1->0->available",
        "value": true,
        "operator": "not contains",
        "type": "boolean"
    }
)

Operator
Type options
Equal =, ==, eql?, equal, equal?
Not Equal !, !=, !eql?, not equal, !equal?
Greater than >, >=, greater than, greater than or equal to
Less than <, <=, less than, less than or equal to, lesser than, lesser than or equal to
Contains contains, has, contains?, has?, include, include?
Not Contains not contains, !contains, not include, !include
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, false
Trueclass trueclass, true
Bignum bignum

JSON response schema validation

validate_schema(
  schema_from_json('./data/schema/get_user_schema.json'),
  {
    "data":
        {
            "id": 2,
            "email": "janet.weaver@reqres.in",
            "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": "janet.weaver@reqres.in",
            "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 response content validation

json response content value validation as a structure

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"
        }
})
validate_json( api.body,
  {
      "posts": [
          {
              "id": 2,
              "title": "Post 2"
          }
      ],
      "profile": {
          "name": "typicode"
      }
  }
)

Response headers validation

validate_headers(
  api.response_headers,
  {
    key: "connection",
    operator: "!=",
    value: "open"
  },
  {
    key: "vary",
    operator: "==",
    value: "Origin, Accept-Encoding"
  }
)

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
You can’t perform that action at this time.