JsonApiToolbox

Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file lib/json_api_toolbox. To experiment with that code, run bin/console for an interactive prompt.

TODO: Delete this and the text above, and describe your gem

Installation

Add this line to your application's Gemfile:

gem 'json_api_toolbox'

And then execute:

$ bundle

Or install it yourself as:

$ gem install json_api_toolbox

Usage

TODO: Write usage instructions here

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/abacha/json_api_toolbox.

Examples

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

Render common

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: pagination_meta(collection))
  end
end

ShareExamplesForControllers

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 obs: 1 - for enums who have '_cd' in the end of attribute name, '_cd' is removed. ex: enum_cd => enum 2 - id attributes are removed from validation 3 - for attributes who have _id in the end of attribute name, they are removed from validation

it_behaves_like 'a json api response with all relations of', SomeModel validate if all relations are included on your data

Example Tests

# 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
    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
    end
  end
end