rest-assured 0.1.4 → 0.2.0.rc1
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/README.markdown +6 -6
- data/db/migrate/20111013122857_create_requests.rb +15 -0
- data/db/migrate/20111016174101_rename_method_to_verb.rb +9 -0
- data/features/call_history.feature +16 -0
- data/features/doubles_via_api.feature +6 -6
- data/features/step_definitions/call_history_steps.rb +24 -0
- data/features/step_definitions/doubles_steps.rb +9 -8
- data/features/support/env.rb +16 -0
- data/features/support/test-server.rb +46 -0
- data/lib/rest-assured.rb +5 -17
- data/lib/rest-assured/client.rb +17 -0
- data/lib/rest-assured/client/double.rb +9 -0
- data/lib/rest-assured/client/resources.rb +7 -0
- data/lib/rest-assured/models/double.rb +7 -5
- data/lib/rest-assured/models/request.rb +12 -0
- data/lib/rest-assured/routes/double.rb +19 -5
- data/lib/rest-assured/routes/response.rb +17 -0
- data/lib/rest-assured/version.rb +1 -1
- data/rest-assured.gemspec +1 -1
- data/spec/client/resource_double_spec.rb +44 -0
- data/spec/functional/double_routes_spec.rb +35 -3
- data/spec/functional/response_spec.rb +56 -0
- data/spec/models/double_spec.rb +6 -5
- data/spec/models/request_spec.rb +15 -0
- data/spec/spec_helper.rb +18 -2
- metadata +46 -9
data/README.markdown
CHANGED
@@ -28,20 +28,20 @@ This starts an instance of rest-assured on port 4578 (changable with --port opti
|
|
28
28
|
|
29
29
|
Double is a stub/mock of a particular external call. There is the following rest API for setting up doubles:
|
30
30
|
|
31
|
-
* `POST '/doubles', { fullpath: path, content: content,
|
31
|
+
* `POST '/doubles', { fullpath: path, content: content, verb: verb }`
|
32
32
|
Creates double with the following parameters:
|
33
33
|
|
34
34
|
- __fullpath__ - e.g., `/some/api/object`, or with parameters in query string (useful for doubling GETs) - `/some/other/api/object?a=2&b=c`. Mandatory.
|
35
35
|
- __content__ - whatever you want this double to respond with. Mandatory.
|
36
|
-
-
|
36
|
+
- __verb__ - one of http the following http verbs: GET, POST, PUT, DELETE. Optional. GET is default.
|
37
37
|
|
38
38
|
Example (using ruby RestClient):
|
39
39
|
|
40
|
-
RestClient.post 'http://localhost:4578
|
40
|
+
RestClient.post 'http://localhost:4578/doubles', { fullpath: '/api/v2/products?type=fresh', verb: 'GET', content: 'this is list of products' }
|
41
41
|
|
42
42
|
Now GETting http://localhost:4578/api/v2/products?type=fresh (in browser for instance) should return "this is list of products".
|
43
43
|
|
44
|
-
If there is more than one double for the same request\_fullpath and
|
44
|
+
If there is more than one double for the same request\_fullpath and verb, the last created one gets served. In UI you can manually control which double is 'active' (gets served).
|
45
45
|
|
46
46
|
* `DELETE '/doubles/all'`
|
47
47
|
Deletes all doubles.
|
@@ -59,7 +59,7 @@ It is sometimes desirable to only double certain calls while letting others thro
|
|
59
59
|
|
60
60
|
RestClient.post 'http://localhost:4578/redirects', { pattern: '^/auth', to: 'https://myserver.com/api' }
|
61
61
|
|
62
|
-
Now request (any
|
62
|
+
Now request (any verb) to http://localhost:4578/auth/services/1 will get redirected to https://myserver.com/api/auth/services/1. Provided of course there is no double matched for that fullpath and verb.
|
63
63
|
Much like rewrite rules, redirects are evaluated in order (of creation). In UI you can manually rearrange the order.
|
64
64
|
|
65
65
|
### Storage
|
@@ -75,7 +75,7 @@ It is sometimes useful to see what requests rest-assured is being hit. Either to
|
|
75
75
|
* Implement expectations
|
76
76
|
* Support headers (extends previous point)
|
77
77
|
* Ruby client library
|
78
|
-
* Support
|
78
|
+
* Support verbs in UI (at the moment it is always GET)
|
79
79
|
* Don't allow to double internal routes. Just in case
|
80
80
|
|
81
81
|
## Author
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateRequests < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :requests do |t|
|
4
|
+
t.integer :double_id
|
5
|
+
t.text :params
|
6
|
+
t.text :body
|
7
|
+
t.text :rack_env
|
8
|
+
t.datetime :created_at
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
drop_table :requests
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: check double's call history
|
2
|
+
In order to verify outcomes of my app that take form of http requests
|
3
|
+
As test developer
|
4
|
+
I want to be able to get double 'call history'
|
5
|
+
|
6
|
+
Scenario: no calls made to double
|
7
|
+
Given there is a double
|
8
|
+
When I request call history for that double
|
9
|
+
Then it should be empty
|
10
|
+
|
11
|
+
@now
|
12
|
+
Scenario: some calls made to double
|
13
|
+
Given there is a double
|
14
|
+
When that double gets requested
|
15
|
+
And I request call history for that double
|
16
|
+
Then I should see history records for those requests
|
@@ -4,11 +4,11 @@ Feature: use doubles via api
|
|
4
4
|
I want to mock rest services my app is consuming from
|
5
5
|
|
6
6
|
Scenario Outline: create double
|
7
|
-
When I create a double with "<fullpath>" as fullpath, "<content>" as response content and "<
|
8
|
-
Then there should be 1 double with "<fullpath>" as fullpath, "<content>" as response content and "<
|
7
|
+
When I create a double with "<fullpath>" as fullpath, "<content>" as response content and "<verb>" as request verb
|
8
|
+
Then there should be 1 double with "<fullpath>" as fullpath, "<content>" as response content and "<result_verb>" as request verb
|
9
9
|
|
10
10
|
Examples:
|
11
|
-
| fullpath | content |
|
11
|
+
| fullpath | content | verb | result_verb |
|
12
12
|
| /api/something | created | POST | POST |
|
13
13
|
| /api/sss | changed | PUT | PUT |
|
14
14
|
| /api/asdfsf | removed | DELETE | DELETE |
|
@@ -16,12 +16,12 @@ Feature: use doubles via api
|
|
16
16
|
| /api/some?a=3&b=dd | more content | | GET |
|
17
17
|
|
18
18
|
Scenario Outline: request fullpath that matches double
|
19
|
-
Given there is double with "<fullpath>" as fullpath, "<content>" as response content and "<
|
20
|
-
When I "<
|
19
|
+
Given there is double with "<fullpath>" as fullpath, "<content>" as response content and "<verb>" as request verb
|
20
|
+
When I "<verb>" "<fullpath>"
|
21
21
|
Then I should get "<content>" in response content
|
22
22
|
|
23
23
|
Examples:
|
24
|
-
| fullpath | content |
|
24
|
+
| fullpath | content | verb |
|
25
25
|
| /api/something | created | POST |
|
26
26
|
| /api/sss | changed | PUT |
|
27
27
|
| /api/asdfsf | removed | DELETE |
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Given /^there is a double$/ do
|
2
|
+
@double = RestAssured::Client::Double.create(:fullpath => '/some/path', :content => 'some content', :verb => 'POST')
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^that double gets requested$/ do
|
6
|
+
post @double.fullpath, { :foo => 'bar' }.to_json, "CONTENT_TYPE" => "application/json"
|
7
|
+
post @double.fullpath, { :fooz => 'baaz'}, 'SOME_HEADER' => 'header_data'
|
8
|
+
end
|
9
|
+
|
10
|
+
When /^I request call history for that double$/ do
|
11
|
+
@requests = @double.reload.requests
|
12
|
+
end
|
13
|
+
|
14
|
+
Then /^I should see history records for those requests$/ do
|
15
|
+
@requests.first.body.should == { :foo => 'bar' }.to_json
|
16
|
+
JSON.parse( @requests.first.rack_env )["CONTENT_TYPE"].should == 'application/json'
|
17
|
+
|
18
|
+
JSON.parse( @requests.last.params ).should == { 'fooz' => 'baaz' }
|
19
|
+
JSON.parse( @requests.last.rack_env )["SOME_HEADER"].should == 'header_data'
|
20
|
+
end
|
21
|
+
|
22
|
+
Then /^it should be empty$/ do
|
23
|
+
@requests.size.should == 0
|
24
|
+
end
|
@@ -9,8 +9,8 @@ When /^I create a double with "([^"]*)" as fullpath and "([^"]*)" as response co
|
|
9
9
|
last_response.should be_ok
|
10
10
|
end
|
11
11
|
|
12
|
-
When /^I create a double with "([^"]*)" as fullpath, "([^"]*)" as response content and "([^"]*)" as request
|
13
|
-
post '/doubles', { :fullpath => fullpath, :content => content, :
|
12
|
+
When /^I create a double with "([^"]*)" as fullpath, "([^"]*)" as response content and "([^"]*)" as request verb$/ do |fullpath, content, verb|
|
13
|
+
post '/doubles', { :fullpath => fullpath, :content => content, :verb => verb }
|
14
14
|
last_response.should be_ok
|
15
15
|
end
|
16
16
|
|
@@ -18,16 +18,16 @@ Then /^there should be (#{CAPTURE_A_NUMBER}) double with "([^"]*)" as fullpath a
|
|
18
18
|
Double.where(:fullpath => fullpath, :content => content).count.should == 1
|
19
19
|
end
|
20
20
|
|
21
|
-
Then /^there should be (#{CAPTURE_A_NUMBER}) double with "([^"]*)" as fullpath, "([^"]*)" as response content and "([^"]*)" as request
|
22
|
-
Double.where(:fullpath => fullpath, :content => content, :
|
21
|
+
Then /^there should be (#{CAPTURE_A_NUMBER}) double with "([^"]*)" as fullpath, "([^"]*)" as response content and "([^"]*)" as request verb$/ do |n, fullpath, content, verb|
|
22
|
+
Double.where(:fullpath => fullpath, :content => content, :verb => verb).count.should == n
|
23
23
|
end
|
24
24
|
|
25
25
|
Given /^there is double with "([^"]*)" as fullpath and "([^"]*)" as response content$/ do |fullpath, content|
|
26
26
|
Double.create(:fullpath => fullpath, :content => content)
|
27
27
|
end
|
28
28
|
|
29
|
-
Given /^there is double with "([^"]*)" as fullpath, "([^"]*)" as response content and "([^"]*)" as request
|
30
|
-
Double.create(:fullpath => fullpath, :content => content, :
|
29
|
+
Given /^there is double with "([^"]*)" as fullpath, "([^"]*)" as response content and "([^"]*)" as request verb$/ do |fullpath, content, verb|
|
30
|
+
Double.create(:fullpath => fullpath, :content => content, :verb => verb)
|
31
31
|
end
|
32
32
|
|
33
33
|
Given /^I register "([^"]*)" as fullpath and "([^"]*)" as response content$/ do |fullpath, content|
|
@@ -39,8 +39,8 @@ When /^I request "([^"]*)"$/ do |fullpath|
|
|
39
39
|
get fullpath
|
40
40
|
end
|
41
41
|
|
42
|
-
When /^I "([^"]*)" "([^"]*)"$/ do |
|
43
|
-
send(
|
42
|
+
When /^I "([^"]*)" "([^"]*)"$/ do |verb, fullpath|
|
43
|
+
send(verb.downcase, fullpath)
|
44
44
|
end
|
45
45
|
|
46
46
|
Then /^I should get "([^"]*)" in response content$/ do |content|
|
@@ -141,3 +141,4 @@ end
|
|
141
141
|
Then /^I should be asked to confirm delete$/ do
|
142
142
|
page.driver.browser.switch_to.alert.accept
|
143
143
|
end
|
144
|
+
|
data/features/support/env.rb
CHANGED
@@ -33,11 +33,27 @@ Spork.prefork do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
World(Capybara, Rack::Test::Methods, RackHeaderHack)
|
36
|
+
|
36
37
|
end
|
37
38
|
|
38
39
|
|
39
40
|
Spork.each_run do
|
40
41
|
require 'rest-assured'
|
42
|
+
require 'rest-assured/client'
|
43
|
+
require File.expand_path('../test-server', __FILE__)
|
44
|
+
|
45
|
+
at_exit do
|
46
|
+
TestServer.stop
|
47
|
+
end
|
48
|
+
|
49
|
+
TestServer.start(:port => 9876)
|
50
|
+
|
51
|
+
while not TestServer.up?
|
52
|
+
puts 'Waiting for TestServer to come up...'
|
53
|
+
sleep 1
|
54
|
+
end
|
55
|
+
|
56
|
+
RestAssured::Client.config.server_address = 'http://localhost:9876'
|
41
57
|
|
42
58
|
def app
|
43
59
|
RestAssured::Application
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
# This is only needed till I get ActiveResource going through rack-test
|
4
|
+
class TestServer
|
5
|
+
@pid_file = "./rest-assured.pid"
|
6
|
+
|
7
|
+
def self.start(opts = {})
|
8
|
+
@server_port = opts[:port] || 9876
|
9
|
+
|
10
|
+
print 'Starting TestServer server... '
|
11
|
+
|
12
|
+
p = Process.fork do
|
13
|
+
if get_pid
|
14
|
+
print "\nPrevious TestServer instance appears to be running. Will be using it."
|
15
|
+
else
|
16
|
+
Process.exec("bundle exec rest-assured -p #{@server_port}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Process.detach(p)
|
21
|
+
puts 'Done.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.stop
|
25
|
+
print 'Shutting down TestServer server... '
|
26
|
+
Process.kill('TERM', get_pid.to_i) rescue puts( "Failed to kill TestServer server: #{$!}" )
|
27
|
+
puts 'Done.'
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.server_address
|
31
|
+
"http://localhost:#{@server_port}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.up?
|
35
|
+
Net::HTTP.new('localhost', @server_port).head('/')
|
36
|
+
true
|
37
|
+
rescue Errno::ECONNREFUSED
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def self.get_pid
|
44
|
+
`ps -eo pid,args`.split("\n").grep( /rest-assured -p #{@server_port}/ ).map{|p| p.split.first }.first
|
45
|
+
end
|
46
|
+
end
|
data/lib/rest-assured.rb
CHANGED
@@ -2,14 +2,15 @@ require 'rubygems'
|
|
2
2
|
require 'sinatra/base'
|
3
3
|
require 'haml'
|
4
4
|
require 'sass'
|
5
|
-
#require 'sinatra/reloader'
|
6
5
|
require 'rack-flash'
|
7
6
|
require 'sinatra/partials'
|
8
7
|
require 'rest-assured/init'
|
9
8
|
require 'rest-assured/models/double'
|
10
9
|
require 'rest-assured/models/redirect'
|
10
|
+
require 'rest-assured/models/request'
|
11
11
|
require 'rest-assured/routes/double'
|
12
12
|
require 'rest-assured/routes/redirect'
|
13
|
+
require 'rest-assured/routes/response'
|
13
14
|
|
14
15
|
module RestAssured
|
15
16
|
class Application < Sinatra::Base
|
@@ -46,23 +47,10 @@ module RestAssured
|
|
46
47
|
scss :base
|
47
48
|
end
|
48
49
|
|
49
|
-
%w{get post put delete}.each do |
|
50
|
-
send
|
51
|
-
|
50
|
+
%w{get post put delete}.each do |verb|
|
51
|
+
send verb, /.*/ do
|
52
|
+
Response.perform(self)
|
52
53
|
end
|
53
54
|
end
|
54
|
-
|
55
|
-
#configure(:development) do
|
56
|
-
#register Sinatra::Reloader
|
57
|
-
#end
|
58
|
-
|
59
|
-
private
|
60
|
-
def try_redirect(request)
|
61
|
-
r = Redirect.ordered.find do |r|
|
62
|
-
request.fullpath =~ /#{r.pattern}/
|
63
|
-
end
|
64
|
-
|
65
|
-
r && redirect( "#{r.to}#{request.fullpath}" )
|
66
|
-
end
|
67
55
|
end
|
68
56
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RestAssured
|
2
|
+
module Client
|
3
|
+
class Config
|
4
|
+
attr_reader :server_address
|
5
|
+
|
6
|
+
def server_address=(addr)
|
7
|
+
@server_address = Double.site = addr
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.config
|
12
|
+
@config ||= Config.new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'rest-assured/client/resources'
|
@@ -1,15 +1,17 @@
|
|
1
1
|
class Double < ActiveRecord::Base
|
2
|
-
attr_accessible :fullpath, :content, :description, :
|
2
|
+
attr_accessible :fullpath, :content, :description, :verb
|
3
3
|
|
4
4
|
METHODS = %w{GET POST PUT DELETE}
|
5
5
|
|
6
6
|
validates_presence_of :fullpath, :content
|
7
|
-
validates_inclusion_of :
|
7
|
+
validates_inclusion_of :verb, :in => METHODS
|
8
8
|
|
9
9
|
before_save :toggle_active
|
10
|
-
before_validation :
|
10
|
+
before_validation :set_verb
|
11
11
|
after_destroy :set_active
|
12
12
|
|
13
|
+
has_many :requests
|
14
|
+
|
13
15
|
private
|
14
16
|
def toggle_active
|
15
17
|
ne = id ? '!=' : 'IS NOT'
|
@@ -19,8 +21,8 @@ class Double < ActiveRecord::Base
|
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
def
|
23
|
-
self.
|
24
|
+
def set_verb
|
25
|
+
self.verb = 'GET' unless verb.present?
|
24
26
|
end
|
25
27
|
|
26
28
|
def set_active
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
1
3
|
module RestAssured
|
2
4
|
module DoubleRoutes
|
3
5
|
def self.included(router)
|
@@ -15,9 +17,19 @@ module RestAssured
|
|
15
17
|
haml :'doubles/new'
|
16
18
|
end
|
17
19
|
|
18
|
-
router.
|
19
|
-
|
20
|
-
|
20
|
+
router.get '/doubles/:id.json' do |id|
|
21
|
+
begin
|
22
|
+
double = Double.find(id)
|
23
|
+
body double.to_json(:include => :requests)
|
24
|
+
rescue ActiveRecord::RecordNotFound
|
25
|
+
status 404
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
router.post /^\/doubles(\.json)?$/ do |passes_json|
|
30
|
+
f = { :fullpath => params['fullpath'], :content => params['content'], :description => params['description'], :verb => params['verb'] }
|
31
|
+
|
32
|
+
@double = Double.create(passes_json ? JSON.parse(request.body.read)['double'] : ( params['double'] || f ))
|
21
33
|
|
22
34
|
if browser?
|
23
35
|
if @double.errors.blank?
|
@@ -29,8 +41,10 @@ module RestAssured
|
|
29
41
|
end
|
30
42
|
else
|
31
43
|
if @double.errors.present?
|
32
|
-
status
|
33
|
-
body @double.errors.
|
44
|
+
status 422
|
45
|
+
body @double.errors.to_json
|
46
|
+
else
|
47
|
+
body @double.to_json
|
34
48
|
end
|
35
49
|
end
|
36
50
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Response
|
2
|
+
def self.perform(app)
|
3
|
+
request = app.request
|
4
|
+
|
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
|
+
d.requests.create!(:rack_env => request.env.to_json, :body => body, :params => request.params.to_json)
|
9
|
+
|
10
|
+
app.body d.content
|
11
|
+
elsif r = Redirect.ordered.find { |r| request.fullpath =~ /#{r.pattern}/ }
|
12
|
+
app.redirect( "#{r.to}#{request.fullpath}" )
|
13
|
+
else
|
14
|
+
app.status 404
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/rest-assured/version.rb
CHANGED
data/rest-assured.gemspec
CHANGED
@@ -22,10 +22,10 @@ Gem::Specification.new do |s|
|
|
22
22
|
|
23
23
|
s.add_dependency 'sinatra', '>= 1.3.1'
|
24
24
|
s.add_dependency 'rack-flash', '>= 0.1.2'
|
25
|
-
#s.add_dependency 'sinatra-reloader'
|
26
25
|
s.add_dependency 'haml', '>= 3.1.3'
|
27
26
|
s.add_dependency 'sass', '>= 3.1.8'
|
28
27
|
s.add_dependency 'activerecord', '~> 3.1.0'
|
29
28
|
s.add_dependency 'sqlite3', '>= 1.3.4'
|
29
|
+
s.add_dependency 'activeresource'
|
30
30
|
end
|
31
31
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
3
|
+
|
4
|
+
module RestAssured::Client
|
5
|
+
describe Double do
|
6
|
+
before do
|
7
|
+
@orig_addr = RestAssured::Client.config.server_address
|
8
|
+
end
|
9
|
+
|
10
|
+
after do
|
11
|
+
RestAssured::Client.config.server_address = @orig_addr
|
12
|
+
end
|
13
|
+
|
14
|
+
it { should be_kind_of ActiveResource::Base }
|
15
|
+
|
16
|
+
it 'knows where rest-assured server is' do
|
17
|
+
RestAssured::Client.config.server_address = 'http://localhost:1234'
|
18
|
+
Double.site.should == URI.parse('http://localhost:1234')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'creates new double' do
|
22
|
+
d = Double.create :fullpath => '/some/api', :content => 'content'
|
23
|
+
::Double.where(:id => d.id).should exist
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'finds exising double' do
|
27
|
+
d = ::Double.create :fullpath => '/some/api', :content => 'content'
|
28
|
+
|
29
|
+
Double.find(d.id).id.should be d.id
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'shows request history' do
|
33
|
+
d = ::Double.create :fullpath => '/some/api', :content => 'content'
|
34
|
+
d.requests << Request.create(:rack_env => 'rack_env json', :body => 'body', :params => 'params')
|
35
|
+
d.requests << Request.create(:rack_env => 'different rack_env', :body => 'other body', :params => 'more params')
|
36
|
+
|
37
|
+
dd = Double.find(d.id)
|
38
|
+
dd.requests.size.should == 2
|
39
|
+
dd.requests.first.rack_env.should == 'rack_env json'
|
40
|
+
dd.requests.first.params.should == 'params'
|
41
|
+
dd.requests.last.body.should == 'other body'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -2,10 +2,10 @@ require File.expand_path('../../spec_helper', __FILE__)
|
|
2
2
|
|
3
3
|
describe 'Double routes' do
|
4
4
|
let :test_double do
|
5
|
-
{ :fullpath => '/api/google?a=5', :content => 'some awesome content', :
|
5
|
+
{ :fullpath => '/api/google?a=5', :content => 'some awesome content', :verb => 'POST' }
|
6
6
|
end
|
7
7
|
let :valid_params do
|
8
|
-
{ 'double[fullpath]' => test_double[:fullpath], 'double[content]' => test_double[:content], 'double[
|
8
|
+
{ 'double[fullpath]' => test_double[:fullpath], 'double[content]' => test_double[:content], 'double[verb]' => test_double[:verb] }
|
9
9
|
end
|
10
10
|
let :invalid_params do
|
11
11
|
{ 'double[fullpath]' => test_double[:fullpath] }
|
@@ -102,7 +102,7 @@ describe 'Double routes' do
|
|
102
102
|
post '/doubles', test_double.except(:content)
|
103
103
|
|
104
104
|
last_response.should_not be_ok
|
105
|
-
last_response.body.should =~
|
105
|
+
last_response.body.should =~ /\{"content":\["can't be blank"\]\}/
|
106
106
|
end
|
107
107
|
|
108
108
|
it "deletes all doubles" do
|
@@ -114,4 +114,36 @@ describe 'Double routes' do
|
|
114
114
|
Double.count.should == 0
|
115
115
|
end
|
116
116
|
end
|
117
|
+
|
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'
|
121
|
+
|
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
|
125
|
+
end
|
126
|
+
|
127
|
+
it "reports failure when creating with invalid parameters" do
|
128
|
+
post '/doubles.json', { :double => test_double.except(:content) }.to_json, 'CONTENT_TYPE' => 'Application/json'
|
129
|
+
|
130
|
+
last_response.should_not be_ok
|
131
|
+
last_response.body.should =~ /\{"content":\["can't be blank"\]\}/
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'loads double as AR resource' do
|
135
|
+
d = Double.create test_double
|
136
|
+
|
137
|
+
get "/doubles/#{d.id}.json", 'CONTENT_TYPE' => 'Application/json'
|
138
|
+
|
139
|
+
last_response.should be_ok
|
140
|
+
last_response.body.should == d.to_json(:include => :requests)
|
141
|
+
end
|
142
|
+
|
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
|
+
end
|
148
|
+
end
|
117
149
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'rest-assured/routes/response'
|
3
|
+
|
4
|
+
describe Response do
|
5
|
+
[:get, :post, :put, :delete].each do |verb|
|
6
|
+
it "processes an unknown request" do
|
7
|
+
|
8
|
+
Response.should_receive(:perform).with(an_instance_of(RestAssured::Application))
|
9
|
+
send verb, '/some/path'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:request) {
|
14
|
+
double('Request',
|
15
|
+
:request_method => 'GET',
|
16
|
+
:fullpath => '/api',
|
17
|
+
:env => stub(:to_json => 'env'),
|
18
|
+
:body => stub(:read => 'body').as_null_object,
|
19
|
+
:params => stub(:to_json => 'params')
|
20
|
+
)
|
21
|
+
}
|
22
|
+
let(:rest_assured_app) { double('App', :request => request).as_null_object }
|
23
|
+
|
24
|
+
it "returns double content if an active one found with the same fullpath and the same method as request" do
|
25
|
+
d = Double.create :fullpath => '/some/path', :content => 'content'
|
26
|
+
request.stub(:fullpath).and_return(d.fullpath)
|
27
|
+
|
28
|
+
rest_assured_app.should_receive(:body).with(d.content)
|
29
|
+
Response.perform(rest_assured_app)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "redirects if double not hit but there is redirect that matches request" do
|
33
|
+
r = Redirect.create :to => 'http://exmple.com/api', :pattern => '.*'
|
34
|
+
fullpath = '/some/other/path'
|
35
|
+
request.stub(:fullpath).and_return(fullpath)
|
36
|
+
|
37
|
+
rest_assured_app.should_receive(:redirect).with(r.to + fullpath)
|
38
|
+
|
39
|
+
Response.perform(rest_assured_app)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns 404 if neither double nor redirect matches the request" do
|
43
|
+
rest_assured_app.should_receive(:status).with(404)
|
44
|
+
|
45
|
+
Response.perform(rest_assured_app)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'records request if double matches' do
|
49
|
+
requests = double
|
50
|
+
Double.stub_chain('where.first').and_return(double(:requests => requests).as_null_object)
|
51
|
+
|
52
|
+
requests.should_receive(:create!).with(:rack_env => 'env', :body => 'body', :params => 'params')
|
53
|
+
|
54
|
+
Response.perform(rest_assured_app)
|
55
|
+
end
|
56
|
+
end
|
data/spec/models/double_spec.rb
CHANGED
@@ -2,16 +2,17 @@ require File.expand_path('../../spec_helper', __FILE__)
|
|
2
2
|
|
3
3
|
describe Double do
|
4
4
|
let :valid_params do
|
5
|
-
{ :fullpath => '/some/api', :content => 'some content', :
|
5
|
+
{ :fullpath => '/some/api', :content => 'some content', :verb => 'GET' }
|
6
6
|
end
|
7
7
|
|
8
8
|
it { should validate_presence_of(:fullpath) }
|
9
9
|
it { should validate_presence_of(:content) }
|
10
|
-
#it { should ensure_inclusion_of(:
|
10
|
+
#it { should ensure_inclusion_of(:verb).in(Double::METHODS) }
|
11
|
+
it { should have_many(:requests) }
|
11
12
|
|
12
|
-
it "defaults
|
13
|
-
f = Double.create valid_params.except(:
|
14
|
-
f.
|
13
|
+
it "defaults verb to GET" do
|
14
|
+
f = Double.create valid_params.except(:verb)
|
15
|
+
f.verb.should == 'GET'
|
15
16
|
end
|
16
17
|
|
17
18
|
it "makes double active by default" do
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'rest-assured/models/request'
|
3
|
+
|
4
|
+
describe Request do
|
5
|
+
it { should belong_to(:double) }
|
6
|
+
it { should validate_presence_of(:rack_env) }
|
7
|
+
|
8
|
+
it 'knows when it has been created' do
|
9
|
+
now = Time.now
|
10
|
+
Time.stub(:now).and_return(now)
|
11
|
+
r = Request.create(:body => 'sdfsd', :rack_env => 'headers')
|
12
|
+
|
13
|
+
r.created_at.should == now
|
14
|
+
end
|
15
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'spork'
|
3
3
|
|
4
|
+
$:.unshift(File.expand_path('../../lib'), __FILE__)
|
5
|
+
|
4
6
|
Spork.prefork do
|
5
7
|
require 'capybara/rspec'
|
6
8
|
require 'rack/test'
|
@@ -40,10 +42,23 @@ Spork.prefork do
|
|
40
42
|
end
|
41
43
|
|
42
44
|
Spork.each_run do
|
43
|
-
require
|
45
|
+
require 'rest-assured'
|
46
|
+
require 'rest-assured/client'
|
44
47
|
require 'shoulda-matchers'
|
48
|
+
require File.expand_path('../../features/support/test-server', __FILE__)
|
45
49
|
|
46
|
-
|
50
|
+
at_exit do
|
51
|
+
TestServer.stop
|
52
|
+
end
|
53
|
+
|
54
|
+
TestServer.start(:port => 9876)
|
55
|
+
|
56
|
+
while not TestServer.up?
|
57
|
+
puts 'Waiting for TestServer to come up...'
|
58
|
+
sleep 1
|
59
|
+
end
|
60
|
+
|
61
|
+
RestAssured::Client.config.server_address = 'http://localhost:9876'
|
47
62
|
|
48
63
|
Capybara.app = RestAssured::Application
|
49
64
|
|
@@ -51,4 +66,5 @@ Spork.each_run do
|
|
51
66
|
RestAssured::Application
|
52
67
|
end
|
53
68
|
|
69
|
+
DatabaseCleaner.strategy = :truncation
|
54
70
|
end
|
metadata
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-assured
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 15424055
|
5
|
+
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
- rc
|
8
11
|
- 1
|
9
|
-
|
10
|
-
version: 0.1.4
|
12
|
+
version: 0.2.0.rc1
|
11
13
|
platform: ruby
|
12
14
|
authors:
|
13
15
|
- Artem Avetisyan
|
@@ -15,7 +17,7 @@ autorequire:
|
|
15
17
|
bindir: bin
|
16
18
|
cert_chain: []
|
17
19
|
|
18
|
-
date: 2011-10-
|
20
|
+
date: 2011-10-17 00:00:00 Z
|
19
21
|
dependencies:
|
20
22
|
- !ruby/object:Gem::Dependency
|
21
23
|
name: sinatra
|
@@ -113,6 +115,20 @@ dependencies:
|
|
113
115
|
version: 1.3.4
|
114
116
|
type: :runtime
|
115
117
|
version_requirements: *id006
|
118
|
+
- !ruby/object:Gem::Dependency
|
119
|
+
name: activeresource
|
120
|
+
prerelease: false
|
121
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
hash: 3
|
127
|
+
segments:
|
128
|
+
- 0
|
129
|
+
version: "0"
|
130
|
+
type: :runtime
|
131
|
+
version_requirements: *id007
|
116
132
|
description:
|
117
133
|
email:
|
118
134
|
- artem.avetisyan@bbc.co.uk
|
@@ -140,25 +156,35 @@ files:
|
|
140
156
|
- db/migrate/20110823132023_add_method_to_fixtures.rb
|
141
157
|
- db/migrate/20110912162948_rename_url_to_fullpath.rb
|
142
158
|
- db/migrate/20110912163705_rename_fixtures_to_doubles.rb
|
159
|
+
- db/migrate/20111013122857_create_requests.rb
|
160
|
+
- db/migrate/20111016174101_rename_method_to_verb.rb
|
161
|
+
- features/call_history.feature
|
143
162
|
- features/doubles_via_api.feature
|
144
163
|
- features/doubles_via_ui.feature
|
145
164
|
- features/persistence.feature
|
146
165
|
- features/redirect_rules_via_api.feature
|
147
166
|
- features/redirect_rules_via_ui.feature
|
167
|
+
- features/step_definitions/call_history_steps.rb
|
148
168
|
- features/step_definitions/doubles_steps.rb
|
149
169
|
- features/step_definitions/persistence_steps.rb
|
150
170
|
- features/step_definitions/redirect_rules_steps.rb
|
151
171
|
- features/step_definitions/support/numeric_transforms.rb
|
152
172
|
- features/support/env.rb
|
153
173
|
- features/support/selenium-fix.rb
|
174
|
+
- features/support/test-server.rb
|
154
175
|
- lib/active_record/leak_connection_patch.rb
|
155
176
|
- lib/rest-assured.rb
|
177
|
+
- lib/rest-assured/client.rb
|
178
|
+
- lib/rest-assured/client/double.rb
|
179
|
+
- lib/rest-assured/client/resources.rb
|
156
180
|
- lib/rest-assured/config.rb
|
157
181
|
- lib/rest-assured/init.rb
|
158
182
|
- lib/rest-assured/models/double.rb
|
159
183
|
- lib/rest-assured/models/redirect.rb
|
184
|
+
- lib/rest-assured/models/request.rb
|
160
185
|
- lib/rest-assured/routes/double.rb
|
161
186
|
- lib/rest-assured/routes/redirect.rb
|
187
|
+
- lib/rest-assured/routes/response.rb
|
162
188
|
- lib/rest-assured/version.rb
|
163
189
|
- lib/sinatra/partials.rb
|
164
190
|
- public/css/grid.inuit.css
|
@@ -177,10 +203,13 @@ files:
|
|
177
203
|
- public/javascript/application.js
|
178
204
|
- public/javascript/jquery.jgrowl_minimized.js
|
179
205
|
- rest-assured.gemspec
|
206
|
+
- spec/client/resource_double_spec.rb
|
180
207
|
- spec/functional/double_routes_spec.rb
|
181
208
|
- spec/functional/redirect_routes_spec.rb
|
209
|
+
- spec/functional/response_spec.rb
|
182
210
|
- spec/models/double_spec.rb
|
183
211
|
- spec/models/redirect_spec.rb
|
212
|
+
- spec/models/request_spec.rb
|
184
213
|
- spec/spec_helper.rb
|
185
214
|
- views/base.scss
|
186
215
|
- views/doubles/_form.haml
|
@@ -214,12 +243,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
214
243
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
215
244
|
none: false
|
216
245
|
requirements:
|
217
|
-
- - "
|
246
|
+
- - ">"
|
218
247
|
- !ruby/object:Gem::Version
|
219
|
-
hash:
|
248
|
+
hash: 25
|
220
249
|
segments:
|
221
|
-
-
|
222
|
-
|
250
|
+
- 1
|
251
|
+
- 3
|
252
|
+
- 1
|
253
|
+
version: 1.3.1
|
223
254
|
requirements: []
|
224
255
|
|
225
256
|
rubyforge_project: rest-assured
|
@@ -228,19 +259,25 @@ signing_key:
|
|
228
259
|
specification_version: 3
|
229
260
|
summary: A tool for high level mocking/stubbing HTTP based REST services
|
230
261
|
test_files:
|
262
|
+
- features/call_history.feature
|
231
263
|
- features/doubles_via_api.feature
|
232
264
|
- features/doubles_via_ui.feature
|
233
265
|
- features/persistence.feature
|
234
266
|
- features/redirect_rules_via_api.feature
|
235
267
|
- features/redirect_rules_via_ui.feature
|
268
|
+
- features/step_definitions/call_history_steps.rb
|
236
269
|
- features/step_definitions/doubles_steps.rb
|
237
270
|
- features/step_definitions/persistence_steps.rb
|
238
271
|
- features/step_definitions/redirect_rules_steps.rb
|
239
272
|
- features/step_definitions/support/numeric_transforms.rb
|
240
273
|
- features/support/env.rb
|
241
274
|
- features/support/selenium-fix.rb
|
275
|
+
- features/support/test-server.rb
|
276
|
+
- spec/client/resource_double_spec.rb
|
242
277
|
- spec/functional/double_routes_spec.rb
|
243
278
|
- spec/functional/redirect_routes_spec.rb
|
279
|
+
- spec/functional/response_spec.rb
|
244
280
|
- spec/models/double_spec.rb
|
245
281
|
- spec/models/redirect_spec.rb
|
282
|
+
- spec/models/request_spec.rb
|
246
283
|
- spec/spec_helper.rb
|