I'm testing my Rails applications with Test::Unit. A problem I often come across is testing my application's routes for which I haven't found a solution yet.
At the moment, I'm working on an application which uses Basecamp-style subdomains to differentiate accounts.
There are routes which require a subdomain
constraints(SubdomainRoute) do
get "/login" => "user_sessions#new", :as => :login
get "/logout" => "user_sessions#destroy", :as => :logout
...
end
as well as routes which can be accessed only without a subdomain
constraints(NoSubdomainRoute) do
match "/" => "public#index", :as => :public_root
match "/signup" => "public#signup", :as => :signup
...
end
The class SubdomainRoute is defined as:
class SubdomainRoute
def self.matches?(request)
request.subdomain.present? && request.subdomain != "api" && request.subdomain != "www"
end
end
The class NoSubdomainRoute pretty much does the opposite.
Routing works as expected, but how do I test those using Test::Unit?
In functional tests, I can do something like
assert_routing "/signup", :controller => "public", :action => "signup"
but I cannot provide a subdomain, so in fact that's only testing Rails internals which adds nothing to testing my application. What I want to test in this case is wheter signup_path/signup_url is accessible with or without a subdomain.
In code, something like this
assert_raise(ActionDispatch::RoutingError) { get "http://account.test.host/signup" }
get "http://www.test.host/signup"
assert_response :success
get does not work in this case because Test::Unit treats the whole URL as the controller's action (... :action => "http://account.test.host/signup").
Setting
@request.host = "subdomain.test.host"
only has influences on your inner controller code (e.g. getting current account by extracting subdomain from host) but does not affect routing in this case.
I don't know if the situation is any different in integration tests.
So the two main questions are
I'm williing to try out different approaches (Capybara and friends) but I don't want to switch my testing framework (already had my RSpec-time) since I'm otherwise very happy with Test::Unit.
Thanks in advance and kind regards!
Actually the solution is very simple as assert_routing
does support URLs:
assert_routing "http://subdomain.example.com/login",
{ :controller => "user_sessions", :action => "new" }
assert_routing "http://www.example.com/signup",
{ :controller => "public", :action => "signup" }
The ability to provide a URL to assert_routing was added here.
Search strategy:
assert_routing
was defined in actionpack
gem install gemedit
gem edit actionpack
lib/action_dispatch/testing/assertions/routing.rb
and found recognized_request_for
is what handles the path processingIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With