Тестирование "Подтверждение учетной записи" с рельсами/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?
Спасибо
Ответы
Ответ 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