Тестирование «Подтверждение аккаунта» с помощью rails / rspec / capybara / devise - PullRequest
13 голосов
/ 17 января 2012

Я использую 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

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

Спасибо

Ответы [ 6 ]

17 голосов
/ 09 декабря 2013

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

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

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

  Scenario: Confirm new account
    Given I have registered for an account as "doe@nowhere.com"
    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
6 голосов
/ 06 ноября 2013

Вы можете просто сделать это, используя 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
4 голосов
/ 29 декабря 2013

Если вам нужно сделать это в спецификации контроллера 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

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

4 голосов
/ 17 января 2012

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

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

1 голос
/ 30 сентября 2017

Следуя ответу 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
1 голос
/ 09 ноября 2013

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

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

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 где-то, но не могу найти его, чтобы сослаться на него, поэтому я не могу полностью отдать ему должное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...