/
runtime_response.rb
73 lines (56 loc) · 1.61 KB
/
runtime_response.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# frozen_string_literal: true
require 'forwardable'
require_relative 'body_parser'
require_relative 'response_validation/validator'
module OpenapiFirst
class RuntimeResponse
extend Forwardable
def initialize(operation, rack_response)
@operation = operation
@rack_response = rack_response
end
def_delegators :@rack_response, :status, :content_type
def_delegators :@operation, :name
def known?
!!response_definition
end
def known_status?
@operation.response_status_defined?(status)
end
def description
response_definition&.description
end
def body
@body ||= content_type =~ /json/i ? load_json(original_body) : original_body
end
def headers
@headers ||= unpack_response_headers
end
def validate
ResponseValidation::Validator.new(@operation).validate(self)
end
def validate!
error = validate
error&.raise!
end
def response_definition
@response_definition ||= @operation.response_for(status, content_type)
end
private
def original_body
@rack_response.body.join
end
def load_json(string)
MultiJson.load(string)
rescue MultiJson::ParseError
raise ParseError, 'Failed to parse response body as JSON'
end
def unpack_response_headers
return {} if response_definition&.headers.nil?
headers_as_parameters = response_definition.headers.map do |name, definition|
definition.merge('name' => name, 'in' => 'header')
end
OpenapiParameters::Header.new(headers_as_parameters).unpack(@rack_response.header)
end
end
end