mirage 2.4.2 → 3.0.0.alpha.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/.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
|