rest-assured 0.2.0.rc8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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