class Acfs::Stub

Global handler for stubbing resources.

Constants

ACTIONS

Attributes

opts[R]

Public Class Methods

new(opts) click to toggle source
# File lib/acfs/stub.rb, line 13
def initialize(opts)
  @opts = opts

  @opts[:with].stringify_keys! if @opts[:with].is_a? Hash
  @opts[:return].stringify_keys! if @opts[:return].is_a? Hash

  if @opts[:return].is_a?(Array) # rubocop:disable Style/GuardClause
    @opts[:return].map! {|h| h.stringify_keys! if h.is_a? Hash }
  end
end

Private Class Methods

allow_requests=(allow) click to toggle source
# File lib/acfs/stub.rb, line 113
def allow_requests=(allow)
  @allow_requests = allow ? true : false
end
allow_requests?() click to toggle source
# File lib/acfs/stub.rb, line 117
def allow_requests?
  @allow_requests ||= false
end
clear(klass = nil) click to toggle source

Clear all stubs.

# File lib/acfs/stub.rb, line 135
def clear(klass = nil)
  klass.nil? ? stubs.clear : stubs[klass].try(:clear)
end
disable() click to toggle source
# File lib/acfs/stub.rb, line 129
def disable
  @enabled = false
end
enable() click to toggle source
# File lib/acfs/stub.rb, line 125
def enable
  @enabled = true
end
enabled?() click to toggle source
# File lib/acfs/stub.rb, line 121
def enabled?
  @enabled ||= false
end
pretty_print() click to toggle source
# File lib/acfs/stub.rb, line 177
def pretty_print
  out = ''
  stubs.each do |klass, actions|
    out << '  ' << klass.name << ":\n"
    actions.each do |action, stubs|
      stubs.each do |stub|
        out << "    #{action}"
        out << " with #{stub.opts[:with].inspect}" if stub.opts[:with]
        if stub.opts[:return]
          out << " and return #{stub.opts[:return].inspect}"
        end
        if stub.opts[:raise]
          out << " and raise #{stub.opts[:raise].inspect}"
        end
        out << "\n"
      end
    end
  end
  out
end
resource(klass, action, opts = {}, &_block) click to toggle source

Stub a resource with given handler block. An already created handler for same resource class will be overridden.

# File lib/acfs/stub.rb, line 100
def resource(klass, action, opts = {}, &_block)
  action = action.to_sym
  unless ACTIONS.include? action
    raise ArgumentError.new "Unknown action `#{action}`."
  end

  Stub.new(opts).tap do |stub|
    stubs[klass]         ||= {}
    stubs[klass][action] ||= []
    stubs[klass][action] << stub
  end
end
stub_for(op) click to toggle source
# File lib/acfs/stub.rb, line 143
def stub_for(op)
  return false unless (classes = stubs[op.resource])
  return false unless (stubs = classes[op.action])

  accepted_stubs = stubs.select {|stub| stub.accept? op }

  if accepted_stubs.size > 1
    raise AmbiguousStubError.new stubs: accepted_stubs, operation: op
  end

  accepted_stubs.first
end
stubbed(op) click to toggle source
# File lib/acfs/stub.rb, line 156
      def stubbed(op)
        stub = stub_for op
        unless stub
          return false if allow_requests?

          raise RealRequestsNotAllowedError.new <<~ERROR
            No stub found for `#{op.action}' on `#{op.resource.name}' \
            with params `#{op.full_params.inspect}', data `#{op.data.inspect}' \
            and id `#{op.id}'.

            Available stubs:
            #{pretty_print}
          ERROR
        end

        stub.call op
        true
      end
stubs() click to toggle source
# File lib/acfs/stub.rb, line 139
def stubs
  @stubs ||= {}
end

Public Instance Methods

accept?(op) click to toggle source
# File lib/acfs/stub.rb, line 24
def accept?(op)
  return opts[:with].call(op) if opts[:with].respond_to?(:call)

  params = op.full_params.stringify_keys
  data   = op.data.stringify_keys
  with   = opts[:with]

  return true if with.nil?

  case opts.fetch(:match, :inclusion)
    when :legacy
      return true if with.empty? && params.empty? && data.empty?
      if with.reject {|_, v| v.nil? } == params.reject {|_, v| v.nil? }
        return true
      end
      if with.reject {|_, v| v.nil? } == data.reject {|_, v| v.nil? }
        return true
      end

      false
    when :inclusion
      with.each_pair.all? do |k, v|
        (params.key?(k) && params[k] == v) || (data.key?(k) && data[k] == v)
      end
  end
end
call(op) click to toggle source
# File lib/acfs/stub.rb, line 61
def call(op)
  calls << op

  err  = opts[:raise]
  data = opts[:return]

  if err
    raise_error op, err, opts[:return]
  elsif data
    data = data.call(op) if data.respond_to?(:call)

    response = Acfs::Response.new op.request,
      headers: opts[:headers] || {},
      status: opts[:status] || 200,
      data: data || {}
    op.call data, response
  else
    raise ArgumentError.new 'Unsupported stub.'
  end
end
called?(count = nil) click to toggle source
# File lib/acfs/stub.rb, line 55
def called?(count = nil)
  count = count.count if count.respond_to?(:count)

  count.nil? ? calls.any? : calls.size == count
end
calls() click to toggle source
# File lib/acfs/stub.rb, line 51
def calls
  @calls ||= []
end

Private Instance Methods

raise_error(op, name, data) click to toggle source
# File lib/acfs/stub.rb, line 84
def raise_error(op, name, data)
  raise name if name.is_a? Class

  data.stringify_keys! if data.respond_to?(:stringify_keys!)

  op.handle_failure ::Acfs::Response.new(
    op.request,
    status: Rack::Utils.status_code(name),
    data: data
  )
end