superuseroi
superuseroi

Reputation: 1348

RSPEC fails controller test (transaction) but works in the browser (rails 4)

I am having a strange issue with RSPEC that I am unable to nail down. The test fails but when I try in the browser the behavior works as expected.

Here is the model code so far:

class QueueItem < ActiveRecord::Base
  belongs_to :video
  belongs_to :user

  validates_presence_of :user_id, :video_id
  validates_uniqueness_of :video_id, scope: :user_id
  validates_numericality_of :position, only_integer: true

  delegate :category, to: :video
  delegate :title, to: :video, prefix: :video

...

end

And here is the controller code so far:

class QueueItemsController < ApplicationController

  ...

  before_action :require_user

  def update_queue
    begin
      ActiveRecord::Base.transaction do
        queue_items_params.each do |queue_item_input|
          queue_item = QueueItem.find(queue_item_input[:id])
          queue_item.update!(position: queue_item_input[:position])
        end
      end
    rescue ActiveRecord::RecordInvalid
      flash[:danger] = "Your queue was not updated, make sure you only use numbers to set the position"
      redirect_to queue_items_path
      return
    end
    current_user.queue_items.each_with_index { |queue_item, i| queue_item.update(position: i+1 )}
    redirect_to queue_items_path

  end


  private

  def queue_items_params
    params.permit(queue_items:[:id, :position])[:queue_items]
  end

  ...
end

And now the controller spec that fails:

  describe "POST #update" do
    context 'when user is signed in' do
      let(:user) { Fabricate(:user) }
      before { session[:user] = user.id }

      context 'with invalid attributes' do
        it "does not update the queue items position" do
          queue_item1 = Fabricate(:queue_item, user: user, position: 1)
          queue_item2 = Fabricate(:queue_item, user: user, position: 2)
          post :update_queue, queue_items: [{id: queue_item1.id, position: 6}, {id: queue_item2.id, position: 2.2}]
          expect(queue_item1.reload.position).to  eq(1)
          expect(queue_item2.reload.position).to  eq(2)
        end
      end

    end
  end

And the error message:

Failures:

  1) QueueItemsController POST #update when user is signed in with invalid attributes does not update the queue items position
     Failure/Error: expect(queue_item1.reload.position).to  eq(1)

       expected: 1
            got: 6

       (compared using ==)

I don't understand why the spec fails but in the browser it works. What am I missing?

Thank you very much

Upvotes: 0

Views: 338

Answers (1)

superuseroi
superuseroi

Reputation: 1348

I actually found the issue! It was due to DatabaseCleaner gem which I am using in my rspec_helper.rb setup.

The following setup did not work:

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

I fixed it by changing it to:

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :deletion
  end

Upvotes: 2

Related Questions