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
@@ -1,85 +1,62 @@
1
1
  Feature: Mirage can be configured with templates that are returned when addressed from ${mirage_url}/responses
2
- On setting a template, a unique id is retuned. This is a key that can be used to manage the template.
3
-
4
- Templates can be configured to respond to either, GET, POST, PUT, or DELETE. If you put more than one template to the same address
5
- but configure them to respond to different HTTP methods, then they are held as seperate resources and are assigned different ids.
6
-
7
- Templates can have following attributes configured by setting the following HTTP headers:
8
- X-mirage-pattern (optional) = criteria for when a response should be returned. see put_with_pattern.feature
9
- X-mirage-delay (optional) = the amount of time in seconds that mirage should wait for before responding (defaults to 0)
10
- X-mirage-method (optional) = http method that this response applies to. Can be set to GET, POST, PUT or DELETE. Templates are configured to respond to GET requests by default
11
- X-mirage-default (optional) = set whether the reponse can act as a default response, see put_as_default.feature (defaults to false)
12
- X-mirage-status-code (optional) = set the http status that is returned, defaults to 200
13
- content-type (optional) = Set the content type to be returned
2
+ On setting a template, a unique id is returned. This is a key that can be used to manage the template.
14
3
 
4
+ Templates can be configured to respond to either, GET, POST, PUT, or DELETE. If you put more than one template to the same resource address
5
+ but configure them to respond to different HTTP methods, then they are held as seperate resources and are assigned different ids.
15
6
 
16
- Scenario: A template without any selection criteria
17
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'Hello'
18
-
19
- When I send GET to 'http://localhost:7001/mirage/responses/greeting'
7
+ The following can be configured as required in order to invoke a response:
8
+ * request parameters
9
+ * body content - defaults to text/plain
10
+ * HTTP Headers
11
+ * HTTP Method - defaults to HTTP GET
12
+
13
+ The following attributes of a response can be configured
14
+ * HTTP status code - defaults to 200
15
+ * Whether this template is to be treated as the default response if a match is not found for a sub URI
16
+ * A delay before the response is returned to the client. This is in seconds, floats are accepted
17
+ * Content-Type
18
+
19
+ Request defaults
20
+ |required request parameters | none |
21
+ |required body content | none |
22
+ |require HTTP headers | none |
23
+ |required HTTP method | GET |
24
+
25
+ Response defaults
26
+ | HTTP status code | 200 |
27
+ | treat as default | false |
28
+ | delay | 0 |
29
+ | Content-Type | text/plain |
30
+
31
+
32
+ Scenario: Setting a template on mirage
33
+ Given the following template template:
34
+ """
35
+ {
36
+ "request":{
37
+ "parameters":{},
38
+ "http_method":"get",
39
+ "headers": {},
40
+ "body_content":[]
41
+ },
42
+ "response":{
43
+ "default":false,
44
+ "body":"Hello",
45
+ "delay":0,
46
+ "content_type":"text/plain",
47
+ "status":200
48
+ }
49
+ }
50
+ """
51
+ And 'response.body' is base64 encoded
52
+ And the template is sent using PUT to 'http://localhost:7001/mirage/templates/greeting'
53
+ And '{"id":1}' should be returned
54
+
55
+ When GET is sent to 'http://localhost:7001/mirage/responses/greeting'
20
56
  Then 'Hello' should be returned
21
57
  And a 200 should be returned
22
-
23
-
24
- Scenario: A template put under a deeper address
25
- Given I send PUT to 'http://localhost:7001/mirage/templates/say/hello/to/me' with body 'Hello to me'
26
-
27
- When I send GET to 'http://localhost:7001/mirage/responses/say/hello/to/me'
28
- Then 'Hello to me' should be returned
29
-
30
-
31
- Scenario: Setting the content-type header
32
- Given I send PUT to 'http://localhost:7001/mirage/templates/say/hello/to/me' with body '<xml></xml>' and headers:
33
- |content-type|text/xml|
34
-
35
- When I send GET to 'http://localhost:7001/mirage/responses/say/hello/to/me'
36
- Then '<xml></xml>' should be returned
37
- And the response 'content-type' should be 'text/xml'
38
58
 
39
-
40
- Scenario: Putting a template to the same resource
41
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'Hello'
42
- Then '1' should be returned
43
-
44
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'Hi'
45
- Then '1' should be returned
46
-
47
- Scenario: Setting the http status code to be returned
48
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'Hello' and headers:
49
- | X-mirage-status | 202 |
50
- When I send GET to 'http://localhost:7001/mirage/responses/greeting'
51
- Then a 202 should be returned
52
-
53
-
54
-
55
-
56
- Scenario Outline: Templates is configured to respond to different http methods
57
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'GET' and headers:
58
- | X-mirage-method | GET |
59
- And '1' should be returned
60
-
61
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'POST' and headers:
62
- | X-mirage-method | POST |
63
- And '2' should be returned
64
-
65
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'DELETE' and headers:
66
- | X-mirage-method | DELETE |
67
- And '3' should be returned
68
-
69
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'PUT' and headers:
70
- | X-mirage-method | PUT |
71
- And '4' should be returned
72
-
73
- When I send <method> to 'http://localhost:7001/mirage/responses/greeting'
74
- Then '<method>' should be returned
75
- Examples:
76
- | method |
77
- | GET |
78
- | POST |
79
- | PUT |
80
- | DELETE |
81
-
82
-
83
- Scenario: Getting a response for a template resources that does not exist
84
- When I send GET to 'http://localhost:7001/mirage/responses/response_that_does_not_exist'
59
+ Scenario: Making a request that is unmatched
60
+ When GET is sent to 'http://localhost:7001/mirage/responses/unmatched'
85
61
  Then a 404 should be returned
62
+
@@ -1,41 +1,21 @@
1
1
  Feature: Parts of a response can be substitued for values found in the request body or query string.
2
2
  This allows dynamic content to be sent back to a client.
3
3
 
4
- To do this, substitution patterns are put in to the response. When the response is triggered, the patterns are used to search the request body
5
- and then the query string for matches. Patterns can be either the name of a parameter found in the query string, or a regular expression with a single
6
- matching group which is what is put in to the response.
7
-
4
+ To do this, substitution, matchers must be put in the the response value.
8
5
 
6
+ Either a string literal or a regex can be used in between ${} to find a match
9
7
 
10
8
  Scenario: A response template populated from matches found in the request body using a regex
11
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'Hello ${<firstname>(.*?)</firstname>} ${<surname>(.*?)</surname>}, how are you?' and headers:
12
- | X-mirage-method | POST |
13
- When I send POST to 'http://localhost:7001/mirage/responses/greeting' with request entity
9
+ Given the following template template:
14
10
  """
15
- <grettingRequest>
16
- <firstname>Leon</firstname>
17
- <surname>Davis</surname>
18
- </greetingRequest>
11
+ {
12
+ "response":{
13
+ "body":"Hello ${name}"
14
+ }
15
+ }
19
16
  """
20
- Then 'Hello Leon Davis, how are you?' should be returned
21
-
22
-
23
- Scenario: A response template populated from match found in the query string using a request parameter name
24
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'Hello ${name}, how are you?'
25
- When I send GET to 'http://localhost:7001/mirage/responses/greeting' with parameters:
26
- | name | Leon |
27
- Then 'Hello Leon, how are you?' should be returned
28
-
29
-
30
- Scenario: Response template populated from match found in the query string using a regex
31
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'Hello ${name=([L\|l]eon)}, how are you?'
17
+ And 'response.body' is base64 encoded
18
+ And the template is sent using PUT to 'http://localhost:7001/mirage/templates/greeting'
32
19
  When I send GET to 'http://localhost:7001/mirage/responses/greeting' with parameters:
33
- | parameter | value |
34
- | name | Leon |
35
- Then 'Hello Leon, how are you?' should be returned
36
-
37
-
38
- Scenario: No match is found in either the request body or query string
39
- Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'Hello ${<name>(.*?)</name>}, how are you?'
40
- When I send GET to 'http://localhost:7001/mirage/responses/greeting'
41
- Then 'Hello ${<name>(.*?)</name>}, how are you?' should be returned
20
+ |name|Joe |
21
+ Then 'Hello Joe' should be returned
@@ -0,0 +1,118 @@
1
+ Feature: Templates set requirements on the following in order for them to be used to generate responses:
2
+
3
+ * request parameters
4
+ * body content
5
+ * HTTP Headers
6
+ * HTTP Method
7
+
8
+ When specifying requirements on Headers, request parameters or the body of a request either a litteral string
9
+ or a regular expression can be used for matching.
10
+
11
+ Background: There is already a default response for 'greeting'
12
+ Given the following template template:
13
+ """
14
+ {
15
+ "request":{
16
+ "parameters":{},
17
+ "http_method":"get",
18
+ "body_content":[]
19
+ },
20
+ "response":{
21
+ "default":false,
22
+ "body":"Hello Stranger",
23
+ "delay":0,
24
+ "content_type":"text/plain",
25
+ "status":200
26
+ }
27
+ }
28
+ """
29
+ And 'response.body' is base64 encoded
30
+ And the template is sent using PUT to 'http://localhost:7001/mirage/templates/greeting'
31
+
32
+ #TODO support http header matching
33
+ # Scenario: Configuring a template with requirements on HTTP headers
34
+ # Given the following template template:
35
+ # """
36
+ # {
37
+ # "request":{
38
+ # "parameters":{},
39
+ # "http_method":"get",
40
+ # "body_content":[]
41
+ # },
42
+ # "response":{
43
+ # "default":false,
44
+ # "body":"Hello Stranger",
45
+ # "delay":0,
46
+ # "content_type":"text/plain",
47
+ # "status":200
48
+ # }
49
+ # }
50
+ # """
51
+ # And 'response.body' is base64 encoded
52
+ # And the template is sent using PUT to 'http://localhost:7001/mirage/templates/greeting'
53
+
54
+
55
+ Scenario: Configuring a template with requirements on request parameters
56
+ Given the following template template:
57
+ """
58
+ {
59
+ "request":{
60
+ "parameters":{
61
+ "firstname" : "%r\{.*e}",
62
+ "surname" : "Blogs"
63
+ },
64
+ "http_method":"get",
65
+ "body_content":[]
66
+ },
67
+ "response":{
68
+ "default":false,
69
+ "body":"Hello Joe",
70
+ "delay":0,
71
+ "content_type":"text/plain",
72
+ "status":200
73
+ }
74
+ }
75
+ """
76
+ And 'response.body' is base64 encoded
77
+ And the template is sent using PUT to 'http://localhost:7001/mirage/templates/greeting'
78
+
79
+ When I send GET to 'http://localhost:7001/mirage/responses/greeting' with parameters:
80
+ |firstname|Joe |
81
+ |surname |Blogs|
82
+ Then 'Hello Joe' should be returned
83
+
84
+ Scenario: Configuring a template with requirements on the body
85
+ Given the following template template:
86
+ """
87
+ {
88
+ "request":{
89
+ "parameters":{},
90
+ "http_method":"POST",
91
+ "body_content":["Joe", "%r{B..gs}"]
92
+ },
93
+ "response":{
94
+ "default":false,
95
+ "body":"Hello Joe",
96
+ "delay":0,
97
+ "content_type":"text/plain",
98
+ "status":200
99
+ }
100
+ }
101
+ """
102
+ And 'response.body' is base64 encoded
103
+ And the template is sent using PUT to 'http://localhost:7001/mirage/templates/greeting'
104
+
105
+ When I send POST to 'http://localhost:7001/mirage/responses/greeting' with body:
106
+ """
107
+ {
108
+ "credentials" : {
109
+ "username" : "Joe",
110
+ "password" : "Blogs"
111
+ }
112
+ }
113
+ """
114
+ Then 'Hello Joe' should be returned
115
+
116
+
117
+
118
+
@@ -1,3 +1,5 @@
1
+ require 'base64'
2
+ require 'hashie'
1
3
  Then /^'([^']*)' should be returned$/ do |expected_response|
2
4
  response_text = @response.body
3
5
  if response_text != expected_response
@@ -78,6 +80,10 @@ Then /^I run$/ do |text|
78
80
  end
79
81
  end
80
82
 
83
+ Given /^the following require statements are needed:$/ do |text|
84
+ @code_snippet = text.gsub("\"", "\\\\\"")
85
+ end
86
+
81
87
  Given /^the following gems are required to run the Mirage client test code:$/ do |text|
82
88
  @code_snippet = text.gsub("\"", "\\\\\"")
83
89
  end
@@ -94,7 +100,7 @@ When /^I send (POST|PUT) to '(http:\/\/localhost:7001\/mirage\/(.*?))' with requ
94
100
  end
95
101
  end
96
102
 
97
- When /^I send (GET|PUT|POST|OPTIONS|HEAD|DELETE) to '(http:\/\/localhost:\d{4}\/mirage([^']*))'$/ do |method, url, endpoint|
103
+ When /^(GET|PUT|POST|OPTIONS|HEAD|DELETE) is sent to '(http:\/\/localhost:\d{4}\/mirage([^']*))'$/ do |method, url, endpoint|
98
104
  start_time = Time.now
99
105
  @response = case method
100
106
  when 'GET' then
@@ -114,9 +120,15 @@ When /^I send (GET|PUT|POST|OPTIONS|HEAD|DELETE) to '(http:\/\/localhost:\d{4}\/
114
120
  end
115
121
 
116
122
 
117
- When /^I send PUT to '(http:\/\/localhost:7001\/mirage\/([^']*))' with body '([^']*)'$/ do |url, endpoint, body|
123
+ When /^I send (PUT|POST) to '(http:\/\/localhost:7001\/mirage\/([^']*))' with body:$/ do |method, url, endpoint, body|
118
124
  start_time = Time.now
119
- @response = http_put(url, body)
125
+ @response = case method
126
+ when 'PUT'
127
+ http_put(url, body)
128
+ when 'POST'
129
+ http_post(url, body)
130
+ end
131
+
120
132
  @response_time = Time.now - start_time
121
133
  end
122
134
 
@@ -126,7 +138,7 @@ When /^I send PUT to '(http:\/\/localhost:7001\/mirage\/([^']*))' with body '([^
126
138
  parameter, value = row[0], row[1]
127
139
  headers[parameter]=value
128
140
  end
129
- @response = http_put(url, body, headers)
141
+ @response = http_put(url, body, :headers => headers)
130
142
  end
131
143
 
132
144
  Then /^I should see '(.*?)' on the command line$/ do |content|
@@ -172,7 +184,7 @@ When /^I send (GET|POST) to '(http:\/\/localhost:7001\/mirage\/(.*?))' with para
172
184
  end
173
185
 
174
186
  Then /^the following should be returned:$/ do |text|
175
- @response.body.should == text
187
+ text.gsub("\n","").gsub(" ", "").should == @response.body
176
188
  end
177
189
 
178
190
  Given /^I send PUT to '(http:\/\/localhost:7001\/mirage\/(.*?))' with file: ([^']*) and headers:$/ do |url, endpoint, path, table|
@@ -183,10 +195,23 @@ Given /^I send PUT to '(http:\/\/localhost:7001\/mirage\/(.*?))' with file: ([^'
183
195
  end
184
196
 
185
197
  Dir.chdir SCRATCH do
186
- http_put(url, File.new(path), headers)
198
+ http_put(url, File.new(path), :headers => headers)
199
+ end
200
+ end
201
+
202
+ Given /^I send PUT to '(http:\/\/localhost:7001\/mirage\/(.*?))' with body '([^']*)' and parameters:$/ do |url, endpoint, body, table|
203
+ headers = {}
204
+ table.raw.each do |row|
205
+ parameter, value = row[0], row[1]
206
+ headers[parameter]=value
207
+ end
208
+
209
+ Dir.chdir SCRATCH do
210
+ http_put(url, File.new("/home/team/Projects/mirage/pkg/mirage-2.1.2.gem"), :parameters => headers)
187
211
  end
188
212
  end
189
213
 
214
+
190
215
  When /^the response '([^']*)' should be '([^']*)'$/ do |header, value|
191
216
  @response.response[header].should include(value)
192
217
  end
@@ -195,4 +220,24 @@ Then /^the response should be the same as the content of '([^']*)'$/ do |path|
195
220
  Dir.chdir SCRATCH do
196
221
  @response.body.should == File.read(path)
197
222
  end
223
+ end
224
+ Given /^the following template template:$/ do |text|
225
+ @response_template = Hashie::Mash.new(JSON.parse(text))
226
+ end
227
+ When /^'(.*)' is base64 encoded$/ do |template_component|
228
+ @response_template.send(:eval, "#{template_component}=Base64.encode64(#{template_component})")
229
+ end
230
+ When /^the template is sent using PUT to '(http:\/\/localhost:7001\/mirage\/(.*?))'$/ do |url, endpoint|
231
+ @response = http_put(url, @response_template.to_hash.to_json, :headers => {"Content-Type" => "application/json"})
232
+ end
233
+ Given /^a template for '(.*)' has been set with a value of '(.*)'$/ do |endpoint, value|
234
+ $mirage.templates.put(endpoint, value)
235
+ end
236
+ Then /^request data should have been retrieved$/ do
237
+ puts @response.body
238
+ request_data = JSON.parse(@response.body)
239
+ request_data.include?('parameters').should == true
240
+ request_data.include?('headers').should == true
241
+ request_data.include?('body').should == true
242
+ request_data.include?('request_url').should == true
198
243
  end
@@ -22,5 +22,5 @@ else
22
22
  MIRAGE_CMD = "#{RUBY_CMD} ../bin/mirage"
23
23
  end
24
24
 
25
- World(Mirage::Web)
25
+
26
26
 
@@ -1,11 +1,8 @@
1
1
  Before do
2
2
  FileUtils.mkdir_p(SCRATCH)
3
3
 
4
- if Mirage.running?
5
- $mirage.clear
6
- else
7
- $mirage = start_mirage_in_scratch_dir
8
- end
4
+ $mirage = start_mirage_in_scratch_dir
5
+ $mirage.templates.delete_all
9
6
 
10
7
  Dir["#{SCRATCH}/*"].each do |file|
11
8
  FileUtils.rm_rf(file) unless file == "#{SCRATCH}/mirage.log"
@@ -13,7 +13,10 @@ module Mirage
13
13
  end
14
14
  end
15
15
 
16
- def http_put url, entity, headers={}
16
+ def http_put url, entity, options={}
17
+ if options[:parameters]
18
+ url << "?#{options[:parameters].to_a.collect{|pair|pair.join("=")}.join("&")}"
19
+ end
17
20
  uri = URI.parse(url)
18
21
  request = Net::HTTP::Put.new(uri.request_uri)
19
22
 
@@ -23,8 +26,15 @@ module Mirage
23
26
  else
24
27
  request.body=entity
25
28
  end
26
- headers.each { |field, value| request.add_field(field, value) }
27
-
29
+
30
+ if options[:headers]
31
+ options[:headers].each { |field, value| request.add_field(field, value) }
32
+ end
33
+
34
+ #if options[:parameters]
35
+ # request.set_form_data options[:parameters]
36
+ #end
37
+
28
38
  Net::HTTP.new(uri.host, uri.port).request(request)
29
39
  end
30
40
 
@@ -56,3 +66,4 @@ module Mirage
56
66
 
57
67
  end
58
68
  end
69
+ World(Mirage::Web)