Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best way to test in integration/system tests? #29

Closed
rickychilcott opened this issue Sep 8, 2018 · 3 comments
Closed

Best way to test in integration/system tests? #29

rickychilcott opened this issue Sep 8, 2018 · 3 comments

Comments

@rickychilcott
Copy link
Collaborator

I've not seen this described anywhere in past issues. What's the best way to fake a sign in without triggering a email flow? I whipped this up and it seems to be working ok.

module Passwordless
  module SignInHelper
    def sign_in_as(authenticatable)
      session = Passwordless::Session.create! authenticatable_type: authenticatable.class,
                                              authenticatable_id: authenticatable.id,
                                              timeout_at: 1.day.from_now,
                                              expires_at: 1.day.from_now,
                                              user_agent: 'fake-user-agent',
                                              remote_addr: '127.0.0.1'

      visit Passwordless::Engine.routes.
                                 url_helpers.
                                 token_sign_in_path(session.token)
    end
  end
end

Any thoughts about adding this to the gem? Is there any other way to do it without hitting the database? Perhaps stubbing the private method find_session in Passwordless::SessionsController to return a fake session with the user attached?

Also, in test mode, we'd ideally not have the Bycrpt::Password line (https://github.com/mikker/passwordless/blob/master/app/controllers/passwordless/sessions_controller.rb#L45)

Any thoughts?

@mikker
Copy link
Owner

mikker commented Sep 10, 2018

Hi @rickychilcott! Thank you for your example – that looks like it should work just fine.

In integration/system tests I usually try to get as close to the real thing as possible, so that's what I've been doing.

So something like:

it 'show my posts' do
  user = User.create email: '[email protected]'
  sign_in_by_email user
  expect(page).to have_content('My posts')
end

# ...

def sign_in_by_email(authenticatable)
  visit '/sign_in'
  fill_in 'Email', with: authenticatable.email
  click_button '✨ Send magic link'

  visit_magic_link_in last_email.html_part.body
end

def visit_magic_link_in(html)
  visit text.match(%r{https?:https://.+(/sign_in/[a-z0-9-]+)}i)[1]
end

def last_email
  ActionMailer::Base.deliveries.last
end

You're totally right about BCrypt in test. I'll skip it 👍

@rickychilcott
Copy link
Collaborator Author

rickychilcott commented Sep 10, 2018

I totally agree that integrations should test the whole flow, but it does seem a bit silly to test/re-test user sign when what the real intent of a test around a feature is to do some action in your app. There are also the speed gains to be had not triggering the email flow and capybara visiting.

I've always thought https://github.com/thoughtbot/clearance#testing did it nicely with their Backdoor middleware, and I'd be willing to try a PR to get something like this if you think it's worth it.

I think I see a fairly clear way of doing it.

@mikker
Copy link
Owner

mikker commented Sep 10, 2018

I like that approach. I wouldn't mind including something like that – a PR would be very welcome! Let me know if you hit any road bumps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants