lib/swagalicious/example_helpers.rb in swagalicious-0.5.3 vs lib/swagalicious/example_helpers.rb in swagalicious-1.0.0
- old
+ new
@@ -1,26 +1,117 @@
require "faraday"
require "faraday/rack"
require "rack"
+require "json"
require "oj"
+require "ox"
+require "yaml"
+require "active_support/core_ext/hash/indifferent_access"
require_relative "response_validator"
class Swagalicious
module ExampleHelpers
include Rack::Test::Methods
+ def self.raise_invalid_response(response:, request:, message:)
+ raise InvalidResponseTypeError.new(
+ headers: response.headers,
+ message: message,
+ request: request,
+ response: response,
+ status: response.status,
+ )
+ end
+
+ class InvalidResponseTypeError < RuntimeError
+ attr_reader :status, :_message, :headers, :response, :request
+
+ def initialize(status:, message:, headers:, response:, request:)
+ @headers = headers
+ @_message = message
+ @request = request
+ @response = response
+ @status = status
+ end
+
+ def inspect
+ JSON.pretty_generate(to_h)
+ end
+
+ def to_h
+ hash = {
+ headers: headers.to_h,
+ message: _message,
+ request: request.slice(:verb, :path, :headers),
+ status: status,
+ }
+
+ if parsed_body = Parser.new(request: request, response: response).parse(raise_on_invalid: false)
+ hash[:parsed_response] = parsed_body
+ end
+
+ hash
+ end
+
+ def to_s
+ "Received unexpected or unparseable response with status code #{status} for #{request[:verb].upcase} #{request[:path]}: #{_message}"
+ end
+
+ def message
+ inspect
+ end
+ end
+
class MockResponse
attr_reader :body, :status, :headers
def initialize(file_name)
@body = File.read(File.expand_path("#{File.join(ENV["MOCK_PATH"], file_name)}.json", __FILE__))
@status = 200
@headers = {}
end
end
+ class Parser
+ attr_accessor :body
+ attr_reader :content_type, :request, :response
+
+ def initialize(response:, request:)
+ @content_type = response.headers["Content-Type"]
+ @body = response.body
+ @response = response
+ @request = request
+ end
+
+ def parse(raise_on_invalid: true)
+ # Redirections shouldnt be parsed
+ if response.status >= 300 && response.status <= 399
+ return
+ end
+
+ case content_type
+ when /json/
+ self.body = "{}" if self.body.empty?
+
+ Oj.load(self.body, symbol_keys: true)
+ when /ya?ml/
+ body = "---" if self.body.empty?
+
+ (YAML.load(self.body) || {}).with_indifferent_access
+ when /xml/
+ (Ox.load(self.body, mode: :hash_no_attrs) || {}).with_indifferent_access
+ when "", nil
+ self.body
+ else
+ return unless raise_on_invalid
+
+ Swagalicious::ExampleHelpers.raise_invalid_response(response: response, request: request, message: "Invalid Content-Type header #{response.headers["Content-Type"]}")
+ end
+ end
+ end
+
def app
@app ||= if defined?(Rails)
Rails.application
elsif Rack::RELEASE >= "3.0.0"
Rack::Builder.parse_file("config.ru")
@@ -50,13 +141,12 @@
req.headers = request[:headers]
req.body = request[:payload]
end
end
- body = response.body
- body = "{}" if body.empty?
+ Swagalicious::ExampleHelpers.raise_invalid_response(response: response, request: request, message: "Received unexpected response code") unless response.status.to_s == metadata[:response][:code].to_s
- @body = Oj.load(body, symbol_keys: true)
+ @body = Parser.new(request: request, response: response).parse
metadata[:paths] ||= []
metadata[:paths] << request[:path]
metadata[:response][:requestBody] ||= {}