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.
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