FIX: Reclaim votes when voting is disabled on a category

This commit is contained in:
David Taylor 2019-07-18 16:53:03 +01:00
parent 9e61d300b9
commit fd5c6d91f9
3 changed files with 114 additions and 0 deletions

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
class ReclaimFromDisabledCategory < ActiveRecord::Migration[5.2]
def up
aliases = {
votes: DiscourseVoting::VOTES,
votes_archive: DiscourseVoting::VOTES_ARCHIVE,
voting_enabled: DiscourseVoting::VOTING_ENABLED
}
# archive votes in non-voting categories
DB.exec(<<~SQL, aliases)
UPDATE user_custom_fields ucf
SET name = :votes_archive
FROM topics t
WHERE ucf.name = :votes
AND t.id::text = ucf.value
AND t.category_id NOT IN (
SELECT category_id FROM category_custom_fields WHERE name=:voting_enabled AND value='true'
)
SQL
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -115,11 +115,56 @@ after_initialize do
end
after_save :reset_voting_cache
after_find :track_voting_enabled
after_save :reclaim_release_votes
protected
def reset_voting_cache
::Category.reset_voting_cache
end
def track_voting_enabled
return unless SiteSetting.voting_enabled
@old_enable_voting = custom_fields[::DiscourseVoting::VOTING_ENABLED]
end
def reclaim_release_votes
return unless SiteSetting.voting_enabled
aliases = {
votes: DiscourseVoting::VOTES,
votes_archive: DiscourseVoting::VOTES_ARCHIVE,
category_id: id
}
was_enabled = @old_enable_voting
is_enabled = custom_fields[::DiscourseVoting::VOTING_ENABLED]
if !was_enabled && is_enabled
# Unarchive all votes in the category
DB.exec(<<~SQL, aliases)
UPDATE user_custom_fields ucf
SET name = :votes
FROM topics t
WHERE ucf.name = :votes_archive
AND NOT t.closed
AND NOT t.archived
AND t.deleted_at IS NULL
AND t.id::text = ucf.value
AND t.category_id = :category_id
SQL
elsif was_enabled && !is_enabled
# Archive all votes in category
DB.exec(<<~SQL, aliases)
UPDATE user_custom_fields ucf
SET name = :votes_archive
FROM topics t
WHERE ucf.name = :votes
AND t.id::text = ucf.value
AND t.category_id = :category_id
SQL
end
end
end
require_dependency 'user'

View File

@ -157,4 +157,46 @@ describe DiscourseVoting do
expect(Jobs::VoteReclaim.jobs.size).to eq(0)
end
end
context "when a category has voting enabled/disabled" do
let(:category3) { Fabricate(:category) }
let(:topic2) { Fabricate(:topic, category: category3) }
before do
category1.custom_fields["enable_topic_voting"] = true
category1.save!
category2.custom_fields["enable_topic_voting"] = true
category2.save!
category3.custom_fields["enable_topic_voting"] = false
category3.save!
user0.custom_fields[DiscourseVoting::VOTES] = [topic0.id, topic1.id]
user0.custom_fields[DiscourseVoting::VOTES_ARCHIVE] = [topic2.id]
user0.save!
end
it "reclaims votes when voting is disabled on a category" do
category = Category.find(category1.id)
category.custom_fields["enable_topic_voting"] = false
category.save!
user0.reload
expect(user0.custom_fields[DiscourseVoting::VOTES]).to contain_exactly(topic1.id)
expect(user0.custom_fields[DiscourseVoting::VOTES_ARCHIVE]).to contain_exactly(topic0.id, topic2.id)
end
it "restores votes when voting is enabled on a category" do
category = Category.find(category3.id)
category.custom_fields["enable_topic_voting"] = true
category.save!
user0.reload
expect(user0.custom_fields[DiscourseVoting::VOTES]).to contain_exactly(topic0.id, topic1.id, topic2.id)
expect(user0.custom_fields[DiscourseVoting::VOTES_ARCHIVE]).to eq(nil)
end
end
end