One of my RSpec tests is throwing an ActionController::InvalidAuthenticityToken error when clicking on a button to send an email.
I have tried adding:
skip_before_action :verify_authenticity_token, only: [:email_expiration2] if Rails.env.test?
in the controller, but the error is then handled and rerouted to a 404 page.
What I find confusing is that the test works as expected when conducted manually, i.e. navigating through the site from a user perspective. I can click the button to send the email and I'm presented with my desired 'Reminder sent!' page. I also have other tests which follow the exact same procedure and format for other areas of the site that involve emailing and they work as expected.
This is the failing test case:
specify 'I can remind coaches of their certificate expiration' do
login_as @user
@test_user = FactoryBot.create :user, email: 'test@running.com', password: 'testtest', first_name: 'Kirito', last_name: 'Adler'
@test_role = FactoryBot.create :role, role_name: 'Volunteer'
FactoryBot.create :coach, DBS: '12-12-2018', appl_status: true, user_id: @test_user.id
FactoryBot.create :user_role, role_id: @test_role.id, user_id: @test_user.id
visit '/email_application_status'
expect(page).to have_no_content 'Kirito Adler'
visit '/email_expiration'
expect(page).to have_content 'Kirito Adler'
expect(page).to have_content 'Expired (12-12-2018)'
#save_and_open_page
#puts page.body
click_button 'KiritoAdler' <-- this throws error
expect(page).to have_content 'Reminder sent!' <-- this fails
end
All the appropriate factories have been declared for the test to work, and all the HTML elements have correct id's.
This is the failing method in the controller:
def email_expiration2
@user_id = params[:recipent][:user_id]
@user = User.find(@user_id)
@expiration = params[:recipent][:expiration]
UserMailer.new_expiration_mail(@user.email, @user.first_name, @expiration).deliver
end
Part of the associated view:
- @all_coaches.each do |user|
- coach = Coach.where(:user_id => user.id).first
= simple_form_for :recipent, url: reminder_sent_path, method: :post do |f|
%tr
%td
= user.first_name
= user.last_name
%p
= Role.find(user.user_roles.first.role_id).role_name
%p
Certificate expiration:
- if !coach.DBS.nil?
- @expiration = (((coach.DBS).to_time - @timenow) / 24.hour).ceil
- if @expiration >= 31
= f.label :expiration, "#@expiration", :style => "font-size:18px;color:green"
days
- elsif (@expiration > 1) && (@expiration < 31)
= f.label :expiration, "#@expiration", :style => "font-size:18px;color:orange"
days
- elsif (@expiration == 1) || ((coach.DBS).to_time == @time)
= f.label :expiration, "1 day", :style => "font-size:18px;color:red"
- elsif @expiration < 1
= f.label :expiration, "Expired", :style => "font-size:18px;color:red"
= "(" + coach.DBS + ")"
%br
%br
= f.hidden_field :expiration, :value => @expiration
= f.hidden_field :user_id, :value => coach.id
= f.button :submit, "Email reminder", id: user.first_name + user.last_name, :style => "background-color:black;color:white"
%br
I expect the test to find 'Reminder sent!' on a page once the email button has been clicked.