ohbarye/route_mechanic

It doesn't work with constraints

Closed this issue · 3 comments

pocke commented

Hi. Thanks for the great gem!

I'm trying to use this gem in my Rails application, but it raises an error with constraints.

We can reproduce the problem with the simple patch to this repository.

diff --git a/fixtures/fake_app/rails_app.rb b/fixtures/fake_app/rails_app.rb
index 09e13d7..c2b1e3d 100644
--- a/fixtures/fake_app/rails_app.rb
+++ b/fixtures/fake_app/rails_app.rb
@@ -8,6 +8,10 @@ FakeApp.config.root = File.dirname(__FILE__)
 FakeApp.initialize!
 
 FakeApp.routes.draw do
+  constraints subdomain: /\A[0-9a-z-]+\z/ do
+    get '/constraints_test' => 'users#index'
+  end
+
   resources :users do
     get 'friends', to: :friends
   end
$ bundle exec rake
# Running:

...F

Failure:
RouteMechanicTestingMethodsTest#test_that_fake_app_has_missing_routes [/home/pocke/ghq/github.com/ohbarye/route_mechanic/test/testing/methods_test.rb:63]:
--- expected
+++ actual
@@ -1,12 +1 @@
-"[Route Mechanic]
-  No route matches to the controllers and action methods below
-    UsersController#unknown
-  No controller and action matches to the routes below
-    GET    /users/:user_id/friends(.:format) users#friends
-    GET    /users(.:format)                  users#index
-    GET    /users/new(.:format)              users#new
-    GET    /users/:id/edit(.:format)         users#edit
-    GET    /users/:id(.:format)              users#show
-    DELETE /users/:id(.:format)              users#destroy
-
-"
+"No route matches \"/constraints_test\""



rails test /home/pocke/ghq/github.com/ohbarye/route_mechanic/test/testing/methods_test.rb:44

it prints No route matches "/constraints_test", but I think it is not an intentional error.


It is raised during the assert_routing method call.

assert_routing({ path: url, method: wrapper.verb }, expected_options)

Thanks for the bug report.

Cause

I understand that's because:

  • route_mechanic passes assert_routing a path that does not match the constraint.
    • e.g. assert_routing({ path: '/constraints_test', method: wrapper.verb }, expected_options).
  • If the path doesn't include a host info nor a subdomain, assert_routing internally uses ActionController::TestRequest that has a domain as "test.host". This doesn't match constraints subdomain: /\A[0-9a-z-]+\z/, then it raises.

Instead, if it use a path with a valid subdomain, assert_routing passes.

> assert_routing({ path: 'http://a16.test.com/constraints_test', method: wrapper.verb }, expected_options)
# => true

Or, if I use another constraint that has nothing to do with subdomain, it works.

constraints method: /\AGETz/ do
   get '/constraints_test' => 'users#index'
end

Solution

It'd be the best that route_mechanic complement information to match constraints like above, but it's hard to know what kind of constraints users have and hard to generate a valid request just in time.

So I try to change assert_routing to assert_generates whose check is a little loose but it can meet this gem's requirement.

pocke commented

Thank you for fixing this problem quickly! I've confirmed the problem is solved in my application. 👏