Files
danbooru/test/unit/post_vote_test.rb
evazion 353e708538 votes: allow admins to remove post votes.
Allow admins to remove votes on posts. This is for fixing vote abuse.

Votes can be removed by going to the vote list on the /post_votes page,
or by clicking on a post's score, then using the "Remove" option in the
"..." dropdown menu next to the vote.

Votes are soft-deleted - they're marked as deleted in the database, but
not fully deleted. Removed votes are only visible to admins, not to
regular users. When a vote is removed by an admin, it leaves a mod
action.

Technically it's possible to undelete votes, but there's no UI for it.
2021-11-23 23:18:54 -06:00

136 lines
4.5 KiB
Ruby

require 'test_helper'
class PostVoteTest < ActiveSupport::TestCase
context "A PostVote" do
setup do
@post = create(:post)
end
context "during validation" do
subject { build(:post_vote, post: @post) }
should validate_inclusion_of(:score).in_array([-1, 1]).with_message("must be 1 or -1")
end
context "creating" do
context "an upvote" do
should "increment the post's score" do
vote = create(:post_vote, post: @post, score: 1)
assert_equal(1, @post.reload.score)
assert_equal(1, @post.up_score)
assert_equal(0, @post.down_score)
assert_equal(1, @post.votes.active.positive.count)
end
should "soft delete other votes" do
@user = create(:user)
vote1 = create(:post_vote, post: @post, user: @user, score: -1)
vote2 = create(:post_vote, post: @post, user: @user, score: 1)
assert_equal(1, @post.reload.score)
assert_equal(1, @post.up_score)
assert_equal(0, @post.down_score)
assert_equal(1, @post.votes.active.positive.count)
assert_equal(0, @post.votes.active.negative.count)
assert_equal(true, vote1.reload.is_deleted?)
end
end
context "a downvote" do
should "decrement the post's score" do
vote = create(:post_vote, post: @post, score: -1)
assert_equal(-1, @post.reload.score)
assert_equal(0, @post.up_score)
assert_equal(-1, @post.down_score)
assert_equal(1, @post.votes.active.negative.count)
end
should "soft delete other votes" do
@user = create(:user)
vote1 = create(:post_vote, post: @post, user: @user, score: 1)
vote2 = create(:post_vote, post: @post, user: @user, score: -1)
assert_equal(-1, @post.reload.score)
assert_equal(0, @post.up_score)
assert_equal(-1, @post.down_score)
assert_equal(0, @post.votes.active.positive.count)
assert_equal(1, @post.votes.active.negative.count)
assert_equal(true, vote1.reload.is_deleted?)
end
end
end
context "soft deleting" do
context "an upvote" do
should "decrement the post's score" do
vote = create(:post_vote, post: @post, score: 1)
assert_equal(1, @post.reload.score)
assert_equal(1, @post.up_score)
assert_equal(0, @post.down_score)
assert_equal(1, @post.votes.active.count)
assert_equal(0, @post.votes.deleted.count)
vote.soft_delete
assert_equal(0, @post.reload.score)
assert_equal(0, @post.up_score)
assert_equal(0, @post.down_score)
assert_equal(0, @post.votes.active.count)
assert_equal(1, @post.votes.deleted.count)
end
end
context "a downvote" do
should "increment the post's score" do
vote = create(:post_vote, post: @post, score: -1)
assert_equal(-1, @post.reload.score)
assert_equal(0, @post.up_score)
assert_equal(-1, @post.down_score)
assert_equal(1, @post.votes.active.count)
assert_equal(0, @post.votes.deleted.count)
vote.soft_delete
assert_equal(0, @post.reload.score)
assert_equal(0, @post.up_score)
assert_equal(0, @post.down_score)
assert_equal(0, @post.votes.active.count)
assert_equal(1, @post.votes.deleted.count)
end
end
end
context "deleting a vote by another user" do
should "leave a mod action" do
admin = create(:admin_user, name: "admin")
vote = create(:post_vote, post: @post, score: 1)
vote.soft_delete!(updater: admin)
assert_match(/admin deleted post vote #\d+ on post #\d+/, ModAction.post_vote_delete.last.description)
end
end
context "undeleting a vote by another user" do
setup do
@admin = create(:admin_user, name: "admin")
@vote = create(:post_vote, post: @post, score: 1)
@vote.soft_delete!(updater: @admin)
@vote.update!(is_deleted: false, updater: @admin)
end
should "restore the score" do
assert_equal(1, @post.reload.score)
assert_equal(1, @post.up_score)
assert_equal(0, @post.down_score)
assert_equal(1, @post.votes.active.count)
assert_equal(0, @post.votes.deleted.count)
end
should "leave a mod action" do
assert_match(/admin undeleted post vote #\d+ on post #\d+/, ModAction.post_vote_undelete.last.description)
end
end
end
end