mikker / passwordless

🗝 Authentication for your Rails app without the icky-ness of passwords
MIT License
1.27k stars 87 forks source link

Test helpers #71

Closed dankimio closed 3 years ago

dankimio commented 4 years ago

Something like Devise's sign_in @user helper.

See also #29.

mikker commented 4 years ago

Hi @dankimio!

I think this could be a nice addition. What kinds of tests would you expect to use this in? request, controller, system?

dankimio commented 4 years ago

Hello!

I think both controller (integration) and system would be nice to have for starters, and would cover most cases.

Devise has IntegrationHelpers.

Uysim commented 4 years ago

Since there is no help in this yet i do like this

  def passwordless_sign_in(resource)
    session = Passwordless::Session.create!(
      authenticatable: resource,
      user_agent: 'Command Line',
      remote_addr: 'unknown'
    )

    visit Passwordless::Engine.routes.url_helpers.token_sign_in_path(session.token)
  end
ryenski commented 4 years ago

How would you do this in controller tests?

mikker commented 4 years ago

You could just mock it. If you're using RSpec, something like

def sign_in(user)
  allow_any_instance_of(ApplicationController).to receive(:current_user) { user }
end
scomma commented 4 years ago

@crispinheneise you could use @Uysim's code and substitute get for visit

ryenski commented 4 years ago

@scomma yes, I did use @Uysim's suggestion.

Here's a module that can be included in test_helper.rb or dropped in test/support/

module PasswordlessSupport
  module TestCase
    def passwordless_sign_out
      delete Passwordless::Engine.routes.url_helpers.sign_out_path
    end

    def passwordless_sign_in(resource)
      session = Passwordless::Session.create!(authenticatable: resource, user_agent: 'TestUnit', remote_addr: 'unknown')
      get Passwordless::Engine.routes.url_helpers.token_sign_in_path(session.token)
    end
  end

  module SystemTestCase
    def passwordless_sign_in(resource)
      session = Passwordless::Session.create!(authenticatable: resource, user_agent: 'TestUnit', remote_addr: 'unknown')
      visit Passwordless::Engine.routes.url_helpers.token_sign_in_path(session.token)
    end
  end
end

class ActiveSupport::TestCase
  include ::PasswordlessSupport::TestCase
end
class ActionDispatch::SystemTestCase
  include ::PasswordlessSupport::SystemTestCase
end

Any recommendations on DRY-ing up this module?

mikker commented 4 years ago

Looks good, @crispinheneise! I don't see a reason to DRY anything up. Very short and succinct 👍

fa11enangel commented 4 years ago

@scomma yes, I did use @Uysim's suggestion.

Here's a module that can be included in test_helper.rb or dropped in test/support/

module PasswordlessSupport
 ...
end

Any recommendations on DRY-ing up this module?

I've tried to use it. It works, but there is follow_redirect! missing for get and delete. If you'll sign_in or sign_out and try to access another url afterwards, it will be broken, as the redirect after login was not finished yet.

module PasswordlessSupport
  module TestCase
    def passwordless_sign_out
      delete Passwordless::Engine.routes.url_helpers.sign_out_path
      follow_redirect!
    end

    def passwordless_sign_in(resource)
      session = Passwordless::Session.create!(authenticatable: resource, user_agent: 'TestUnit', remote_addr: 'unknown')
      get Passwordless::Engine.routes.url_helpers.token_sign_in_path(session.token)
      follow_redirect!
    end
  end

  module SystemTestCase
    def passwordless_sign_in(resource)
      session = Passwordless::Session.create!(authenticatable: resource, user_agent: 'TestUnit', remote_addr: 'unknown')
      visit Passwordless::Engine.routes.url_helpers.token_sign_in_path(session.token)
    end
  end
end

class ActiveSupport::TestCase
  include ::PasswordlessSupport::TestCase
end
class ActionDispatch::SystemTestCase
  include ::PasswordlessSupport::SystemTestCase
end