Where do I confirm user created with FactoryGirl?
Asked Answered
M

8

16

Using rails, devise, rspec & factorygirl:

Trying to create some tests for my site. I'm using the confirmable model for devise so when I create a user using FactoryGirl, the user isn't confirmed.

This is my factories.rb:

FactoryGirl.define do
  factory :user do
    full_name             "Aren Admin"
    email                 "[email protected]"
    password              "arenaren"
    password_confirmation "arenaren"
    role_id               ADMIN
  end
end

And this is my rspec test file:

require 'spec_helper'

describe "Admin pages" do

  subject { page }

  describe "home page" do
    let(:user) { FactoryGirl.create(:user) }
    before { visit admin_home_path }

    it { should have_content("#{ROLE_TYPES[user.role_id]}") }
  end
end

I'm getting an error because the user is not confirmed. By searching around I'm pretty sure I need to use the method 'confirm!' and that it belongs in the factories.rb file, but I'm not sure where to put it.

Matthew answered 25/8, 2012 at 19:35 Comment(0)
F
9

Try user.confirm! in your before block

found here

Fattish answered 25/8, 2012 at 20:44 Comment(1)
Your link is outdated. And which "before" block is it? Could you please give us an example?Ningsia
B
35

You could also set the confirmed_at attribute as follows. Works for me:

FactoryGirl.define do
  factory :user do
    full_name             "Aren Admin"
    email                 "[email protected]"
    password              "arenaren"
    password_confirmation "arenaren"
    role_id               ADMIN
    confirmed_at          Time.now
  end
end
Belk answered 25/8, 2012 at 20:52 Comment(3)
I have been preferring this method over confirm! because it is one less operation.Devitt
replaced two lines with one...and a little more intuitive, imo. Thanks!Somatoplasm
Note that Time.now would be executed when the factory is defined, not when the user object is created. It's recommended to pass a block like confirmed_at { Time.now } to set confirmed_at when it's created.Sexagenarian
H
24

Better yet, do the following (then you don't need to create a before filter for every test suite)

Factory.define :confirmed_user, :parent => :user do |f|
  f.after_create { |user| user.confirm! }
end

found here: https://mcmap.net/q/446127/-testing-rspec-with-devise-39-s-confirmable-module

Edit to add non-deprecated syntax

FactoryGirl.define do |f|
  #Other factory definitions

  factory :confirmed_user, :parent => :user do
    after_create { |user| user.confirm! }
  end
end

Edit 01/27 To Update Syntax Again

FactoryGirl.define do
  #Other factory definitions

  factory :confirmed_user, :parent => :user do
    after(:create) { |user| user.confirm! }
  end
end
Hogarth answered 25/8, 2012 at 20:47 Comment(3)
hi! I have used your method and it says > undefined method after_create. why is that?Flag
I need more information, what object is it trying to run after_create on? It might be that this is pulled from an old answer. I think the Factory.define <your factory name> syntax might be depricated. I'll edit my answer with the up-to-date syntax. Let me know if that doesn't work.Hogarth
This is a good answer and what I usually use... except ThoughtBot changed the syntax again (are we there yet?). It should be after(:create) {...etcDevitt
F
9

Try user.confirm! in your before block

found here

Fattish answered 25/8, 2012 at 20:44 Comment(1)
Your link is outdated. And which "before" block is it? Could you please give us an example?Ningsia
V
3

Put the Devise confirmable logic in the after(:build) callback...

FactoryGirl.define do
  factory :user do
    after(:build) do |u|
      u.confirm!
      u.skip_confirmation_notification!
    end
 ...
end

For me, putting confirm! or skip_confirmation! in the after(:create) block caused validation errors on the email parameter and did not work.

Vallejo answered 21/4, 2014 at 15:2 Comment(2)
just u.skip_confirmation! after build works for me. it also makes user creation faster.Gravamen
That's the only thing working in 2020 (just remove the confirm!)Inkerman
O
3

This is the factory that worked for me

FactoryGirl.define do
  factory :user do
    sequence :email do |n|
      "address#{n}@example.com"
    end
    sequence :password do |n|
      "password#{n}"
    end

    factory :confirmed_user do
      before(:create) {|user| user.skip_confirmation! }
    end
  end
end
Olympium answered 6/7, 2017 at 0:46 Comment(0)
Z
2

Add this line to your User factory definition:

before(:create) { |user| user.skip_confirmation! }
Zoilazoilla answered 26/12, 2013 at 8:46 Comment(0)
C
1

You should call skip_confirmation! before create so this is persisted on the user.

before(:create) do |user|
  user.skip_confirmation!
end
Clark answered 28/12, 2016 at 21:34 Comment(0)
I
0

2023

Does not work:

before(:create, &:skip_confirmation!)

Works:

after(:build, &:skip_confirmation!)
Islek answered 17/2, 2023 at 20:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.