using ruby 2.6.5, Rails 6.0.3.7
There is before_action filter which are working fine when running the project in the development server. But while running the integration tests of the rails application. The call back do not execute and the request goes directly to the called function rather than going to the before action first.
Here attaching my controller and integration test case and error output. Controller
class TvSeriesController < ApplicationController
before_action :check_file, only: [:create, :tv_seriel_comments]
require 'roo'
def index
@tv_series = TvSeriel.includes(:comments).all
end
def show
@series = TvSeriel.includes({ comments: [:user] }).find(params[:id])
end
def create
spreadsheet = Roo::Spreadsheet.open(params[:file])
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |line|
row = HashWithIndifferentAccess[[header, spreadsheet.row(line)].transpose]
tv_serial = TvSeriel.new
tv_serial.name = row['TV Series']
tv_serial.genre = row["Genre"]
tv_serial.seasons = row["No of seasons"]
tv_serial.release_date = row["Date of First Release"]
tv_serial.director = row["Director"]
tv_serial.actor = row["Actor"]
tv_serial.shoot_location = row["Shoot location"]
tv_serial.country = row["Country"]
tv_serial.save
end
flash[:notice] = 'TV series uploaded!'
redirect_back(fallback_location: tv_series_index_path)
end
def tv_seriel_comments
spreadsheet = Roo::Spreadsheet.open(params[:file])
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |line|
row = HashWithIndifferentAccess[[header, spreadsheet.row(line)].transpose]
comment = Comment.new
user = User.find_by_name(row["User"])
comment.user = user
tv_serial = TvSeriel.find_by_name(row['TV Series'])
comment.tv_seriel = tv_serial
comment.stars = row['Stars']
comment.review = row['Review']
comment.save
end
flash[:notice] = 'TV series comment uploaded!'
redirect_back(fallback_location: tv_series_index_path)
end
def destroy
TvSeriel.find(params[:id]).destroy
flash[:notice] = 'TV series removed success!'
redirect_back(fallback_location: tv_series_index_path)
end
def search_actor
@tv_series = TvSeriel.includes(:comments).where("actor like ?", "%#{params[:actor]}%")
render 'tv_series/index'
end
## check if uploaded file is a cvs
def check_file
unless params[:file].blank?
if params[:file].content_type.eql?("text/csv")
else
flash[:alert] = "file format Invalid, expected: text/csv Got #{params[:file].content_type}"
redirect_back(fallback_location: :tv_series_index_path)
end
else
flash[:alert] = 'Please provide a file to be uploaded !'
end
end
end
Integration test:
require 'test_helper'
class UserFlowsTest < ActionDispatch::IntegrationTest
fixtures :all
include Devise::Test::IntegrationHelpers
include Warden::Test::Helpers
test 'Get list of all users' do
@user = users(:vidur)
sign_in(@user)
get "/users"
assert_response :success
assert_select "h2", "User List"
end
test 'Update Series' do
@user = users(:vidur)
sign_in(@user)
post '/tv_series'
assert_response :success
end
end
Error:
# Running:
E
Error:
UserFlowsTest#test_Update_Series:
TypeError: no implicit conversion of nil into String
app/controllers/tv_series_controller.rb:15:in `create'
test/integration/user_flows_test.rb:19:in `block in <class:UserFlowsTest>'
Here the before_action filter do not execute and the request goes directly to the defined action can any body give the reason why only running test, and how to correct it, Thanks in advance. Here is the git repo for complete code: https://github.com/vidurpunj/sopra_test.
It's because you don't have a file
parameter.
So your check_file
is using this part:
flash[:alert] = 'Please provide a file to be uploaded !'
And since you don't render or redirect, the controller action is called normally. See the Rails documentation on filters for more details:
If a "before" filter renders or redirects, the action will not run