module Airborne::RequestExpectations

Public Instance Methods

date() { |parse| ... } click to toggle source
# File lib/airborne/request_expectations.rb, line 55
def date
  ->(value) { yield DateTime.parse(value) }
end
expect_header(key, content) click to toggle source
# File lib/airborne/request_expectations.rb, line 39
def expect_header(key, content)
  expect_header_impl(key, content)
end
expect_header_contains(key, content) click to toggle source
# File lib/airborne/request_expectations.rb, line 43
def expect_header_contains(key, content)
  expect_header_impl(key, content, true)
end
expect_json(*args) click to toggle source
# File lib/airborne/request_expectations.rb, line 17
def expect_json(*args)
  call_with_path(args) do |param, body|
    expect_json_impl(param, body)
  end
end
expect_json_keys(*args) click to toggle source
# File lib/airborne/request_expectations.rb, line 23
def expect_json_keys(*args)
  call_with_path(args) do |param, body|
    expect(body.keys).to include(*param)
  end
end
expect_json_sizes(*args) click to toggle source
# File lib/airborne/request_expectations.rb, line 29
def expect_json_sizes(*args)
  args.push(convert_expectations_for_json_sizes(args.pop))

  expect_json_types(*args)
end
expect_json_types(*args) click to toggle source
# File lib/airborne/request_expectations.rb, line 11
def expect_json_types(*args)
  call_with_path(args) do |param, body|
    expect_json_types_impl(param, body)
  end
end
expect_status(code) click to toggle source
# File lib/airborne/request_expectations.rb, line 35
def expect_status(code)
  expect(response.code).to eq(resolve_status(code, response.code))
end
optional(hash) click to toggle source
# File lib/airborne/request_expectations.rb, line 47
def optional(hash)
  OptionalHashTypeExpectations.new(hash)
end
regex(reg) click to toggle source
# File lib/airborne/request_expectations.rb, line 51
def regex(reg)
  Regexp.new(reg)
end

Private Instance Methods

call_with_path(args) { |args, json_chunk| ... } click to toggle source
# File lib/airborne/request_expectations.rb, line 133
def call_with_path(args)
  if args.length == 2
    get_by_path(args[0], json_body) do |json_chunk|
      yield(args[1], json_chunk)
    end
  else
    yield(args[0], json_body)
  end
end
check_array_types(value, prop_name, expected_type) click to toggle source
# File lib/airborne/request_expectations.rb, line 185
def check_array_types(value, prop_name, expected_type)
  expect_array(value, prop_name, expected_type)
  value.each do |val|
    expect_type(expected_type, val, prop_name)
  end
end
convert_expectation_for_json_sizes(expected_size) click to toggle source
# File lib/airborne/request_expectations.rb, line 219
def convert_expectation_for_json_sizes(expected_size)
  ->(data) { expect(data.size).to eq(expected_size) }
end
convert_expectations_for_json_sizes(old_expectations) click to toggle source
# File lib/airborne/request_expectations.rb, line 204
def convert_expectations_for_json_sizes(old_expectations)
  unless old_expectations.is_a?(Hash)
    return convert_expectation_for_json_sizes(old_expectations)
  end

  old_expectations.each_with_object({}) do |(prop_name, expected_size), memo|
    new_value = if expected_size.is_a?(Hash)
                  convert_expectations_for_json_sizes(expected_size)
                else
                  convert_expectation_for_json_sizes(expected_size)
                end
    memo[prop_name] = new_value
  end
end
convert_to_date(value) click to toggle source
# File lib/airborne/request_expectations.rb, line 178
def convert_to_date(value)
  begin
    DateTime.parse(value)
  rescue
  end
end
ensure_hash_contains_prop(prop_name, hash) { || ... } click to toggle source
# File lib/airborne/request_expectations.rb, line 223
def ensure_hash_contains_prop(prop_name, hash)
  begin
    yield
  rescue
    raise ExpectationError, "Expected #{hash.class} #{hash}\nto be an object with property #{prop_name}"
  end
end
expect_array(value, prop_name, expected_type) click to toggle source
# File lib/airborne/request_expectations.rb, line 200
def expect_array(value, prop_name, expected_type)
  expect(value.class).to eq(Array), "Expected #{prop_name}\n to be of type #{expected_type}\n got #{value.class} instead"
end
expect_header_impl(key, content, contains = nil) click to toggle source
# File lib/airborne/request_expectations.rb, line 61
def expect_header_impl(key, content, contains = nil)
  header = headers[key]
  if header
    if contains
      expect(header.downcase).to include(content.downcase)
    else
      expect(header.downcase).to eq(content.downcase)
    end
  else
    fail RSpec::Expectations::ExpectationNotMetError, "Header #{key} not present in the HTTP response"
  end
end
expect_json_impl(expected, actual) click to toggle source
# File lib/airborne/request_expectations.rb, line 74
def expect_json_impl(expected, actual)
  return if nil_optional_hash?(expected, actual)

  actual = actual.to_s if expected.is_a?(Regexp)

  return expect(actual).to match(expected) if property?(expected)

  keys = []

  keys << expected.keys if match_expected?
  keys << actual.keys if match_actual?
  keys = expected.keys & actual.keys if match_none?

  keys.flatten.uniq.each do |prop|
    expected_value  = extract_expected_value(expected, prop)
    actual_value    = extract_actual(actual, prop)

    next expect_json_impl(expected_value, actual_value) if hash?(expected_value) && hash?(actual_value)
    next expected_value.call(actual_value) if expected_value.is_a?(Proc)
    next expect(actual_value.to_s).to match(expected_value) if expected_value.is_a?(Regexp)

    expect(actual_value).to eq(expected_value)
  end
end
expect_json_types_impl(expected, actual) click to toggle source
# File lib/airborne/request_expectations.rb, line 99
def expect_json_types_impl(expected, actual)
  return if nil_optional_hash?(expected, actual)

  @mapper ||= get_mapper

  actual = convert_to_date(actual) if ((expected == :date) || (expected == :date_or_null))

  return expect_type(expected, actual) if expected.is_a?(Symbol)
  return expected.call(actual) if expected.is_a?(Proc)

  keys = []

  keys << expected.keys if match_expected?
  keys << actual.keys if match_actual?
  keys = expected.keys & actual.keys if match_none?

  keys.flatten.uniq.each do |prop|
    type  = extract_expected_type(expected, prop)
    value = extract_actual(actual, prop)
    value = convert_to_date(value) if ((type == :date) || (type == :date_or_null))

    next expect_json_types_impl(type, value) if hash?(type)
    next type.call(value) if type.is_a?(Proc)

    type_string = type.to_s

    if type_string.include?('array_of') && !(type_string.include?('or_null') && value.nil?)
      check_array_types(value, prop, type)
    else
      expect_type(type, value, prop)
    end
  end
end
expect_type(expected_type, value, prop_name = nil) click to toggle source
# File lib/airborne/request_expectations.rb, line 169
def expect_type(expected_type, value, prop_name = nil)
  fail ExpectationError, "Expected type #{expected_type}\nis an invalid type" if @mapper[expected_type].nil?

  insert = prop_name.nil? ? '' : "#{prop_name} to be of type"
  message = "Expected #{insert} #{expected_type}\n got #{value.class} instead"

  expect(@mapper[expected_type].any?{|type| value.is_a?(type)}).to eq(true), message
end
extract_actual(actual, prop) click to toggle source
# File lib/airborne/request_expectations.rb, line 161
def extract_actual(actual, prop)
  begin
    value = actual[prop]
  rescue
    raise ExpectationError, "Expected #{actual.class} #{actual}\nto be an object with property #{prop}"
  end
end
extract_expected_type(expected, prop) click to toggle source
# File lib/airborne/request_expectations.rb, line 152
def extract_expected_type(expected, prop)
  begin
    type = expected[prop]
    type.nil? ? raise : type
  rescue
    raise ExpectationError, "Expectation is expected to contain property: #{prop}"
  end
end
extract_expected_value(expected, prop) click to toggle source
# File lib/airborne/request_expectations.rb, line 143
def extract_expected_value(expected, prop)
  begin
    raise unless expected.keys.include?(prop)
    expected[prop]
  rescue
    raise ExpectationError, "Expectation is expected to contain property: #{prop}"
  end
end
get_mapper() click to toggle source
# File lib/airborne/request_expectations.rb, line 235
def get_mapper
  base_mapper = {
    integer: [Integer],
    array_of_integers: [Integer],
    int: [Integer],
    array_of_ints: [Integer],
    float: [Float, Integer],
    array_of_floats: [Float, Integer],
    string: [String],
    array_of_strings: [String],
    boolean: [TrueClass, FalseClass],
    array_of_booleans: [TrueClass, FalseClass],
    bool: [TrueClass, FalseClass],
    array_of_bools: [TrueClass, FalseClass],
    object: [Hash],
    array_of_objects: [Hash],
    array: [Array],
    array_of_arrays: [Array],
    date: [DateTime],
    null: [NilClass]
  }

  mapper = base_mapper.clone
  base_mapper.each do |key, value|
    mapper[(key.to_s + '_or_null').to_sym] = value + [NilClass]
  end
  mapper
end
hash?(hash) click to toggle source
# File lib/airborne/request_expectations.rb, line 196
def hash?(hash)
  hash.is_a?(Hash) || hash.is_a?(Airborne::OptionalHashTypeExpectations)
end
match_actual?() click to toggle source
# File lib/airborne/request_expectations.rb, line 277
def match_actual?
  Airborne.configuration.match_actual?
end
match_expected?() click to toggle source
# File lib/airborne/request_expectations.rb, line 281
def match_expected?
  Airborne.configuration.match_expected?
end
match_none?() click to toggle source
# File lib/airborne/request_expectations.rb, line 273
def match_none?
  !match_actual? && !match_expected?
end
nil_optional_hash?(expected, hash) click to toggle source
# File lib/airborne/request_expectations.rb, line 192
def nil_optional_hash?(expected, hash)
  expected.is_a?(Airborne::OptionalHashTypeExpectations) && hash.nil?
end
property?(expectation) click to toggle source
# File lib/airborne/request_expectations.rb, line 231
def property?(expectation)
  [String, Regexp, Float, Integer, TrueClass, FalseClass, NilClass, Array].any?{|type| expectation.is_a?(type)}
end
resolve_status(candidate, authority) click to toggle source
# File lib/airborne/request_expectations.rb, line 264
def resolve_status(candidate, authority)
  candidate = Rack::Utils::SYMBOL_TO_STATUS_CODE[candidate] if candidate.is_a?(Symbol)
  case authority
  when String then candidate.to_s
  when Integer then candidate.to_i
  else candidate
  end
end