I have a controller method to authenticate a user who has received a link with a token (see method at the bottom). I have an integration test:
def test
get login_path('invalid token') // Login_path routes to the controller method below.
assert flash[:danger]
assert_redirected_to root_path
end
This test produces the following error (referring to get login_path('invalid token')
):
ActionView::MissingTemplate: Missing template invitations/login, application/login with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}.
The view invitiations/login
indeed doesn't exist. However, such a view should never be needed given the controller method below (it always either redirects to the root_path
or renders profiles/show
). What could be causing this error?
The controller method:
def login
inv = Invitation.where('email = ?', params[:email])
if inv
inv.each do |person|
if person.authenticated?(:invitation, params[:id])
@organization = person.organization
unless @organization.nil?
render 'profiles/show' and return
else
flash[:danger] = "Error"
redirect_to root_path and return
end
end
flash[:danger] = "Invalid link"
redirect_to root_path
end
else
flash[:danger] = "Invalid link"
redirect_to root_path
end
end
P.S. The test used to pass, i.e. until I rewrote the controller method to accommodate for multiple inv
's (see Retrieve multiple records with find_by method).
You use
if inv
- this will still returntrue
if no invitations with matching email exist, sinceinv
is an ActiveRecord query object. But then theeach
does nothing, i.e. does not redirect or render explicitly. Default render will be invoked and expect a template to exist.Using
if inv.present?
will fix this.(Also, you might want to make sure the
inv
collection only contains one result. Redirecting or rendering multiple times in the same request will result in an error.)