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
@@ -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)