Подтвердить что ты не робот

Тестирование "Подтверждение учетной записи" с рельсами/rspec/capybara/devise

Я использую rspec/capybara/devise для проведения тестирования интеграции в приложении. Одной из особенностей приложения является постоянно заполняемая "Регистрация учетной записи" с использованием функции подтверждения (т.е. зарегистрируйтесь - получите подтверждение по электронной почте - нажмите на ссылку - учетная запись будет проверена).

require 'spec_helper'

describe "User Authentication" do
  describe "New user" do
    before(:each) do
      @user = Factory.build(:user)
    end

    it "can confirm account by clicking on confirmation link" do
      visit root_path
      click_link "Register"
      page.should have_content "Register for an account"
      fill_in "user_email", :with => @user.email
      fill_in "user_password", :with => @user.password
      fill_in "user_password_confirmation", :with => @user.password
      fill_in "user_first_name", :with => @user.first_name
      fill_in "user_last_name", :with => @user.last_name
      fill_in "user_city", :with => @user.city
      fill_in "user_province", :with => @user.province
      fill_in "user_country", :with => @user.country
      fill_in "user_expertise", :with => @user.expertise
      choose "user_experience_professional"
      click_button "Go!"
      last_email.to.should include(@user.email)
    end
  end
end

Вот мои помощники:

module MailerMacros
  def last_email
    ActionMailer::Base.deliveries.last
  end
end

Подтверждающая ссылка находится в созданном HTML-письме. Было бы замечательно иметь возможность сделать что-то вроде этого (при условии, что "Подтвердить мою учетную запись" ) является ссылкой на проверку учетной записи.

last_email.body.find_link("Confirm My Account").click_link

Есть ли у кого-нибудь какие-либо предложения по определению ссылок в электронном письме, которое может войти в request_spec?

Спасибо

4b9b3361

Ответ 1

Я понимаю, что этот вопрос - год, но он указал мне на решение, которое другие могут найти полезным, поэтому я решил, что все равно отправлю его.

Я не полностью изучил драгоценный камень email_spec, упомянутый выше, так что это может быть гораздо более изящный подход, но это хорошо работает для моего случая. В моем приложении мы разработали модификацию, чтобы пользователи могли регистрироваться только с адресом электронной почты, после чего они должны подтвердить свою учетную запись и получить дополнительную информацию. Поэтому мне нужно было проверить, что подтверждения работают.

Мой файл свойств выглядит следующим образом:

  Scenario: Confirm new account
    Given I have registered for an account as "[email protected]"
    When I follow the confirmation link in the confirmation email
    Then I should be able to set a password

Во-первых, я добавил помощника last_email в мой каталог поддержки огурца как mailer_helper.rb:

def last_email
  ActionMailer::Base.deliveries.last
end

Во-вторых, я написал свои определения шагов следующим образом:

Given(/^I have registered for an account as "(.*?)"$/) do |user_email|
  visit root_path
  click_link 'register'
  fill_in('Email', with: user_email)
  click_button 'Sign up'
  user = User.find_by_email(user_email)
  user.should_not be_nil
  user.confirmation_token.should_not be_nil
end

When(/^I follow the confirmation link in the confirmation email$/) do
  ctoken = last_email.body.match(/confirmation_token=\w*/)
  visit "/users/confirmation?#{ctoken}"
end

Then(/^I should be able to set a password$/) do
  fill_in('user[password]', with: 'passw0rd')
  fill_in('user[password_confirmation]', with: 'passw0rd')
  fill_in('user[first_name]', with: 'John')
  fill_in('user[last_name]', with: 'Doe')
  click_button 'Activate'
  page.should have_content('Your account was successfully confirmed. You are now signed in.')
  page.should have_css('div#flash_notice.alert.alert-success')
end

Ответ 2

Вы можете просто сделать это, используя rspec, capybara, gem 'email_spec' и `gem 'action_mailer_cache_delivery'.

click_button "Go!"
email = open_email(@user.email)
email.should deliver_to(@user.email)
click_link "Confirm My Account"
sleep 2

Ответ 3

Ссылка "Подтвердить мою учетную запись" автоматически генерируется и обычно основывается на каком-то марке, который сохраняется в базе данных.

Вы можете сделать утверждение, что токен для этого пользователя включен в ссылку подтверждения, которая была отправлена ​​этому пользователю. Или вы можете захватить эту ссылку из почты и использовать метод visit helper, который поставляется с rspec. И затем проверьте, подтвержден ли пользователь.

Ответ 4

Если вам нужно сделать это в спецификации контроллера RSpec, не вводя дополнительные драгоценные камни:

# in spec/support/controllers/mailer_helper.rb
module Controllers
  module MailerHelpers
    def last_email
      ActionMailer::Base.deliveries.last
    end

    def extract_confirmation_token(email)
      email && email.body && email.body.match(/confirmation_token=(.+)">/x)[1]
    end
  end
end

# in spec_helper.rb in RSpec.configure block
config.include Controllers::MailerHelpers, type: :controller

# in spec/controllers/confirmations_controller_spec.rb
describe ConfirmationsController do
   it "confirms registered user" do
       user.confirmation_token
       token = extract_confirmation_token last_email
       get :show, confirmation_token: token

       # fill in your expectation here
       expect(user...).to be[...]
    end
end

Надеюсь, что это поможет.

Ответ 5

Аналогичный метод, описанный @socjopata.

Я делаю это, определяя помощник в файлах specs/support/*, которые будут извлекать токен, сгенерированный при создании:

def extract_token_from_email(token_name)
  mail_body = last_email.body.to_s
  mail_body[/#{token_name.to_s}_token=([^"]+)/, 1]
end

а затем используйте:

visit whatever_path({ some_token: token_name })

Я украл этот код из GitHub gist где-то, но не могу найти его, чтобы ссылаться на него, поэтому я не могу взять на себя полную ответственность.

Ответ 6

После ответа demisx я не смог заставить его работать, фактически не вызывая метод send_confirmation_instructions и перезагружая объект user:

require 'rails_helper'

RSpec.describe Users::ConfirmationsController, type: :controller do

  describe 'ConfirmationsController' do
    before(:each) do
      @user = FactoryGirl.build(:user)
      @request.env["devise.mapping"] = Devise.mappings[:user]
    end

    it "confirms registered user" do
      @user.send_confirmation_instructions
      token = extract_confirmation_token last_email
      get :show, confirmation_token: token

      expect(@user.reload.confirmed?).to be(true)
    end
  end

end