Class: OpenApi::RSpec::SchemaParser

Inherits:
Object
  • Object
show all
Defined in:
lib/open_api/rspec/schema_parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(openapi_schema, request, response) ⇒ SchemaParser

Returns a new instance of SchemaParser.



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
74
75
76
77
# File 'lib/open_api/rspec/schema_parser.rb', line 8

def initialize(openapi_schema, request, response)
  @openapi_schema = openapi_schema
  @request = request
  @response = response

  url = request.path.gsub(@openapi_schema['basePath'], '')
  url_fragments = url.split('/')

  @openapi_schema['paths'].each do |path, meta|
    path_fragments = path.to_s.split('/')
    next if path_fragments.count != url_fragments.count

    mismatch = false
    @request_path_params = {}
    path_fragments.each_with_index do |a, i|
      if has_documented_param_in_openapi_url_fragments(a)
        openapi_for_http_method = meta[request.method.to_s.downcase.to_s]
        unless openapi_for_http_method
          mismatch = true
          break
        end
        openapi_params = openapi_for_http_method['parameters']
        unless openapi_params
          mismatch = true
          break
        end
        openapi_path_params = openapi_params.select do |path_param|
          path_param['in'].to_s == 'path'
        end
        unless openapi_path_params
          mismatch = true
          break
        end
        meta_param = openapi_path_params.find do |path_param|
          path_param['name'].to_s == openapi_url_fragment_name(a).to_s
        end
        if meta_param
          case meta_param['type'].to_s
          when 'integer'
            if (url_fragments[i] =~ /\d/) != 0
              mismatch = true
              break
            else
              @request_path_params[a.delete('{').delete('}')] = url_fragments[i]
              next
            end
          when 'string'
            @request_path_params[a.delete('{').delete('}')] = url_fragments[i]
            next
          else
            mismatch = true
            break
          end
        else
          mismatch = true
          break
        end
      end

      mismatch = a != url_fragments[i]
      break if mismatch
    end

    next if mismatch

    @schema_for_url = meta

    break
  end
end

Instance Attribute Details

#openapi_schemaObject (readonly)

Returns the value of attribute openapi_schema.



6
7
8
# File 'lib/open_api/rspec/schema_parser.rb', line 6

def openapi_schema
  @openapi_schema
end

#requestObject (readonly)

Returns the value of attribute request.



6
7
8
# File 'lib/open_api/rspec/schema_parser.rb', line 6

def request
  @request
end

#responseObject (readonly)

Returns the value of attribute response.



6
7
8
# File 'lib/open_api/rspec/schema_parser.rb', line 6

def response
  @response
end

#schema_for_urlObject (readonly)

Returns the value of attribute schema_for_url.



6
7
8
# File 'lib/open_api/rspec/schema_parser.rb', line 6

def schema_for_url
  @schema_for_url
end

Instance Method Details

#deep_body_keys(name, hash) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/open_api/rspec/schema_parser.rb', line 167

def deep_body_keys(name, hash)
  if hash['type'] == 'object'
    hash['properties'].flat_map do |p_name, p_hash|
      parent = name.to_s.camelize(:lower).to_s
      sub_keys = deep_body_keys(p_name, p_hash)
      sub_keys.flat_map do |sub|
        "#{parent}##{sub}".to_s
      end
    end
  else
    [name.to_s.camelize(:lower).to_s]
  end
end

#get_deep_keys(hash) ⇒ Object



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/open_api/rspec/schema_parser.rb', line 214

def get_deep_keys(hash)
  return [] if hash.empty?

  hash.flat_map do |k, v|
    if v.is_a? Hash
      parent = k.to_s.camelize(:lower).to_s
      sub_keys = get_deep_keys(v)
      sub_keys.map do |sub|
        "#{parent}##{sub}".to_s
      end
    else
      k.to_s.camelize(:lower).to_s
    end
  end
end

#has_documented_param_in_openapi_url_fragments(fragment) ⇒ Object



79
80
81
# File 'lib/open_api/rspec/schema_parser.rb', line 79

def has_documented_param_in_openapi_url_fragments(fragment)
  (fragment =~ /^{.+}$/) == 0
end

#openapi_body_paramsObject



153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/open_api/rspec/schema_parser.rb', line 153

def openapi_body_params
  schema_for_url_and_request_method_body_parameters.flat_map do |p|
    if p['schema'].present?
      scheme = p['schema']['$ref'].tr('/', ' ')[2..-1].strip.split.map(&:to_s)
      body = @openapi_schema.dig(*scheme)
      body['properties'].flat_map do |k, v|
        deep_body_keys(k, v)
      end
    else
      p['name'].to_s
    end
  end
end

#openapi_form_data_paramsObject



140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/open_api/rspec/schema_parser.rb', line 140

def openapi_form_data_params
  schema_for_url_and_request_method_form_data_parameters.flat_map do |p|
    if p['schema'].present?
      keys = p['schema']['properties'].flat_map do |k, v|
        deep_body_keys(k, v)
      end
      keys.map { |key| "#{p['name']}##{key}" }
    else
      p['name'].to_s
    end
  end
end

#openapi_path_paramsObject



136
137
138
# File 'lib/open_api/rspec/schema_parser.rb', line 136

def openapi_path_params
  schema_for_url_and_request_method_path_parameters.map { |p| p['name'].to_s }
end

#openapi_query_string_paramsObject



132
133
134
# File 'lib/open_api/rspec/schema_parser.rb', line 132

def openapi_query_string_params
  schema_for_url_and_request_method_query_string_parameters.map { |p| p['name'].to_s }
end

#openapi_request_paramsObject



181
182
183
184
185
186
187
188
# File 'lib/open_api/rspec/schema_parser.rb', line 181

def openapi_request_params
  [
    openapi_query_string_params,
    openapi_path_params,
    openapi_form_data_params,
    openapi_body_params
  ].flatten.compact
end

#openapi_required_form_data_paramsObject



190
191
192
193
194
# File 'lib/open_api/rspec/schema_parser.rb', line 190

def openapi_required_form_data_params
  schema_for_url_and_request_method_form_data_parameters
    .select { |p| p['required'] == true }
    .map { |p| p['name'].to_s }
end

#openapi_required_path_paramsObject



196
197
198
199
200
# File 'lib/open_api/rspec/schema_parser.rb', line 196

def openapi_required_path_params
  schema_for_url_and_request_method_path_parameters
    .select { |p| p['required'] == true }
    .map { |p| p['name'].to_s }
end

#openapi_required_query_string_paramsObject



202
203
204
205
206
# File 'lib/open_api/rspec/schema_parser.rb', line 202

def openapi_required_query_string_params
  schema_for_url_and_request_method_query_string_parameters
    .select { |p| p['required'] == true }
    .map { |p| p['name'].to_s }
end

#openapi_url_fragment_name(fragment) ⇒ Object



83
84
85
# File 'lib/open_api/rspec/schema_parser.rb', line 83

def openapi_url_fragment_name(fragment)
  fragment.match(/^{(.+)}$/).captures.first
end

#request_paramsObject



208
209
210
211
212
# File 'lib/open_api/rspec/schema_parser.rb', line 208

def request_params
  valid_params = get_deep_keys(request.params.except('format', 'action', 'controller'))

  valid_params - request_path_params
end

#request_path_paramsObject



87
88
89
# File 'lib/open_api/rspec/schema_parser.rb', line 87

def request_path_params
  @request_path_params.map { |k, _| k.to_s }
end

#schema_for_url_and_request_methodObject



91
92
93
94
95
96
97
# File 'lib/open_api/rspec/schema_parser.rb', line 91

def schema_for_url_and_request_method
  if schema_for_url
    schema_for_url[request.method.to_s.downcase.to_s]
  else
    {}
  end
end

#schema_for_url_and_request_method_and_response_statusObject



123
124
125
126
127
128
129
130
# File 'lib/open_api/rspec/schema_parser.rb', line 123

def schema_for_url_and_request_method_and_response_status
  if schema_for_url_and_request_method['responses']
    schema = schema_for_url_and_request_method['responses'][response.status.to_s]
    schema
  else
    {}
  end
end

#schema_for_url_and_request_method_body_parametersObject



118
119
120
121
# File 'lib/open_api/rspec/schema_parser.rb', line 118

def schema_for_url_and_request_method_body_parameters
  schema_for_url_and_request_method_parameters
    .select { |p| p['in'].to_s == 'body' }
end

#schema_for_url_and_request_method_form_data_parametersObject



113
114
115
116
# File 'lib/open_api/rspec/schema_parser.rb', line 113

def schema_for_url_and_request_method_form_data_parameters
  schema_for_url_and_request_method_parameters
    .select { |p| p['in'].to_s == 'formData' }
end

#schema_for_url_and_request_method_parametersObject



99
100
101
# File 'lib/open_api/rspec/schema_parser.rb', line 99

def schema_for_url_and_request_method_parameters
  schema_for_url_and_request_method['parameters'] || [{}]
end

#schema_for_url_and_request_method_path_parametersObject



108
109
110
111
# File 'lib/open_api/rspec/schema_parser.rb', line 108

def schema_for_url_and_request_method_path_parameters
  schema_for_url_and_request_method_parameters
    .select { |p| p['in'].to_s == 'path' }
end

#schema_for_url_and_request_method_query_string_parametersObject



103
104
105
106
# File 'lib/open_api/rspec/schema_parser.rb', line 103

def schema_for_url_and_request_method_query_string_parameters
  schema_for_url_and_request_method_parameters
    .select { |p| p['in'].to_s == 'query' }
end