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>'
- 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
- 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
- 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
- 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
- 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.
- 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
- comments_controller
private
def comment_params
params.require(:comment).permit(:content, :movie_id) #fixed
end
CodePudding user response:
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 } }
.