Last active
August 29, 2015 14:16
-
-
Save vasilakisfil/a463eee233a00772ba59 to your computer and use it in GitHub Desktop.
Rspec API Helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#rspec/support/rspec_api_helper.rb | |
module RspecApiHelper | |
module ExampleMethods | |
def objectize_resources(json, root: root) | |
array = [] | |
array_hash = HashWithIndifferentAccess.new(MultiJson.load(json)) | |
if root | |
array_hash = array_hash[root] | |
end | |
array_hash.each do |resource| | |
array << object_hash(resource) | |
end | |
return array | |
end | |
def objectize_resource(json, root: root) | |
hash = HashWithIndifferentAccess.new(MultiJson.load(json)) | |
if root | |
obj = object_hash(hash[root]) | |
else | |
obj = object_hash(hash) | |
end | |
return obj | |
end | |
def object_hash(hash) | |
ObjectHash.new(hash) | |
end | |
class ObjectHash | |
attr_accessor :hash | |
def initialize(hash) | |
@hash = HashWithIndifferentAccess.new(hash) | |
end | |
def method_missing(name) | |
return hash[name] if hash.key? name | |
raise KeyError.new("Attribute not found: #{name}") | |
end | |
end | |
end | |
module ExampleGroupMethods | |
def it_returns_status(status) | |
it 'returns the correct status' do | |
expect(last_response.status).to eql(status) | |
end | |
end | |
def it_returns_attributes(resource:, model:, only: [], modifier: nil) | |
it "expects returned resource to have the following model's attributes" do | |
@api_resource = objectize_resource(last_response.body, root: resource) | |
@model = eval(model) | |
if @model.is_a? Hash | |
@model = object_hash(@model) | |
end | |
if only | |
only.each do |attribute| | |
if modifier | |
expect(@api_resource.send(attribute)).to( | |
eql(@model.send(attribute).send(modifier.to_sym)) | |
) | |
else | |
expect(@api_resource.send(attribute)).to eql(@model.send(attribute)) | |
end | |
end | |
end | |
end | |
end | |
alias_method :it_returns_db_model, :it_returns_attributes | |
alias_method :it_returns_more_attributes, :it_returns_attributes | |
def it_includes_in_headers(headers: {}) | |
it 'returns the correct headers' do | |
headers.each do |header, value| | |
expect(last_response.headers[header.to_s]).to eq(eval(value)) | |
end | |
end | |
end | |
def it_returns_the_resources(root:, number:) | |
it 'returns the correct number of data in the body' do | |
users = objectize_resources(last_response.body, root: root) | |
expect(users.length).to eql(number) | |
end | |
end | |
end | |
def self.included(receiver) | |
receiver.extend ExampleGroupMethods | |
receiver.send :include, ExampleMethods | |
end | |
end | |
RSpec.configure do |config| | |
config.include RspecApiHelper, type: :api #apply to all spec for apis folder | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#rspec/apis/users_spec.rb | |
require 'rails_helper' | |
describe Api::V1::UsersController, type: :api do | |
context :index do | |
before do | |
create_and_sign_in_user | |
5.times{ FactoryGirl.create(:user) } | |
get api_v1_users_path, format: :json | |
end | |
it_returns_status(200) | |
it_returns_the_resources(root: 'users', number: 5+1) | |
end | |
context :create do | |
before do | |
@user = FactoryGirl.attributes_for(:user) | |
post api_v1_users_path, user: @user.as_json, format: :json | |
end | |
it_returns_status(201) | |
it_returns_attributes(resource: 'user', model: '@user', only: [ | |
:email, :first_name, :last_name | |
]) | |
it_returns_more_attributes( | |
resource: 'user', | |
model: 'User.last!', | |
only: [:updated_at, :created_at], | |
modifier: 'iso8601' | |
) | |
end | |
context :show do | |
before do | |
create_and_sign_in_user | |
@user = FactoryGirl.create(:user) | |
get api_v1_user_path(@user.id), format: :json | |
end | |
it_returns_status(200) | |
it_returns_attributes(resource: 'user', model: '@user', only: [ | |
:email, :first_name, :last_name | |
]) | |
it_returns_more_attributes( | |
resource: 'user', | |
model: '@user', | |
only: [:updated_at, :created_at], | |
modifier: 'iso8601' | |
) | |
end | |
context :update do | |
before do | |
create_and_sign_in_user | |
@user = FactoryGirl.create(:user) | |
@user.first_name = 'Another name' | |
put api_v1_user_path(@user.id), user: @user.as_json, format: :json | |
end | |
it_returns_status(200) | |
it_includes_in_headers(headers: {Location: 'api_v1_user_path(@user.id)'}) | |
it_returns_attributes(resource: 'user', model: '@user', only: [ | |
:email, :first_name, :last_name | |
]) | |
it_returns_more_attributes( | |
resource: 'user', | |
model: '@user', | |
only: [:updated_at, :created_at], | |
modifier: 'iso8601' | |
) | |
end | |
context :delete do | |
context 'when the resource does NOT exist' do | |
before do | |
create_and_sign_in_user | |
@user = FactoryGirl.create(:user) | |
delete api_v1_user_path(rand(100..1000)), format: :json | |
end | |
it_returns_status(404) | |
end | |
context 'when the resource does exist' do | |
before do | |
create_and_sign_in_user | |
@user = FactoryGirl.create(:user) | |
delete api_v1_user_path(@user.id), format: :json | |
end | |
it_returns_status(204) | |
it 'actually deletes the resource' do | |
expect(User.find_by(id: @user.id)).to eql(nil) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment