rest-assured 0.2.0.rc8 → 0.2.0
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.lock +2 -2
- data/LICENSE +4 -19
- data/README.markdown +123 -36
- data/bin/console +1 -2
- data/bin/rest-assured +12 -0
- data/features/command_line_options.feature +20 -1
- data/features/{doubles_via_api.feature → rest_api/doubles.feature} +0 -0
- data/features/{redirect_rules_via_api.feature → rest_api/redirects.feature} +11 -8
- data/features/{call_history.feature → ruby_api/verify_requests.feature} +0 -0
- data/features/ruby_api/wait_for_requests.feature +39 -0
- data/features/step_definitions/command_line_options_steps.rb +12 -0
- data/features/step_definitions/doubles_steps.rb +10 -10
- data/features/step_definitions/redirect_rules_steps.rb +24 -5
- data/features/step_definitions/ruby_api_steps.rb +69 -0
- data/features/support/env.rb +3 -1
- data/features/{doubles_via_ui.feature → web_ui/doubles.feature} +0 -0
- data/features/{redirect_rules_via_ui.feature → web_ui/redirects.feature} +0 -0
- data/lib/rest-assured.rb +2 -1
- data/lib/rest-assured/client/resources.rb +12 -2
- data/lib/rest-assured/config.rb +24 -0
- data/lib/rest-assured/models/double.rb +32 -28
- data/lib/rest-assured/models/redirect.rb +28 -24
- data/lib/rest-assured/models/request.rb +11 -7
- data/lib/rest-assured/routes/double.rb +8 -8
- data/lib/rest-assured/routes/redirect.rb +8 -8
- data/lib/rest-assured/routes/response.rb +16 -14
- data/lib/rest-assured/version.rb +1 -1
- data/lib/sinatra/handler_options_patch.rb +25 -0
- data/spec/client/resource_double_spec.rb +42 -6
- data/spec/config_spec.rb +35 -0
- data/spec/functional/double_routes_spec.rb +109 -107
- data/spec/functional/redirect_routes_spec.rb +86 -75
- data/spec/functional/response_spec.rb +57 -55
- data/spec/models/double_spec.rb +67 -65
- data/spec/models/redirect_spec.rb +28 -26
- data/spec/models/request_spec.rb +10 -8
- data/ssl/localhost.crt +14 -0
- data/ssl/localhost.key +15 -0
- metadata +25 -24
- data/features/step_definitions/call_history_steps.rb +0 -24
@@ -2,17 +2,17 @@ module RestAssured
|
|
2
2
|
module RedirectRoutes
|
3
3
|
def self.included(router)
|
4
4
|
router.get '/redirects' do
|
5
|
-
@redirects = Redirect.ordered
|
5
|
+
@redirects = Models::Redirect.ordered
|
6
6
|
haml :'redirects/index'
|
7
7
|
end
|
8
8
|
|
9
9
|
router.get '/redirects/new' do
|
10
|
-
@redirect = Redirect.new
|
10
|
+
@redirect = Models::Redirect.new
|
11
11
|
haml :'redirects/new'
|
12
12
|
end
|
13
13
|
|
14
14
|
router.post '/redirects' do
|
15
|
-
@redirect = Redirect.create(params['redirect'] || { :pattern => params['pattern'], :to => params['to'] })
|
15
|
+
@redirect = Models::Redirect.create(params['redirect'] || { :pattern => params['pattern'], :to => params['to'] })
|
16
16
|
|
17
17
|
if browser?
|
18
18
|
if @redirect.errors.blank?
|
@@ -31,12 +31,12 @@ module RestAssured
|
|
31
31
|
end
|
32
32
|
|
33
33
|
router.get %r{/redirects/(\d+)/edit} do |id|
|
34
|
-
@redirect = Redirect.find(id)
|
34
|
+
@redirect = Models::Redirect.find(id)
|
35
35
|
haml :'redirects/edit'
|
36
36
|
end
|
37
37
|
|
38
38
|
router.put %r{/redirects/(\d+)} do |id|
|
39
|
-
@redirect = Redirect.find(id)
|
39
|
+
@redirect = Models::Redirect.find(id)
|
40
40
|
|
41
41
|
@redirect.update_attributes(params['redirect'])
|
42
42
|
|
@@ -51,7 +51,7 @@ module RestAssured
|
|
51
51
|
|
52
52
|
router.put '/redirects/reorder' do
|
53
53
|
if params['redirect']
|
54
|
-
if Redirect.update_order(params['redirect'])
|
54
|
+
if Models::Redirect.update_order(params['redirect'])
|
55
55
|
'Changed'
|
56
56
|
else
|
57
57
|
'Crumps! It broke'
|
@@ -60,14 +60,14 @@ module RestAssured
|
|
60
60
|
end
|
61
61
|
|
62
62
|
router.delete %r{/redirects/(\d+)} do |id|
|
63
|
-
if Redirect.destroy(id)
|
63
|
+
if Models::Redirect.destroy(id)
|
64
64
|
flash[:notice] = 'Redirect deleted'
|
65
65
|
redirect '/redirects'
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
69
|
router.delete '/redirects/all' do
|
70
|
-
status Redirect.delete_all ? 200 : 500
|
70
|
+
status Models::Redirect.delete_all ? 200 : 500
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
@@ -1,20 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module RestAssured
|
2
|
+
class Response
|
3
|
+
def self.perform(app)
|
4
|
+
request = app.request
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
if d = Models::Double.where(:fullpath => request.fullpath, :active => true, :verb => request.request_method).first
|
7
|
+
request.body.rewind
|
8
|
+
body = request.body.read #without temp variable ':body = > body' is always nil. mistery
|
9
|
+
env = request.env.except('rack.input', 'rack.errors', 'rack.logger')
|
9
10
|
|
10
|
-
|
11
|
+
d.requests.create!(:rack_env => env.to_json, :body => body, :params => request.params.to_json)
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
app.body d.content
|
14
|
+
app.status d.status
|
15
|
+
elsif r = Models::Redirect.ordered.find { |r| request.fullpath =~ /#{r.pattern}/ }
|
16
|
+
app.redirect( "#{r.to}#{request.fullpath}" )
|
17
|
+
else
|
18
|
+
app.status 404
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
data/lib/rest-assured/version.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Sinatra
|
2
|
+
class Base
|
3
|
+
class << self
|
4
|
+
def run!(options={})
|
5
|
+
set options
|
6
|
+
handler = detect_rack_handler
|
7
|
+
handler_name = handler.name.gsub(/.*::/, '')
|
8
|
+
# handler specific options use the lower case handler name as hash key, if present
|
9
|
+
handler_opts = begin
|
10
|
+
send(handler_name.downcase)
|
11
|
+
rescue NoMethodError
|
12
|
+
{}
|
13
|
+
end
|
14
|
+
puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
|
15
|
+
"on #{port} for #{environment} with backup from #{handler_name}" unless handler_name =~/cgi/i
|
16
|
+
handler.run self, handler_opts.merge(:Host => bind, :Port => port) do |server|
|
17
|
+
[:INT, :TERM].each { |sig| trap(sig) { quit!(server, handler_name) } }
|
18
|
+
set :running, true
|
19
|
+
end
|
20
|
+
rescue Errno::EADDRINUSE => e
|
21
|
+
puts "== Someone is already performing on port #{port}!"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require File.expand_path('../../spec_helper', __FILE__)
|
3
3
|
|
4
|
-
module RestAssured
|
4
|
+
module RestAssured
|
5
5
|
describe Double do
|
6
6
|
before do
|
7
7
|
@orig_addr = RestAssured::Client.config.server_address
|
@@ -20,11 +20,11 @@ module RestAssured::Client
|
|
20
20
|
|
21
21
|
it 'creates new double' do
|
22
22
|
d = Double.create :fullpath => '/some/api', :content => 'content'
|
23
|
-
::Double.where(:fullpath => d.fullpath, :content => d.content).should exist
|
23
|
+
Models::Double.where(:fullpath => d.fullpath, :content => d.content).should exist
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'finds exising double' do
|
27
|
-
d = ::Double.create :fullpath => '/some/api', :content => 'content'
|
27
|
+
d = Models::Double.create :fullpath => '/some/api', :content => 'content'
|
28
28
|
|
29
29
|
dd = Double.find(d.id)
|
30
30
|
|
@@ -33,9 +33,9 @@ module RestAssured::Client
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'shows request history' do
|
36
|
-
d = ::Double.create :fullpath => '/some/api', :content => 'content'
|
37
|
-
d.requests << Request.create(:rack_env => 'rack_env json', :body => 'body', :params => 'params')
|
38
|
-
d.requests << Request.create(:rack_env => 'different rack_env', :body => 'other body', :params => 'more params')
|
36
|
+
d = Models::Double.create :fullpath => '/some/api', :content => 'content'
|
37
|
+
d.requests << Models::Request.create(:rack_env => 'rack_env json', :body => 'body', :params => 'params')
|
38
|
+
d.requests << Models::Request.create(:rack_env => 'different rack_env', :body => 'other body', :params => 'more params')
|
39
39
|
|
40
40
|
dd = Double.find(d.id)
|
41
41
|
dd.requests.size.should == 2
|
@@ -43,5 +43,41 @@ module RestAssured::Client
|
|
43
43
|
dd.requests.first.params.should == 'params'
|
44
44
|
dd.requests.last.body.should == 'other body'
|
45
45
|
end
|
46
|
+
|
47
|
+
context 'when waits requests' do
|
48
|
+
after do
|
49
|
+
@t.join if @t.respond_to?(:join)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'waits for specified number of requests' do
|
53
|
+
d = Models::Double.create :fullpath => '/some/api', :content => 'content'
|
54
|
+
dd = Double.find(d.id)
|
55
|
+
|
56
|
+
@t = Thread.new do
|
57
|
+
3.times do
|
58
|
+
sleep 1
|
59
|
+
d.requests << Models::Request.create(:rack_env => 'rack_env json', :body => 'body', :params => 'params')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
dd.wait_for_requests(2)
|
64
|
+
|
65
|
+
dd.requests.count.should >= 2
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'raises exception if requests have not happened within timeout' do
|
69
|
+
d = Models::Double.create :fullpath => '/some/api', :content => 'content'
|
70
|
+
dd = Double.find(d.id)
|
71
|
+
dd.stub(:sleep)
|
72
|
+
|
73
|
+
@t = Thread.new do
|
74
|
+
2.times do
|
75
|
+
d.requests << Models::Request.create(:rack_env => 'rack_env json', :body => 'body', :params => 'params')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
lambda { dd.wait_for_requests(3) }.should raise_error(MoreRequestsExpected, 'Expected 3 requests. Got 2.')
|
80
|
+
end
|
81
|
+
end
|
46
82
|
end
|
47
83
|
end
|
data/spec/config_spec.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require File.expand_path('../../lib/rest-assured/config', __FILE__)
|
2
2
|
require 'rack'
|
3
|
+
require 'openssl'
|
4
|
+
require 'webrick'
|
3
5
|
|
4
6
|
describe RestAssured::Config do
|
5
7
|
#this is thoroughly covered in cucumber (since there it also serves documentation purposes)
|
@@ -94,5 +96,38 @@ describe RestAssured::Config do
|
|
94
96
|
RestAssured::Config.included(app)
|
95
97
|
end
|
96
98
|
|
99
|
+
context 'when ssl true' do
|
100
|
+
before do
|
101
|
+
AppConfig.stub(:use_ssl).and_return(true)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'makes sure only webrick can be used' do
|
105
|
+
app.should_receive(:set).with(:server, %[webrick])
|
106
|
+
RestAssured::Config.included(app)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'sets up webrick ssl' do
|
110
|
+
OpenSSL::X509::Certificate.stub(:new).with( File.read( AppConfig.ssl_cert ) ).and_return('ssl_cert')
|
111
|
+
OpenSSL::PKey::RSA.stub(:new).with( File.read( AppConfig.ssl_key ) ).and_return('ssl_key')
|
112
|
+
|
113
|
+
ssl_config = {
|
114
|
+
:SSLEnable => true,
|
115
|
+
:SSLCertificate => 'ssl_cert',
|
116
|
+
:SSLPrivateKey => 'ssl_key',
|
117
|
+
:SSLCertName => [ ["CN", WEBrick::Utils::getservername] ],
|
118
|
+
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE
|
119
|
+
}
|
120
|
+
|
121
|
+
app.should_receive(:set).with(:webrick, hash_including(ssl_config))
|
122
|
+
RestAssured::Config.included(app)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'does all that only if ssl true' do
|
126
|
+
AppConfig.stub(:use_ssl).and_return(false)
|
127
|
+
|
128
|
+
app.should_not_receive(:set).with(:webrick, anything)
|
129
|
+
RestAssured::Config.included(app)
|
130
|
+
end
|
131
|
+
end
|
97
132
|
end
|
98
133
|
end
|
@@ -1,149 +1,151 @@
|
|
1
1
|
require File.expand_path('../../spec_helper', __FILE__)
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
describe "through ui", :ui => true do
|
15
|
-
it "shows doubles page by default" do
|
16
|
-
visit '/'
|
17
|
-
current_path.should == '/doubles'
|
3
|
+
module RestAssured
|
4
|
+
describe 'Double routes' do
|
5
|
+
let :test_double do
|
6
|
+
{ :fullpath => '/api/google?a=5', :content => 'some awesome content', :verb => 'POST', :status => '201' }
|
7
|
+
end
|
8
|
+
let :valid_params do
|
9
|
+
{ 'double[fullpath]' => test_double[:fullpath], 'double[content]' => test_double[:content], 'double[verb]' => test_double[:verb], 'double[status]' => test_double[:status] }
|
10
|
+
end
|
11
|
+
let :invalid_params do
|
12
|
+
valid_params.except('double[fullpath]')
|
18
13
|
end
|
19
14
|
|
20
|
-
|
21
|
-
|
15
|
+
describe "through ui", :ui => true do
|
16
|
+
it "shows doubles page by default" do
|
17
|
+
visit '/'
|
18
|
+
current_path.should == '/doubles'
|
19
|
+
end
|
22
20
|
|
23
|
-
|
21
|
+
it "shows list of doubles" do
|
22
|
+
f = Models::Double.create test_double
|
24
23
|
|
25
|
-
|
26
|
-
end
|
24
|
+
visit '/doubles'
|
27
25
|
|
28
|
-
|
29
|
-
|
26
|
+
page.should have_content(f.fullpath)
|
27
|
+
end
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
page.should have_css('#double_description')
|
34
|
-
end
|
29
|
+
it "shows form for creating new double" do
|
30
|
+
visit '/doubles/new'
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
page.should have_css('#double_fullpath')
|
33
|
+
page.should have_css('#double_content')
|
34
|
+
page.should have_css('#double_description')
|
35
|
+
end
|
39
36
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
37
|
+
it "creates double" do
|
38
|
+
post '/doubles', valid_params
|
39
|
+
follow_redirect!
|
44
40
|
|
45
|
-
|
46
|
-
|
41
|
+
last_request.fullpath.should == '/doubles'
|
42
|
+
last_response.body.should =~ /Double created/
|
43
|
+
Models::Double.exists?(test_double).should be true
|
44
|
+
end
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
end
|
46
|
+
it "reports failure when creating with invalid parameters" do
|
47
|
+
post '/doubles', invalid_params
|
51
48
|
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
last_response.should be_ok
|
50
|
+
last_response.body.should =~ /Crumps!.*Fullpath can't be blank/
|
51
|
+
end
|
55
52
|
|
56
|
-
|
57
|
-
|
58
|
-
|
53
|
+
it "brings up double edit form" do
|
54
|
+
f = Models::Double.create test_double
|
55
|
+
visit "/doubles/#{f.id}/edit"
|
59
56
|
|
60
|
-
|
61
|
-
|
57
|
+
find('#double_fullpath').value.should == f.fullpath
|
58
|
+
find('#double_content').value.should == f.content
|
59
|
+
end
|
62
60
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
last_request.fullpath.should == '/doubles'
|
67
|
-
last_response.body.should =~ /Double updated/
|
68
|
-
f.reload.fullpath.should == '/some/other/api'
|
69
|
-
end
|
61
|
+
it "updates double" do
|
62
|
+
f = Models::Double.create test_double
|
70
63
|
|
71
|
-
|
72
|
-
|
64
|
+
put "/doubles/#{f.id}", 'double[fullpath]' => '/some/other/api'
|
65
|
+
follow_redirect!
|
73
66
|
|
74
|
-
|
67
|
+
last_request.fullpath.should == '/doubles'
|
68
|
+
last_response.body.should =~ /Double updated/
|
69
|
+
f.reload.fullpath.should == '/some/other/api'
|
70
|
+
end
|
75
71
|
|
76
|
-
|
77
|
-
|
78
|
-
end
|
72
|
+
it "chooses active double" do
|
73
|
+
f = Models::Double.create test_double.merge!(:active => false)
|
79
74
|
|
80
|
-
|
81
|
-
f = Double.create test_double
|
75
|
+
ajax "/doubles/#{f.id}", :as => :put, :active => true
|
82
76
|
|
83
|
-
|
84
|
-
|
77
|
+
last_response.should be_ok
|
78
|
+
last_response.body.should == 'Changed'
|
79
|
+
end
|
85
80
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
Double.exists?(test_double).should be_false
|
90
|
-
end
|
91
|
-
end
|
81
|
+
it "deletes double" do
|
82
|
+
f = Models::Double.create test_double
|
92
83
|
|
93
|
-
|
94
|
-
|
95
|
-
post '/doubles', test_double
|
84
|
+
delete "/doubles/#{f.id}"
|
85
|
+
follow_redirect!
|
96
86
|
|
97
|
-
|
98
|
-
|
87
|
+
last_response.should be_ok
|
88
|
+
last_response.body.should =~ /Double deleted/
|
89
|
+
|
90
|
+
Models::Double.exists?(test_double).should be_false
|
91
|
+
end
|
99
92
|
end
|
100
93
|
|
101
|
-
|
102
|
-
|
94
|
+
describe "through REST api", :ui => false do
|
95
|
+
it "creates double" do
|
96
|
+
post '/doubles', test_double
|
103
97
|
|
104
|
-
|
105
|
-
|
106
|
-
|
98
|
+
last_response.should be_ok
|
99
|
+
Models::Double.exists?(test_double).should be_true
|
100
|
+
end
|
107
101
|
|
108
|
-
|
109
|
-
|
102
|
+
it "reports failure when creating with invalid parameters" do
|
103
|
+
post '/doubles', test_double.except(:fullpath)
|
110
104
|
|
111
|
-
|
105
|
+
last_response.should_not be_ok
|
106
|
+
last_response.body.should =~ /\{"fullpath":\["can't be blank"\]\}/
|
107
|
+
end
|
112
108
|
|
113
|
-
|
114
|
-
|
115
|
-
end
|
116
|
-
end
|
109
|
+
it "deletes all doubles" do
|
110
|
+
Models::Double.create test_double
|
117
111
|
|
118
|
-
|
119
|
-
it "creates double as AR resource" do
|
120
|
-
post '/doubles.json', { :double => test_double }.to_json, 'CONTENT_TYPE' => 'Application/json'
|
112
|
+
delete '/doubles/all'
|
121
113
|
|
122
|
-
|
123
|
-
|
124
|
-
|
114
|
+
last_response.should be_ok
|
115
|
+
Models::Double.count.should == 0
|
116
|
+
end
|
125
117
|
end
|
126
118
|
|
127
|
-
|
128
|
-
|
119
|
+
describe 'through REST (ActiveResource compatible) json api', :ui => false do
|
120
|
+
it "creates double as AR resource" do
|
121
|
+
post '/doubles.json', { :double => test_double }.to_json, 'CONTENT_TYPE' => 'Application/json'
|
129
122
|
|
130
|
-
|
131
|
-
|
132
|
-
|
123
|
+
last_response.should be_ok
|
124
|
+
Models::Double.exists?(test_double).should be_true
|
125
|
+
last_response.body.should == Models::Double.where(test_double).first.to_json
|
126
|
+
end
|
133
127
|
|
134
|
-
|
135
|
-
|
128
|
+
it "reports failure when creating with invalid parameters" do
|
129
|
+
post '/doubles.json', { :double => test_double.except(:fullpath) }.to_json, 'CONTENT_TYPE' => 'Application/json'
|
136
130
|
|
137
|
-
|
131
|
+
last_response.should_not be_ok
|
132
|
+
last_response.body.should =~ /\{"fullpath":\["can't be blank"\]\}/
|
133
|
+
end
|
138
134
|
|
139
|
-
|
140
|
-
|
141
|
-
|
135
|
+
it 'loads double as AR resource' do
|
136
|
+
d = Models::Double.create test_double
|
137
|
+
|
138
|
+
get "/doubles/#{d.id}.json", 'CONTENT_TYPE' => 'Application/json'
|
139
|
+
|
140
|
+
last_response.should be_ok
|
141
|
+
last_response.body.should == d.to_json(:include => :requests)
|
142
|
+
end
|
143
|
+
|
144
|
+
it '404s if double is not found' do
|
145
|
+
get "/doubles/345345.json", 'CONTENT_TYPE' => 'Application/json'
|
142
146
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
last_response.status.should == 404
|
147
|
+
last_response.status.should == 404
|
148
|
+
end
|
147
149
|
end
|
148
150
|
end
|
149
151
|
end
|