Search code examples
ruby-on-railsrubyruby-on-rails-6minitest

The before_action call back do not execute while running the integration test cases rails


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.


Solution

  • 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