JsonApiToolbox
This toolbox serve as a JSON API helper within Guide TI specs
The current features are:
- Integrates the gems
jsonapi-serializable
,json-api-vanilla
andlog_toolbox
- Rspec support through a series of shares examples
- Suport for JSON API services
Installation
Add this line in your Gemfile
:
gem 'json_api_toolbox'
then execute:
$ bundle install
For rspec support, add this line on your rails_helper.rb
:
require 'json_api_toolbox/rspec'
Usage Examples
You can check some gem uses within the examples below:
Service
class MyService < JsonApiToolbox::Service
BASE_URL = 'http://localhost:3000/my_model'
class << self
def all(includes: nil, query_string: nil)
get(url: BASE_URL, includes: includes, query_string: query_string)
end
def find(id, includes: includes)
get(url: "#{BASE_URL}/#{id}", includes: includes)
end
def create(payload)
post(url: BASE_URL, body: payload)
end
def update(payload)
patch(url: "#{BASE_URL}/#{payload.delete(:id)}", body: payload)
end
end
end
Renderizable
A simple render:
render_object(Quota.all)
To render an object with a custom serializable, you will need to send a Hash that contains a key called 'class' and its values must be another Hash. In this new Hash, the key must be 'Hash' and the value must be your Serializable.
render_object(QuotaGap.all, class: { Hash: SerializableQuotaGap })
Paginable
To render a collection with a json api pagination, you will need to send a Hash that contains two keys called 'links' and 'meta', and its values must be Hashs.
class MyController
include JsonApiToolbox::Paginable
def index
collection = MyModel
.all
.paginate(page: params[:page],
per_page: params[:per_page])
render_object(collection, links: pagination(collection),
meta: (collection))
end
end
Rspec Shared Examples
it_behaves_like 'a http method'
- validate if your response have http status 200
it_behaves_like 'a get method'
- validate if your response have http status 200
- validate if your response responde to body method
it_behaves_like 'a json api response with included node'
- validate if yor response.body has included node
it_behaves_like 'a get with jsonapi with default value of', SomeModel
validate if all attributes are present on your data based on the current criteria:
- for enums who have
_cd
in the end of attribute name,_cd
is removed.
ex:
enum_cd
=>enum
- id attributes are removed from validation
- for attributes who have
_id
in the end of attribute name, they are removed from validation
- for enums who have
it_behaves_like 'a json api response with all relations of', SomeModel
- validate if all relations are included on your data
it_behaves_like 'a failed attempt to retrieve a resource'
- checks if the api response will include an error when
find
raise a exception retrieving a resource.
Test example
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe ManagersController, type: :controller do
let(:body) { JSON.parse(response.body) }
let(:data) { body['data'] }
describe 'GET' do
let!(:manager) { create(:manager) }
let(:params) { {} }
describe '#index' do
let(:data) { body['data'].first }
before { get :index, params: params }
it_behaves_like 'a get method'
it_behaves_like 'a json api response with all relations of', Manager
it_behaves_like 'a get with jsonapi with default value of', Manager
context 'including contacts' do
let(:params) { { includes: :contacts } }
it { expect(data['relationships']['contacts']['data'].size).to eq(1) }
end
end
describe '#show' do
before { get :show, params: { id: manager.id } }
it_behaves_like 'a get method'
it_behaves_like 'a json api response with included node'
it_behaves_like 'a json api response with all relations of', Manager
it_behaves_like 'a get with jsonapi with default value of', Manager
context 'When the manager does not exist' do
before { get :show, params: { id: 300 } }
it_behaves_like 'a failed attempt to retrieve a resource'
end
end
end
describe 'POST' do
describe '#create' do
let(:params) do
attributes_for(:manager).merge(
contacts: attributes_for_list(:contact, 2)
)
end
before { post :create, params: params }
it_behaves_like 'a get method'
it_behaves_like 'a json api response with included node'
it_behaves_like 'a json api response with all relations of', Manager
it_behaves_like 'a get with jsonapi with default value of', Manager
it { expect(data['relationships']['contacts']['data'].count).to eq(2) }
end
end
describe 'PATCH' do
describe '#update' do
let(:manager) { create(:manager) }
let(:new_name) { 'Manager 100' }
let(:params) do
{
id: manager.id,
name: new_name,
short_name: manager.short_name
}
end
before { post :update, params: params }
it_behaves_like 'a get method'
it_behaves_like 'a json api response with included node'
it_behaves_like 'a json api response with all relations of', Manager
it_behaves_like 'a get with jsonapi with default value of', Manager
it 'validates if values were updated' do
expect(data['attributes']['name']).to eq(new_name)
end
context 'When the manager does not exist' do
before { get :show, params: { id: 300 } }
it_behaves_like 'a failed attempt to retrieve a resource'
end
end
end
end
Development
To change the gem is simple, just clone this repository and run the bin/setup
script
Then you can make your changes and check them with rspec
or rubocop .
.
On docker
Building
docker build . -t json-api-toolbox-dev
Running tests
docker run --rm -it -v "$(echo $HOME)/.ssh:/root/.ssh" -v "$(pwd):/gem" json-api-toolbox-dev
Contributing
To be written