class NOMS::HttpClient::RestMock

Public Class Methods

new(delegator) click to toggle source
# File lib/noms/httpclient.rb, line 180
def initialize(delegator)
    @delegator = delegator
    @data = { }
    @opt = @delegator.opt
    @opt['return-hash'] = true unless @opt.has_key? 'return-hash'
    self.dbg "Initialized with options: #{opt.inspect}"
end

Public Instance Methods

all_data() click to toggle source
# File lib/noms/httpclient.rb, line 221
def all_data
    maybe_read
    @data
end
allow_partial_updates() click to toggle source
# File lib/noms/httpclient.rb, line 188
def allow_partial_updates
    @delegator.allow_partial_updates
end
config_key() click to toggle source
# File lib/noms/httpclient.rb, line 192
def config_key
    @delegator.config_key
end
default_content_type() click to toggle source
# File lib/noms/httpclient.rb, line 196
def default_content_type
    @delegator.default_content_type
end
do_request(opt={}) click to toggle source
# File lib/noms/httpclient.rb, line 226
def do_request(opt={})
    maybe_read
    method = [:GET, :PUT, :POST, :DELETE].find do |m|
        opt.has_key? m
    end
    method ||= :GET
    opt[method] ||= ''

    rel_uri = opt[method]
    dbg "relative URI is #{rel_uri}"
    url = URI.parse(myconfig 'url')
    unless opt[method] == ''
        url.path = rtrim(url.path) + '/' + ltrim(rel_uri) unless opt[:absolute]
    end
    url.query = opt[:query] if opt.has_key? :query
    dbg "url=#{url}"

    handled = handle_mock(method, url, opt)
    return handled if handled

    # We're not mocking absolute URLs specifically
    case method

    when :PUT
        # Upsert - whole objects only
        dbg "Processing PUT"
        @data[url.host] ||= { }
        collection_path_components = url.path.split('/')
        id = collection_path_components.pop
        collection_path = collection_path_components.join('/')
        @data[url.host][collection_path] ||= [ ]
        object_index =
            @data[url.host][collection_path].index { |el| el[id_field(collection_path)] == id }
        if object_index.nil?
            if allow_put_to_create
                object = opt[:body].merge({ id_field(collection_path) => id })
                dbg "creating in collection #{collection_path}: #{object.inspect}"
                @data[url.host][collection_path] << opt[:body].merge({ id_field(collection_path) => id })
            else
                dbg "not creating in collection #{collection_path}: #{id} (allow_put_to_create is false)"
                raise NOMS::Error, "There is no resource at this location"
            end
        else
            if allow_partial_updates
                object = @data[url.host][collection_path][object_index].merge(opt[:body])
                dbg "updating in collection #{collection_path}: to => #{object.inspect}"
            else
                object = opt[:body].merge({ id_field(collection_path) => id })
                dbg "replacing in collection #{collection_path}: #{object.inspect}"
            end
            @data[url.host][collection_path][object_index] = object
        end
        maybe_save
        object

    when :POST
        # Insert/Create
        dbg "Processing POST"
        @data[url.host] ||= { }
        collection_path = url.path
        @data[url.host][collection_path] ||= [ ]
        id = opt[:body][id_field(collection_path)] || opt[:body].object_id
        object = opt[:body].merge({id_field(collection_path) => id})
        dbg "creating in collection #{collection_path}: #{object.inspect}"
        @data[url.host][collection_path] << object
        maybe_save
        object

    when :DELETE
        dbg "Processing DELETE"
        if @data[url.host]
            if @data[url.host].has_key? url.path
                # DELETE on a collection
                @data[url.host].delete url.path
                true
            elsif @data[url.host].has_key? url.path.split('/')[0 .. -2].join('/')
                # DELETE on an object by Id
                path_components = url.path.split('/')
                id = path_components.pop
                collection_path = path_components.join('/')
                object_index = @data[url.host][collection_path].index { |obj| obj[id_field(collection_path)] == id }
                if object_index.nil?
                    raise NOMS::Error, "Error (#{self.class} making #{config_key} request " +
                        "(404): No such object id (#{id_field(collection_path)} == #{id}) in #{collection_path}"
                else
                    @data[url.host][collection_path].delete_at object_index
                end
                maybe_save
                true
            else
                raise NOMS::Error, "Error (#{self.class}) making #{config_key} request " +
                    "(404): No objects at location or in collection #{url.path}"
            end
        else
            raise NOMS::Error, "Error (#{self.class}) making #{config_key} request " +
                "(404): No objects on #{url.host}"
        end

    when :GET
        dbg "Performing GET"
        if @data[url.host]
            dbg "we store data for #{url.host}"
            if @data[url.host].has_key? url.path
                # GET on a collection
                # TODO get on the query string
                dbg "returning collection #{url.path}"
                @data[url.host][url.path]
            elsif @data[url.host].has_key? url.path.split('/')[0 .. -2].join('/')
                # GET on an object by Id
                path_components = url.path.split('/')
                id = path_components.pop
                collection_path = path_components.join('/')
                dbg "searching in collection #{collection_path}: id=#{id}"
                dbg "data: #{@data[url.host][collection_path].inspect}"
                object = @data[url.host][collection_path].find { |obj| obj[id_field(collection_path)] == id }
                if object.nil?
                    raise NOMS::Error, "Error (#{self.class} making #{config_key} request " +
                        "(404): No such object id (#{id_field(collection_path)} == #{id}) in #{collection_path}"
                end
                dbg "   found #{object.inspect}"
                object
            else
                raise NOMS::Error, "Error (#{self.class}) making #{config_key} request " +
                    "(404): No objects at location or in collection #{url.path}"
            end
        else
            raise NOMS::Error, "Error (#{self.class}) making #{config_key} request " +
                "(404): No objects on #{url.host}"
        end
    end
end
id_field(dummy=nil) click to toggle source
# File lib/noms/httpclient.rb, line 205
def id_field(dummy=nil)
    'id'
end
ignore_content_type() click to toggle source
# File lib/noms/httpclient.rb, line 200
def ignore_content_type
    @delegator.ignore_content_type
end
maybe_read() click to toggle source
# File lib/noms/httpclient.rb, line 215
def maybe_read
    if @@mockdata and File.exist? @@mockdata
        @data = File.open(@@mockdata, 'r') { |fh| JSON.load(fh) }
    end
end
maybe_save() click to toggle source
# File lib/noms/httpclient.rb, line 209
def maybe_save
    if @@mockdata
        File.open(@@mockdata, 'w') { |fh| fh << JSON.pretty_generate(@data) }
    end
end