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.
Files changed (40) hide show
  1. data/Gemfile.lock +2 -2
  2. data/LICENSE +4 -19
  3. data/README.markdown +123 -36
  4. data/bin/console +1 -2
  5. data/bin/rest-assured +12 -0
  6. data/features/command_line_options.feature +20 -1
  7. data/features/{doubles_via_api.feature → rest_api/doubles.feature} +0 -0
  8. data/features/{redirect_rules_via_api.feature → rest_api/redirects.feature} +11 -8
  9. data/features/{call_history.feature → ruby_api/verify_requests.feature} +0 -0
  10. data/features/ruby_api/wait_for_requests.feature +39 -0
  11. data/features/step_definitions/command_line_options_steps.rb +12 -0
  12. data/features/step_definitions/doubles_steps.rb +10 -10
  13. data/features/step_definitions/redirect_rules_steps.rb +24 -5
  14. data/features/step_definitions/ruby_api_steps.rb +69 -0
  15. data/features/support/env.rb +3 -1
  16. data/features/{doubles_via_ui.feature → web_ui/doubles.feature} +0 -0
  17. data/features/{redirect_rules_via_ui.feature → web_ui/redirects.feature} +0 -0
  18. data/lib/rest-assured.rb +2 -1
  19. data/lib/rest-assured/client/resources.rb +12 -2
  20. data/lib/rest-assured/config.rb +24 -0
  21. data/lib/rest-assured/models/double.rb +32 -28
  22. data/lib/rest-assured/models/redirect.rb +28 -24
  23. data/lib/rest-assured/models/request.rb +11 -7
  24. data/lib/rest-assured/routes/double.rb +8 -8
  25. data/lib/rest-assured/routes/redirect.rb +8 -8
  26. data/lib/rest-assured/routes/response.rb +16 -14
  27. data/lib/rest-assured/version.rb +1 -1
  28. data/lib/sinatra/handler_options_patch.rb +25 -0
  29. data/spec/client/resource_double_spec.rb +42 -6
  30. data/spec/config_spec.rb +35 -0
  31. data/spec/functional/double_routes_spec.rb +109 -107
  32. data/spec/functional/redirect_routes_spec.rb +86 -75
  33. data/spec/functional/response_spec.rb +57 -55
  34. data/spec/models/double_spec.rb +67 -65
  35. data/spec/models/redirect_spec.rb +28 -26
  36. data/spec/models/request_spec.rb +10 -8
  37. data/ssl/localhost.crt +14 -0
  38. data/ssl/localhost.key +15 -0
  39. metadata +25 -24
  40. 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
- class Response
2
- def self.perform(app)
3
- request = app.request
1
+ module RestAssured
2
+ class Response
3
+ def self.perform(app)
4
+ request = app.request
4
5
 
5
- if d = Double.where(:fullpath => request.fullpath, :active => true, :verb => request.request_method).first
6
- request.body.rewind
7
- body = request.body.read #without temp variable ':body = > body' is always nil. mistery
8
- env = request.env.except('rack.input', 'rack.errors', 'rack.logger')
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
- d.requests.create!(:rack_env => env.to_json, :body => body, :params => request.params.to_json)
11
+ d.requests.create!(:rack_env => env.to_json, :body => body, :params => request.params.to_json)
11
12
 
12
- app.body d.content
13
- app.status d.status
14
- elsif r = Redirect.ordered.find { |r| request.fullpath =~ /#{r.pattern}/ }
15
- app.redirect( "#{r.to}#{request.fullpath}" )
16
- else
17
- app.status 404
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
@@ -1,3 +1,3 @@
1
1
  module RestAssured
2
- VERSION = '0.2.0.rc8'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -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::Client
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
@@ -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
- describe 'Double routes' do
4
- let :test_double do
5
- { :fullpath => '/api/google?a=5', :content => 'some awesome content', :verb => 'POST', :status => '201' }
6
- end
7
- let :valid_params do
8
- { 'double[fullpath]' => test_double[:fullpath], 'double[content]' => test_double[:content], 'double[verb]' => test_double[:verb], 'double[status]' => test_double[:status] }
9
- end
10
- let :invalid_params do
11
- valid_params.except('double[fullpath]')
12
- end
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
- it "shows list of doubles" do
21
- f = Double.create test_double
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
- visit '/doubles'
21
+ it "shows list of doubles" do
22
+ f = Models::Double.create test_double
24
23
 
25
- page.should have_content(f.fullpath)
26
- end
24
+ visit '/doubles'
27
25
 
28
- it "shows form for creating new double" do
29
- visit '/doubles/new'
26
+ page.should have_content(f.fullpath)
27
+ end
30
28
 
31
- page.should have_css('#double_fullpath')
32
- page.should have_css('#double_content')
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
- it "creates double" do
37
- post '/doubles', valid_params
38
- follow_redirect!
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
- last_request.fullpath.should == '/doubles'
41
- last_response.body.should =~ /Double created/
42
- Double.exists?(test_double).should be true
43
- end
37
+ it "creates double" do
38
+ post '/doubles', valid_params
39
+ follow_redirect!
44
40
 
45
- it "reports failure when creating with invalid parameters" do
46
- post '/doubles', invalid_params
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
- last_response.should be_ok
49
- last_response.body.should =~ /Crumps!.*Fullpath can't be blank/
50
- end
46
+ it "reports failure when creating with invalid parameters" do
47
+ post '/doubles', invalid_params
51
48
 
52
- it "brings up double edit form" do
53
- f = Double.create test_double
54
- visit "/doubles/#{f.id}/edit"
49
+ last_response.should be_ok
50
+ last_response.body.should =~ /Crumps!.*Fullpath can't be blank/
51
+ end
55
52
 
56
- find('#double_fullpath').value.should == f.fullpath
57
- find('#double_content').value.should == f.content
58
- end
53
+ it "brings up double edit form" do
54
+ f = Models::Double.create test_double
55
+ visit "/doubles/#{f.id}/edit"
59
56
 
60
- it "updates double" do
61
- f = Double.create test_double
57
+ find('#double_fullpath').value.should == f.fullpath
58
+ find('#double_content').value.should == f.content
59
+ end
62
60
 
63
- put "/doubles/#{f.id}", 'double[fullpath]' => '/some/other/api'
64
- follow_redirect!
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
- it "chooses active double" do
72
- f = Double.create test_double.merge!(:active => false)
64
+ put "/doubles/#{f.id}", 'double[fullpath]' => '/some/other/api'
65
+ follow_redirect!
73
66
 
74
- ajax "/doubles/#{f.id}", :as => :put, :active => true
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
- last_response.should be_ok
77
- last_response.body.should == 'Changed'
78
- end
72
+ it "chooses active double" do
73
+ f = Models::Double.create test_double.merge!(:active => false)
79
74
 
80
- it "deletes double" do
81
- f = Double.create test_double
75
+ ajax "/doubles/#{f.id}", :as => :put, :active => true
82
76
 
83
- delete "/doubles/#{f.id}"
84
- follow_redirect!
77
+ last_response.should be_ok
78
+ last_response.body.should == 'Changed'
79
+ end
85
80
 
86
- last_response.should be_ok
87
- last_response.body.should =~ /Double deleted/
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
- describe "through REST api", :ui => false do
94
- it "creates double" do
95
- post '/doubles', test_double
84
+ delete "/doubles/#{f.id}"
85
+ follow_redirect!
96
86
 
97
- last_response.should be_ok
98
- Double.exists?(test_double).should be_true
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
- it "reports failure when creating with invalid parameters" do
102
- post '/doubles', test_double.except(:fullpath)
94
+ describe "through REST api", :ui => false do
95
+ it "creates double" do
96
+ post '/doubles', test_double
103
97
 
104
- last_response.should_not be_ok
105
- last_response.body.should =~ /\{"fullpath":\["can't be blank"\]\}/
106
- end
98
+ last_response.should be_ok
99
+ Models::Double.exists?(test_double).should be_true
100
+ end
107
101
 
108
- it "deletes all doubles" do
109
- Double.create test_double
102
+ it "reports failure when creating with invalid parameters" do
103
+ post '/doubles', test_double.except(:fullpath)
110
104
 
111
- delete '/doubles/all'
105
+ last_response.should_not be_ok
106
+ last_response.body.should =~ /\{"fullpath":\["can't be blank"\]\}/
107
+ end
112
108
 
113
- last_response.should be_ok
114
- Double.count.should == 0
115
- end
116
- end
109
+ it "deletes all doubles" do
110
+ Models::Double.create test_double
117
111
 
118
- describe 'through REST (ActiveResource compatible) json api', :ui => false do
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
- last_response.should be_ok
123
- Double.exists?(test_double).should be_true
124
- last_response.body.should == Double.where(test_double).first.to_json
114
+ last_response.should be_ok
115
+ Models::Double.count.should == 0
116
+ end
125
117
  end
126
118
 
127
- it "reports failure when creating with invalid parameters" do
128
- post '/doubles.json', { :double => test_double.except(:fullpath) }.to_json, 'CONTENT_TYPE' => 'Application/json'
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
- last_response.should_not be_ok
131
- last_response.body.should =~ /\{"fullpath":\["can't be blank"\]\}/
132
- end
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
- it 'loads double as AR resource' do
135
- d = Double.create test_double
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
- get "/doubles/#{d.id}.json", 'CONTENT_TYPE' => 'Application/json'
131
+ last_response.should_not be_ok
132
+ last_response.body.should =~ /\{"fullpath":\["can't be blank"\]\}/
133
+ end
138
134
 
139
- last_response.should be_ok
140
- last_response.body.should == d.to_json(:include => :requests)
141
- end
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
- it '404s if double is not found' do
144
- get "/doubles/345345.json", 'CONTENT_TYPE' => 'Application/json'
145
-
146
- last_response.status.should == 404
147
+ last_response.status.should == 404
148
+ end
147
149
  end
148
150
  end
149
151
  end