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.
Files changed (68) hide show
  1. data/.simplecov +6 -0
  2. data/Gemfile +11 -3
  3. data/Gemfile.lock +41 -14
  4. data/VERSION +1 -1
  5. data/features/client/clear.feature +41 -50
  6. data/features/client/configure.feature +2 -2
  7. data/features/client/put.feature +17 -6
  8. data/features/client/requests.feature +5 -9
  9. data/features/client/start.feature +19 -11
  10. data/features/client/stop.feature +10 -44
  11. data/features/server/commandline_interface/start.feature +2 -14
  12. data/features/server/commandline_interface/stop.feature +6 -4
  13. data/features/server/logging.feature +2 -2
  14. data/features/server/prime.feature +11 -66
  15. data/features/server/requests/delete.feature +34 -33
  16. data/features/server/requests/get.feature +21 -18
  17. data/features/server/save_and_revert.feature +24 -11
  18. data/features/server/templates/delete.feature +29 -32
  19. data/features/server/templates/get.feature +44 -25
  20. data/features/server/templates/put/put.feature +55 -78
  21. data/features/server/templates/put/put_with_substitutions.feature +12 -32
  22. data/features/server/templates/put/required_content.feature +118 -0
  23. data/features/step_definitions/my_steps.rb +51 -6
  24. data/features/support/env.rb +1 -1
  25. data/features/support/hooks.rb +2 -5
  26. data/{lib/mirage/client → features/support}/web.rb +14 -3
  27. data/lib/mirage/client.rb +5 -2
  28. data/lib/mirage/client/client.rb +22 -129
  29. data/lib/mirage/client/request.rb +25 -0
  30. data/lib/mirage/client/requests.rb +13 -0
  31. data/lib/mirage/client/runner.rb +4 -4
  32. data/lib/mirage/client/template.rb +108 -0
  33. data/lib/mirage/client/template_configuration.rb +22 -0
  34. data/lib/mirage/client/templates.rb +26 -0
  35. data/mirage.gemspec +42 -22
  36. data/mirage_server.rb +1 -135
  37. data/rakefile +22 -7
  38. data/server/app.rb +4 -0
  39. data/server/binary_data_checker.rb +15 -0
  40. data/server/helpers.rb +28 -0
  41. data/server/mock_response.rb +140 -58
  42. data/server/server.rb +167 -0
  43. data/spec/{cli_bridge_spec.rb → client/cli_bridge_spec.rb} +15 -11
  44. data/spec/client/client_spec.rb +139 -0
  45. data/spec/client/request_spec.rb +52 -0
  46. data/spec/client/requests_spec.rb +10 -0
  47. data/spec/{runner_spec.rb → client/runner_spec.rb} +3 -3
  48. data/spec/client/template_configuration_spec.rb +32 -0
  49. data/spec/client/template_spec.rb +241 -0
  50. data/spec/client/templates_spec.rb +79 -0
  51. data/spec/resources/binary.file +0 -0
  52. data/spec/server/binary_data_checker_spec.rb +22 -0
  53. data/spec/server/helpers_spec.rb +34 -0
  54. data/spec/server/mock_response_spec.rb +526 -0
  55. data/spec/server/server_spec.rb +132 -0
  56. data/spec/spec_helper.rb +61 -2
  57. data/test.html +12 -0
  58. data/test.rb +20 -17
  59. data/todo.lst +2 -0
  60. data/views/index.haml +22 -0
  61. data/views/response.haml +24 -0
  62. metadata +134 -49
  63. data/features/server/templates/put/put_as_default.feature +0 -42
  64. data/features/server/templates/put/put_with_delay.feature +0 -8
  65. data/features/server/templates/put/put_with_pattern.feature +0 -80
  66. data/lib/mirage/client/response.rb +0 -29
  67. data/spec/client_spec.rb +0 -38
  68. 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