fdoc 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -0
- data/README.md +120 -0
- data/Rakefile +7 -0
- data/bin/fdoc_to_html +77 -0
- data/fdoc.gemspec +36 -0
- data/lib/endpoint-schema.yaml +30 -0
- data/lib/fdoc.rb +46 -0
- data/lib/fdoc/endpoint.rb +110 -0
- data/lib/fdoc/endpoint_scaffold.rb +132 -0
- data/lib/fdoc/meta_service.rb +46 -0
- data/lib/fdoc/presenters/endpoint_presenter.rb +152 -0
- data/lib/fdoc/presenters/html_presenter.rb +58 -0
- data/lib/fdoc/presenters/meta_service_presenter.rb +65 -0
- data/lib/fdoc/presenters/response_code_presenter.rb +32 -0
- data/lib/fdoc/presenters/schema_presenter.rb +138 -0
- data/lib/fdoc/presenters/service_presenter.rb +56 -0
- data/lib/fdoc/service.rb +88 -0
- data/lib/fdoc/spec_watcher.rb +48 -0
- data/lib/fdoc/templates/endpoint.html.erb +75 -0
- data/lib/fdoc/templates/meta_service.html.erb +60 -0
- data/lib/fdoc/templates/service.html.erb +54 -0
- data/lib/fdoc/templates/styles.css +63 -0
- data/spec/fdoc/endpoint_scaffold_spec.rb +242 -0
- data/spec/fdoc/endpoint_spec.rb +243 -0
- data/spec/fdoc/presenters/endpoint_presenter_spec.rb +93 -0
- data/spec/fdoc/presenters/service_presenter_spec.rb +18 -0
- data/spec/fdoc/service_spec.rb +63 -0
- data/spec/fixtures/members/add-PUT.fdoc +20 -0
- data/spec/fixtures/members/draft-POST.fdoc +5 -0
- data/spec/fixtures/members/list/GET.fdoc +50 -0
- data/spec/fixtures/members/list/complex-params-GET.fdoc +94 -0
- data/spec/fixtures/members/list/filter-GET.fdoc +60 -0
- data/spec/fixtures/members/members.fdoc.service +11 -0
- data/spec/fixtures/sample_group.fdoc.meta +9 -0
- data/spec/spec_helper.rb +2 -0
- metadata +174 -0
@@ -0,0 +1,242 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fdoc::EndpointScaffold do
|
4
|
+
subject { described_class.new('spec/fixtures/network-GET.fdoc') }
|
5
|
+
let(:action_parameters) { {
|
6
|
+
"scaffold" => true,
|
7
|
+
"description" => "???",
|
8
|
+
"responseCodes" => []
|
9
|
+
} }
|
10
|
+
|
11
|
+
describe "#consume_request" do
|
12
|
+
request_params = {
|
13
|
+
"depth" => 5,
|
14
|
+
"max_connections" => 20,
|
15
|
+
"root_node" => "41EAF42"
|
16
|
+
}
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
subject.request_parameters.should be_empty
|
20
|
+
end
|
21
|
+
|
22
|
+
it "creates properties for top-level keys, and populates them with examples" do
|
23
|
+
subject.consume_request(request_params, true)
|
24
|
+
subject.request_parameters["type"].should == nil
|
25
|
+
subject.request_parameters["properties"].should have(3).keys
|
26
|
+
subject.request_parameters["properties"]["depth"]["type"].should == "integer"
|
27
|
+
subject.request_parameters["properties"]["max_connections"]["example"].should == 20
|
28
|
+
subject.request_parameters["properties"]["root_node"]["type"].should == "string"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "infers boolean types" do
|
32
|
+
bool_params = {
|
33
|
+
"with_cheese" => false,
|
34
|
+
"hold_the_lettuce" => true
|
35
|
+
}
|
36
|
+
subject.consume_request(bool_params)
|
37
|
+
subject.request_parameters["properties"].should have(2).keys
|
38
|
+
subject.request_parameters["properties"]["with_cheese"]["type"].should == "boolean"
|
39
|
+
subject.request_parameters["properties"]["hold_the_lettuce"]["type"].should == "boolean"
|
40
|
+
end
|
41
|
+
|
42
|
+
context "infers formats" do
|
43
|
+
it "detects date-time formats as objects, or as is08601 strings" do
|
44
|
+
datetime_params = {
|
45
|
+
"time_str" => Time.now.iso8601,
|
46
|
+
"time_obj" => Time.now
|
47
|
+
}
|
48
|
+
subject.consume_request(datetime_params)
|
49
|
+
subject.request_parameters["properties"].should have(2).keys
|
50
|
+
subject.request_parameters["properties"]["time_str"]["type"].should == "string"
|
51
|
+
subject.request_parameters["properties"]["time_str"]["format"].should == "date-time"
|
52
|
+
subject.request_parameters["properties"]["time_obj"]["type"].should == "string"
|
53
|
+
subject.request_parameters["properties"]["time_obj"]["format"].should == "date-time"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "detects uri formats" do
|
57
|
+
uri_params = {
|
58
|
+
"sample_uri" => "http://my.example.com"
|
59
|
+
}
|
60
|
+
subject.consume_request(uri_params)
|
61
|
+
subject.request_parameters["properties"].should have(1).keys
|
62
|
+
subject.request_parameters["properties"]["sample_uri"]["type"].should == "string"
|
63
|
+
subject.request_parameters["properties"]["sample_uri"]["format"].should == "uri"
|
64
|
+
end
|
65
|
+
|
66
|
+
it "detects color formats (hex only for now)" do
|
67
|
+
color_params = { "page_color" => "#AABBCC" }
|
68
|
+
subject.consume_request(color_params)
|
69
|
+
subject.request_parameters["properties"]["page_color"]["type"].should == "string"
|
70
|
+
subject.request_parameters["properties"]["page_color"]["format"].should == "color"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "uses strings (not symbols) as keys" do
|
75
|
+
mixed_params = {
|
76
|
+
:with_symbol => false,
|
77
|
+
"with_string" => true
|
78
|
+
}
|
79
|
+
subject.consume_request(mixed_params)
|
80
|
+
subject.request_parameters["properties"].should have(2).keys
|
81
|
+
subject.request_parameters["properties"].should have_key "with_symbol"
|
82
|
+
subject.request_parameters["properties"].should_not have_key :with_symbol
|
83
|
+
subject.request_parameters["properties"].should have_key "with_string"
|
84
|
+
subject.request_parameters["properties"].should_not have_key :with_string
|
85
|
+
end
|
86
|
+
|
87
|
+
it "uses strings (not symbols) for keys of nested hashes" do
|
88
|
+
mixed_params = {
|
89
|
+
"nested_object" => {
|
90
|
+
:with_symbol => false,
|
91
|
+
"with_string" => true
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
subject.consume_request(mixed_params)
|
96
|
+
subject.request_parameters["properties"]["nested_object"]["properties"].keys.sort.should == ["with_string", "with_symbol"]
|
97
|
+
end
|
98
|
+
|
99
|
+
it "uses strings (not symbols) for nested hashes inside arrays" do
|
100
|
+
mixed_params = {
|
101
|
+
"nested_array" => [
|
102
|
+
{
|
103
|
+
:with_symbol => false,
|
104
|
+
"with_string" => true
|
105
|
+
}
|
106
|
+
]
|
107
|
+
}
|
108
|
+
|
109
|
+
subject.consume_request(mixed_params)
|
110
|
+
subject.request_parameters["properties"]["nested_array"]["items"]["properties"].keys.sort.should == ["with_string", "with_symbol"]
|
111
|
+
end
|
112
|
+
|
113
|
+
it "produces a valid JSON schema for the response" do
|
114
|
+
subject.consume_request(request_params)
|
115
|
+
subject.request_parameters["properties"].should have(3).keys
|
116
|
+
JSON::Validator.validate!(subject.request_parameters, request_params).should be_true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#consume_response" do
|
121
|
+
let(:response_params) { {
|
122
|
+
"nodes" => [{
|
123
|
+
"id" => "12941",
|
124
|
+
"name" => "Bobjoe Smith",
|
125
|
+
"linked_to" => [ "111", "121", "999"]
|
126
|
+
}, {
|
127
|
+
"id" => "111",
|
128
|
+
"name" => "Sally",
|
129
|
+
"linked_to" => ["12941"]
|
130
|
+
}, {
|
131
|
+
"id" => "121",
|
132
|
+
"name" => "Captain Smellypants",
|
133
|
+
"linked_to" => ["12941", "999"]
|
134
|
+
}, {
|
135
|
+
"id" => "999",
|
136
|
+
"name" => "Linky McLinkface",
|
137
|
+
"linked_to" => ["12941", "121"]
|
138
|
+
}
|
139
|
+
],
|
140
|
+
"root_node" => {
|
141
|
+
"id" => "12941",
|
142
|
+
"name" => "Bobjoe Smith",
|
143
|
+
"linked_to" => [ "111", "121", "999"]
|
144
|
+
},
|
145
|
+
"version" => 1,
|
146
|
+
"std_dev" => 1.231,
|
147
|
+
"updated_at" => nil
|
148
|
+
} }
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
context "for succesful responses" do
|
153
|
+
before(:each) do
|
154
|
+
subject.should have(0).response_codes
|
155
|
+
end
|
156
|
+
|
157
|
+
it "adds response codes" do
|
158
|
+
subject.consume_response({}, "200 OK")
|
159
|
+
subject.should have(1).response_codes
|
160
|
+
|
161
|
+
subject.consume_response({}, "201 Created")
|
162
|
+
subject.should have(2).response_codes
|
163
|
+
end
|
164
|
+
|
165
|
+
it "does not add duplicate response codes" do
|
166
|
+
subject.consume_response({}, "200 OK")
|
167
|
+
subject.should have(1).response_codes
|
168
|
+
|
169
|
+
subject.consume_response({}, "200 OK")
|
170
|
+
subject.should have(1).response_codes
|
171
|
+
|
172
|
+
subject.response_codes.each do |response|
|
173
|
+
response["description"].should == "???"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
it "creates properties for top-level keys, and populates them with examples" do
|
178
|
+
subject.consume_response(response_params, "200 OK")
|
179
|
+
subject.response_parameters["type"].should == nil
|
180
|
+
subject.response_parameters["properties"].keys.should =~ ["nodes", "root_node", "std_dev", "version", "updated_at"]
|
181
|
+
|
182
|
+
subject.response_parameters["properties"]["nodes"]["type"].should == "array"
|
183
|
+
subject.response_parameters["properties"]["nodes"]["description"].should == "???"
|
184
|
+
subject.response_parameters["properties"]["nodes"]["required"].should == "???"
|
185
|
+
|
186
|
+
subject.response_parameters["properties"]["root_node"]["type"].should == "object"
|
187
|
+
subject.response_parameters["properties"]["root_node"]["description"].should == "???"
|
188
|
+
subject.response_parameters["properties"]["root_node"]["required"].should == "???"
|
189
|
+
|
190
|
+
subject.response_parameters["properties"]["version"]["type"].should == "integer"
|
191
|
+
subject.response_parameters["properties"]["std_dev"]["type"].should == "number"
|
192
|
+
end
|
193
|
+
|
194
|
+
it "populates items in arrays" do
|
195
|
+
subject.consume_response(response_params, "200 OK")
|
196
|
+
subject.response_parameters["properties"]["nodes"]["type"].should == "array"
|
197
|
+
subject.response_parameters["properties"]["nodes"]["items"]["type"].should == "object"
|
198
|
+
subject.response_parameters["properties"]["nodes"]["items"]["properties"].keys.sort.should == [
|
199
|
+
"id", "linked_to","name"]
|
200
|
+
end
|
201
|
+
|
202
|
+
it "turns nil into null" do
|
203
|
+
subject.consume_response(response_params, "200 OK")
|
204
|
+
subject.response_parameters["properties"]["updated_at"]["type"].should == "null"
|
205
|
+
end
|
206
|
+
|
207
|
+
it "uses strings (not symbols) as keys" do
|
208
|
+
mixed_params = {
|
209
|
+
:with_symbol => false,
|
210
|
+
"with_string" => true
|
211
|
+
}
|
212
|
+
subject.consume_response(mixed_params, "200 OK")
|
213
|
+
subject.response_parameters["properties"].should have(2).keys
|
214
|
+
subject.response_parameters["properties"].should have_key "with_symbol"
|
215
|
+
subject.response_parameters["properties"].should_not have_key :with_symbol
|
216
|
+
subject.response_parameters["properties"].should have_key "with_string"
|
217
|
+
subject.response_parameters["properties"].should_not have_key :with_string
|
218
|
+
end
|
219
|
+
|
220
|
+
it "produces a valid JSON schema for the response" do
|
221
|
+
subject.consume_response(response_params, "200 OK")
|
222
|
+
JSON::Validator.validate!(subject.response_parameters, response_params).should be_true
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context "for unsuccessful responses" do
|
227
|
+
it "adds response codes" do
|
228
|
+
subject.should have(0).response_codes
|
229
|
+
subject.consume_response({}, "400 Bad Request", false)
|
230
|
+
subject.should have(1).response_codes
|
231
|
+
subject.consume_response({}, "404 Not Found", false)
|
232
|
+
subject.should have(2).response_codes
|
233
|
+
end
|
234
|
+
|
235
|
+
it "does not modify the response_parameters" do
|
236
|
+
subject.response_parameters.should be_empty
|
237
|
+
subject.consume_response(response_params, "403 Forbidden", false)
|
238
|
+
subject.response_parameters.should be_empty
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fdoc::Endpoint do
|
4
|
+
let(:endpoint) { test_service.open(*fdoc_fixture) }
|
5
|
+
let(:fdoc_fixture) { ["GET", "members/list"] }
|
6
|
+
let (:test_service) { Fdoc::Service.new('spec/fixtures') }
|
7
|
+
subject { endpoint }
|
8
|
+
|
9
|
+
def remove_optional(obj)
|
10
|
+
case obj
|
11
|
+
when Hash
|
12
|
+
res = {}
|
13
|
+
obj.each do |k, v|
|
14
|
+
next if k =~ /optional/
|
15
|
+
res[k] = remove_optional(v)
|
16
|
+
end
|
17
|
+
obj.clear
|
18
|
+
obj.merge!(res)
|
19
|
+
when Array then obj.map { |v| remove_optional(v) }
|
20
|
+
else obj
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#verb" do
|
25
|
+
it "infers the verb from the filename and service" do
|
26
|
+
subject.verb.should == "GET"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#path" do
|
31
|
+
it "infers its path from the filename and service" do
|
32
|
+
subject.path.should == "members/list"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#consume_request" do
|
37
|
+
subject { endpoint.consume_request(params) }
|
38
|
+
let(:params) {
|
39
|
+
{
|
40
|
+
"limit" => 0,
|
41
|
+
"offset" => 100,
|
42
|
+
"order_by" => "name"
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
context "with a well-behaved request" do
|
47
|
+
it "returns true" do
|
48
|
+
subject.should be_true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when the response contains additional properties" do
|
53
|
+
before { params.merge!("extra_goodness" => true) }
|
54
|
+
|
55
|
+
it "should have the unknown keys in the error message" do
|
56
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /extra_goodness/)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when the response contains an unknown enum value" do
|
61
|
+
before { params.merge!("order_by" => "some_stuff") }
|
62
|
+
|
63
|
+
it "should have the value in the error messages" do
|
64
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /some_stuff/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when the response encounters an object of an known type" do
|
69
|
+
before { params.merge!("offset" => "woot") }
|
70
|
+
|
71
|
+
it "should have the Ruby type in the error message" do
|
72
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /String/)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "complex examples" do
|
77
|
+
let(:fdoc_fixture) { ["GET", "/members/list/complex-params"] }
|
78
|
+
let(:params) {
|
79
|
+
{
|
80
|
+
"toplevel_param" => "here",
|
81
|
+
"optional_nested_array" => [
|
82
|
+
{
|
83
|
+
"required_param" => "here",
|
84
|
+
"optional_param" => "here"
|
85
|
+
}
|
86
|
+
],
|
87
|
+
"required_nested_array" => [
|
88
|
+
{
|
89
|
+
"required_param" => "here",
|
90
|
+
"optional_param" => "here",
|
91
|
+
"optional_second_nested_object" => {
|
92
|
+
"required_param" => "here",
|
93
|
+
"optional_param" => "here"
|
94
|
+
}
|
95
|
+
},
|
96
|
+
],
|
97
|
+
"optional_nested_object" => {
|
98
|
+
"required_param" => "here",
|
99
|
+
"optional_param" => "here"
|
100
|
+
},
|
101
|
+
"required_nested_object" => {
|
102
|
+
"required_param" => "here",
|
103
|
+
"optional_param" => "here",
|
104
|
+
"optional_second_nested_object" => {
|
105
|
+
"required_param" => "here",
|
106
|
+
"optional_param" => "here"
|
107
|
+
}
|
108
|
+
},
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
it "is successful" do
|
113
|
+
subject.should be_true
|
114
|
+
end
|
115
|
+
|
116
|
+
context "with no optional keys" do
|
117
|
+
before { remove_optional(params) }
|
118
|
+
|
119
|
+
it "does not contain optional keys" do
|
120
|
+
params.keys.sort.should == ["required_nested_array", "required_nested_object", "toplevel_param"]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "is successful" do
|
124
|
+
subject.should be_true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "non documented field added" do
|
129
|
+
before { params.merge!("non_documented" => true) }
|
130
|
+
it "raises an error" do
|
131
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /non_documented/)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "non document field in an optional array" do
|
136
|
+
before { params["optional_nested_array"][0].merge!("non_documented" => true) }
|
137
|
+
|
138
|
+
it "raises an error" do
|
139
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /non_documented/)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "non document field in a required array" do
|
144
|
+
before { params["required_nested_array"][0].merge!("non_documented" => true) }
|
145
|
+
|
146
|
+
it "raises an error" do
|
147
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /non_documented/)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "non document field in an optional object" do
|
152
|
+
before { params["optional_nested_object"].merge!("non_documented" => true) }
|
153
|
+
|
154
|
+
it "raises an error" do
|
155
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /non_documented/)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "non document field in a required object" do
|
160
|
+
before { params["required_nested_object"].merge!("non_documented" => true) }
|
161
|
+
|
162
|
+
it "raises an error" do
|
163
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /non_documented/)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "non document field in a deeply nested object" do
|
168
|
+
before { params["required_nested_object"]["optional_second_nested_object"].merge!("non_documented" => true) }
|
169
|
+
|
170
|
+
it "raises an error" do
|
171
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /non_documented/)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context "required field in a deeply nested object is missing" do
|
176
|
+
before { params["required_nested_object"]["optional_second_nested_object"].delete("required_param") }
|
177
|
+
|
178
|
+
it "raises an error" do
|
179
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /required_param/)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context "non document field in a deeply nested object in an array" do
|
184
|
+
before { params["required_nested_array"][0]["optional_second_nested_object"].merge!("non_documented" => true) }
|
185
|
+
|
186
|
+
it "raises an error" do
|
187
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /non_documented/)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "required field in a deeply nested object is missing" do
|
192
|
+
before { params["required_nested_array"][0]["optional_second_nested_object"].delete("required_param") }
|
193
|
+
|
194
|
+
it "raises an error" do
|
195
|
+
expect { subject }.to raise_exception(JSON::Schema::ValidationError, /required_param/)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "#consume_response" do
|
202
|
+
good_response_params = {
|
203
|
+
"members" => [
|
204
|
+
{"name" => "Captain Smelly Pants"},
|
205
|
+
{"name" => "Sally Pants"},
|
206
|
+
{"name" => "Joe Shorts"}
|
207
|
+
]
|
208
|
+
}
|
209
|
+
|
210
|
+
it "throws an error when there is no response corresponding to the success-code error" do
|
211
|
+
expect { subject.consume_response(good_response_params, "404 Not Found") }.to raise_exception Fdoc::UndocumentedResponseCode
|
212
|
+
expect { subject.consume_response(good_response_params, "200 OK", false) }.to raise_exception Fdoc::UndocumentedResponseCode
|
213
|
+
end
|
214
|
+
|
215
|
+
context "for successful responses" do
|
216
|
+
it "validates the response parameters against the schema" do
|
217
|
+
subject.consume_response(good_response_params, "200 OK").should be_true
|
218
|
+
end
|
219
|
+
|
220
|
+
context "with unknown keys" do
|
221
|
+
it "throws an error when there an unknown key at the top level" do
|
222
|
+
bad_params = good_response_params.merge({"extra_goodness" => true})
|
223
|
+
expect { subject.consume_response(bad_params, "200 OK") }.to raise_exception JSON::Schema::ValidationError
|
224
|
+
end
|
225
|
+
|
226
|
+
it "throws an error when there is an unknown key a few layers deep" do
|
227
|
+
bad_nested_params = good_response_params.dup
|
228
|
+
bad_nested_params["members"][0]["smelliness"] = "the_max"
|
229
|
+
expect { subject.consume_response(bad_nested_params, "200 OK") }.to raise_exception JSON::Schema::ValidationError
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
context "for unsuccessful responses" do
|
235
|
+
context "when there is a valid success-code response" do
|
236
|
+
it "does not throw an error with bad response parameters" do
|
237
|
+
bad_params = good_response_params.merge({"extra_goodness" => true})
|
238
|
+
subject.consume_response(bad_params, "400 Bad Request", false).should be_true
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|