I am using request_confirmation_test.rb file from devise
confirmation test from devise
I have included the helper too but the file is showing errors on each line. Looks like something is missing that is necessary for the file to work correctly.This is the error that I am getting currently
ConfirmationInstructionsTest#test_set_up_sender_from_custom_mailer_defaults:
NoMethodError: undefined method `from' for nil:NilClass
test/integration/request_confirmation_test.rb:46:in `block in <class:ConfirmationInstructionsTest>'
this is my code for testing file
require 'test_helper'
class ConfirmationInstructionsTest < ActionMailer::TestCase
def setup
setup_mailer
Devise.mailer = 'Devise::Mailer'
Devise.mailer_sender = 'johnmax.rtc#gmail.com'
end
def teardown
Devise.mailer = 'Devise::Mailer'
Devise.mailer_sender = 'please-change-me#config-initializers-devise.com'
end
def user
#user ||= create_user
end
def mail
#mail ||= begin
user
ActionMailer::Base.deliveries.first
end
end
test 'email sent after creating the user' do
assert_not_nil mail
end
# test 'content type should be set to html' do
# assert mail.content_type.include?('text/html')
# end
test 'send confirmation instructions to the user email' do
mail
assert_equal [user.email], mail.to
end
test 'set up sender from configuration' do
assert_equal ['johnmax.rtc#gmail.com'], mail.from
end
test 'set up sender from custom mailer defaults' do
Devise.mailer = 'Users::Mailer'
assert_equal ['johnmax.rtc#gmail.com'], mail.from
end
# test 'set up sender from custom mailer defaults with proc' do
# Devise.mailer = 'Users::FromProcMailer'
# assert_equal ['johnmax.rtc#gmail.com'], mail.from
# end
# test 'custom mailer renders parent mailer template' do
# Devise.mailer = 'Users::Mailer'
# assert_present mail.body.encoded
# end
# test 'set up reply to as copy from sender' do
# assert_equal ['johnmax.rtc#gmail.com'], mail.reply_to
# end
# test 'set up reply to as different if set in defaults' do
# Devise.mailer = 'Users::ReplyToMailer'
# assert_equal ['johnmax.rtc#gmail.com'], mail.from
# assert_equal ['johnmax.rtc#gmail.com'], mail.reply_to
# end
test 'set up subject from I18n' do
store_translations :en, devise: { mailer: { confirmation_instructions: { subject: 'Account Confirmation' } } } do
assert_equal 'Account Confirmation', mail.subject
end
end
test 'subject namespaced by model' do
store_translations :en, devise: { mailer: { confirmation_instructions: { user_subject: 'User Account Confirmation' } } } do
assert_equal 'User Account Confirmation', mail.subject
end
end
test 'body should have user info' do
assert_match user.email, mail.body.encoded
end
test 'body should have link to confirm the account' do
host, port = ActionMailer::Base.default_url_options.values_at :host, :port
if mail.body.encoded =~ %r{<a href=\"http://#{host}:#{port}/users/confirmation\?confirmation_token=([^"]+)">}
assert_equal $1, user.confirmation_token
else
flunk "expected confirmation url regex to match"
end
end
# test 'renders a scoped if scoped_views is set to true' do
# swap Devise, scoped_views: true do
# assert_equal user.email, mail.body.decoded
# end
# end
# test 'renders a scoped if scoped_views is set in the mailer class' do
# begin
# Devise::Mailer.scoped_views = true
# assert_equal user.email, mail.body.decoded
# ensure
# Devise::Mailer.send :remove_instance_variable, :#scoped_views
# end
# end
test 'mailer sender accepts a proc' do
swap Devise, mailer_sender: proc { "another#example.com" } do
assert_equal ['another#example.com'], mail.from
end
end
end
This is the helper file
require 'active_support/test_case'
class ActiveSupport::TestCase
VALID_AUTHENTICATION_TOKEN = 'AbCdEfGhIjKlMnOpQrSt'.freeze
def setup_mailer
ActionMailer::Base.deliveries = []
end
def store_translations(locale, translations, &block)
# Calling 'available_locales' before storing the translations to ensure
# that the I18n backend will be initialized before we store our custom
# translations, so they will always override the translations for the
# YML file.
I18n.available_locales
I18n.backend.store_translations(locale, translations)
yield
ensure
I18n.reload!
end
def generate_unique_email
##email_count ||= 0
##email_count += 1
"test#{##email_count}#example.com"
end
def valid_attributes(attributes={})
{ first_name: "usertest",
email: generate_unique_email,
password: '12345678',
password_confirmation: '12345678' }.update(attributes)
end
def new_user(attributes={})
User.new(valid_attributes(attributes))
end
def create_user(attributes={})
User.create!(valid_attributes(attributes))
end
def create_admin(attributes={})
valid_attributes = valid_attributes(attributes)
valid_attributes.delete(:first_name)
Admin.create!(valid_attributes)
end
def create_user_without_email(attributes={})
UserWithoutEmail.create!(valid_attributes(attributes))
end
def create_user_with_validations(attributes={})
UserWithValidations.create!(valid_attributes(attributes))
end
# Execute the block setting the given values and restoring old values after
# the block is executed.
def swap(object, new_values)
old_values = {}
new_values.each do |key, value|
old_values[key] = object.send key
object.send :"#{key}=", value
end
clear_cached_variables(new_values)
yield
ensure
clear_cached_variables(new_values)
old_values.each do |key, value|
object.send :"#{key}=", value
end
end
def clear_cached_variables(options)
if options.key?(:case_insensitive_keys) || options.key?(:strip_whitespace_keys)
Devise.mappings.each do |_, mapping|
mapping.to.instance_variable_set(:#devise_parameter_filter, nil)
end
end
end
end
Any help would be highly appreciated.
Related
All the other answers are wrong or out of date. I've tried several things. This is what I have:
require 'test_helper'
class DealsControllerTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
setup do
#deal = deals(:one)
#user = users(:one)
# https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-(and-RSpec)
##request.env["devise.mapping"] = Devise.mappings[:one]
#sign_in #user
#log_in_as #user
ApplicationController.allow_forgery_protection = false
post user_session_path, params: {user: {email: #user.email, password: #user.password}}
assert_select "p", "Invalid Email or password."
assert_response :redirect ############ line 16
#assert_text "Invalid Email or password."
assert_redirected_to root_url
end
Failure:
DealsControllerTest#test_should_destroy_deal [C:/Users/Chloe/workspace/fortuneempire/test/controllers/deals_controller_test.rb:16]:
Expected response to be a <3XX: redirect>, but was a <200: OK>
Since it passes the "Invalid email/password" test, that means the user is NOT logging in!
I tried these answers:
How to sign in a user using Devise from a Rails console?
How to sign_in for Devise to Test Controller with Minitest
https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-(and-RSpec)
Rails: Capybara can't log in user with Devise fixture data
This worked
require 'test_helper'
class DealsControllerTest < ActionDispatch::IntegrationTest
include Warden::Test::Helpers
setup do
#deal = deals(:one)
#user = users(:one)
# https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara
#user.confirmed_at = Time.now
#user.save
login_as(#user, :scope => :user)
end
teardown do
Warden.test_reset!
end
Okay,
this is driving me nuts, since I don't understand the error in this case.
I have the following class defined:
module Admins
class BasePresenter < ::BasePresenter
def render_customer(id:)
return I18n.t('admin.admin') if id.nil?
::Customer.where(id: id).first.try(:name) || I18n.t('admin.deleted')
end
def percent_of(count, total)
((count.to_f / total.to_f) * 100.0).to_i
end
end
end
Which inherits from the BasePresenter below:
class BasePresenter
def initialize(object, template)
#object = object
#template = template
end
def self.presents(name)
define_method(name) do
#object
end
end
def underscored_class
#object.class.name.underscore
end
protected
def h
#template
end
def handle_none(value, html = true)
if value.present?
if block_given?
yield
else
value
end
else
return h.content_tag(:span, '-', class: 'none') if html
'-'
end
end
def current_customer
#current_customer ||= h.current_customer
end
def current_user
#current_user ||= h.current_user
end
end
However when I try to run my specs, I receive the following error from RSpec:
ArgumentError: wrong number of arguments (0 for 2)
./app/presenters/base_presenter.rb:3:in initialize'
./spec/presenters/admins/base_presenter_spec.rb:24:inblock (3
levels) in '
The class is no different from other presents, where the the inheritance works in the exact same way and those tests are passing.
Just the test for this class is failing with this error, and only when testing the method percent_of.
What am I failing to see?
EDIT
This is my RSpec test:
require 'spec_helper'
describe ::Admins::BasePresenter do
describe '#render_customer' do
let(:customer) { Customer.first }
subject { ::Admins::BasePresenter.new(Object.new, ApplicationController.new.view_context) }
it 'returns the I18n translations for (admin) when no customer is set.' do
expect(subject.render_customer(id: nil)).to eql(I18n.t('admin.admin'))
end
it 'returns the proper name when a valid ID is given' do
expect(subject.render_customer(id: customer.id)).to eql(customer.name)
end
it 'returns the I18n translations for (deleted) when an invalid ID is given' do
expect(subject.render_customer(id: -1)).to eql(I18n.t('admin.deleted'))
end
end
describe '#percent_of' do
it 'calculates the percentage correctly' do
expect(subject.percent_of(0, 1)).to eql(0)
expect(subject.percent_of(1, 1)).to eql(100)
expect(subject.percent_of(1, 2)).to eql(50)
expect(subject.percent_of(1, 3)).to eql(33)
end
end
end
Ugh,
I'm an idiot....
The problem was that my subject was defined inside a Describe block for specific tests and the second one did not have any.
Which means our hooks try to create an instance of the class in the outer describe block...
This was the fix:
require 'spec_helper'
describe ::Admins::BasePresenter do
let(:customer) { Customer.first }
subject { ::Admins::BasePresenter.new(Object.new, ApplicationController.new.view_context) }
describe '#render_customer' do
it 'returns the I18n translations for (admin) when no customer is set.' do
expect(subject.render_customer(id: nil)).to eql(I18n.t('admin.admin'))
end
it 'returns the proper name when a valid ID is given' do
expect(subject.render_customer(id: customer.id)).to eql(customer.name)
end
it 'returns the I18n translations for (deleted) when an invalid ID is given' do
expect(subject.render_customer(id: -1)).to eql(I18n.t('admin.deleted'))
end
end
describe '#percent_of' do
it 'calculates the percentage correctly' do
expect(subject.percent_of(0, 1)).to eql(0)
expect(subject.percent_of(1, 1)).to eql(100)
expect(subject.percent_of(1, 2)).to eql(50)
expect(subject.percent_of(1, 3)).to eql(33)
end
end
end
I've been stuck on this one for a while and keep getting 2 errors when I rake test. Referencing Listing 9.23 testing point. Any help would be much appreciated.
Test Error:
1) Error:
UsersControllerTest#test_should_redirect_update_when_logged_in_as_wrong_user:
NameError: undefined local variable or method `user_id' for #<UsersControllerTest:0x007fbff6be3120>
test/test_helper.rb:24:in `log_in_as'
test/controllers/users_controller_test.rb:35:in `block in <class:UsersControllerTest>'
2) Error:
UsersControllerTest#test_should_redirect_edit_when_logged_in_as_wrong_user:
NameError: undefined local variable or method `user_id' for #<UsersControllerTest:0x007fbff6c01850>
test/test_helper.rb:24:in `log_in_as'
test/controllers/users_controller_test.rb:28:in `block in <class:UsersControllerTest>'
29 runs, 66 assertions, 0 failures, 2 errors, 0 skips
User_Controller_Test file:
require 'test_helper'
class UsersControllerTest < ActionController::TestCase
def setup
#user = users(:michael)
#other_user = users(:archer)
end
test "should get new" do
get :new
assert_response :success
end
test "should redirect edit when not logged in" do
get :edit, id: #user
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect update when not logged in" do
patch :update, id: #user, user: { name: #user.name, email: #user.email }
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect edit when logged in as wrong user" do
log_in_as(#other_user)
get :edit, id: #user
assert flash.empty?
assert_redirected_to root_url
end
Test_Helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
def is_logged_in?
!session[:user_id].nil?
end
#logs in a test user
def log_in_as(user, options = {})
password = options[:password] || 'password'
remember_me = options[:remember_me] || '1'
if integration_test?
post login_path, session: { email: user.email,
password: password,
remember_me: remember_me}
else
session[:user_id] = user_id
end
end
private
#returns true inside an int. test
def integration_test?
defined?(post_via_redirect)
end
end
And where does user_id come from here?
def log_in_as(user, options = {})
...
if integration_test?
...
else
session[:user_id] = user_id
end
end
Seems it should be:
session[:user_id] = user.id
I'm trying to test some mailers with rspec but deliveries are always empty. Here is my rspec test:
require "spec_helper"
describe "AccountMailer", :type => :helper do
before(:each) do
ActionMailer::Base.delivery_method = :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
end
it "should send welcome email to account email" do
account = FactoryGirl.create :account
account.send_welcome_email
ActionMailer::Base.deliveries.empty?.should be_false
ActionMailer::Base.deliveries.last.to.should == account.email
end
end
It fails with:
1) AccountMailer should send welcome email to account email
Failure/Error: ActionMailer::Base.deliveries.empty?.should be_false
expected true to be false
My send_welcome_email function looks like this ( that's my model ):
def send_welcome_email
AccountMailer.welcome self
end
And my mailer:
class AccountMailer < ActionMailer::Base
default from: APP_CONFIG['email']['from']
def welcome data
if data.locale == 'es'
template = 'welcome-es'
else
template = 'welcome-en'
end
mail(:to => data.email, :subject => I18n.t('welcome_email_subject'), :template_name => template)
end
end
Any ideas? I'm not sure about how to proceed.
Have you tested that it's working when you're actually running the app? Perhaps your test is correct to be failing.
I noticed that you're never calling deliver when you create the mail, so I suspect that the test is failing because email is, in fact, not getting sent. I would expect your send_welcome_email method to look more like
def send_welcome_email
AccountMailer.welcome(self).deliver
end
I've just started using rails, and decided to follow the "Ruby on Rails Tutorial" by M. Hartl. Seems like a good intro.
Am running into a failed test that's driving me nuts.
I am running rails 3.1.1, with rspec 2.7.0
I have tried modifying the condition, and tests on the "has_password" method work.
The failing test:
1) User password encryption authenticate method should return the user on email/password match
Failure/Error: matching_user.should == #user
expected: #
got: nil (using ==)
# ./spec/models/user_spec.rb:149:in `block (4 levels) in '
The rspec test:
describe User do
before(:each) do
#attr = {:name => 'testing',
:email =>'testing#example.com',
:password => "testtest",
:password_confirmation => "testtest"}
end
...
describe "password encryption" do
before(:each) do
#user = User.create!(#attr)
end
...
describe "authenticate method" do
it "should exist" do
User.should respond_to(:authenticate)
end
it "should return nil on email/password mismatch" do
User.authenticate(#attr[:email], "wrongpass").should be_nil
end
it "should return nil for an email address with no user" do
User.authenticate("bar#foo.com", #attr[:password]).should be_nil
end
it "should return the user on email/password match" do
matching_user = User.authenticate(#attr[:email], #attr[:password])
matching_user.should == #user
end
end
In the User model:
...
def has_password?(submitted_password)
encrypt_password == encrypt(submitted_password)
end
def self.authenticate(email, submitted_password)
user = find_by_email(email) #self.where("email = ?", email)
return nil if user.nil?
return user if user.has_password?(submitted_password)
end
private
def encrypt_password
self.salt = make_salt if new_record?
self.encrypted_password = encrypt(password)
end
I cannot figure out what I'm doing wrong here.
In your failing spec you have
matching_user.should == #user
But #user isn't defined anywhere so it's set to nil.
Edit:
Try adding the following puts into the failing spec and see what results you get in your spec output after running it.
it "should return the user on email/password match" do
matching_user = User.authenticate(#attr[:email], #attr[:password])
puts matching_user # add this
puts #user # and also this
matching_user.should == #user
end