Class: Endpoint::Stub

Inherits:
Object
  • Object
show all
Defined in:
lib/endpoint/stub.rb

Overview

Represents a stubbed endpoint that creates, updates, destroys, and stores data based on http requests.

Defined Under Namespace

Classes: Response

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, options) ⇒ Stub



75
76
77
78
79
80
81
82
83
84
# File 'lib/endpoint/stub.rb', line 75

def initialize(model, options)
  @defaults = options[:defaults] || {}

  @model = model
  @site = URI "#{model.site}/#{model.name.underscore.pluralize}"

  @responses = {}

  @records = []
end

Class Attribute Details

.stubsObject (readonly)

Returns the value of attribute stubs.



11
12
13
# File 'lib/endpoint/stub.rb', line 11

def stubs
  @stubs
end

Instance Attribute Details

#defaultsObject (readonly)

Returns the value of attribute defaults.



72
73
74
# File 'lib/endpoint/stub.rb', line 72

def defaults
  @defaults
end

#modelObject (readonly)

Returns the value of attribute model.



73
74
75
# File 'lib/endpoint/stub.rb', line 73

def model
  @model
end

#recordsObject

Returns the value of attribute records.



74
75
76
# File 'lib/endpoint/stub.rb', line 74

def records
  @records
end

Class Method Details

.[](model) ⇒ Object

Gets or creates a stub for the given model. i.e. Endpoint::Stub



58
59
60
# File 'lib/endpoint/stub.rb', line 58

def [](model)
  create_for model or get_for model
end

.clear!Object

Clears all endpoint stubs.



51
52
53
# File 'lib/endpoint/stub.rb', line 51

def clear!
  @stubs = {}
end

.clear_for(model) ⇒ Object

Removes fake endpoint for the given model, meaning any ActiveResource activity on the model will raise errors once again.



41
42
43
# File 'lib/endpoint/stub.rb', line 41

def clear_for(model)
  stubs.delete assure_model model
end

.create_for(model, options = {}, &block) ⇒ Object

Creates a fake endpoint for the given ActiveResource model.

The options hash currently only accepts :defaults, which allows you to define default attribute values for the endpoint to consider on record creation.

If a block is supplied, it will be executed in the context of the new Endpoint::Stub, allowing you to elegantly mock custom responses if needed.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/endpoint/stub.rb', line 22

def create_for(model, options={}, &block)
  model = assure_model model
  return if stubs.keys.include? model
  new_stub = Stub.new(model, options)

  EndpointStub::Config.default_responses.each do |response|
    new_stub.mock_response(*response)
  end

  @stubs[model] = new_stub

  new_stub.instance_eval(&block) if block_given?
  new_stub
end

.get_for(model) ⇒ Object



45
46
47
# File 'lib/endpoint/stub.rb', line 45

def get_for(model)
  @stubs[assure_model(model)]
end

Instance Method Details

#add_default(attrs) ⇒ Object Also known as: add_defaults

Adds default attributes for record creation.



152
153
154
# File 'lib/endpoint/stub.rb', line 152

def add_default(attrs)
  @defaults.merge!(attrs)
end

#add_record(attrs) ⇒ Object

Adds a record to the stub, automatically assigning an id as though it were in a database.



89
90
91
92
93
94
95
96
# File 'lib/endpoint/stub.rb', line 89

def add_record(attrs)
  unless attrs.is_a? Hash
    raise "Endpoint::Stub#add_record expects a Hash. Got #{attrs.class.name}."
  end
  attrs[:id] = current_id
  attrs.merge!(@defaults) { |k,a,b| a }
  @records << attrs
end

#current_idObject

The next id for a record to be assigned to.



132
133
134
# File 'lib/endpoint/stub.rb', line 132

def current_id
  @records.count
end

#last_idObject

The last assigned id.



126
127
128
# File 'lib/endpoint/stub.rb', line 126

def last_id
  @records.count-1
end

#location(id) ⇒ Object

Gets the url location for the given id, as used by RESTful record creation.



145
146
147
148
# File 'lib/endpoint/stub.rb', line 145

def location(id)
  site = @site.to_s[-1] == '/' ? @site.to_s[0...-1] : @site
  "#{site}/#{id}"
end

#mock_response(type, route = '', proc = nil, &block) ⇒ Object

Mock a custom response. Requires a type (http mthod), and route. This method will override any previous responses assigned to the given type and route.

The route is the uri relative to the record’s assigned site and can be formatted similarly to rails routes. Such as: ‘/test/:some_param.json’ or ‘.xml’ to simply imply the model’s site with ‘.xml’ appended.

Lastly, a proc or block is needed to actually handle requests. The proc will be called with the request object, the extracted parameters from the uri, and the stub object so that you can interact with the stubbed records.



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/endpoint/stub.rb', line 172

def mock_response(type, route='', proc=nil, &block)
  proc = block if block_given?

  route = clean_route route

  site = "#{@site.scheme}://#{@site.host}"
  path = @site.path.split(/\/+/).reject(&:empty?)
  if route[0] == '.' && !route.include?('/')
    # This allows passing '.json', etc as the route
    if path.last
      path = path[0...-1] + [path.last+route]
    else
      site += route
    end
  else
    path += route.split('/')
  end

  @responses[type] ||= {}
  @responses[type][route] = Response.new(type, URI.parse(site+'/'+path.join('/')), self, &proc)
  @responses[type][route].activate!
end

#model_nameObject

The name of the represented model in underscore notation.



138
139
140
# File 'lib/endpoint/stub.rb', line 138

def model_name
  @model.name.underscore
end

#record(id) ⇒ Object



120
121
122
# File 'lib/endpoint/stub.rb', line 120

def record(id)
  @records[id.to_i]
end

#remove_record(id) ⇒ Object

Removes the record with the given id from the fake database.



112
113
114
115
116
117
118
# File 'lib/endpoint/stub.rb', line 112

def remove_record(id)
  id = id.to_i
  if @records[id]
    @records[id] = nil
    true
  end
end

#unmock_response(type, route) ⇒ Object

Remove a mocked response with the given type and route.



197
198
199
200
201
202
203
204
# File 'lib/endpoint/stub.rb', line 197

def unmock_response(type, route)
  route = clean_route route
  if @responses[type] && @responses[type][route]
    @responses[type][route].deactivate!
    @responses[type][route] = nil
    true
  end
end

#update_record(id, attrs) ⇒ Object

Updates the record with the given id with the given attributes.



100
101
102
103
104
105
106
107
108
# File 'lib/endpoint/stub.rb', line 100

def update_record(id, attrs)
  unless attrs.is_a? Hash
    raise "Endpoint::Stub#update_record expects a Hash. Got #{attrs.class.name}."
  end
  id = id.to_i
  if @records[id]
    @records[id].merge! attrs
  end
end