Fitting

Fitting avatar: Documents with hangers

Library add improve test log, validate its according to your API documentation, show the documentation coverage with log.

Test log setting supports RSpec test and WebMock stubbing for Ruby On Rails application, API documentation supports API Blueprint and OpenAPI.

This reduces the costs of support, testers and analysts.

Log

FITTING incoming request {"method":"POST","path":"/public/api/v1/inboxes/tEX5JiZyceiwuKMi1oN9Sf8S/contacts","body":{},"response":{"status":200,"content_type":"application/json","body":{"source_id":"00dbf18d-879e-47cb-ac45-e9aece266eb1","pubsub_token":"ktn6YwPus57JDf4e59eFPom5","id":3291,"name":"shy-surf-401","email":null,"phone_number":null}},"title":"./spec/controllers/public/api/v1/inbox/contacts_controller_spec.rb:9","group":"./spec/controllers/public/api/v1/inbox/contacts_controller_spec.rb","host":"www.example.com"}
FITTING outgoing request {"method":"POST","path":"/v1/organizations/org_id/meeting","body":{},"response":{"status":200,"content_type":"application/json","body":{"success":true,"data":{"meeting":{"id":"meeting_id","roomName":"room_name"}}}},"title":"./spec/controllers/api/v1/accounts/integrations/dyte_controller_spec.rb:50","group":"./spec/controllers/api/v1/accounts/integrations/dyte_controller_spec.rb","host":"api.cluster.dyte.in"}

validation

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.FFF..FFFFFFFFFF....F.......F...FF.....F...F....F..............................FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF..FF.F..FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF..FF........FFF...FFFF......FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF........FFFFFFFFFFF..FFFFFF..FFFFFFFFFFFFFFFFF.......FFFFFF.............FFFFFFFFFFFF....F........FFF.F...FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF............FF........FFF......FFFFFFFFFFFFFFFFFFFFFF....FFFFFF......F............FFFF........FFFFFFFFFFFFFF.....FFFFFFFFFFFFFFFFFFFFFFF..FF.....FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.....FF..........FFFFFFFFFFFFFFFFFF...FFFF...............F.F....FF..FFFFFFFF

  1) Fitting::Doc::NotFound log error:

host: www.example.com
method: POST
path: /public/api/v1/inboxes/{inbox_identifier}/contacts
code: 200

content-type: application/json

json-schema: {
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "description": "Id of the contact"
    },
    "source_id": {
      "type": "string",
      "description": "The session identifier of the contact"
    },
    "name": {
      "type": "string",
      "description": "Name of the contact"
    },
    "email": {
      "type": "string",
      "description": "Email of the contact"
    },
    "pubsub_token": {
      "type": "string",
      "description": "The token to be used to connect to chatwoot websocket"
    }
  }
}

body: {
  "source_id": "c9e8c31f-06df-49b4-8fb9-4466457ae65b",
  "pubsub_token": "Zgc7DEvaj5TkgZ1a4C7AvJXo",
  "id": 3293,
  "name": "restless-snowflake-670",
  "email": null,
  "phone_number": null
}

error [
  "The property '#/email' of type null did not match the following type: string in schema e56b7e65-d70c-5f7a-a96c-982df5f8f2f7"
]

...

804 examples, 565 failure, 0 pending

Coverage: 65.51%

and cover exmaple

exmaple

exmaple

exmaple

Installation

Add this line to your application's Gemfile:

gem 'fitting'

After that execute:

$ bundle

Or install the gem by yourself:

$ gem install fitting

Usage

Log

Firstly, improve test.log.

To your spec_helper.rb:

require 'fitting'

Fitting.logger

Delete all files log/*.log and run rspec

You get more information about incoming and outgoing request in log/fitting*.log.

FITTING incoming request {"method":"POST","path":"/public/api/v1/inboxes/tEX5JiZyceiwuKMi1oN9Sf8S/contacts","body":{},"response":{"status":200,"content_type":"application/json","body":{"source_id":"00dbf18d-879e-47cb-ac45-e9aece266eb1","pubsub_token":"ktn6YwPus57JDf4e59eFPom5","id":3291,"name":"shy-surf-401","email":null,"phone_number":null}},"title":"./spec/controllers/public/api/v1/inbox/contacts_controller_spec.rb:9","group":"./spec/controllers/public/api/v1/inbox/contacts_controller_spec.rb","host":"www.example.com"}
FITTING outgoing request {"method":"POST","path":"/v1/organizations/org_id/meeting","body":{},"response":{"status":200,"content_type":"application/json","body":{"success":true,"data":{"meeting":{"id":"meeting_id","roomName":"room_name"}}}},"title":"./spec/controllers/api/v1/accounts/integrations/dyte_controller_spec.rb:50","group":"./spec/controllers/api/v1/accounts/integrations/dyte_controller_spec.rb","host":"api.cluster.dyte.in"}

Validation

Secondly, validate the log to the documentation.

Add this to your .fitting.yml:

APIs:
  - host: www.example.com
    type: openapi2
    path: swagger/swagger.json

Run

bundle e rake fitting:validate

Console output

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.FFF..FFFFFFFFFF....F.......F...FF.....F...F....F..............................FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF..FF.F..FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF..FF........FFF...FFFF......FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF........FFFFFFFFFFF..FFFFFF..FFFFFFFFFFFFFFFFF.......FFFFFF.............FFFFFFFFFFFF....F........FFF.F...FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF............FF........FFF......FFFFFFFFFFFFFFFFFFFFFF....FFFFFF......F............FFFF........FFFFFFFFFFFFFF.....FFFFFFFFFFFFFFFFFFFFFFF..FF.....FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.....FF..........FFFFFFFFFFFFFFFFFF...FFFF...............F.F....FF..FFFFFFFF

  1) Fitting::Doc::NotFound log error:

host: www.example.com
method: POST
path: /public/api/v1/inboxes/{inbox_identifier}/contacts
code: 200

content-type: application/json

json-schema: {
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "description": "Id of the contact"
    },
    "source_id": {
      "type": "string",
      "description": "The session identifier of the contact"
    },
    "name": {
      "type": "string",
      "description": "Name of the contact"
    },
    "email": {
      "type": "string",
      "description": "Email of the contact"
    },
    "pubsub_token": {
      "type": "string",
      "description": "The token to be used to connect to chatwoot websocket"
    }
  }
}

body: {
  "source_id": "c9e8c31f-06df-49b4-8fb9-4466457ae65b",
  "pubsub_token": "Zgc7DEvaj5TkgZ1a4C7AvJXo",
  "id": 3293,
  "name": "restless-snowflake-670",
  "email": null,
  "phone_number": null
}

error [
  "The property '#/email' of type null did not match the following type: string in schema e56b7e65-d70c-5f7a-a96c-982df5f8f2f7"
]

...

804 examples, 565 failure, 0 pending

Coverage: 65.51%

Coverage

And task will create HTML (coverage/fitting.html) reports.

exmaple

exmaple

More information on action coverage

exmaple2

exmaple2

Settings

APIs

type

OpenAPI 2.0

Swagger

APIs:
  - host: www.example.com
    type: openapi2
    path: doc/api.json
OpenAPI 3.0

Also OpenAPI

APIs:
  - host: www.example.com
    type: openapi3
    path: doc/api.json
API Blueprint

First you need to install drafter or crafter. Works after conversion from API Blueprint to API Elements (in YAML file) with Drafter or Crafter.

That is, I mean that you first need to do this

drafter doc.apib -o doc.yaml

or

node_modules/.bin/crafter doc.apib > doc.yaml

and then

APIs:
  - host: www.example.com
    type: drafter
    path: doc/api.yaml

or

APIs:
  - host: www.example.com
    type: crafter
    path: doc/api.yaml
Tomograph

To use additional features of the pre-converted tomograph

example

bundle exec tomograph -d crafter --exclude-description doc/api.yml doc/api.json

and then

APIs:
  - host: www.example.com
    type: tomogram
    path: doc/api.json

prefix

Setting the prefix name is optional. For example, you can do this:

APIs:
  - host: www.example.com
    prefix: /api/v3
    type: openapi2
    path: swagger/swagger.json

SkipValidation

host

It is not necessary to immediately describe each host in detail, you can only specify its name and skip it until you are ready to documented it

SkipValidation:
  - host: api.cluster.dyte.in

prefix

If you want to skip a specific prefix in the host

SkipValidation:
  - host: api.cluster.dyte.in
    prefix: /admin/api

method and path

If you want to skip a specific request in the host

SkipValidation:
  - host: api.cluster.dyte.in
    method: GET
    path: /api/v1/cars

NoCov

It is not necessary to immediately test each doc in detail, you can only specify its name and skip it until you are ready to test it

host

NoCov:
  - host: sso.test

method

NoCov:
  - host: sso.test
    method: GET

path

NoCov:
  - host: sso.test
    method: GET
    path: /users/{userId}

code

NoCov:
  - host: sso.test
    method: GET
    path: /users/{userId}
    code: 200

content-type

NoCov:
  - host: sso.test
    method: GET
    path: /users/{userId}
    code: 200
    content-type: application/json

combination

NoCov:
  - host: sso.test
    method: GET
    path: /users/{userId}
    code: 200
    content-type: application/json
    combination: oneOf.0

combination_next

NoCov:
  - host: sso.test
    method: GET
    path: /users/{userId}
    code: 200
    content-type: application/json
    combination: oneOf.0
    combination_next: oneOf.0.required.users

Debug

If you find bug, you can debug it or create task in this github project with new file coverage/fitting.debug.yml

Debug:
  - host: www.example.com
    method: GET
    path: /api/v3/users
    code: 200
    content-type: application/json

Contributing

Bug reports and pull requests are welcome on GitHub at github.com/tuwilof/fitting. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Sponsored by FunBox