2012-01-16 14 views
12

Używam rspec/capybara/devise do przeprowadzania testów integracyjnych w aplikacji. Jedną z funkcji aplikacji jest zawsze wypełnianie "Rejestracja konta" za pomocą funkcji potwierdzenia (np. Rejestracja - otrzymanie wiadomości e-mail z potwierdzeniem - kliknięcie łącza - potwierdzenie konta).Testowanie "Potwierdzenie konta" za pomocą szyn/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 

Oto moi pomocnicy:

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

Potwierdzenie znajduje się w wiadomości e-mail HTML generowanego. Byłoby cudownie móc zrobić coś takiego (zakładając "Potwierdź moje konto") jest linkiem do sprawdzania konta.

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

Czy ktoś ma jakieś sugestie dotyczące możliwości identyfikacji linków w wiadomości e-mail, które mogłyby przejść do request_spec?

Dzięki

Odpowiedz

4

„Potwierdź Moje konto” link jest automatycznie generowane i zazwyczaj bazuje na jakiś znak, który jest zapisany w bazie danych.

Możesz zadeklarować, że token dla tego użytkownika znajduje się w łączu potwierdzającym, który został wysłany do tego użytkownika. Możesz też pobrać ten link z poczty i użyć metody pomocniczej visit dostarczanej z rspec. A następnie sprawdź, czy użytkownik jest potwierdzony.

6

Można po prostu to zrobić za pomocą rspec, capybara, gem 'email_spec' i `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

sobie sprawę, że jest to letni pytanie. – PriyankaK

+1

Wciąż mi pomogłeś. Połóż mnie na klejnotu email_spec, który jest niesamowity! Możesz także użyć "click_first_link_in_email email" w email_spec – mattvv

+0

@mattvv Próbowałem '' 'click_first_link_in_email''', ale nie działało dla mnie. Dzięki za odpowiedź! – PriyankaK

1

Metoda podobna do opisanej przez @socjopata.

to zrobić poprzez określenie pomocnika w sprawie o specyfikacje/support/* plików, które wydobędzie token wygenerowany przez devise:

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

a następnie użyć przez:

visit whatever_path({ some_token: token_name }) 

I ukradłem ten kod z jakiegoś miejsca w GitHub, ale nie mogę go znaleźć, żeby się do niego odnieść, więc nie mogę wziąć pełnego kredytu.

16

Zdaję sobie sprawę, że to pytanie ma rok, ale wskazało mi rozwiązanie, które inni mogą uznać za pomocne, więc pomyślałem, że i tak to zrobię.

Nie odkryłem w pełni wspomnianego wyżej klejnotu email_spec, dzięki czemu może być bardziej eleganckie podejście, ale działa to całkiem dobrze w moim przypadku. W mojej aplikacji opracowaliśmy modyfikację umożliwiającą użytkownikom rejestrację tylko za pomocą adresu e-mail, a następnie muszą potwierdzić swoje konto i zostaną poproszeni o dodatkowe informacje. Musiałem więc przetestować, czy potwierdzenia działają.

Mój plik funkcja wygląda tak:

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 

pierwsze, dodałem last_email pomocnika do mojego katalogu wsparcia ogórka jako mailer_helper.rb:

def last_email 
    ActionMailer::Base.deliveries.last 
end 

drugie, pisałem definicje mój krok tak:

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

To może być po prostu dla mnie, ale myślę, że adres URL potwierdzenia powinien być "/ user/...", choć wiem, że devise zapewnia helpera potwierdzenia_url, że nie mógłbym pracować. –

+1

Aby to działało, musiałem wykonać email.body.parts [0] .body.decoded.match (/ confirmation_token = [^ \ n] * /) w moim przypadku wysyłam pocztę wieloczęściową, więc wyodrębniam token z wersję tekstową i wiem, że umieściłem znak po linku. –

+0

W 'rspec' użyłem' confirmation_token = $ 1 if ActionMailer :: Base.deliveries.last.body.raw_source = ~/confirmation_token = ([^ '"] +) /' – ghayes

3

W przypadku, gdy musisz to zrobić w RSpec Specyfikacja ntroller bez wprowadzania dodatkowych klejnotów:

# 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 

Mam nadzieję, że to pomoże.

0

następującą odpowiedź demisx jest, nie mogłem zrobić to praca bez faktycznie wywołanie metody send_confirmation_instructions i przeładunkowe obiektu 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 
Powiązane problemy