mirage 2.4.2 → 3.0.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.simplecov +6 -0
- data/Gemfile +11 -3
- data/Gemfile.lock +41 -14
- data/VERSION +1 -1
- data/features/client/clear.feature +41 -50
- data/features/client/configure.feature +2 -2
- data/features/client/put.feature +17 -6
- data/features/client/requests.feature +5 -9
- data/features/client/start.feature +19 -11
- data/features/client/stop.feature +10 -44
- data/features/server/commandline_interface/start.feature +2 -14
- data/features/server/commandline_interface/stop.feature +6 -4
- data/features/server/logging.feature +2 -2
- data/features/server/prime.feature +11 -66
- data/features/server/requests/delete.feature +34 -33
- data/features/server/requests/get.feature +21 -18
- data/features/server/save_and_revert.feature +24 -11
- data/features/server/templates/delete.feature +29 -32
- data/features/server/templates/get.feature +44 -25
- data/features/server/templates/put/put.feature +55 -78
- data/features/server/templates/put/put_with_substitutions.feature +12 -32
- data/features/server/templates/put/required_content.feature +118 -0
- data/features/step_definitions/my_steps.rb +51 -6
- data/features/support/env.rb +1 -1
- data/features/support/hooks.rb +2 -5
- data/{lib/mirage/client → features/support}/web.rb +14 -3
- data/lib/mirage/client.rb +5 -2
- data/lib/mirage/client/client.rb +22 -129
- data/lib/mirage/client/request.rb +25 -0
- data/lib/mirage/client/requests.rb +13 -0
- data/lib/mirage/client/runner.rb +4 -4
- data/lib/mirage/client/template.rb +108 -0
- data/lib/mirage/client/template_configuration.rb +22 -0
- data/lib/mirage/client/templates.rb +26 -0
- data/mirage.gemspec +42 -22
- data/mirage_server.rb +1 -135
- data/rakefile +22 -7
- data/server/app.rb +4 -0
- data/server/binary_data_checker.rb +15 -0
- data/server/helpers.rb +28 -0
- data/server/mock_response.rb +140 -58
- data/server/server.rb +167 -0
- data/spec/{cli_bridge_spec.rb → client/cli_bridge_spec.rb} +15 -11
- data/spec/client/client_spec.rb +139 -0
- data/spec/client/request_spec.rb +52 -0
- data/spec/client/requests_spec.rb +10 -0
- data/spec/{runner_spec.rb → client/runner_spec.rb} +3 -3
- data/spec/client/template_configuration_spec.rb +32 -0
- data/spec/client/template_spec.rb +241 -0
- data/spec/client/templates_spec.rb +79 -0
- data/spec/resources/binary.file +0 -0
- data/spec/server/binary_data_checker_spec.rb +22 -0
- data/spec/server/helpers_spec.rb +34 -0
- data/spec/server/mock_response_spec.rb +526 -0
- data/spec/server/server_spec.rb +132 -0
- data/spec/spec_helper.rb +61 -2
- data/test.html +12 -0
- data/test.rb +20 -17
- data/todo.lst +2 -0
- data/views/index.haml +22 -0
- data/views/response.haml +24 -0
- metadata +134 -49
- data/features/server/templates/put/put_as_default.feature +0 -42
- data/features/server/templates/put/put_with_delay.feature +0 -8
- data/features/server/templates/put/put_with_pattern.feature +0 -80
- data/lib/mirage/client/response.rb +0 -29
- data/spec/client_spec.rb +0 -38
- data/views/index.erb +0 -28
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mirage/client'
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
describe Mirage::TemplateConfiguration do
|
7
|
+
TemplateConfiguration = Mirage::TemplateConfiguration
|
8
|
+
it 'should have defaults' do
|
9
|
+
configuration = TemplateConfiguration.new
|
10
|
+
assert_defaults configuration
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should be reset' do
|
14
|
+
configuration = TemplateConfiguration.new
|
15
|
+
configuration.http_method = :post
|
16
|
+
configuration.status = 202
|
17
|
+
configuration.delay = 3
|
18
|
+
configuration.default = true
|
19
|
+
configuration.content_type = "text/xml"
|
20
|
+
|
21
|
+
configuration.reset
|
22
|
+
assert_defaults configuration
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert_defaults configuration
|
26
|
+
configuration.http_method.should == :get
|
27
|
+
configuration.status.should == 200
|
28
|
+
configuration.delay.should == 0
|
29
|
+
configuration.default.should == false
|
30
|
+
configuration.content_type.should == "text/plain"
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mirage/client'
|
3
|
+
|
4
|
+
|
5
|
+
describe Mirage::Template do
|
6
|
+
Template = Mirage::Template
|
7
|
+
Request = Mirage::Request
|
8
|
+
|
9
|
+
describe 'get' do
|
10
|
+
it 'should load a template given its id' do
|
11
|
+
endpoint = "endpoint"
|
12
|
+
id = 1
|
13
|
+
requests_url = 'request_url'
|
14
|
+
value = "Hello"
|
15
|
+
default = false
|
16
|
+
delay = 1.2
|
17
|
+
content_type = "application/json"
|
18
|
+
status = 201
|
19
|
+
|
20
|
+
|
21
|
+
required_parameters = {"name" => 'joe'}
|
22
|
+
required_body_content = %{content}
|
23
|
+
required_headers = {"header" => 'value'}
|
24
|
+
http_method = "get"
|
25
|
+
|
26
|
+
template_json = {
|
27
|
+
endpoint: endpoint,
|
28
|
+
id: id,
|
29
|
+
requests_url: requests_url,
|
30
|
+
response:{
|
31
|
+
default: default,
|
32
|
+
body: value,
|
33
|
+
delay: delay,
|
34
|
+
content_type: content_type,
|
35
|
+
status: status,
|
36
|
+
},
|
37
|
+
request: {
|
38
|
+
parameters: required_parameters,
|
39
|
+
body_content: required_body_content,
|
40
|
+
headers: required_headers,
|
41
|
+
http_method: http_method
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
template_url = "url"
|
46
|
+
Template.should_receive(:backedup_get).with(template_url, :format => :json).and_return(template_json)
|
47
|
+
|
48
|
+
template = Template.get(template_url)
|
49
|
+
template.value.should == value
|
50
|
+
template.endpoint.should == endpoint
|
51
|
+
template.id.should == id
|
52
|
+
|
53
|
+
template.default.should == default
|
54
|
+
template.default.should == default
|
55
|
+
template.delay.should == delay
|
56
|
+
template.content_type.should == content_type
|
57
|
+
template.status.should == status
|
58
|
+
|
59
|
+
template.required_parameters.should == required_parameters
|
60
|
+
template.required_body_content.should == required_body_content
|
61
|
+
template.required_headers.should == required_headers
|
62
|
+
template.http_method.should == http_method
|
63
|
+
template.url.should == template_url
|
64
|
+
template.requests_url.should == requests_url
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
describe 'creating' do
|
70
|
+
json = "reponse json"
|
71
|
+
endpoint = "greeting"
|
72
|
+
|
73
|
+
it 'should create a template on mirage' do
|
74
|
+
template = Template.new(endpoint,json)
|
75
|
+
|
76
|
+
template.should_receive(:to_json).and_return(json)
|
77
|
+
Template.should_receive(:put).with(endpoint, :body => json, :headers => {'content-type' => 'application/json'}).and_return(convert_keys_to_strings({:id => 1}))
|
78
|
+
template.create
|
79
|
+
template.id.should == 1
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should have default values set' do
|
83
|
+
template = Template.new(endpoint,json)
|
84
|
+
template.http_method.should == :get
|
85
|
+
template.status.should == 200
|
86
|
+
template.content_type.should == "text/plain"
|
87
|
+
template.default.should == false
|
88
|
+
template.delay.should == 0
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
describe 'deleting' do
|
94
|
+
|
95
|
+
it 'should clear a response' do
|
96
|
+
id = 1
|
97
|
+
template_url = "base_url/templates/#{id}"
|
98
|
+
request_url = "base_url/requests/#{id}"
|
99
|
+
|
100
|
+
template = Template.new("", "")
|
101
|
+
template.url = template_url
|
102
|
+
template.requests_url = request_url
|
103
|
+
|
104
|
+
|
105
|
+
template.stub(:id).and_return(id)
|
106
|
+
|
107
|
+
Template.should_receive(:delete).with(template_url)
|
108
|
+
|
109
|
+
Mirage::Request.should_receive(:delete).with(request_url)
|
110
|
+
template.delete
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "json representation" do
|
116
|
+
|
117
|
+
describe 'response body' do
|
118
|
+
it 'should base64 encode response values' do
|
119
|
+
response = Template.new "endpoint", "value"
|
120
|
+
JSON.parse(response.to_json)["response"]["body"].should == Base64.encode64("value")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'required request parameters' do
|
125
|
+
|
126
|
+
it 'should contain expected request parameters' do
|
127
|
+
response = Template.new "endpoint", "value"
|
128
|
+
required_parameters = {:key => "value"}
|
129
|
+
response.required_parameters = required_parameters
|
130
|
+
JSON.parse(response.to_json)["request"]["parameters"].should == convert_keys_to_strings(required_parameters)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should encode parameter requirements that are regexs' do
|
134
|
+
response = Template.new "endpoint", "value"
|
135
|
+
response.required_parameters = {:key => /regex/}
|
136
|
+
JSON.parse(response.to_json)["request"]["parameters"].should == convert_keys_to_strings({:key => "%r{regex}"})
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe 'required body content' do
|
141
|
+
it 'should contain expected body content' do
|
142
|
+
response = Template.new "endpoint", "value"
|
143
|
+
required_body_content = ["body content"]
|
144
|
+
response.required_body_content = required_body_content
|
145
|
+
JSON.parse(response.to_json)["request"]["body_content"].should == required_body_content
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should encode body content requirements that are regexs' do
|
149
|
+
response = Template.new "endpoint", "value"
|
150
|
+
response.required_body_content = [/regex/]
|
151
|
+
JSON.parse(response.to_json)["request"]["body_content"].should == %w(%r{regex})
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe 'required headers' do
|
156
|
+
it 'should contain expected headers' do
|
157
|
+
response = Template.new "endpoint", "value"
|
158
|
+
required_headers = {:header => "value"}
|
159
|
+
response.required_headers = required_headers
|
160
|
+
JSON.parse(response.to_json)["request"]["headers"].should == convert_keys_to_strings(required_headers)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should encode header requirements that are regexs' do
|
164
|
+
response = Template.new "endpoint", "value"
|
165
|
+
response.required_headers = {:header => /regex/}
|
166
|
+
JSON.parse(response.to_json)["request"]["headers"].should == convert_keys_to_strings(:header => "%r{regex}")
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe 'delay' do
|
171
|
+
it 'should default to 0' do
|
172
|
+
response = Template.new "endpoint", "value"
|
173
|
+
JSON.parse(response.to_json)["delay"].should == 0
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should set the delay' do
|
177
|
+
delay = 5
|
178
|
+
response = Template.new "endpoint", "value"
|
179
|
+
response.delay = delay
|
180
|
+
JSON.parse(response.to_json)["delay"].should == delay
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe 'status code' do
|
185
|
+
it 'should default to 200' do
|
186
|
+
response = Template.new "endpoint", "value"
|
187
|
+
JSON.parse(response.to_json)["response"]["status"].should == 200
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should set the status' do
|
191
|
+
status = 404
|
192
|
+
response = Template.new "endpoint", "value"
|
193
|
+
response.status = status
|
194
|
+
JSON.parse(response.to_json)["response"]["status"].should == status
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe 'http method' do
|
199
|
+
it 'should default to get' do
|
200
|
+
response = Template.new "endpoint", "value"
|
201
|
+
JSON.parse(response.to_json)["request"]["http_method"].should == "get"
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'should set the http method' do
|
205
|
+
method = :post
|
206
|
+
response = Template.new "endpoint", "value"
|
207
|
+
response.http_method = method
|
208
|
+
JSON.parse(response.to_json)["request"]["http_method"].should == "post"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe 'response as default' do
|
213
|
+
it 'should be false by default' do
|
214
|
+
response = Template.new "endpoint", "value"
|
215
|
+
JSON.parse(response.to_json)["response"]["default"].should == false
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should set the default value' do
|
219
|
+
default = true
|
220
|
+
response = Template.new "endpoint", "value"
|
221
|
+
response.default = default
|
222
|
+
JSON.parse(response.to_json)["response"]["default"].should == default
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe 'content type' do
|
227
|
+
it 'should be text/plain by default' do
|
228
|
+
response = Template.new "endpoint", "value"
|
229
|
+
JSON.parse(response.to_json)["response"]["content_type"].should == "text/plain"
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'should set the default value' do
|
233
|
+
content_type = "application/json"
|
234
|
+
response = Template.new "endpoint", "value"
|
235
|
+
response.content_type = content_type
|
236
|
+
JSON.parse(response.to_json)["response"]["content_type"].should == content_type
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'mirage/client'
|
3
|
+
|
4
|
+
describe 'templates' do
|
5
|
+
Templates = Mirage::Templates
|
6
|
+
Requests = Mirage::Requests
|
7
|
+
Template = Mirage::Template
|
8
|
+
|
9
|
+
describe 'deleting' do
|
10
|
+
it 'should delete all templates and associated request data' do
|
11
|
+
base_url = "base_url"
|
12
|
+
requests = mock('requests')
|
13
|
+
Requests.should_receive(:new).with(base_url).and_return(requests)
|
14
|
+
|
15
|
+
Templates.should_receive(:delete).with("#{base_url}/templates")
|
16
|
+
requests.should_receive(:delete_all)
|
17
|
+
|
18
|
+
Templates.new(base_url).delete_all
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'setting default config' do
|
23
|
+
it 'should preset configuration for templates' do
|
24
|
+
Template.stub(:put).and_return(convert_keys_to_strings({:id => 1}))
|
25
|
+
templates = Templates.new "base_url"
|
26
|
+
|
27
|
+
http_method = :post
|
28
|
+
status = 202
|
29
|
+
default = true
|
30
|
+
delay = 2
|
31
|
+
content_type = "text/xml"
|
32
|
+
|
33
|
+
templates.default_config do |defaults|
|
34
|
+
defaults.http_method = http_method
|
35
|
+
defaults.status = status
|
36
|
+
defaults.default = default
|
37
|
+
defaults.delay = delay
|
38
|
+
defaults.content_type = content_type
|
39
|
+
end
|
40
|
+
|
41
|
+
template = templates.put('greeting', 'hello')
|
42
|
+
|
43
|
+
template.http_method.should == http_method
|
44
|
+
template.status.should == status
|
45
|
+
template.default.should == default
|
46
|
+
template.delay.should == delay
|
47
|
+
template.content_type.should == content_type
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'putting templates' do
|
52
|
+
|
53
|
+
endpoint = "greeting"
|
54
|
+
value = "hello"
|
55
|
+
|
56
|
+
before :each do
|
57
|
+
@base_url = "base_url"
|
58
|
+
@templates = Templates.new(@base_url)
|
59
|
+
|
60
|
+
@template_mock = mock('template')
|
61
|
+
Template.should_receive(:new).with("#{@base_url}/templates/#{endpoint}", value, @templates.default_config).and_return(@template_mock)
|
62
|
+
@template_mock.should_receive(:create)
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
it 'should create a template' do
|
67
|
+
@templates.put(endpoint, value)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should accept a block to allow the template to be customised' do
|
71
|
+
block_called = false
|
72
|
+
@templates.put(endpoint, value) do |template|
|
73
|
+
block_called = true
|
74
|
+
template.should == @template_mock
|
75
|
+
end
|
76
|
+
block_called.should == true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
Binary file
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'binary_data_checker'
|
3
|
+
|
4
|
+
|
5
|
+
describe Mirage::BinaryDataChecker do
|
6
|
+
BinaryDataChecker = Mirage::BinaryDataChecker
|
7
|
+
include_context :resources
|
8
|
+
it 'should find binary data' do
|
9
|
+
BinaryDataChecker.contains_binary_data?(File.read("#{resources_dir}/binary.file")).should == true
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should not find binary data' do
|
13
|
+
BinaryDataChecker.contains_binary_data?("string").should == false
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should clean up the temporary file created when checking string content' do
|
17
|
+
tmpfile = Tempfile.new("file")
|
18
|
+
Tempfile.should_receive(:new).and_return tmpfile
|
19
|
+
FileUtils.should_receive(:rm).with(tmpfile.path)
|
20
|
+
BinaryDataChecker.contains_binary_data?("string")
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'sinatra'
|
3
|
+
require 'helpers'
|
4
|
+
|
5
|
+
|
6
|
+
describe "helpers" do
|
7
|
+
include_context :resources
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
@helper = Object.new
|
11
|
+
@helper.extend(Mirage::Server::Helpers)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'converting raw parameter requirements' do
|
15
|
+
it 'should split on split on the (:) to derive the required parameter and value' do
|
16
|
+
@helper.convert_raw_required_params(%w(name:leon)).should == {'name' => 'leon'}
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should store regular expression matcher' do
|
20
|
+
@helper.convert_raw_required_params(%w(name:%r{.*eon})).should == {'name' => /.*eon/}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'converting raw body content requirements' do
|
25
|
+
it 'should extract plan text requirements' do
|
26
|
+
@helper.convert_raw_required_body_content_requirements(%w(leon)).should == %w(leon)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should extract plan requirements in the form of a regexp' do
|
30
|
+
@helper.convert_raw_required_body_content_requirements(%w(%r{.*eon})).should == [/.*eon/]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,526 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'extensions/object'
|
3
|
+
require 'mock_response'
|
4
|
+
|
5
|
+
describe Mirage::MockResponse do
|
6
|
+
MockResponse = Mirage::MockResponse
|
7
|
+
ServerResponseNotFound = Mirage::ServerResponseNotFound
|
8
|
+
BinaryDataChecker = Mirage::BinaryDataChecker
|
9
|
+
before :each do
|
10
|
+
MockResponse.delete_all
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'initialisation' do
|
14
|
+
it 'should find binary data' do
|
15
|
+
string="string"
|
16
|
+
response_spec = convert_keys_to_strings({:response => {:body => string}})
|
17
|
+
BinaryDataChecker.should_receive(:contains_binary_data?).with(string).and_return(true)
|
18
|
+
MockResponse.new("greeting", response_spec).binary?.should == true
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should not find binary data' do
|
22
|
+
string="string"
|
23
|
+
response_spec = convert_keys_to_strings({:response => {:body => string}})
|
24
|
+
BinaryDataChecker.should_receive(:contains_binary_data?).with(string).and_return(false)
|
25
|
+
MockResponse.new("greeting", response_spec).binary?.should == false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'defaults' do
|
30
|
+
describe 'request' do
|
31
|
+
it 'should default http_method' do
|
32
|
+
MockResponse.new("greeting", {}).request_spec['http_method'].should == "get"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'response' do
|
37
|
+
|
38
|
+
it 'should default content_type' do
|
39
|
+
MockResponse.new("greeting", {}).response_spec['content_type'].should == "text/plain"
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should default status code' do
|
43
|
+
MockResponse.new("greeting", {}).response_spec['status'].should == 200
|
44
|
+
end
|
45
|
+
it 'should default delay' do
|
46
|
+
MockResponse.new("greeting", {}).response_spec['delay'].should == 0
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should default default' do
|
50
|
+
MockResponse.new("greeting", {}).response_spec['default'].should == false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'saving state' do
|
56
|
+
it 'should store the current set of responses' do
|
57
|
+
greeting = MockResponse.new("greeting")
|
58
|
+
farewell = MockResponse.new("farewell")
|
59
|
+
|
60
|
+
MockResponse.backup
|
61
|
+
MockResponse.new("farewell", "cheerio")
|
62
|
+
MockResponse.revert
|
63
|
+
|
64
|
+
MockResponse.all.should == [greeting, farewell]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "response values" do
|
69
|
+
|
70
|
+
it 'should return the response value' do
|
71
|
+
response_spec = convert_keys_to_strings({:response => {:body => Base64.encode64("hello")}})
|
72
|
+
MockResponse.new("greeting", response_spec).value.should == "hello"
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should return if the value contains binary data' do
|
76
|
+
response_spec = convert_keys_to_strings({:response => {:body => Base64.encode64("hello ${name}")}})
|
77
|
+
BinaryDataChecker.should_receive(:contains_binary_data?).and_return(true)
|
78
|
+
response = MockResponse.new("greeting", response_spec)
|
79
|
+
|
80
|
+
response.value("", {"name" => "leon"}).should == "hello ${name}"
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should replace patterns with values found in request parameters' do
|
84
|
+
response_spec = convert_keys_to_strings({:response => {:body => Base64.encode64("hello ${name}")}})
|
85
|
+
MockResponse.new("greeting", response_spec).value("", {"name" => "leon"}).should == "hello leon"
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should base64 decode values' do
|
89
|
+
response_spec = convert_keys_to_strings({:response => {:body => "encoded value"}})
|
90
|
+
Base64.should_receive(:decode64).and_return("decoded value")
|
91
|
+
MockResponse.new("greeting", response_spec).value("")
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should replace patterns with values found in the body' do
|
95
|
+
response_spec = convert_keys_to_strings({:response => {:body => Base64.encode64("hello ${name>(.*?)<}")}})
|
96
|
+
MockResponse.new("greeting", response_spec).value("<name>leon</name>").should == "hello leon"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "Matching http method" do
|
101
|
+
it 'should find the response with the correct http method' do
|
102
|
+
response_spec = convert_keys_to_strings({:request => {:http_method => "post"}})
|
103
|
+
response = MockResponse.new("greeting", response_spec)
|
104
|
+
|
105
|
+
options = {:body => "", :params => {}, :endpoint => "greeting", :http_method => "post",:headers => {}}
|
106
|
+
MockResponse.find(options).should == response
|
107
|
+
options[:http_method] = "get"
|
108
|
+
expect { MockResponse.find(options) }.to raise_error(ServerResponseNotFound)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe 'Finding by id' do
|
113
|
+
it 'should find a response given its id' do
|
114
|
+
response1 = MockResponse.new("greeting", "hello")
|
115
|
+
MockResponse.new("farewell", "goodbye")
|
116
|
+
MockResponse.find_by_id(response1.response_id).should == response1
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe 'deleting' do
|
121
|
+
|
122
|
+
it 'should delete a response given its id' do
|
123
|
+
response1 = MockResponse.new("greeting", "hello")
|
124
|
+
MockResponse.delete(response1.response_id)
|
125
|
+
expect { MockResponse.find_by_id(response1.response_id) }.to raise_error(ServerResponseNotFound)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should delete all responses' do
|
129
|
+
MockResponse.new("greeting", "hello")
|
130
|
+
MockResponse.new("farewell", "goodbye")
|
131
|
+
MockResponse.delete_all
|
132
|
+
MockResponse.all.size.should == 0
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "matching on request parameters" do
|
138
|
+
it 'should find the response if all required parameters are present' do
|
139
|
+
get_spec = convert_keys_to_strings(
|
140
|
+
{
|
141
|
+
:request => {
|
142
|
+
:http_method => "get",
|
143
|
+
:parameters => {
|
144
|
+
:firstname => "leon"
|
145
|
+
}
|
146
|
+
},
|
147
|
+
:response => {
|
148
|
+
:body => Base64.encode64("get response")
|
149
|
+
}
|
150
|
+
}
|
151
|
+
)
|
152
|
+
|
153
|
+
post_spec = convert_keys_to_strings(
|
154
|
+
{
|
155
|
+
:request => {
|
156
|
+
:http_method => "post",
|
157
|
+
:parameters => {
|
158
|
+
:firstname => "leon"
|
159
|
+
}
|
160
|
+
},
|
161
|
+
:response => {
|
162
|
+
:body => Base64.encode64("post response")
|
163
|
+
}
|
164
|
+
}
|
165
|
+
)
|
166
|
+
get_response = MockResponse.new("greeting", get_spec)
|
167
|
+
post_response = MockResponse.new("greeting", post_spec)
|
168
|
+
|
169
|
+
options = {:body => "", :params => {"firstname" => "leon"}, :endpoint => "greeting", :http_method => "post",:headers => {}}
|
170
|
+
|
171
|
+
MockResponse.find(options).should == post_response
|
172
|
+
MockResponse.find(options.merge(:http_method => "get")).should == get_response
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should match request parameter values using regexps' do
|
176
|
+
response_spec = convert_keys_to_strings(
|
177
|
+
{
|
178
|
+
:request => {
|
179
|
+
:parameters => {:firstname => "%r{leon.*}"}
|
180
|
+
},
|
181
|
+
:response => {
|
182
|
+
:body => 'response'
|
183
|
+
}
|
184
|
+
|
185
|
+
}
|
186
|
+
)
|
187
|
+
response = MockResponse.new("greeting", response_spec)
|
188
|
+
|
189
|
+
options = {:body => "", :params => {"firstname" => "leon"}, :endpoint => "greeting", :http_method => "get",:headers => {}}
|
190
|
+
MockResponse.find(options).should == response
|
191
|
+
MockResponse.find(options.merge(:params => {"firstname" => "leonard"})).should == response
|
192
|
+
expect { MockResponse.find(options.merge(:params => {"firstname" => "leo"})) }.to raise_error(ServerResponseNotFound)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe 'matching against request http_headers' do
|
197
|
+
it 'should match using literals' do
|
198
|
+
required_headers = {
|
199
|
+
'HEADER-1' => 'value1',
|
200
|
+
'HEADER-2' => 'value2'
|
201
|
+
}
|
202
|
+
spec = convert_keys_to_strings(
|
203
|
+
{
|
204
|
+
:request => {
|
205
|
+
:headers => required_headers
|
206
|
+
},
|
207
|
+
:response => {
|
208
|
+
:body => 'response'
|
209
|
+
}
|
210
|
+
|
211
|
+
}
|
212
|
+
)
|
213
|
+
response = MockResponse.new("greeting", spec)
|
214
|
+
|
215
|
+
options = {:body => "<name>leon</name>", :params => {}, :endpoint => "greeting", :http_method => "get", :headers => required_headers}
|
216
|
+
MockResponse.find(options).should == response
|
217
|
+
expect{MockResponse.find(options.merge(:headers => {}))}.to raise_error(ServerResponseNotFound)
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should match using regex' do
|
222
|
+
required_headers = {
|
223
|
+
'CONTENT-TYPE' => '%r{.*/json}',
|
224
|
+
}
|
225
|
+
spec = convert_keys_to_strings(
|
226
|
+
{
|
227
|
+
:request => {
|
228
|
+
:headers => required_headers
|
229
|
+
},
|
230
|
+
:response => {
|
231
|
+
:body => 'response'
|
232
|
+
}
|
233
|
+
|
234
|
+
}
|
235
|
+
)
|
236
|
+
response = MockResponse.new("greeting", spec)
|
237
|
+
|
238
|
+
options = {:body => "<name>leon</name>", :params => {}, :endpoint => "greeting", :http_method => "get", :headers => {'CONTENT-TYPE' => 'application/json'}}
|
239
|
+
MockResponse.find(options).should == response
|
240
|
+
expect{MockResponse.find(options.merge(:headers => {'CONTENT-TYPE' => 'text/xml'}))}.to raise_error(ServerResponseNotFound)
|
241
|
+
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe 'matching against the request body' do
|
246
|
+
it 'should match required fragments in the request body' do
|
247
|
+
|
248
|
+
response_spec = convert_keys_to_strings(
|
249
|
+
{
|
250
|
+
:request => {
|
251
|
+
:body_content => %w(leon)
|
252
|
+
},
|
253
|
+
:response => {
|
254
|
+
:body => 'response'
|
255
|
+
}
|
256
|
+
|
257
|
+
}
|
258
|
+
)
|
259
|
+
|
260
|
+
response = MockResponse.new("greeting", response_spec)
|
261
|
+
|
262
|
+
options = {:body => "<name>leon</name>", :params => {}, :endpoint => "greeting", :http_method => "get", :headers => {} }
|
263
|
+
|
264
|
+
MockResponse.find(options).should == response
|
265
|
+
expect { MockResponse.find(options.merge(:body => "<name>jeff</name>")) }.to raise_error(ServerResponseNotFound)
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should use regexs to match required fragements in the request body' do
|
269
|
+
response_spec = convert_keys_to_strings(
|
270
|
+
{
|
271
|
+
:request => {
|
272
|
+
:body_content => %w(%r{leon.*})
|
273
|
+
},
|
274
|
+
:response => {
|
275
|
+
:body => 'response'
|
276
|
+
}
|
277
|
+
|
278
|
+
}
|
279
|
+
)
|
280
|
+
|
281
|
+
response = MockResponse.new("greeting", response_spec)
|
282
|
+
|
283
|
+
|
284
|
+
options = {:body => "<name>leon</name>", :params => {}, :endpoint => "greeting", :http_method => "get", :headers => {} }
|
285
|
+
MockResponse.find(options).should == response
|
286
|
+
MockResponse.find(options.merge(:body => "<name>leonard</name>")).should == response
|
287
|
+
expect { MockResponse.find(options.merge(:body => "<name>jeff</name>")) }.to raise_error(ServerResponseNotFound)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'should be equal to another response that is the same not including the response value' do
|
292
|
+
|
293
|
+
spec = convert_keys_to_strings({:response => {:body => "hello1",
|
294
|
+
:content_type => "text/xml",
|
295
|
+
:status => 202,
|
296
|
+
:delay => 1.0,
|
297
|
+
:default => true,
|
298
|
+
:file => false}
|
299
|
+
|
300
|
+
})
|
301
|
+
|
302
|
+
response = MockResponse.new("greeting", spec)
|
303
|
+
response.should_not == MockResponse.new("greeting", {})
|
304
|
+
response.should == MockResponse.new("greeting", spec)
|
305
|
+
end
|
306
|
+
|
307
|
+
describe "scoring to represent the specificity of a response" do
|
308
|
+
|
309
|
+
it 'should score an exact requirement match at 2' do
|
310
|
+
response_spec = convert_keys_to_strings(
|
311
|
+
{
|
312
|
+
:request => {
|
313
|
+
:parameters => {:firstname => "leon"}
|
314
|
+
},
|
315
|
+
:response => {
|
316
|
+
:body => 'response'
|
317
|
+
}
|
318
|
+
|
319
|
+
}
|
320
|
+
)
|
321
|
+
MockResponse.new("greeting", response_spec).score.should == 2
|
322
|
+
|
323
|
+
response_spec = convert_keys_to_strings(
|
324
|
+
{
|
325
|
+
:request => {
|
326
|
+
:body_content => %w(login)
|
327
|
+
},
|
328
|
+
:response => {
|
329
|
+
:body => 'response'
|
330
|
+
}
|
331
|
+
|
332
|
+
}
|
333
|
+
)
|
334
|
+
MockResponse.new("greeting", response_spec).score.should == 2
|
335
|
+
|
336
|
+
response_spec = convert_keys_to_strings(
|
337
|
+
{
|
338
|
+
:request => {
|
339
|
+
:headers => {'header' => 'header'}
|
340
|
+
},
|
341
|
+
:response => {
|
342
|
+
:body => 'response'
|
343
|
+
}
|
344
|
+
|
345
|
+
}
|
346
|
+
)
|
347
|
+
MockResponse.new("greeting", response_spec).score.should == 2
|
348
|
+
end
|
349
|
+
|
350
|
+
it 'should score a match found by regexp at 1' do
|
351
|
+
|
352
|
+
response_spec = convert_keys_to_strings(
|
353
|
+
{
|
354
|
+
:request => {
|
355
|
+
:parameters => {:firstname => "%r{leon.*}"}
|
356
|
+
},
|
357
|
+
:response => {
|
358
|
+
:body => 'response'
|
359
|
+
}
|
360
|
+
|
361
|
+
}
|
362
|
+
)
|
363
|
+
MockResponse.new("greeting", response_spec).score.should == 1
|
364
|
+
|
365
|
+
response_spec = convert_keys_to_strings(
|
366
|
+
{
|
367
|
+
:request => {
|
368
|
+
:body_content => %w(%r{input|output})
|
369
|
+
},
|
370
|
+
:response => {
|
371
|
+
:body => 'response'
|
372
|
+
}
|
373
|
+
|
374
|
+
}
|
375
|
+
)
|
376
|
+
MockResponse.new("greeting", response_spec).score.should == 1
|
377
|
+
|
378
|
+
response_spec = convert_keys_to_strings(
|
379
|
+
{
|
380
|
+
:request => {
|
381
|
+
:headers => {'header' => '%r{.*blah}'}
|
382
|
+
},
|
383
|
+
:response => {
|
384
|
+
:body => 'response'
|
385
|
+
}
|
386
|
+
|
387
|
+
}
|
388
|
+
)
|
389
|
+
MockResponse.new("greeting", response_spec).score.should == 1
|
390
|
+
end
|
391
|
+
|
392
|
+
it 'should find the most specific response' do
|
393
|
+
default_response_spec = convert_keys_to_strings(
|
394
|
+
{
|
395
|
+
:request => {
|
396
|
+
:body_content => %w(login)
|
397
|
+
},
|
398
|
+
:response => {
|
399
|
+
:body => 'default_response'
|
400
|
+
}
|
401
|
+
|
402
|
+
}
|
403
|
+
)
|
404
|
+
|
405
|
+
specific_response_spec = convert_keys_to_strings(
|
406
|
+
{
|
407
|
+
:request => {
|
408
|
+
:body_content => %w(login),
|
409
|
+
:parameters => {
|
410
|
+
:name => "leon"
|
411
|
+
}
|
412
|
+
},
|
413
|
+
:response => {
|
414
|
+
:body => 'specific response'
|
415
|
+
}
|
416
|
+
|
417
|
+
}
|
418
|
+
)
|
419
|
+
|
420
|
+
MockResponse.new("greeting", default_response_spec)
|
421
|
+
expected_response = MockResponse.new("greeting", specific_response_spec)
|
422
|
+
options = {:body => "<action>login</action>", :params => {"name" => "leon"}, :endpoint => "greeting", :http_method => "get",:headers => {}}
|
423
|
+
MockResponse.find(options).should == expected_response
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
|
428
|
+
it 'should all matching to be based on body content, request parameters and http method' do
|
429
|
+
response_spec = convert_keys_to_strings({
|
430
|
+
:request => {
|
431
|
+
:body_content => %w(login),
|
432
|
+
:parameters => {
|
433
|
+
:name => "leon"
|
434
|
+
},
|
435
|
+
:http_method => "post"
|
436
|
+
},
|
437
|
+
:response => {
|
438
|
+
:body => "response"
|
439
|
+
}
|
440
|
+
})
|
441
|
+
|
442
|
+
|
443
|
+
response = MockResponse.new("greeting", response_spec)
|
444
|
+
options = {:body => "<action>login</action>", :params => {"name" => "leon"}, :endpoint => "greeting", :http_method => "post",:headers => {}}
|
445
|
+
MockResponse.find(options).should == response
|
446
|
+
|
447
|
+
options[:http_method] = 'get'
|
448
|
+
expect { MockResponse.find(options) }.to raise_error(ServerResponseNotFound)
|
449
|
+
end
|
450
|
+
|
451
|
+
it 'should recycle response ids' do
|
452
|
+
response_spec = convert_keys_to_strings({
|
453
|
+
:request => {
|
454
|
+
:body_content => %w(login),
|
455
|
+
:parameters => {
|
456
|
+
:name => "leon"
|
457
|
+
},
|
458
|
+
:http_method => "post"
|
459
|
+
},
|
460
|
+
:response => {
|
461
|
+
:body => "response"
|
462
|
+
}
|
463
|
+
})
|
464
|
+
response1 = MockResponse.new("greeting", response_spec)
|
465
|
+
response2 = MockResponse.new("greeting", response_spec)
|
466
|
+
|
467
|
+
response1.response_id.should_not == nil
|
468
|
+
response1.response_id.should == response2.response_id
|
469
|
+
end
|
470
|
+
|
471
|
+
it 'should raise an exception when a response is not found' do
|
472
|
+
expect { MockResponse.find(:body => "<action>login</action>", :params => {:name => "leon"}, :endpoint => "greeting", :http_method => "post",:headers => {}) }.to raise_error(ServerResponseNotFound)
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'should return all responses' do
|
476
|
+
MockResponse.new("greeting", convert_keys_to_strings({:response => {:body => "hello"}}))
|
477
|
+
MockResponse.new("greeting", convert_keys_to_strings({:request => {:body_content => %w(leon)}, :response => {:body => "hello leon"}}))
|
478
|
+
MockResponse.new("greeting", convert_keys_to_strings({:request => {:body_content => %w(leon), :http_method => "post"}, :response => {:body => "hello leon"}}))
|
479
|
+
MockResponse.new("deposit", convert_keys_to_strings({:request => {:body_content => %w(amount), :http_method => "post"}, :response => {:body => "received"}}))
|
480
|
+
MockResponse.all.size.should == 4
|
481
|
+
end
|
482
|
+
|
483
|
+
describe 'finding defaults' do
|
484
|
+
it 'most appropriate response under parent resource and same http method' do
|
485
|
+
level1_response = MockResponse.new("level1", convert_keys_to_strings({:response => {:body => "level1", :default => true}}))
|
486
|
+
MockResponse.new("level1/level2", convert_keys_to_strings({:response => {:body => "level2", :default => true}, :request => {:body_content => %w(body)}}))
|
487
|
+
MockResponse.find_default(:body => "", :http_method => "get", :endpoint => "level1/level2/level3", :params =>{}, :headers =>{}).should == level1_response
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
it 'should generate subdomains' do
|
492
|
+
MockResponse.subdomains("1/2/3").should == ["1/2/3", '1/2', '1']
|
493
|
+
end
|
494
|
+
|
495
|
+
it 'should generate a json representation of itself' do
|
496
|
+
endpoint = "greeting"
|
497
|
+
requests_url = "requests_url"
|
498
|
+
response_spec = convert_keys_to_strings({
|
499
|
+
:id => 1,
|
500
|
+
:endpoint => endpoint,
|
501
|
+
:requests_url => requests_url,
|
502
|
+
:request => {
|
503
|
+
:body_content => %w(login),
|
504
|
+
:parameters => {
|
505
|
+
:name => "leon"
|
506
|
+
},
|
507
|
+
:headers =>{
|
508
|
+
:header => 'header'
|
509
|
+
},
|
510
|
+
:http_method => "post"
|
511
|
+
},
|
512
|
+
:response => {
|
513
|
+
:body => "response",
|
514
|
+
:delay => 0,
|
515
|
+
:content_type => 'text/plain',
|
516
|
+
:status => 200,
|
517
|
+
:default => false
|
518
|
+
}
|
519
|
+
})
|
520
|
+
|
521
|
+
mock_response = MockResponse.new(endpoint, response_spec)
|
522
|
+
mock_response.requests_url = requests_url
|
523
|
+
JSON.parse(mock_response.raw).should == response_spec
|
524
|
+
end
|
525
|
+
|
526
|
+
end
|