12
12
13
13
let ( :controller_class ) { described_class }
14
14
15
+ def get_ref ( ref )
16
+ name = ref . split ( '#/definitions/' ) [ 1 ] . to_sym
17
+ swagger [ :definitions ] [ name ]
18
+ end
19
+
20
+ def resolve_refs ( schema )
21
+ if schema [ '$ref' ]
22
+ return get_ref ( schema [ '$ref' ] )
23
+ end
24
+ schema
25
+ end
26
+
15
27
def swagger_response_for ( path , code = 200 , method = 'get' )
16
- swagger [ :paths ] [ path ] [ method ] [ :responses ] [ code ]
28
+ response = swagger [ :paths ] [ path ] [ method ] [ :responses ] [ code ]
29
+ response [ :schema ] = resolve_refs ( response [ :schema ] )
30
+ response
17
31
end
18
32
19
33
def swagger_params_for ( path , method = 'get' )
@@ -32,6 +46,64 @@ def swagger_param_by_name(param_name, path, method='get')
32
46
33
47
34
48
49
+
50
+ #
51
+ # Matcher to validate the hierarchy of fields described in an internal 'returns' object (without checking their type)
52
+ #
53
+ # For example, code such as:
54
+ # returns_obj = Apipie.get_resource_description(...)._methods.returns.detect{|e| e.code=200})
55
+ # expect(returns_obj).to match_param_structure([:pet_name, :animal_type, :pet_measurements => [:weight, :height]])
56
+ #
57
+ # will verify that the payload structure described for the response of return code 200 is:
58
+ # {
59
+ # "pet_name": <any>,
60
+ # "animal_type": <any>,
61
+ # "pet_measurements": {
62
+ # "weight": <any>,
63
+ # "height": <any>
64
+ # }
65
+ # }
66
+ #
67
+ #
68
+ RSpec ::Matchers . define :match_field_structure do |expected |
69
+ @last_message = nil
70
+
71
+ match do |actual |
72
+ deep_match? ( actual , expected )
73
+ end
74
+
75
+ def deep_match? ( actual , expected , breadcrumb = [ ] )
76
+ num = 0
77
+ for pdesc in expected do
78
+ if pdesc . is_a? Symbol
79
+ return false unless fields_match? ( actual . params_ordered [ num ] , pdesc , breadcrumb )
80
+ elsif pdesc . is_a? Hash
81
+ return false unless fields_match? ( actual . params_ordered [ num ] , pdesc . keys [ 0 ] , breadcrumb )
82
+ return false unless deep_match? ( actual . params_ordered [ num ] . validator , pdesc . values [ 0 ] , breadcrumb + [ pdesc . keys [ 0 ] ] )
83
+ end
84
+ num +=1
85
+ end
86
+ @fail_message = "expected property count#{ breadcrumb == [ ] ? '' : ' of ' + ( breadcrumb ) . join ( '.' ) } (#{ actual . params_ordered . count } ) to be #{ num } "
87
+ actual . params_ordered . count == num
88
+ end
89
+
90
+ def fields_match? ( param , expected_name , breadcrumb )
91
+ return false unless have_field? ( param , expected_name , breadcrumb )
92
+ @fail_message = "expected #{ ( breadcrumb + [ param . name ] ) . join ( '.' ) } to eq #{ ( breadcrumb + [ expected_name ] ) . join ( '.' ) } "
93
+ param . name . to_s == expected_name . to_s
94
+ end
95
+
96
+ def have_field? ( field , expected_name , breadcrumb )
97
+ @fail_message = "expected property #{ ( breadcrumb +[ expected_name ] ) . join ( '.' ) } "
98
+ !field . nil?
99
+ end
100
+
101
+ failure_message do |actual |
102
+ @fail_message
103
+ end
104
+ end
105
+
106
+
35
107
describe PetsController do
36
108
37
109
@@ -57,7 +129,7 @@ def swagger_param_by_name(param_name, path, method='get')
57
129
schema = response [ :schema ]
58
130
expect ( schema [ :type ] ) . to eq ( "array" )
59
131
60
- a_schema = schema [ :items ]
132
+ a_schema = resolve_refs ( schema [ :items ] )
61
133
expect ( a_schema ) . to have_field ( :pet_name , 'string' , { :description => 'Name of pet' , :required => false } )
62
134
expect ( a_schema ) . to have_field ( :animal_type , 'string' , { :description => 'Type of pet' , :enum => [ 'dog' , 'cat' , 'iguana' , 'kangaroo' ] } )
63
135
end
0 commit comments