module JsonapiExpectations

Public Instance Methods

expect_attributes(attrs) click to toggle source
# File lib/jsonapi_expectations.rb, line 9
def expect_attributes attrs
  expect_valid_data
  location = if array_response?
               'data.?.attributes'
             else
               'data.attributes'
             end
  expect_json location, dasherize_keys(attrs)
rescue RSpec::Expectations::ExpectationNotMetError
  msg = "Expected attributes #{attrs} to be present in json response"
  raise Exceptions::ExpectationError, msg
end
Also aliased as: expect_attributes_in_list
expect_attributes_absent(*keys) click to toggle source
# File lib/jsonapi_expectations.rb, line 22
def expect_attributes_absent *keys
  expect_valid_data
  if array_response?
    json_body[:data].each do |data|
      dasherize_array(keys).each do |key|
        expect(data[:attributes].key?(key)).to be_falsey
      end
    end
  else
    dasherize_array(keys).each do |key|
      expect(json_body[:data][:attributes].key?(key)).to be_falsey
    end
  end
rescue RSpec::Expectations::ExpectationNotMetError
  msg = "Expected #{keys} not to be present in json response"
  raise Exceptions::ExpectationError, msg
end
expect_attributes_absent_in_list(*keys)
expect_attributes_in_list(attrs)

TODO: deprecate these

Alias for: expect_attributes
expect_item_count(number) click to toggle source
# File lib/jsonapi_expectations.rb, line 73
def expect_item_count number
  expect_valid_data
  expect_json_sizes data: number
end
expect_item_in_list(record, opts = {})
Alias for: expect_record
expect_item_not_in_list(dont_find_me, opts = {})
expect_item_not_to_be_in_list(dont_find_me, opts = {})
expect_item_to_not_be_in_list(dont_find_me, opts = {})
expect_record(record, opts = {}) click to toggle source
# File lib/jsonapi_expectations.rb, line 78
def expect_record record, opts = {}
  found = find_record record, opts
  expect(found).to be_truthy
rescue RSpec::Expectations::ExpectationNotMetError
  msg = "Expected #{record} to be present in json response"
  raise Exceptions::ExpectationError, msg
end
Also aliased as: expect_item_in_list
expect_record_absent(dont_find_me, opts = {}) click to toggle source
# File lib/jsonapi_expectations.rb, line 86
def expect_record_absent dont_find_me, opts = {}
  opts[:type] ||= jsonapi_type dont_find_me
  location = if opts[:included]
               json_body[:included]
             else
               json_body[:data]
             end
  expect_valid_data location
  location.each do |item|
    expect(jsonapi_match?(dont_find_me, item, opts[:type])).to be_falsey
  end
rescue RSpec::Expectations::ExpectationNotMetError
  msg = "Expected #{dont_find_me} to not be present in json response"
  raise Exceptions::ExpectationError, msg
end
expect_records_sorted_by(attr, opts = {}) click to toggle source
# File lib/jsonapi_expectations.rb, line 102
def expect_records_sorted_by attr, opts = {}
  direction = opts.fetch :direction, :asc
  allow_nils = opts.fetch :allow_nils, false

  json_body[:data].each_with_index do |item, index|
    return if item == json_body[:data].last

    this_one = item[:attributes][attr]
    next_one = json_body[:data][index + 1][:attributes][attr]

    unless this_one && next_one
      return if allow_nils
      msg = "Expected response to be sorted by #{attr} #{direction}, but some attribues were nil"
      raise Exceptions::ExpectationError, msg
    end

    if direction == :asc
      expect(this_one).to be <= next_one
    elsif direction == :desc
      expect(next_one).to be <= this_one
    else
      raise 'Direction option needs to be :asc or :desc'
    end
  end
rescue RSpec::Expectations::ExpectationNotMetError
  msg = "Expected response to be sorted by #{attr} #{direction}"
  raise Exceptions::ExpectationError, msg
end
expect_relationship(opts) click to toggle source
# File lib/jsonapi_expectations.rb, line 40
def expect_relationship opts
  expect_valid_data
  type = opts[:type] || opts[:key].pluralize
  location = if array_response?
               "data.?.relationships.#{opts[:key]}"
             else
               "data.relationships.#{opts[:key]}"
             end

  if opts[:link]
    begin
      expect_json "#{location}.links.related", opts[:link]
    rescue # check if it's in an array
      expect_json "#{location}.?.links.related", opts[:link]
    end
  end

  if opts[:id]
    location = "#{location}.data"

    if opts[:id].is_a? Array # if array was passed in, check each
      opts[:id].each do |id|
        expect_linkage_data "#{location}.?", { type: type, id: id }, opts[:included]
      end
    else # otherwise just look for it
      expect_linkage_data location, { type: type, id: opts[:id] }, opts[:included]
    end
  end
rescue RSpec::Expectations::ExpectationNotMetError
  msg = "Expected relationship to #{type} in response"
  raise Exceptions::ExpectationError, msg
end
Also aliased as: expect_relationship_in_list
expect_relationship_in_list(opts)
Alias for: expect_relationship
find_record(record, opts = {}) click to toggle source
# File lib/jsonapi_expectations.rb, line 131
def find_record record, opts = {}
  opts[:type] ||= jsonapi_type record
  location = if opts[:included]
               json_body[:included]
             else
               json_body[:data]
             end
  expect_valid_data location

  [location].flatten.detect do |item|
    jsonapi_match? record, item, opts[:type]
  end
end

Private Instance Methods

array_response?() click to toggle source
# File lib/jsonapi_expectations.rb, line 156
def array_response?
  json_body[:data].is_a? Array
end
dasherize(thing) click to toggle source
# File lib/jsonapi_expectations.rb, line 187
def dasherize thing
  thing.to_s.tr('_', '-').to_sym
end
dasherize_array(array) click to toggle source
# File lib/jsonapi_expectations.rb, line 179
def dasherize_array array
  array.map { |item| dasherize item }
end
dasherize_keys(hash) click to toggle source
# File lib/jsonapi_expectations.rb, line 183
def dasherize_keys hash
  hash.deep_transform_keys { |key| dasherize key }
end
expect_linkage_data(location, relationship_data, included) click to toggle source
# File lib/jsonapi_expectations.rb, line 169
def expect_linkage_data location, relationship_data, included
  begin
    expect_json location, relationship_data
  rescue # check if it's in an array
    expect_json "#{location}.?", relationship_data
  end

  expect_json 'included.?', relationship_data if included
end
expect_valid_data(location = nil) click to toggle source
# File lib/jsonapi_expectations.rb, line 160
def expect_valid_data location = nil
  location ||= json_body[:data]
  expect(location).to_not be_nil
  expect(location).to_not be_empty
rescue RSpec::Expectations::ExpectationNotMetError
  msg = "#{location} is does not contain data"
  raise Exceptions::ExpectationError, msg
end
jsonapi_match?(model, data, type) click to toggle source
# File lib/jsonapi_expectations.rb, line 191
def jsonapi_match? model, data, type
  (data[:type] == type) && (data[:id] == model.id.to_s)
end
jsonapi_type(model) click to toggle source
# File lib/jsonapi_expectations.rb, line 195
def jsonapi_type model
  model.class.to_s.underscore.downcase.pluralize.tr('_', '-')
end