FIX: Voting buttons should reset on navigation (#38234)

Fixes 2 bugs introduced in the DMenu UX rewrite
(https://github.com/discourse/discourse/pull/35917):

- Vote button label cached between topics
- "Remove vote" shown on closed topics with no votes
This commit is contained in:
Natalie Tay
2026-03-04 19:09:55 +08:00
committed by GitHub
parent c3bd55b5d2
commit b57140b2b8
3 changed files with 72 additions and 10 deletions
@@ -15,9 +15,10 @@ export default class VoteBox extends Component {
@tracked hasVoted = false;
@tracked hasSeenSuccessMenu = false;
topic = this.args.topic;
alreadyVoted = this.topic.user_voted;
get topic() {
return this.args.topic;
}
get buttonContent() {
const content = {};
@@ -58,6 +59,11 @@ export default class VoteBox extends Component {
@action
onShowMenu() {
if (!this.topic.user_voted) {
this.hasVoted = false;
this.hasSeenSuccessMenu = false;
}
applyBehaviorTransformer("topic-vote-button-click", () => {
if (!this.currentUser) {
return this.args.showLogin();
@@ -174,14 +180,16 @@ export default class VoteBox extends Component {
class="btn-transparent see-votes topic-voting-menu__row-btn"
/>
</dropdown.item>
<dropdown.item class="topic-voting-menu__row">
<DButton
@translatedLabel={{i18n "topic_voting.remove_vote"}}
@action={{this.removeVote}}
@icon="arrow-rotate-left"
class="btn-transparent remove-vote topic-voting-menu__row-btn --danger"
/>
</dropdown.item>
{{#if this.topic.user_voted}}
<dropdown.item class="topic-voting-menu__row">
<DButton
@translatedLabel={{i18n "topic_voting.remove_vote"}}
@action={{this.removeVote}}
@icon="arrow-rotate-left"
class="btn-transparent remove-vote topic-voting-menu__row-btn --danger"
/>
</dropdown.item>
{{/if}}
{{/if}}
</DropdownMenu>
</:content>
@@ -33,6 +33,14 @@ module TopicVotingTopic
def click_my_votes
find(".topic-voting-menu__votes-left").click
end
def has_vote_button_label?(text)
has_css?("button.vote-button", text: text)
end
def has_no_remove_vote_button?
has_no_css?("button.remove-vote")
end
end
PageObjects::Pages::Topic.include(TopicVotingTopic)
@@ -63,6 +63,52 @@ RSpec.describe "Topic voting", type: :system do
expect(topic_page.vote_count).to have_text("0")
end
context "when navigating between voting topics" do
fab!(:voting_post1) { Fabricate(:post, topic: voting_topic1) }
fab!(:voting_post2) { Fabricate(:post, topic: voting_topic2) }
fab!(:voting_post3) { Fabricate(:post, topic: voting_topic3) }
before { DiscourseTopicVoting::CategorySetting.create!(category: voting_category) }
it "resets vote UI state after route transitions" do
voting_topic3.update!(closed: true)
Fabricate(:post, topic: voting_topic3, raw: "Check out #{voting_topic1.url}")
Fabricate(:post, topic: voting_topic1, raw: "Check out #{voting_topic2.url}")
visit("/t/#{voting_topic3.slug}/#{voting_topic3.id}")
expect(topic_page).to have_vote_button_label(I18n.t("js.topic_voting.voting_closed_title"))
find("a[href='#{voting_topic1.url}']").click
expect(topic_page).to have_vote_button_label(I18n.t("js.topic_voting.vote_title"))
topic_page.vote
expect(topic_page.vote_popup).to have_text(
I18n.t("js.topic_voting.see_votes", count: 9, max: 10),
)
find("a[href='#{voting_topic2.url}']").click
expect(topic_page).to have_vote_button_label(I18n.t("js.topic_voting.vote_title"))
topic_page.vote
expect(topic_page.vote_popup).to have_text(
I18n.t("js.topic_voting.see_votes", count: 8, max: 10),
)
end
end
context "when viewing a closed voting topic without having voted" do
before { DiscourseTopicVoting::CategorySetting.create!(category: voting_category) }
it "does not show the remove vote button" do
voting_topic1.update!(closed: true)
Fabricate(:post, topic: voting_topic1)
visit("/t/#{voting_topic1.slug}/#{voting_topic1.id}")
topic_page.vote
expect(topic_page).to have_no_remove_vote_button
end
end
context "when no votes are left" do
before do
DiscourseTopicVoting::CategorySetting.create!(category: category1)