Rails - "Comment.count" didn't change by 1

Viewed 60

This question's been solved. Check the bottom line.

Nowadays, I'm building my movie review website on Ruby on Rails but stuck with the Comment.count error. Already checked and tried a lot of options, but any solutions didn't work. Actually, my website works well, but still this test says the error, and I don't understand what is the problem and why it happens. Could you help me to fix this error? Thank you.

error code

 test_comment_interface#CommentsInterfaceTest (3.43s)
        "Comment.count" didn't change by 1.
        Expected: 39
          Actual: 38
        test/integration/comments_interface_test.rb:19:in `block in <class:CommentsInterfaceTest>'
  1. comments_interface_test
require 'test_helper'

class CommentsInterfaceTest < ActionDispatch::IntegrationTest
  
  def setup
    @user = users(:michael)
  end
  
  test "comment interface" do
    log_in_as(@user)
    get root_path
    assert_select 'div.pagination'
    
    assert_no_difference 'Comment.count' do
      post comments_path, params: { comment: { content: "" } }
    end
    assert_select 'div#error_explanation'
    content = "This comment really ties the room together"
    assert_difference 'Comment.count', 1 do  #<-----------------------error point
      post comments_path, params: { comment: { content: content } }
    end
    assert_redirected_to root_url
    follow_redirect!
    assert_match content, response.body
    assert_select 'a', text: 'delete'
    first_comment = @user.comments.paginate(page: 1).first
    assert_difference 'Comment.count', -1 do
      delete comment_path(first_comment)
    end
    get user_path(users(:archer))
    assert_select 'a', text: 'delete', count: 0
  end
end
  1. comment.rb
class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :movie, optional: true, primary_key: "id"
  has_many :favorites, dependent: :destroy
  
  
  default_scope -> { order(created_at: :desc) }
  validates :user_id,   presence: true
  validates :movie_id,  presence: true
  validates :content,   presence: true, length: { maximum: 250}
  
end
  1. comments_controller
class CommentsController < ApplicationController
  include HTTParty
  before_action :logged_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy
  
  def create
    @comment = current_user.comments.build(comment_params)
    comment_count = Comment.where(movie_id: params[:id]).where(user_id: current_user.id).count
 
    if @comment.valid?
      if comment_count < 1
        @comment.save
        flash[:success] = "Comment created!"
        redirect_to root_url
      else
        flash[:success] = "Can't post a comment twice on the same movie"
        redirect_to request.referrer || root_url
      end
      
    else
      @feed_items = []
      render 'static_pages/home'
    end
  end
  
  def destroy
    @comment.destroy
    flash[:success] = "Comment deleted"
    redirect_to request.referrer || root_url
  end
  
  def edit
    @movie_info = Movie.details(params[:movie_id])
    @comment = Comment.find(params[:id])
    
    if Movie.exists?(@movie_info["id"])
      @movie_db = Movie.find(@movie_info["id"])
      @comments = @movie_db.comments.paginate(page: params[:page])
    end
  end
  
  def update
    @comment = Comment.find(params[:id])
    if @comment.update(comment_params)
      redirect_to root_url
    else
      render :edit
    end
  end
  
  private
  
    def comment_params
      params.require(:comment).permit(:content)
    end
    
    def correct_user
      @comment = current_user.comments.find_by(id: params[:id])
      redirect_to root_url if @comment.nil?
    end
end
  1. comments_controller_test
require 'test_helper'

class CommentsControllerTest < ActionDispatch::IntegrationTest
  
  def setup
    @user = users(:michael)
    @comment = comments(:orange)
  end
  
  test "should redirect create when not logged in" do
    assert_no_difference 'Comment.count' do
      post comments_path, params: { comment: { content: "Lorem ipsum" } }
    end
    assert_redirected_to login_url
  end
  
  test "should redirect destroy when not logged in" do
    assert_no_difference 'Comment.count' do
      delete comment_path(@comment)
    end
    assert_redirected_to login_url
  end
  
  test "should redirect destroy for wrong comment" do
    log_in_as(users(:michael))
    comment = comments(:ants)
    assert_no_difference 'Comment.count' do
      delete comment_path(comment)
    end
    assert_redirected_to root_url
  end
end
  1. comments.yml
orange:
  content: "I just ate an orange!"
  created_at: <%= 10.minutes.ago %>
  user: michael
  movie: harry
  
tau_manifesto:
  content: "Check out the @tauday site by @mhartl: http://tauday.com"
  created_at: <%= 3.years.ago %>
  user: michael
  movie: harry
  
cat_video:
  content: "Sad cats are sad: http://youtu.be/PKffm2uI4dk"
  created_at: <%= 2.hours.ago %>
  user: michael
  movie: harry
  
most_recent:
  content: "Writing a short test"
  created_at: <%= Time.zone.now.to_s(:db) %>
  user: michael
  movie: harry
  
<% 30.times do |n| %>
comment_<%= n %>:
  content: <%= Faker::Lorem.sentence(5) %>
  created_at: <%= 42.days.ago %>
  user: michael
  movie: harry
<% end %>

ants:
  content: "Oh, is that what you want? Because that's how you get ants!"
  created_at: <%= 2.years.ago %>
  user: archer
  movie: harry

zone:
  content: "Danger zone!"
  created_at: <%= 3.days.ago %>
  user: archer
  movie: harry

tone:
  content: "I'm sorry. Your words made sense, but your sarcastic tone did not."
  created_at: <%= 10.minutes.ago %>
  user: lana
  movie: harry

van:
  content: "Dude, this van's, like, rolling probable cause."
  created_at: <%= 4.hours.ago %>
  user: lana
  movie: harry

From the comments below, I fixed some codes like this. Finally it worked, and the problem was solved.

  1. comments_interface_test
  def setup
    @user  = users(:michael)
    @movie = movies(:harry)  #add
  end

  assert_difference 'Comment.count', 1 do
      post comments_path, params: { comment: { content: content, movie_id: @movie.id } } #fixed
  end
  1. comments_controller
  private
  
    def comment_params
      params.require(:comment).permit(:content, :movie_id) #fixed
    end
    
1 Answers

By looking at your Comment model it looks like a validation error. You have the following validations on the model but on the test, you didn't specify movie_id.

comment.rb

  validates :user_id,   presence: true
  validates :movie_id,  presence: true

Instead it should be something like the following params: { id: movie_id, comment: { content: content } }.

Related