waiting-for-dev / warden-jwt_auth

JWT token authentication with warden
MIT License
113 stars 56 forks source link

Trying to access subject.current_user in tests throws an error. #7

Closed rastogiachyut closed 7 years ago

rastogiachyut commented 7 years ago

I am doing the following in my tests:

@user = login_user
  before(:each) do
    byebug
    @user = subject.current_user
    @localytics_user = create(:localytics_user, company: @user.company)
  end

and I get an error as mentioned below:

 Failure/Error: @user = subject.current_user

 NoMethodError:
   undefined method `match' for nil:NilClass
   Did you mean?  catch
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-jwt_auth-0.1.3/lib/warden/jwt_auth/hooks.rb:44:in `block in request_matches?'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-jwt_auth-0.1.3/lib/warden/jwt_auth/hooks.rb:42:in `each'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-jwt_auth-0.1.3/lib/warden/jwt_auth/hooks.rb:42:in `request_matches?'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-jwt_auth-0.1.3/lib/warden/jwt_auth/hooks.rb:32:in `token_should_be_added?'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-jwt_auth-0.1.3/lib/warden/jwt_auth/hooks.rb:26:in `prepare_token'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-jwt_auth-0.1.3/lib/warden/jwt_auth/hooks.rb:18:in `after_set_user'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-jwt_auth-0.1.3/lib/warden/jwt_auth/hooks.rb:54:in `block in <top (required)>'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-1.2.6/lib/warden/hooks.rb:14:in `block in _run_callbacks'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-1.2.6/lib/warden/hooks.rb:9:in `each'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-1.2.6/lib/warden/hooks.rb:9:in `_run_callbacks'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-1.2.6/lib/warden/manager.rb:51:in `_run_callbacks'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-1.2.6/lib/warden/proxy.rb:179:in `set_user'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-1.2.6/lib/warden/proxy.rb:217:in `user'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-1.2.6/lib/warden/proxy.rb:322:in `_perform_authentication'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/warden-1.2.6/lib/warden/proxy.rb:104:in `authenticate'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/devise-4.2.0/lib/devise/controllers/helpers.rb:124:in `current_user'
 # ./spec/controllers/localytics_users_controller_spec.rb:8:in `block (2 levels) in <top (required)>'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/rspec-retry-0.5.3/lib/rspec/retry.rb:112:in `block in run'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/rspec-retry-0.5.3/lib/rspec/retry.rb:101:in `loop'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/rspec-retry-0.5.3/lib/rspec/retry.rb:101:in `run'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/rspec-retry-0.5.3/lib/rspec_ext/rspec_ext.rb:12:in `run_with_retry'
 # /home/achyut/.rvm/gems/ruby-2.3.3/gems/rspec-retry-0.5.3/lib/rspec/retry.rb:30:in `block (2 levels) in setup'
rastogiachyut commented 7 years ago

@waiting-for-dev How do I set env['PATH_INFO']?

waiting-for-dev commented 7 years ago

What is subject? env['PATH_INFO'] is set by rack, you don't have to set it.

waiting-for-dev commented 7 years ago

Doesn't seem a warden-jwt_auth issue. Please, don't hesitate to add more comments if you come back with more information pointing at the opposite.

rastogiachyut commented 7 years ago

@waiting-for-dev I am using devise-jwt for authentication, is there some additional configuration required for running my tests?

The above code is a test for a controller(a feature test), subject here refers to the controller being tested, devise injects the method current_user into it using controller_helpers.

waiting-for-dev commented 7 years ago

@waiting-for-dev I am using devise-jwt for authentication, is there some additional configuration required for running my tests?

No, not additional configuration is needed. If you want to mock an authenticated request through devise-jwt, just generate the token and add it to the request headers. You can use UserEncoder for that.

The above code is a test for a controller(a feature test), subject here refers to the controller being tested, devise injects the method current_user into it using controller_helpers.

devise-jwt doesn't interfere with devise defined controller helpers, so I guess you have some problem with devise itself or with your test configuration.

rastogiachyut commented 7 years ago

@waiting-for-dev I guess this happens because the request didn't come through a route, so when devise-jwt tries to match the route, it fires an error, is it possible to "turn off" devise-jwt for tests?

waiting-for-dev commented 7 years ago

Not sure what you are trying to do, but I guess that if you are trying to mock requests your best bet is to try with rack-test.

rastogiachyut commented 7 years ago

@waiting-for-dev Looks like I have to do: request.env['PATH_INFO'] = "" before I call subject.current_user, since this library doesn't handle the case when env['PATH_INFO'] == nil and throws an error. I think this should be done cause: 1) Nobody sets there request.env['PATH_INFO'] by default. 2) I shouldn't have to set it when I don't care about its value, so long as it doesn't throw an error. 3) When writing feature tests, one shouldn't have to care about what happens outside of the controllers code(or in the back ground code implicitly), thus routes or request.env keys are not set generally.

We just need to add a .to_s to ensure a string is passed to match. Making a PR for this.

waiting-for-dev commented 7 years ago

Oks. Following the conversation there, then.