rswag/lib/swagger_rails/testing/example_builder.rb
2016-02-25 09:47:09 -08:00

86 lines
2.4 KiB
Ruby

module SwaggerRails
class ExampleBuilder
attr_reader :expected_status
def initialize(path_template, http_method, swagger)
@path_template = path_template
@http_method = http_method
@swagger = swagger
@swagger_operation = find_swagger_operation!
@expected_status = find_swagger_success_status!
@param_values = {}
end
def expect(status)
@expected_status = status
end
def set(param_values)
@param_values.merge!(param_values.stringify_keys)
end
def path
@path_template.dup.tap do |template|
template.prepend(@swagger['basePath'].presence || '')
path_params = param_values_for('path')
path_params.each { |name, value| template.sub!("\{#{name}\}", value) }
end
end
def params
query_params = param_values_for('query')
body_params = param_values_for('body')
query_params.merge(body_params.values.first || {})
end
def headers
param_values_for('header')
end
private
def find_swagger_operation!
find_swagger_item!('paths', @path_template, @http_method)
end
def find_swagger_success_status!
path_keys = [ 'paths', @path_template, @http_method, 'responses' ]
responses = find_swagger_item!(*path_keys)
key = responses.keys.find { |k| k.start_with?('2') }
key ? key.to_i : (raise MetadataError.new(path_keys.concat('2xx')))
end
def find_swagger_item!(*path_keys)
item = @swagger
path_keys.each do |key|
item = item[key] || (raise MetadataError.new(*path_keys))
end
item
end
def param_values_for(location)
params = (@swagger_operation['parameters'] || []).select { |p| p['in'] == location }
Hash[params.map { |param| [ param['name'], value_for(param) ] }]
end
def value_for(param)
return @param_values[param['name']] if @param_values.has_key?(param['name'])
return param['default'] unless param['in'] == 'body'
schema_for(param['schema'])['example']
end
def schema_for(schema_or_ref)
return schema_or_ref if schema_or_ref['$ref'].nil?
@swagger['definitions'][schema_or_ref['$ref'].sub('#/definitions/', '')]
end
end
class MetadataError < StandardError
def initialize(*path_keys)
path = path_keys.map { |key| "['#{key}']" }.join('')
super("Swagger document is missing expected metadata at #{path}")
end
end
end