Files
danbooru/test/functional/post_votes_controller_test.rb
evazion d0c9f6e0b8 posts: allow toggling between upvotes and downvotes.
Like 9efb374ae, allow users to toggle between upvoting and downvoting a
post without raising an error or having to manually remove the vote
first. If you upvote a post, then downvote it, the upvote is
automatically removed and replaced by the downvote.

Other changes:

* Tagging a post with `upvote:self` or `downvote:self` is now silently
  ignored when the user doesn't have permission to vote, instead of
  raising an error.
* Undoing a vote that doesn't exist now does nothing instead of
  returning an error. This can happen if you open the same post in two
  tabs, undo the vote in tab 1, then try to undo the vote again in tab 2.

Changes to the /post_votes API:

* `POST /post_votes` and `DELETE /post_votes` now return a post vote
  instead of a post.
* The `score` param in `POST /post_votes` is now 1 or -1, not `up` or
  `down`.
2021-01-29 02:22:23 -06:00

141 lines
4.5 KiB
Ruby

require 'test_helper'
class PostVotesControllerTest < ActionDispatch::IntegrationTest
context "The post vote controller" do
setup do
@user = create(:gold_user, name: "meiling")
@post = create(:post, tag_string: "dragon")
end
context "index action" do
setup do
@admin = create(:admin_user)
as(@user) { @post_vote = create(:post_vote, post: @post, user: @user) }
as(@admin) { @admin_vote = create(:post_vote, post: @post, user: @admin) }
@unrelated_vote = create(:post_vote)
end
should "render" do
get_auth post_votes_path, @user
assert_response :success
end
context "as a user" do
setup do
CurrentUser.user = @user
end
should respond_to_search({}).with { @post_vote }
end
context "as a moderator" do
setup do
CurrentUser.user = @admin
end
should respond_to_search({}).with { [@unrelated_vote, @admin_vote, @post_vote] }
should respond_to_search(score: 1).with { [@unrelated_vote, @admin_vote, @post_vote].select{ |v| v.score == 1 } }
context "using includes" do
should respond_to_search(post_tags_match: "dragon").with { [@admin_vote, @post_vote] }
should respond_to_search(user_name: "meiling").with { @post_vote }
should respond_to_search(user: {level: User::Levels::ADMIN}).with { @admin_vote }
end
end
end
context "create action" do
should "not allow anonymous users to vote" do
post post_post_votes_path(post_id: @post.id), params: { score: 1, format: "js" }
assert_response 403
assert_equal(0, @post.reload.score)
end
should "not allow banned users to vote" do
post_auth post_post_votes_path(post_id: @post.id), create(:banned_user), params: { score: 1, format: "js"}
assert_response 403
assert_equal(0, @post.reload.score)
end
should "not allow members to vote" do
post_auth post_post_votes_path(post_id: @post.id), create(:user), params: { score: 1, format: "js" }
assert_response 403
assert_equal(0, @post.reload.score)
end
should "not allow invalid scores" do
post_auth post_post_votes_path(post_id: @post.id), @user, params: { score: 3, format: "js" }
assert_response 200
assert_equal(0, @post.reload.score)
assert_equal(0, @post.up_score)
assert_equal(0, @post.votes.count)
end
should "increment a post's score if the score is positive" do
post_auth post_post_votes_path(post_id: @post.id), @user, params: { score: 1, format: "js" }
assert_response :success
assert_equal(1, @post.reload.score)
assert_equal(1, @post.up_score)
assert_equal(1, @post.votes.count)
end
should "decrement a post's score if the score is negative" do
post_auth post_post_votes_path(post_id: @post.id), @user, params: { score: -1, format: "js" }
assert_response :success
assert_equal(-1, @post.reload.score)
assert_equal(-1, @post.down_score)
assert_equal(1, @post.votes.count)
end
context "for a post that has already been voted on" do
should "replace the vote" do
@post.vote!(1, @user)
assert_no_difference("@post.votes.count") do
post_auth post_post_votes_path(post_id: @post.id), @user, params: { score: -1, format: "js" }
assert_response :success
assert_equal(-1, @post.reload.score)
assert_equal(0, @post.up_score)
assert_equal(-1, @post.down_score)
end
end
end
end
context "destroy action" do
should "do nothing for anonymous users" do
delete post_post_votes_path(post_id: @post.id), xhr: true
assert_response 200
assert_equal(0, @post.reload.score)
end
should "do nothing if the post hasn't been voted on" do
delete_auth post_post_votes_path(post_id: @post.id), @user, xhr: true
assert_response :success
assert_equal(0, @post.reload.score)
assert_equal(0, @post.down_score)
assert_equal(0, @post.votes.count)
end
should "remove a vote" do
@post.vote!(1, @user)
delete_auth post_post_votes_path(post_id: @post.id), @user, xhr: true
assert_response :success
assert_equal(0, @post.reload.score)
assert_equal(0, @post.down_score)
assert_equal(0, @post.votes.count)
end
end
end
end