diff --git a/src/components/views/messages/MPollBody.tsx b/src/components/views/messages/MPollBody.tsx index 2243b20be4..592a00e4ff 100644 --- a/src/components/views/messages/MPollBody.tsx +++ b/src/components/views/messages/MPollBody.tsx @@ -215,6 +215,19 @@ export default class MPollBody extends React.Component { const totalVotes = this.totalVotes(votes); const userId = this.context.getUserId(); const myVote = userVotes.get(userId)?.answers[0]; + let totalText: string; + if (myVote === undefined) { + if (totalVotes === 0) { + totalText = _t("No votes cast"); + } else { + totalText = _t( + "%(count)s votes cast. Vote to see the results", + { count: totalVotes }, + ); + } + } else { + totalText = _t( "Based on %(count)s votes", { count: totalVotes } ); + } return

{ pollInfo.question[TEXT_NODE_TYPE] }

@@ -225,7 +238,12 @@ export default class MPollBody extends React.Component { const classNames = `mx_MPollBody_option${ checked ? " mx_MPollBody_option_checked": "" }`; - const answerVotes = votes.get(answer.id) ?? 0; + let answerVotes = 0; + let votesText = ""; + if (myVote !== undefined) { // Votes hidden if I didn't vote + answerVotes = votes.get(answer.id) ?? 0; + votesText = _t("%(count)s votes", { count: answerVotes }); + } const answerPercent = Math.round( 100.0 * answerVotes / totalVotes); return
{ { answer[TEXT_NODE_TYPE] }
- { _t("%(count)s votes", { count: answerVotes }) } + { votesText }
@@ -259,7 +277,7 @@ export default class MPollBody extends React.Component { }
- { _t( "Based on %(count)s votes", { count: totalVotes } ) } + { totalText }
; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0ffb92f549..0212331015 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2065,10 +2065,13 @@ "You sent a verification request": "You sent a verification request", "Vote not registered": "Vote not registered", "Sorry, your vote was not registered. Please try again.": "Sorry, your vote was not registered. Please try again.", - "%(count)s votes|other": "%(count)s votes", - "%(count)s votes|one": "%(count)s vote", + "No votes cast": "No votes cast", + "%(count)s votes cast. Vote to see the results|other": "%(count)s votes cast. Vote to see the results", + "%(count)s votes cast. Vote to see the results|one": "%(count)s vote cast. Vote to see the results", "Based on %(count)s votes|other": "Based on %(count)s votes", "Based on %(count)s votes|one": "Based on %(count)s vote", + "%(count)s votes|other": "%(count)s votes", + "%(count)s votes|one": "%(count)s vote", "Error decrypting video": "Error decrypting video", "Error processing voice message": "Error processing voice message", "Add reaction": "Add reaction", diff --git a/test/components/views/messages/MPollBody-test.tsx b/test/components/views/messages/MPollBody-test.tsx index 11d0fc0087..2baaaa944d 100644 --- a/test/components/views/messages/MPollBody-test.tsx +++ b/test/components/views/messages/MPollBody-test.tsx @@ -63,19 +63,19 @@ describe("MPollBody", () => { ]); }); - it("finds no votes if none were made", () => { + it("renders no votes if none were made", () => { const votes = []; const body = newMPollBody(votes); - expect(votesCount(body, "pizza")).toBe("0 votes"); - expect(votesCount(body, "poutine")).toBe("0 votes"); - expect(votesCount(body, "italian")).toBe("0 votes"); - expect(votesCount(body, "wings")).toBe("0 votes"); - expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 0 votes"); + expect(votesCount(body, "pizza")).toBe(""); + expect(votesCount(body, "poutine")).toBe(""); + expect(votesCount(body, "italian")).toBe(""); + expect(votesCount(body, "wings")).toBe(""); + expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("No votes cast"); }); it("finds votes from multiple people", () => { const votes = [ - responseEvent("@andyb:example.com", "pizza"), + responseEvent("@me:example.com", "pizza"), responseEvent("@bellc:example.com", "pizza"), responseEvent("@catrd:example.com", "poutine"), responseEvent("@dune2:example.com", "wings"), @@ -88,10 +88,39 @@ describe("MPollBody", () => { expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 4 votes"); }); + it("hides scores if I have not voted", () => { + const votes = [ + responseEvent("@alice:example.com", "pizza"), + responseEvent("@bellc:example.com", "pizza"), + responseEvent("@catrd:example.com", "poutine"), + responseEvent("@dune2:example.com", "wings"), + ]; + const body = newMPollBody(votes); + expect(votesCount(body, "pizza")).toBe(""); + expect(votesCount(body, "poutine")).toBe(""); + expect(votesCount(body, "italian")).toBe(""); + expect(votesCount(body, "wings")).toBe(""); + expect(body.find(".mx_MPollBody_totalVotes").text()).toBe( + "4 votes cast. Vote to see the results"); + }); + + it("hides a single vote if I have not voted", () => { + const votes = [ + responseEvent("@alice:example.com", "pizza"), + ]; + const body = newMPollBody(votes); + expect(votesCount(body, "pizza")).toBe(""); + expect(votesCount(body, "poutine")).toBe(""); + expect(votesCount(body, "italian")).toBe(""); + expect(votesCount(body, "wings")).toBe(""); + expect(body.find(".mx_MPollBody_totalVotes").text()).toBe( + "1 vote cast. Vote to see the results"); + }); + it("takes someone's most recent vote if they voted several times", () => { const votes = [ - responseEvent("@fiona:example.com", "pizza", 12), - responseEvent("@fiona:example.com", "wings", 20), // latest fiona + responseEvent("@me:example.com", "pizza", 12), + responseEvent("@me:example.com", "wings", 20), // latest me responseEvent("@qbert:example.com", "pizza", 14), responseEvent("@qbert:example.com", "poutine", 16), // latest qbert responseEvent("@qbert:example.com", "wings", 15), @@ -219,7 +248,7 @@ describe("MPollBody", () => { // When cb votes for 2 things, we consider the first only const votes = [ responseEvent("@cb:example.com", ["pizza", "wings"]), - responseEvent("@da:example.com", "wings"), + responseEvent("@me:example.com", "wings"), ]; const body = newMPollBody(votes); expect(votesCount(body, "pizza")).toBe("1 vote"); @@ -233,7 +262,7 @@ describe("MPollBody", () => { const votes = [ responseEvent("@nc:example.com", "pizza", 12), responseEvent("@nc:example.com", [], 13), - responseEvent("@md:example.com", "italian"), + responseEvent("@me:example.com", "italian"), ]; const body = newMPollBody(votes); expect(votesCount(body, "pizza")).toBe("0 votes"); @@ -248,7 +277,7 @@ describe("MPollBody", () => { responseEvent("@op:example.com", "pizza", 12), responseEvent("@op:example.com", [], 13), responseEvent("@op:example.com", "italian", 14), - responseEvent("@qr:example.com", "italian"), + responseEvent("@me:example.com", "italian"), ]; const body = newMPollBody(votes); expect(votesCount(body, "pizza")).toBe("0 votes"); @@ -263,8 +292,8 @@ describe("MPollBody", () => { // the ballot is still spoiled because the second answer is // invalid, even though we would ignore it if we continued. const votes = [ - responseEvent("@tr:example.com", "pizza", 12), - responseEvent("@tr:example.com", ["pizza", "doesntexist"], 13), + responseEvent("@me:example.com", "pizza", 12), + responseEvent("@me:example.com", ["pizza", "doesntexist"], 13), responseEvent("@uy:example.com", "italian", 14), responseEvent("@uy:example.com", "doesntexist", 15), ]; @@ -278,8 +307,8 @@ describe("MPollBody", () => { it("allows re-voting after a spoiled ballot", () => { const votes = [ - responseEvent("@tr:example.com", "pizza", 12), - responseEvent("@tr:example.com", ["pizza", "doesntexist"], 13), + responseEvent("@me:example.com", "pizza", 12), + responseEvent("@me:example.com", ["pizza", "doesntexist"], 13), responseEvent("@uy:example.com", "italian", 14), responseEvent("@uy:example.com", "doesntexist", 15), responseEvent("@uy:example.com", "poutine", 16), @@ -389,7 +418,7 @@ describe("MPollBody", () => { responseEvent("@op:example.com", "pizza", 12), responseEvent("@op:example.com", [], 13), responseEvent("@op:example.com", "italian", 14), - responseEvent("@st:example.com", "wings", 15), + responseEvent("@me:example.com", "wings", 15), responseEvent("@qr:example.com", "italian", 16), ]; const body = newMPollBody(votes); @@ -409,6 +438,18 @@ describe("MPollBody", () => { clickRadio(body, "italian"); expect(body).toMatchSnapshot(); }); + + it("renders a poll that I have not voted in", () => { + const votes = [ + responseEvent("@op:example.com", "pizza", 12), + responseEvent("@op:example.com", [], 13), + responseEvent("@op:example.com", "italian", 14), + responseEvent("@yo:example.com", "wings", 15), + responseEvent("@qr:example.com", "italian", 16), + ]; + const body = newMPollBody(votes); + expect(body).toMatchSnapshot(); + }); }); function newPollRelations(relationEvents: Array): Relations { diff --git a/test/components/views/messages/__snapshots__/MPollBody-test.tsx.snap b/test/components/views/messages/__snapshots__/MPollBody-test.tsx.snap index 543f178274..626a7dfa96 100644 --- a/test/components/views/messages/__snapshots__/MPollBody-test.tsx.snap +++ b/test/components/views/messages/__snapshots__/MPollBody-test.tsx.snap @@ -1,5 +1,346 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`MPollBody renders a poll that I have not voted in 1`] = ` + + +
+

+ What should we order for the party? +

+
+
+ +