Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Changes redirects to support references to regex captured groups

  • Loading branch information...
commit 02d8bf0a81a0bbad08a64f6fae628e0bc799103d 1 parent eaedcfe
@artemave artemave authored
View
1  .rspec
@@ -0,0 +1 @@
+--color
View
1  Gemfile
@@ -3,6 +3,7 @@ source "http://rubygems.org"
# Specify your gem's dependencies in rest-assured.gemspec
gemspec
+gem 'awesome_print'
gem 'cucumber'
gem 'database_cleaner'
gem 'rspec'
View
4 README.markdown
@@ -163,7 +163,7 @@ For those using rest-assured from non-ruby environments.
It is sometimes desirable to only double certain calls while letting others through to the 'real' services. Meet Redirects. Kind of "rewrite rules" for requests that didn't match any double.
-Another potential use for redirects is setting up a 'default' double that matches multiple fullpaths. This is of course given your app does not mind an extra redirect. Also note that 'default' double still covers only one http verb so requests with different methods won't match.
+Another potential use for redirects is setting up a 'default' double that matches multiple fullpaths. This is of course given your app does not mind an extra redirect. Also note that 'default' double still covers single http verb so requests with different methods won't match.
Here is the rest API for managing redirects:
@@ -179,7 +179,7 @@ Here is the rest API for managing redirects:
bash$ curl -d 'pattern=^/auth&to=https://myserver.com/api' http://localhost:4578/redirects
- 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.
+ Now request (any verb) to 'http://localhost:4578/auth/services/1' will get redirected to 'https://myserver.com/api/'. Provided of course there is no double matched for that fullpath and verb. Captured group in pattern can be referenced from replacement e.g. \\1, \\2, etc.
Much like rewrite rules, redirects are evaluated in order (of creation). In UI you can manually rearrange the order.
### Delete all redirects
View
19 features/rest_api/redirects.feature
@@ -1,3 +1,4 @@
+@now
Feature: manage redirect rules
In order to be able to mock only part of api
As a developer
@@ -10,21 +11,21 @@ Feature: manage redirect rules
Scenario: add redirect rule
Given blank slate
- When I register redirect with pattern "^/api" and uri "http://real.api.co.uk"
+ When I create redirect from "^/api/(.*)" to "http://example.com/\1"
And I request "/api/something"
- Then it should redirect to "http://real.api.co.uk/api/something"
+ Then it should redirect to "http://example.com/something"
Scenario: add second redirect that match the same request
- Given there is redirect with pattern "/api/something" and uri "http://real.api.co.uk"
- When I register redirect with pattern "/api/some.*" and uri "http://real.com"
+ Given there is redirect from "/api/something" to "http://example.com"
+ When I create redirect from "/api/some.*" to "http://real.com"
And I request "/api/something"
- Then it should redirect to "http://real.api.co.uk/api/something"
+ Then it should redirect to "http://example.com/"
Scenario: add second redirect that does not match the same request
- Given there is redirect with pattern "/api/something" and uri "http://real.api.co.uk"
- When I register redirect with pattern "/api/some" and uri "http://real.com"
- And I request "/api/someth"
- Then it should redirect to "http://real.com/api/someth"
+ Given there is redirect from "/api/thing" to "http://real.com"
+ When I create redirect from "/api/some.*" to "http://example.com"
+ And I request "/api/something"
+ Then it should redirect to "http://example.com/"
Scenario: clear redirects
Given there are some redirects
View
4 features/step_definitions/doubles_steps.rb
@@ -39,6 +39,10 @@
get fullpath
end
+When /sleep (\d+)/ do |n|
+ sleep n
+end
+
When /^I "([^"]*)" "([^"]*)"$/ do |verb, fullpath|
send(verb.downcase, fullpath)
end
View
8 features/step_definitions/redirect_rules_steps.rb
@@ -2,18 +2,14 @@
last_response.status.should.to_s == code
end
-Given /^there is redirect with pattern "([^"]*)" and uri "([^"]*)"$/ do |pattern, url|
+When /^(?:I create|there is) redirect from "([^"]*)" to "([^"]*)"$/ do |pattern, url|
post '/redirects', { :pattern => pattern, :to => url }
last_response.should be_ok
end
-When /^I register redirect with pattern "([^"]*)" and uri "([^"]*)"$/ do |pattern, url|
- step %{there is redirect with pattern "#{pattern}" and uri "#{url}"}
-end
-
Then /^it should redirect to "([^"]*)"$/ do |real_api_url|
follow_redirect!
- last_response.header['Location'].should == real_api_url
+ last_request.url.should == real_api_url
end
Given /^the following redirects exist:$/ do |redirects|
View
1  features/support/env.rb
@@ -9,6 +9,7 @@
require 'capybara/firebug'
require 'capybara/cucumber'
require 'database_cleaner'
+ require 'awesome_print'
require File.dirname(__FILE__) + '/world_helpers'
ENV['RACK_ENV'] = 'test'
View
6 lib/rest-assured/models/redirect.rb
@@ -9,6 +9,12 @@ class Redirect < ActiveRecord::Base
before_create :assign_position
+ def self.find_redirect_url_for(fullpath)
+ if redirect = ordered.find { |r| fullpath =~ /#{r.pattern}/ }
+ fullpath.sub /#{redirect.pattern}/, redirect.to
+ end
+ end
+
def self.update_order(ordered_redirect_ids)
success = true
View
8 lib/rest-assured/routes/response.rb
@@ -5,16 +5,16 @@ def self.perform(app)
if d = Models::Double.where(:fullpath => request.fullpath, :active => true, :verb => request.request_method).first
request.body.rewind
- body = request.body.read #without temp variable ':body = > body' is always nil. mistery
- env = request.env.except('rack.input', 'rack.errors', 'rack.logger')
+ body = request.body.read #without temp variable ':body = > body' is always nil. mistery
+ env = request.env.except('rack.input', 'rack.errors', 'rack.logger')
d.requests.create!(:rack_env => env.to_json, :body => body, :params => request.params.to_json)
app.headers d.response_headers
app.body d.content
app.status d.status
- elsif r = Models::Redirect.ordered.find { |r| request.fullpath =~ /#{r.pattern}/ }
- app.redirect( "#{r.to}#{request.fullpath}" )
+ elsif redirect_url = Models::Redirect.find_redirect_url_for(request.fullpath)
+ app.redirect redirect_url
else
app.status 404
end
View
7 spec/functional/response_spec.rb
@@ -63,11 +63,13 @@ module RestAssured
end
it "redirects if double not hit but there is redirect that matches request" do
- r = Models::Redirect.create :to => 'http://exmple.com/api', :pattern => '.*'
+ #r = Models::Redirect.create :to => 'http://exmple.com/api', :pattern => '.*'
+ #
fullpath = '/some/other/path'
request.stub(:fullpath).and_return(fullpath)
+ Models::Redirect.stub(:find_redirect_url_for).with(fullpath).and_return('new_url')
- rest_assured_app.should_receive(:redirect).with(r.to + fullpath)
+ rest_assured_app.should_receive(:redirect).with('new_url')
Response.perform(rest_assured_app)
end
@@ -78,6 +80,7 @@ module RestAssured
Response.perform(rest_assured_app)
end
+ # TODO change to instead exclude anything that does not respond_to?(:to_s)
it 'excludes "rack.input" and "rack.errors" as they break with "IOError - not opened for reading:" on consequent #to_json (as they are IO and StringIO)' do
requests = double.as_null_object
Models::Double.stub_chain('where.first').and_return(double(:requests => requests).as_null_object)
View
22 spec/models/redirect_spec.rb
@@ -37,5 +37,27 @@ module RestAssured::Models
Redirect.update_order([nil, 34]).should == false
end
+
+ context 'redirect url' do
+ it 'constructs url to redirect to' do
+ path = rand(1000)
+ r = Redirect.create :pattern => '/api/(.*)\?.*', :to => 'http://external.com/some/url/\1?p=5'
+ Redirect.find_redirect_url_for("/api/#{path}?param=1").should == "http://external.com/some/url/#{path}?p=5"
+ end
+
+ it 'returns the one that matches the substring' do
+ r1 = Redirect.create :pattern => '/ai/path', :to => 'someurl'
+ r2 = Redirect.create :pattern => '/api/path', :to => 'someurl'
+
+ Redirect.find_redirect_url_for('/api/path').should == 'someurl'
+ end
+
+ it 'returns the oldest one that match' do
+ r1 = Redirect.create :pattern => '/api', :to => 'someurl'
+ r2 = Redirect.create :pattern => '/api/path', :to => 'otherurl'
+
+ Redirect.find_redirect_url_for('/api/path').should == 'someurl/path'
+ end
+ end
end
end

0 comments on commit 02d8bf0

Please sign in to comment.
Something went wrong with that request. Please try again.