mirage 1.3.6 → 2.0.0.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +7 -4
- data/VERSION +1 -1
- data/bin/mirage +2 -0
- data/features/client/clear.feature +38 -20
- data/features/client/peek.feature +11 -11
- data/features/client/save_and_revert.feature +14 -8
- data/features/client/set.feature +59 -13
- data/features/client/track.feature +5 -3
- data/features/server/clear.feature +59 -47
- data/features/server/logging.feature +2 -3
- data/features/server/peek.feature +12 -10
- data/features/server/prime.feature +15 -13
- data/features/server/response_templates.feature +9 -16
- data/features/server/save_and_revert.feature +11 -14
- data/features/server/set.feature +44 -17
- data/features/server/set_default_response.feature +19 -25
- data/features/server/set_with_a_delay.feature +3 -5
- data/features/server/set_with_a_pattern.feature +24 -29
- data/features/server/track_requests.feature +71 -0
- data/features/server/web_user_interface.feature +7 -8
- data/features/step_definitions/my_steps.rb +83 -28
- data/features/support/env.rb +0 -14
- data/lib/mirage.rb +3 -0
- data/lib/mirage/client.rb +48 -43
- data/lib/mirage/core.rb +65 -152
- data/lib/mirage/mock_response.rb +49 -0
- data/lib/mirage/mock_responses_collection.rb +109 -0
- data/lib/mirage/object.rb +5 -0
- data/lib/mirage/web.rb +37 -28
- data/lib/start_mirage.rb +27 -5
- data/lib/{view/mirage/index.xhtml → views/index.erb} +5 -5
- data/mirage.gemspec +7 -7
- metadata +57 -23
- data/features/client/get.feature +0 -46
- data/features/server/file_responses.feature +0 -8
- data/features/server/track.feature +0 -74
@@ -2,15 +2,14 @@ Feature: Mirage's home page allows you to see what response are currently being
|
|
2
2
|
From this page you can:
|
3
3
|
- Peek at a responses content
|
4
4
|
- Track the response to see if a request has been made to it
|
5
|
-
|
6
|
-
|
5
|
+
|
6
|
+
#TODO tests needed for displaying pattern and delay values and http method
|
7
7
|
|
8
8
|
Background: There are already a couple of responses hosted on he Mirage server
|
9
|
-
Given I
|
10
|
-
|
|
11
|
-
|
|
12
|
-
And I
|
13
|
-
| response | goodbye |
|
9
|
+
Given I send PUT to 'http://localhost:7001/mirage/templates/greeting' with body 'hello' and headers:
|
10
|
+
| X-mirage-default | true |
|
11
|
+
| X-mirage-method | POST |
|
12
|
+
And I send PUT to 'http://localhost:7001/mirage/templates/leaving' with body 'goodbye'
|
14
13
|
|
15
14
|
Scenario: Using the home page to see what response are being hosted
|
16
15
|
Given I goto 'http://localhost:7001/mirage'
|
@@ -23,7 +22,7 @@ Feature: Mirage's home page allows you to see what response are currently being
|
|
23
22
|
Then I should see 'hello'
|
24
23
|
|
25
24
|
Scenario: Using the home page to track if a request has been made
|
26
|
-
Given I
|
25
|
+
Given I send POST to 'http://localhost:7001/mirage/responses/greeting' with request entity
|
27
26
|
"""
|
28
27
|
Yo!
|
29
28
|
"""
|
@@ -6,18 +6,16 @@ After('@command_line') do
|
|
6
6
|
stop_mirage
|
7
7
|
end
|
8
8
|
|
9
|
-
Then /^'(
|
9
|
+
Then /^'([^']*)' should be returned$/ do |expected_response|
|
10
10
|
response_text = @response.body
|
11
|
-
if
|
12
|
-
expected_response.length.should == response_text.length
|
11
|
+
if response_text != expected_response
|
13
12
|
expected_response.split('&').each { |param_value_pair| response_text.should =~ /#{param_value_pair}/ }
|
14
|
-
|
15
|
-
response_text.should == expected_response
|
13
|
+
expected_response.length.should == response_text.length
|
16
14
|
end
|
17
15
|
end
|
18
16
|
|
19
|
-
Then /^a (404|500) should be returned$/ do |error_code|
|
20
|
-
@response.code.should == error_code.to_i
|
17
|
+
Then /^a (200|404|500) should be returned$/ do |error_code|
|
18
|
+
@response.code.to_i.should == error_code.to_i
|
21
19
|
end
|
22
20
|
|
23
21
|
Then /^it should take at least '(.*)' seconds$/ do |time|
|
@@ -25,12 +23,6 @@ Then /^it should take at least '(.*)' seconds$/ do |time|
|
|
25
23
|
end
|
26
24
|
|
27
25
|
|
28
|
-
Then /^the response should be a file the same as '([^']*)'$/ do |file_path|
|
29
|
-
download_path = "#{SCRATCH}/temp.download"
|
30
|
-
@response.save_as(download_path)
|
31
|
-
FileUtils.cmp(download_path, file_path).should == true
|
32
|
-
end
|
33
|
-
|
34
26
|
Then /^mirage should be running on '(.*)'$/ do |url|
|
35
27
|
get(url).code.to_i.should == 200
|
36
28
|
end
|
@@ -49,13 +41,11 @@ Given /^Mirage (is|is not) running$/ do |running|
|
|
49
41
|
end
|
50
42
|
|
51
43
|
Then /^Connection should be refused to '(.*)'$/ do |url|
|
52
|
-
|
53
44
|
begin
|
54
45
|
get(url)
|
55
46
|
fail "Mirage is still running"
|
56
47
|
rescue Errno::ECONNREFUSED
|
57
48
|
end
|
58
|
-
|
59
49
|
end
|
60
50
|
|
61
51
|
Given /^the file '(.*)' contains:$/ do |file_path, content|
|
@@ -74,7 +64,7 @@ Then /^the usage information should be displayed$/ do
|
|
74
64
|
end
|
75
65
|
Given /^usage information:$/ do |table|
|
76
66
|
@usage = table.raw.flatten.collect { |line| normalise(line) }
|
77
|
-
end
|
67
|
+
end
|
78
68
|
|
79
69
|
Then /^I run$/ do |text|
|
80
70
|
text.gsub!("\"", "\\\\\"")
|
@@ -85,24 +75,51 @@ Given /^the following gems are required to run the Mirage client test code:$/ do
|
|
85
75
|
@code_snippet = text.gsub("\"", "\\\\\"")
|
86
76
|
end
|
87
77
|
|
88
|
-
When /^I
|
89
|
-
|
78
|
+
When /^I send (POST|PUT) to '(http:\/\/localhost:7001\/mirage\/(.*?))' with request entity$/ do |method, url, endpoint, entity|
|
79
|
+
|
80
|
+
@response = case method
|
81
|
+
when 'POST'
|
82
|
+
then
|
83
|
+
post(url, entity)
|
84
|
+
when 'PUT'
|
85
|
+
then
|
86
|
+
put(url, entity)
|
87
|
+
end
|
90
88
|
end
|
91
89
|
|
92
|
-
When /^I (
|
90
|
+
When /^I send (GET|PUT|POST|OPTIONS|HEAD|DELETE) to '(http:\/\/localhost:7001\/mirage([^']*))'$/ do |method, url, endpoint|
|
91
|
+
start_time = Time.now
|
92
|
+
@response = case method
|
93
|
+
when 'GET' then
|
94
|
+
get(url)
|
95
|
+
when 'PUT' then
|
96
|
+
put(url, '')
|
97
|
+
when 'POST' then
|
98
|
+
post(url, '')
|
99
|
+
when 'HEAD' then
|
100
|
+
head(url)
|
101
|
+
when 'OPTIONS' then
|
102
|
+
options(url)
|
103
|
+
when 'DELETE' then
|
104
|
+
delete(url)
|
105
|
+
end
|
106
|
+
@response_time = Time.now - start_time
|
107
|
+
end
|
93
108
|
|
94
|
-
parameters = {}
|
95
|
-
table.raw.each do |row|
|
96
|
-
parameter, value = row[0].to_sym, row[1]
|
97
|
-
value = File.exists?(value) ? File.open(value, 'rb') : value
|
98
|
-
parameters[parameter]=value
|
99
|
-
end
|
100
109
|
|
101
|
-
|
110
|
+
When /^I send PUT to '(http:\/\/localhost:7001\/mirage\/([^']*))' with body '([^']*)'$/ do |url, endpoint, body|
|
111
|
+
start_time = Time.now
|
112
|
+
@response = put(url, body)
|
113
|
+
@response_time = Time.now - start_time
|
102
114
|
end
|
103
115
|
|
104
|
-
When /^I
|
105
|
-
|
116
|
+
When /^I send PUT to '(http:\/\/localhost:7001\/mirage\/([^']*))' with body '([^']*)' and headers:$/ do |url, endpoint, body, table|
|
117
|
+
headers = {}
|
118
|
+
table.raw.each do |row|
|
119
|
+
parameter, value = row[0], row[1]
|
120
|
+
headers[parameter]=value
|
121
|
+
end
|
122
|
+
@response = put(url, body, headers)
|
106
123
|
end
|
107
124
|
|
108
125
|
Then /^I should see '(.*?)' on the command line$/ do |content|
|
@@ -128,4 +145,42 @@ end
|
|
128
145
|
|
129
146
|
When /^I click '(.*)'$/ do |thing|
|
130
147
|
@page = @page.links.find { |link| link.attributes['id'] == thing }.click
|
148
|
+
end
|
149
|
+
|
150
|
+
When /^I send (GET|POST) to '(http:\/\/localhost:7001\/mirage\/(.*?))' with parameters:$/ do |http_method, url, endpoint, table|
|
151
|
+
|
152
|
+
parameters = {}
|
153
|
+
table.raw.each do |row|
|
154
|
+
parameter, value = row[0].to_sym, row[1]
|
155
|
+
value = File.exists?(value) ? File.open(value, 'rb') : value
|
156
|
+
parameters[parameter]=value
|
157
|
+
end
|
158
|
+
|
159
|
+
@response = case http_method
|
160
|
+
when 'POST' then
|
161
|
+
post(url, parameters)
|
162
|
+
when 'GET' then
|
163
|
+
get(url, parameters)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
Then /^the following should be returned:$/ do |text|
|
168
|
+
@response.body.should == text
|
169
|
+
end
|
170
|
+
|
171
|
+
Given /^I send PUT to '(http:\/\/localhost:7001\/mirage\/(.*?))' with file: ([^']*) and headers:$/ do |url, endpoint, path, table|
|
172
|
+
headers = {}
|
173
|
+
table.raw.each do |row|
|
174
|
+
parameter, value = row[0], row[1]
|
175
|
+
headers[parameter]=value
|
176
|
+
end
|
177
|
+
put(url, File.new(path), headers)
|
178
|
+
end
|
179
|
+
|
180
|
+
When /^the response '([^']*)' should be '([^']*)'$/ do |header, value|
|
181
|
+
@response.response[header].should include(value)
|
182
|
+
end
|
183
|
+
|
184
|
+
Then /^the response should be the same as the content of '([^']*)'$/ do |path|
|
185
|
+
@response.body.should == File.read(path)
|
131
186
|
end
|
data/features/support/env.rb
CHANGED
@@ -48,20 +48,6 @@ end
|
|
48
48
|
module Web
|
49
49
|
include Mirage::Web
|
50
50
|
|
51
|
-
def get(url)
|
52
|
-
browser = Mechanize.new
|
53
|
-
browser.keep_alive= false
|
54
|
-
browser.get(url)
|
55
|
-
end
|
56
|
-
|
57
|
-
def hit_mirage(url, parameters={})
|
58
|
-
start_time = Time.now
|
59
|
-
file = parameters.values.find { |value| value.is_a?(File) }
|
60
|
-
response = (file ? http_post(url, parameters) : http_get(url, parameters))
|
61
|
-
@response_time = Time.now - start_time
|
62
|
-
response
|
63
|
-
end
|
64
|
-
|
65
51
|
def normalise text
|
66
52
|
text.gsub(/[\n]/, ' ').gsub(/\s+/, ' ')
|
67
53
|
end
|
data/lib/mirage.rb
CHANGED
data/lib/mirage/client.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'uri'
|
2
|
-
require 'mechanize'
|
3
2
|
require 'open-uri'
|
4
3
|
require 'mirage/web'
|
5
4
|
|
@@ -13,6 +12,12 @@ module Mirage
|
|
13
12
|
@code = message, code
|
14
13
|
end
|
15
14
|
end
|
15
|
+
|
16
|
+
class Response
|
17
|
+
|
18
|
+
attr_accessor :method, :pattern, :content_type
|
19
|
+
|
20
|
+
end
|
16
21
|
|
17
22
|
class InternalServerException < MirageError;
|
18
23
|
end
|
@@ -32,24 +37,6 @@ module Mirage
|
|
32
37
|
@url = url
|
33
38
|
end
|
34
39
|
|
35
|
-
# Get a response at the given endpoint
|
36
|
-
# Mirage::Client.get(endpoint) => response as a string
|
37
|
-
# If a response is not found a ResponseNotFound exception is thrown
|
38
|
-
#
|
39
|
-
# Examples:
|
40
|
-
# Getting a response without any parameters or body content
|
41
|
-
# Mirage::Client.get(endpoint)
|
42
|
-
#
|
43
|
-
# Getting a response, passing request parameters
|
44
|
-
# Mirage::Client.new.get('greeting', :param1 => 'value1', param2=>'value2')
|
45
|
-
#
|
46
|
-
# Getting a response, passing a content in the body of the request
|
47
|
-
# Mirage::Client.new.get('greeting', 'content')
|
48
|
-
|
49
|
-
def get endpoint, body_or_params={}
|
50
|
-
body_or_params = {:body => body_or_params} if body_or_params.is_a?(String)
|
51
|
-
response(http_get("#{@url}/get/#{endpoint}", body_or_params))
|
52
|
-
end
|
53
40
|
|
54
41
|
# Set a text or file based response, to be hosted at a given end point optionally with a given pattern and delay
|
55
42
|
# Client.set(endpoint, response, params) => unique id that can be used to call back to the server
|
@@ -59,16 +46,31 @@ module Mirage
|
|
59
46
|
# Client.set('greeting', 'hello', :pattern => /regexp/)
|
60
47
|
# Client.set('greeting', 'hello', :pattern => 'text')
|
61
48
|
# Client.set('greeting', 'hello', :delay => 5) # number of seconds
|
62
|
-
def set endpoint,
|
63
|
-
|
64
|
-
|
65
|
-
response
|
49
|
+
def set endpoint, response_value, params={}
|
50
|
+
response = Response.new
|
51
|
+
|
52
|
+
yield response if block_given?
|
53
|
+
|
54
|
+
headers = {}
|
55
|
+
headers['X-mirage-method'] = response.method.to_s if response.method
|
56
|
+
|
57
|
+
headers['X-mirage-pattern'] = response.pattern if response.pattern
|
58
|
+
headers['Content-Type'] = response.content_type || 'text/plain'
|
59
|
+
|
60
|
+
response(put("#{@url}/templates/#{endpoint}",response_value, headers))
|
66
61
|
end
|
67
62
|
|
68
63
|
# Use to look at what a response contains without actually triggering it.
|
69
64
|
# Client.peek(response_id) => response held on the server as a String
|
70
65
|
def peek response_id
|
71
|
-
response(
|
66
|
+
response = response(get("#{@url}/templates/#{response_id}"))
|
67
|
+
case response
|
68
|
+
when String then
|
69
|
+
return response
|
70
|
+
when Mirage::Web::FileResponse then
|
71
|
+
return response.response.body
|
72
|
+
end
|
73
|
+
|
72
74
|
end
|
73
75
|
|
74
76
|
# Clear Content from Mirage
|
@@ -81,19 +83,19 @@ module Mirage
|
|
81
83
|
# Client.new.clear(:requests) # Clear all tracked request information
|
82
84
|
# Client.new.clear(:request => response_id) # Clear the tracked request for a given response id
|
83
85
|
def clear thing=nil
|
86
|
+
|
84
87
|
case thing
|
85
|
-
when
|
86
|
-
|
87
|
-
when
|
88
|
-
|
89
|
-
when :requests then
|
90
|
-
http_get("#{@url}/clear/requests")
|
88
|
+
when :requests
|
89
|
+
delete("#{@url}/requests")
|
90
|
+
when Numeric then
|
91
|
+
delete("#{@url}/templates/#{thing}")
|
91
92
|
when Hash then
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
puts "deleteing request #{thing[:request]}"
|
94
|
+
delete("#{@url}/requests/#{thing[:request]}") if thing[:request]
|
95
|
+
else NilClass
|
96
|
+
delete("#{@url}/templates")
|
96
97
|
end
|
98
|
+
|
97
99
|
end
|
98
100
|
|
99
101
|
|
@@ -103,40 +105,43 @@ module Mirage
|
|
103
105
|
# Example:
|
104
106
|
# Client.new.track(response_id) => Tracked request as a String
|
105
107
|
def track response_id
|
106
|
-
response(
|
108
|
+
response(get("#{@url}/requests/#{response_id}"))
|
107
109
|
end
|
108
110
|
|
109
111
|
# Save the state of the Mirage server so that it can be reverted back to that exact state at a later time.
|
110
112
|
def save
|
111
|
-
|
113
|
+
put("#{@url}/backup",'').code == 200
|
112
114
|
end
|
113
115
|
|
114
116
|
|
115
117
|
# Revert the state of Mirage back to the state that was last saved
|
116
118
|
# If there is no snapshot to rollback to, nothing happens
|
117
119
|
def revert
|
118
|
-
|
120
|
+
put("#{@url}",'').code == 200
|
119
121
|
end
|
120
122
|
|
121
123
|
|
122
124
|
# Check to see if Mirage is up and running
|
123
125
|
def running?
|
124
|
-
|
126
|
+
begin
|
127
|
+
get(@url) and return true
|
128
|
+
rescue Errno::ECONNREFUSED
|
129
|
+
return false
|
130
|
+
end
|
125
131
|
end
|
126
132
|
|
127
133
|
# Clear down the Mirage Server and load any defaults that are in Mirages default responses directory.
|
128
134
|
def prime
|
129
|
-
response(
|
135
|
+
response(put("#{@url}/defaults",''))
|
130
136
|
end
|
131
137
|
|
132
138
|
private
|
133
139
|
def response response
|
134
|
-
|
135
|
-
case response.code
|
140
|
+
case response.code.to_i
|
136
141
|
when 500 then
|
137
|
-
raise ::Mirage::InternalServerException.new(response.
|
142
|
+
raise ::Mirage::InternalServerException.new(response.body, response.code.to_i)
|
138
143
|
when 404 then
|
139
|
-
raise ::Mirage::ResponseNotFound.new(response.
|
144
|
+
raise ::Mirage::ResponseNotFound.new(response.body, response.code.to_i)
|
140
145
|
else
|
141
146
|
response.body
|
142
147
|
end
|
data/lib/mirage/core.rb
CHANGED
@@ -1,207 +1,120 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/reloader'
|
3
3
|
|
4
|
-
class Object
|
5
|
-
def deep_clone
|
6
|
-
Marshal.load(Marshal.dump(self))
|
7
|
-
end
|
8
|
-
end
|
9
4
|
|
10
5
|
module Mirage
|
11
6
|
|
12
|
-
class
|
13
|
-
@@id_count = 0
|
14
|
-
attr_reader :response_id, :delay, :name, :pattern
|
15
|
-
attr_accessor :response_id
|
7
|
+
class MirageServer < Sinatra::Base
|
16
8
|
|
17
|
-
|
18
|
-
@name, @value, @pattern, @response_id, @delay, @default = name, value, pattern, @@id_count+=1, delay, default
|
19
|
-
end
|
9
|
+
REQUESTS= {}
|
20
10
|
|
21
|
-
|
22
|
-
@@id_count = 0
|
23
|
-
end
|
11
|
+
MOCK_RESPONSES = MockResponsesCollection.new
|
24
12
|
|
25
|
-
|
26
|
-
|
27
|
-
end
|
13
|
+
put '/mirage/templates/*' do |name|
|
14
|
+
response = request.body.read
|
28
15
|
|
29
|
-
|
30
|
-
|
31
|
-
end
|
16
|
+
headers = request.env
|
17
|
+
http_method = headers['HTTP_X_MIRAGE_METHOD'] || 'GET'
|
32
18
|
|
19
|
+
pattern = headers['HTTP_X_MIRAGE_PATTERN'] ? /#{headers['HTTP_X_MIRAGE_PATTERN']}/ : :basic
|
33
20
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
value = @value
|
38
|
-
value.scan(/\$\{([^\}]*)\}/).flatten.each do |pattern|
|
21
|
+
MOCK_RESPONSES << MockResponse.new(name, response, headers['CONTENT_TYPE'], http_method, pattern, headers['HTTP_X_MIRAGE_DELAY'].to_f, headers['HTTP_X_MIRAGE_DEFAULT'], headers['HTTP_X_MIRAGE_FILE'])
|
22
|
+
end
|
39
23
|
|
40
|
-
|
41
|
-
|
42
|
-
|
24
|
+
['get', 'post', 'delete', 'put'].each do |http_method|
|
25
|
+
send(http_method, '/mirage/responses/*') do |name|
|
26
|
+
body, query_string = Rack::Utils.unescape(request.body.read.to_s), request.env['QUERY_STRING']
|
27
|
+
record = MOCK_RESPONSES.get_response(name, http_method.upcase, body, query_string)
|
43
28
|
|
44
|
-
|
45
|
-
|
46
|
-
value = value.gsub("${#{pattern}}", string_match)
|
47
|
-
end
|
48
|
-
end
|
29
|
+
return 404 unless record
|
30
|
+
REQUESTS[record.response_id] = body.empty? ? query_string : body
|
49
31
|
|
32
|
+
sleep record.delay
|
33
|
+
send_response(record, body, request, query_string)
|
50
34
|
end
|
51
|
-
value
|
52
35
|
end
|
53
36
|
|
54
|
-
|
55
|
-
|
56
|
-
|
37
|
+
delete '/mirage/templates/:id' do
|
38
|
+
response_id = params[:id].to_i
|
39
|
+
MOCK_RESPONSES.delete(response_id)
|
40
|
+
REQUESTS.delete(response_id)
|
57
41
|
end
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
class MirageServer < Ramaze::Controller
|
62
|
-
include Ramaze::Helper::SendFile
|
63
|
-
map '/mirage'
|
64
|
-
RESPONSES, REQUESTS, SNAPSHOT= {}, {}, {}
|
65
|
-
|
66
|
-
def index
|
67
|
-
@responses = {}
|
68
42
|
|
69
|
-
|
70
|
-
|
71
|
-
pattern = pattern.is_a?(Regexp) ? "pattern = #{pattern.source}" : ''
|
72
|
-
delay = response.delay > 0 ? "delay = #{response.delay}" : ''
|
73
|
-
pattern << ' ,' unless pattern.empty? || delay.empty?
|
74
|
-
@responses["#{name}#{'/*' if response.default?}: #{pattern} #{delay}"] = response
|
75
|
-
end
|
76
|
-
end
|
43
|
+
delete '/mirage/requests' do
|
44
|
+
REQUESTS.clear
|
77
45
|
end
|
78
46
|
|
79
|
-
|
80
|
-
|
81
|
-
RESPONSES.values.each do |responses|
|
82
|
-
peeked_response = responses.values.find { |response| response.response_id == response_id.to_i }
|
83
|
-
break unless peeked_response.nil?
|
84
|
-
end
|
85
|
-
respond("Can not peek reponse, id:#{response_id} does not exist}", 404) unless peeked_response
|
86
|
-
send_response(peeked_response)
|
47
|
+
delete '/mirage/requests/:id' do
|
48
|
+
REQUESTS.delete(params[:id].to_i)
|
87
49
|
end
|
88
50
|
|
89
|
-
def set *args
|
90
|
-
delay = (request['delay']||0)
|
91
|
-
pattern = request['pattern'] ? /#{request['pattern']}/ : :basic
|
92
|
-
name = args.join('/')
|
93
|
-
is_default = request['default'] == 'true'
|
94
|
-
|
95
|
-
response = MockResponse.new(name, response_value, pattern, delay.to_f, is_default)
|
96
51
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
# Right not an the main id count goes up by one even if the id is not used because the old id is reused from another response
|
103
|
-
response.response_id = old_response.response_id if old_response
|
104
|
-
response.response_id
|
52
|
+
delete '/mirage/templates' do
|
53
|
+
[REQUESTS].each { |map| map.clear }
|
54
|
+
MOCK_RESPONSES.clear
|
55
|
+
MockResponse.reset_count
|
105
56
|
end
|
106
57
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
if stored_responses
|
113
|
-
record = find_response(body, query_string, stored_responses)
|
114
|
-
else
|
115
|
-
default_responses, record = find_default_responses(name), nil
|
58
|
+
get '/mirage/templates/:id' do
|
59
|
+
response = MOCK_RESPONSES.find(params[:id].to_i)
|
60
|
+
return 404 if response.is_a? Array
|
61
|
+
send_response(response)
|
62
|
+
end
|
116
63
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
121
|
-
end
|
64
|
+
get '/mirage/requests/:id' do
|
65
|
+
REQUESTS[params[:id].to_i] || 404
|
66
|
+
end
|
122
67
|
|
123
|
-
respond('Response not found', 404) unless record
|
124
|
-
REQUESTS[record.response_id] = body.empty? ? query_string : body
|
125
68
|
|
126
|
-
|
127
|
-
|
128
|
-
end
|
69
|
+
get '/mirage' do
|
70
|
+
@responses = {}
|
129
71
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
when 'responses' then
|
136
|
-
RESPONSES.clear and REQUESTS.clear and MockResponse.reset_count
|
137
|
-
when /\d+/ then
|
138
|
-
response_id = datatype.to_i
|
139
|
-
delete_response(response_id)
|
140
|
-
REQUESTS.delete(response_id)
|
141
|
-
when 'request'
|
142
|
-
REQUESTS.delete(response_id)
|
143
|
-
when nil
|
144
|
-
[REQUESTS, RESPONSES].each { |map| map.clear }
|
145
|
-
MockResponse.reset_count
|
72
|
+
MOCK_RESPONSES.all.each do |response|
|
73
|
+
pattern = response.pattern.is_a?(Regexp) ? "pattern = #{response.pattern.source}" : ''
|
74
|
+
delay = response.delay > 0 ? "delay = #{response.delay}" : ''
|
75
|
+
pattern << ' ,' unless pattern.empty? || delay.empty?
|
76
|
+
@responses["#{response.name}#{'/*' if response.default?}: #{pattern} #{delay}"] = response
|
146
77
|
end
|
78
|
+
erb :index
|
147
79
|
end
|
148
80
|
|
149
|
-
|
150
|
-
|
81
|
+
error do
|
82
|
+
erb request.env['sinatra.error'].message
|
151
83
|
end
|
152
84
|
|
153
|
-
|
154
|
-
|
155
|
-
end
|
156
|
-
|
157
|
-
def revert
|
158
|
-
RESPONSES.clear and RESPONSES.replace(SNAPSHOT.deep_clone)
|
159
|
-
end
|
85
|
+
put '/mirage/defaults' do
|
86
|
+
MOCK_RESPONSES.clear
|
160
87
|
|
161
|
-
def prime
|
162
|
-
clear
|
163
88
|
Dir["#{DEFAULT_RESPONSES_DIR}/**/*.rb"].each do |default|
|
164
89
|
begin
|
165
90
|
load default
|
166
91
|
rescue Exception
|
167
|
-
|
92
|
+
raise "Unable to load default responses from: #{default}"
|
168
93
|
end
|
169
94
|
|
170
95
|
end
|
171
96
|
end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
pattern_match = stored_responses.keys.find_all { |pattern| pattern != :basic }.find { |pattern| body =~ pattern || query_string =~ pattern }
|
176
|
-
record = pattern_match ? stored_responses[pattern_match] : stored_responses[:basic]
|
177
|
-
record
|
97
|
+
#
|
98
|
+
put '/mirage/backup' do
|
99
|
+
MOCK_RESPONSES.backup
|
178
100
|
end
|
179
101
|
|
180
|
-
def response_value
|
181
|
-
return request['response'] unless request['response'].nil?
|
182
|
-
respond('response or file parameter required', 500)
|
183
|
-
end
|
184
102
|
|
185
|
-
|
186
|
-
|
187
|
-
matches.collect { |key| RESPONSES[key] }
|
103
|
+
put '/mirage' do
|
104
|
+
MOCK_RESPONSES.revert
|
188
105
|
end
|
189
106
|
|
190
|
-
|
191
|
-
|
192
|
-
|
107
|
+
|
108
|
+
helpers do
|
109
|
+
|
110
|
+
def response_value
|
111
|
+
return request['response'] unless request['response'].nil?
|
193
112
|
end
|
194
|
-
end
|
195
113
|
|
196
|
-
|
197
|
-
|
198
|
-
tempfile, filename, type = response.value.values_at(:tempfile, :filename, :type)
|
199
|
-
tempfile.binmode
|
200
|
-
send_file(tempfile.path, type, "Content-Length: #{tempfile.size}; Content-Disposition: attachment; filename=#{filename}")
|
201
|
-
else
|
114
|
+
def send_response(response, body='', request={}, query_string='')
|
115
|
+
content_type(response.content_type)
|
202
116
|
response.value(body, request, query_string)
|
203
117
|
end
|
204
118
|
end
|
205
|
-
|
206
119
|
end
|
207
120
|
end
|