2012-01-16 28 views
12

Estoy usando rspec/capybara/idear para realizar pruebas de integración en una aplicación. Una de las características de la aplicación es el "Registro de la cuenta", que siempre se completa con una función de confirmación (es decir, registrarse, obtener un correo electrónico de confirmación, hacer clic en el enlace, validar la cuenta).Prueba de "Confirmación de cuenta" con rails/rspec/capybara/idear

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 

Éstos son mis ayudantes:

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

La confirmación se encuentra en el correo electrónico HTML generado. Sería maravilloso poder hacer algo como esto (asumiendo "Confirmar mi cuenta") es el enlace a la validación de la cuenta.

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

¿Alguien tiene alguna sugerencia para poder identificar los enlaces en un correo electrónico que podría entrar en un request_spec?

Gracias

Respuesta

4

"Confirmar Mi Cuenta" se genera automática de enlaces, y suele basar en una especie de símbolo que se guarda en la base de datos.

Puede hacer una afirmación de que el token para ese usuario está incluido en el enlace de confirmación que ha sido enviado a ese usuario. O puede tomar ese enlace del correo y usar el método de ayuda visit, que viene con rspec. Y luego verifica si el usuario está confirmado.

6

simplemente puede hacer esto utilizando rspec, capybara, gem 'email_spec' y `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 
+0

di cuenta de que esto es una cuestión de antigüedad. – PriyankaK

+1

Todavía me ayudó. Ponme en la gema email_spec, ¡que es increíble! También puede usar 'click_first_link_in_email email' en email_spec – mattvv

+0

@mattvv Intenté '' 'click_first_link_in_email''', pero no funcionó para mí.Gracias por la respuesta! – PriyankaK

1

Método similar al descrito por @socjopata.

que lo hacen mediante la definición de un ayudante en el de las especificaciones/Asistencia/* archivos que extraerá el token generado por legado:

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

y luego utilizar por:

visit whatever_path({ some_token: token_name }) 

I robé ese código de un GitHub en alguna parte pero no puedo encontrarlo para referenciarlo, así que no puedo tomar todo el crédito.

16

Me doy cuenta de que esta pregunta tiene un año de antigüedad, pero me señaló una solución que otros pueden encontrar útil, así que pensé que la publicaría de todos modos.

No he explorado por completo la gema email_spec mencionada anteriormente, por lo que puede ser un enfoque mucho más elegante, pero esto funciona bastante bien para mi caso. En mi aplicación, hemos modificado para permitir a los usuarios suscribirse con solo una dirección de correo electrónico, luego tienen que confirmar su cuenta y se les solicita información adicional. Así que necesitaba probar que las confirmaciones están funcionando.

Mi archivo de función tiene el siguiente aspecto:

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 

En primer lugar, añade el ayudante last_email a mi directorio de soporte de pepino como mailer_helper.rb:

def last_email 
    ActionMailer::Base.deliveries.last 
end 

En segundo lugar, escribí mis definiciones paso como esto:

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 "https://stackoverflow.com/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 
+0

Puede que sea solo para mí, pero creo que la URL de confirmación debería ser "/ user/...", aunque sé que el dispositivo proporciona una ayuda de confirmación_url, que no pude ponerme en funcionamiento. –

+1

Para hacerlo funcionar, tuve que hacer un email.body.parts [0] .body.decoded.match (/ confirmation_token = [^ \ n] * /) En mi caso, envié un correo de varias partes, por lo que extraje el token de la versión de texto, y sé que he puesto una nueva línea después del enlace. –

+0

En 'rspec', utilicé' confirmation_token = $ 1 si ActionMailer :: Base.deliveries.last.body.raw_source = ~/confirmation_token = ([^ '"] +) /' – ghayes

3

En caso de que necesite hacer esto en RSpec co especificaciones del interventor sin la introducción de gemas adicionales:

# 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 

Espero que esto ayude.

0

Tras la respuesta de demisx, no pude hacer que funcione sin tener que invocar el método send_confirmation_instructions y volver a cargar el objeto 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 
Cuestiones relacionadas