class Endpoint::Stub
Represents a stubbed endpoint that creates, updates, destroys, and stores data based on http requests.
Attributes
Public Class Methods
Gets or creates a stub for the given model. i.e. Endpoint::Stub
# File lib/endpoint/stub.rb, line 63 def [](model) create_for model or get_for model end
Clears all endpoint stubs.
# File lib/endpoint/stub.rb, line 56 def clear! @stubs = {} end
# File lib/endpoint/stub.rb, line 50 def clear_all_records! @stubs.values.each(&:clear_records!) end
Removes fake endpoint for the given model, meaning any ActiveResource activity on the model will raise errors once again.
# File lib/endpoint/stub.rb, line 42 def clear_for(model) stubs.delete assure_model model end
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.
# File lib/endpoint/stub.rb, line 23 def create_for(model, options={}, &block) model = assure_model model return if stubs.keys.map(&:name).include? model.name 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
# File lib/endpoint/stub.rb, line 67 def each(&block) @stubs.each(&block) end
# File lib/endpoint/stub.rb, line 46 def get_for(model) @stubs[assure_model(model)] end
# File lib/endpoint/stub.rb, line 85 def initialize(model, options) @defaults = options[:defaults] || {} @model = model @site = URI "#{model.site}/#{model.name.split('::').last.underscore.pluralize}" @responses = {} @records = [] end
Private Class Methods
# File lib/endpoint/stub.rb, line 72 def assure_model(model) if model.ancestors.include? ActiveResource::Base model else Kernel.const_get model end end
Public Instance Methods
Adds default attributes for record creation.
# File lib/endpoint/stub.rb, line 171 def add_default(attrs) @defaults.merge!(attrs) end
Adds a record to the stub, automatically assigning an id as though it were in a database.
# File lib/endpoint/stub.rb, line 99 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 attrs end
Clear all records in this stub.
# File lib/endpoint/stub.rb, line 133 def clear_records! @records = [] end
The next id for a record to be assigned to.
# File lib/endpoint/stub.rb, line 151 def current_id @records.count end
Removes all overrides, reducing each response to their originals.
# File lib/endpoint/stub.rb, line 234 def drop_overrides! @responses.each do |type, responses| responses.each do |route, response| response.drop_overrides! end end end
The last assigned id.
# File lib/endpoint/stub.rb, line 145 def last_id @records.count-1 end
Gets the url location for the given id, as used by RESTful record creation.
# File lib/endpoint/stub.rb, line 164 def location(id) site = @site.to_s[-1] == '/' ? @site.to_s[0...-1] : @site "#{site}/#{id}" end
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.
# File lib/endpoint/stub.rb, line 191 def mock_response(type, route='', proc=nil, &block) proc = block if block_given? route = clean_route route @responses[type] ||= {} @responses[type][route].deactivate! if @responses[type][route] @responses[type][route] = Response.new(type, prepare_uri(type, route), self, &proc) @responses[type][route].activate! end
The name of the represented model in underscore notation.
# File lib/endpoint/stub.rb, line 157 def model_name @model.name.underscore end
Overrides all currently assigned responses. Will not have any effect on responses mocked after this method is called.
# File lib/endpoint/stub.rb, line 224 def override_all(&block) @responses.each do |type, responses| responses.each do |route, response| response.add_to_stack(&block) end end end
Same thing as mock_response
, except it will not overWRITE existing mocks. Instead, it allows you to call a block inside of your response which will act as a 'super' call, invoking previously defined responses. Yielding inside a top-level response will give you an empty hash, so no nil related issues should arrise (unless of course the super-response returns nil, which it shouldn't).
Also note that this does not re-activate a deactivated response.
# File lib/endpoint/stub.rb, line 210 def override_response(type, route, proc=nil, &block) proc = block if block_given? route = clean_route route if @responses[type] and @responses[type][route] @responses[type][route].add_to_stack(&proc) else mock_response(type, route, proc) end end
Get the record at the given id. Accepts strings as well as ints.
# File lib/endpoint/stub.rb, line 139 def record(id) @records[id.to_i] end
Removes the record with the given id from the fake database.
# File lib/endpoint/stub.rb, line 123 def remove_record(id) id = id.to_i if @records[id] @records[id] = nil true end end
Remove a mocked response with the given type and route.
# File lib/endpoint/stub.rb, line 244 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
Updates the record with the given id with the given attributes.
# File lib/endpoint/stub.rb, line 111 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
Private Instance Methods
# File lib/endpoint/stub.rb, line 272 def clean_route(route) route = route[1..-1] if route[0] == '/' route = route[0...-1] if route[-1] == '/' route end
# File lib/endpoint/stub.rb, line 254 def prepare_uri(type, route) site = "#{@site.scheme}://#{@site.host}:#{@site.port}" 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 URI.parse site+'/'+path.join('/') end