· 2 min read
Screencast: Testen von Password-Reset und Erinnerung
Downloads in verschiedenen Formaten:
Resourcen:
- Episode 274: Remember Me & Reset Password
- Episode 257: Request Specs and Capybara
- Episode 264: Guard
- Episode 158: Factories not Fixtures
bash
[bash] bundle rails g rspec:install mkdir spec/support spec/models spec/routing guard init rspec gem install rb-fsevent rails g integration_test password_reset rails g controller password_resets new —no-test-framework rails g mailer user_mailer password_reset rails g migration add_password_reset_to_users password_reset_token:string password_reset_sent_at:datetime rake db:migrate [/bash]
Gemfile
[ruby] gem “rspec-rails”, :group => [:test, :development] group :test do gem “factory_girl_rails” gem “capybara” gem “guard-rspec” end [/ruby]
spec_helper.rb
[ruby] require ‘capybara/rspec’ RSpec.configure do |config| # … config.include(MailerMacros) config.before(:each) { reset_email } end [/ruby]
spec/support/mailer_macros.rb
[ruby] module MailerMacros def last_email ActionMailer::Base.deliveries.last end def reset_email ActionMailer::Base.deliveries = [] end end [/ruby]
config/environments/test.rb
[ruby] config.action_mailer.default_url_options = { :host => “www.example.com” } [/ruby]
spec/requests/password_resets_spec.rb
[ruby] describe “PasswordResets” do it “emails user when requesting password reset” do user = Factory(:user) visit login_path click_link “password” fill_in “Email”, :with => user.email click_button “Reset Password” current_path.should eq(root_path) page.should have_content(“Email sent”) last_email.to.should include(user.email) end it “does not email invalid user when requesting password reset” do visit login_path click_link “password” fill_in “Email”, :with => “nobody@example.com” click_button “Reset Password” current_path.should eq(root_path) page.should have_content(“Email sent”) last_email.should be_nil end it “updates the user password when confirmation matches” do user = Factory(:user, :password_reset_token => “something”, :password_reset_sent_at => 1.hour.ago) visit edit_password_reset_path(user.password_reset_token) fill_in “Password”, :with => “foobar” click_button “Update Password” page.should have_content(“Password doesn’t match confirmation”) fill_in “Password”, :with => “foobar” fill_in “Password confirmation”, :with => “foobar” click_button “Update Password” page.should have_content(“Password has been reset”) end it “reports when password token has expired” do user = Factory(:user, :password_reset_token => “something”, :password_reset_sent_at => 5.hour.ago) visit edit_password_reset_path(user.password_reset_token) fill_in “Password”, :with => “foobar” fill_in “Password confirmation”, :with => “foobar” click_button “Update Password” page.should have_content(“Password reset has expired”) end it “raises record not found when password token is invalid” do lambda { visit edit_password_reset_path(“invalid”) }.should raise_exception(ActiveRecord::RecordNotFound) end end [/ruby]
spec/models/user_spec.rb
[ruby] describe User do describe “#send_password_reset” do let(:user) { Factory(:user) } it “generates a unique password_reset_token each time” do user.send_password_reset last_token = user.password_reset_token user.send_password_reset user.password_reset_token.should_not eq(last_token) end it “saves the time the password reset was sent” do user.send_password_reset user.reload.password_reset_sent_at.should be_present end it “delivers email to user” do user.send_password_reset last_email.to.should include(user.email) end end end [/ruby]
spec/mailers/user_mailer_spec.rb
[ruby] describe UserMailer do describe “password_reset” do let(:user) { Factory(:user, :password_reset_token => “anything”) } let(:mail) { UserMailer.password_reset(user) } it “send user password reset url” do mail.subject.should eq(“Password Reset”) mail.to.should eq([user.email]) mail.from.should eq([“from@example.com”]) mail.body.encoded.should match(edit_password_reset_path(user.password_reset_token)) end end end [/ruby]