Support "closed" polls whose votes are not visible until they are ended (#7842)
This commit is contained in:
parent
eca64d776a
commit
f1e1b7be86
8 changed files with 248 additions and 11 deletions
|
@ -23,6 +23,7 @@ import { RelatedRelations } from "matrix-js-sdk/src/models/related-relations";
|
|||
import {
|
||||
M_POLL_END,
|
||||
M_POLL_KIND_DISCLOSED,
|
||||
M_POLL_KIND_UNDISCLOSED,
|
||||
M_POLL_RESPONSE,
|
||||
M_POLL_START,
|
||||
M_POLL_START_EVENT_CONTENT,
|
||||
|
@ -474,6 +475,60 @@ describe("MPollBody", () => {
|
|||
).toBe(20);
|
||||
});
|
||||
|
||||
it("hides scores if I voted but the poll is undisclosed", () => {
|
||||
const votes = [
|
||||
responseEvent("@me:example.com", "pizza"),
|
||||
responseEvent("@alice:example.com", "pizza"),
|
||||
responseEvent("@bellc:example.com", "pizza"),
|
||||
responseEvent("@catrd:example.com", "poutine"),
|
||||
responseEvent("@dune2:example.com", "wings"),
|
||||
];
|
||||
const body = newMPollBody(votes, [], null, false);
|
||||
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(
|
||||
"Results will be visible when the poll is ended");
|
||||
});
|
||||
|
||||
it("highlights my vote if the poll is undisclosed", () => {
|
||||
const votes = [
|
||||
responseEvent("@me:example.com", "pizza"),
|
||||
responseEvent("@alice:example.com", "poutine"),
|
||||
responseEvent("@bellc:example.com", "poutine"),
|
||||
responseEvent("@catrd:example.com", "poutine"),
|
||||
responseEvent("@dune2:example.com", "wings"),
|
||||
];
|
||||
const body = newMPollBody(votes, [], null, false);
|
||||
|
||||
// My vote is marked
|
||||
expect(body.find('input[value="pizza"]').prop("checked")).toBeTruthy();
|
||||
|
||||
// Sanity: other items are not checked
|
||||
expect(body.find('input[value="poutine"]').prop("checked")).toBeFalsy();
|
||||
});
|
||||
|
||||
it("shows scores if the poll is undisclosed but ended", () => {
|
||||
const votes = [
|
||||
responseEvent("@me:example.com", "pizza"),
|
||||
responseEvent("@alice:example.com", "pizza"),
|
||||
responseEvent("@bellc:example.com", "pizza"),
|
||||
responseEvent("@catrd:example.com", "poutine"),
|
||||
responseEvent("@dune2:example.com", "wings"),
|
||||
];
|
||||
const ends = [
|
||||
endEvent("@me:example.com", 12),
|
||||
];
|
||||
const body = newMPollBody(votes, ends, null, false);
|
||||
expect(endedVotesCount(body, "pizza")).toBe("3 votes");
|
||||
expect(endedVotesCount(body, "poutine")).toBe("1 vote");
|
||||
expect(endedVotesCount(body, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(body, "wings")).toBe("1 vote");
|
||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe(
|
||||
"Final result based on 5 votes");
|
||||
});
|
||||
|
||||
it("sends a vote event when I choose an option", () => {
|
||||
const receivedEvents = [];
|
||||
MatrixClientPeg.matrixClient.sendEvent = (
|
||||
|
@ -993,6 +1048,34 @@ describe("MPollBody", () => {
|
|||
const body = newMPollBody(votes, ends);
|
||||
expect(body).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders an undisclosed, unfinished poll", () => {
|
||||
const votes = [
|
||||
responseEvent("@ed:example.com", "pizza", 12),
|
||||
responseEvent("@rf:example.com", "pizza", 12),
|
||||
responseEvent("@th:example.com", "wings", 13),
|
||||
responseEvent("@yh:example.com", "wings", 14),
|
||||
responseEvent("@th:example.com", "poutine", 13),
|
||||
responseEvent("@yh:example.com", "poutine", 14),
|
||||
];
|
||||
const ends = [];
|
||||
const body = newMPollBody(votes, ends, null, false);
|
||||
expect(body.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders an undisclosed, finished poll", () => {
|
||||
const votes = [
|
||||
responseEvent("@ed:example.com", "pizza", 12),
|
||||
responseEvent("@rf:example.com", "pizza", 12),
|
||||
responseEvent("@th:example.com", "wings", 13),
|
||||
responseEvent("@yh:example.com", "wings", 14),
|
||||
responseEvent("@th:example.com", "poutine", 13),
|
||||
responseEvent("@yh:example.com", "poutine", 14),
|
||||
];
|
||||
const ends = [endEvent("@me:example.com", 25)];
|
||||
const body = newMPollBody(votes, ends, null, false);
|
||||
expect(body.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
function newVoteRelations(relationEvents: Array<MatrixEvent>): Relations {
|
||||
|
@ -1018,12 +1101,13 @@ function newMPollBody(
|
|||
relationEvents: Array<MatrixEvent>,
|
||||
endEvents: Array<MatrixEvent> = [],
|
||||
answers?: POLL_ANSWER[],
|
||||
disclosed = true,
|
||||
): ReactWrapper {
|
||||
const mxEvent = new MatrixEvent({
|
||||
"type": M_POLL_START.name,
|
||||
"event_id": "$mypoll",
|
||||
"room_id": "#myroom:example.com",
|
||||
"content": newPollStart(answers),
|
||||
"content": newPollStart(answers, null, disclosed),
|
||||
});
|
||||
return newMPollBodyFromEvent(mxEvent, relationEvents, endEvents);
|
||||
}
|
||||
|
@ -1096,6 +1180,7 @@ function endedVotesCount(wrapper: ReactWrapper, value: string): string {
|
|||
function newPollStart(
|
||||
answers?: POLL_ANSWER[],
|
||||
question?: string,
|
||||
disclosed = true,
|
||||
): M_POLL_START_EVENT_CONTENT {
|
||||
if (!answers) {
|
||||
answers = [
|
||||
|
@ -1121,7 +1206,11 @@ function newPollStart(
|
|||
"question": {
|
||||
[M_TEXT.name]: question,
|
||||
},
|
||||
"kind": M_POLL_KIND_DISCLOSED.name,
|
||||
"kind": (
|
||||
disclosed
|
||||
? M_POLL_KIND_DISCLOSED.name
|
||||
: M_POLL_KIND_UNDISCLOSED.name
|
||||
),
|
||||
"answers": answers,
|
||||
},
|
||||
[M_TEXT.name]: fallback,
|
||||
|
|
|
@ -2872,3 +2872,7 @@ exports[`MPollBody renders a poll with only non-local votes 1`] = `
|
|||
</MPollBody>
|
||||
</Wrapper>
|
||||
`;
|
||||
|
||||
exports[`MPollBody renders an undisclosed, finished poll 1`] = `"<div class=\\"mx_MPollBody\\"><h2>What should we order for the party?</h2><div class=\\"mx_MPollBody_allOptions\\"><div class=\\"mx_MPollBody_option mx_MPollBody_option_checked mx_MPollBody_option_ended\\"><div class=\\"mx_MPollBody_endedOption mx_MPollBody_endedOptionWinner\\" data-value=\\"pizza\\"><div class=\\"mx_MPollBody_optionDescription\\"><div class=\\"mx_MPollBody_optionText\\">Pizza</div><div class=\\"mx_MPollBody_optionVoteCount\\">2 votes</div></div></div><div class=\\"mx_MPollBody_popularityBackground\\"><div class=\\"mx_MPollBody_popularityAmount\\" style=\\"width: 50%;\\"></div></div></div><div class=\\"mx_MPollBody_option mx_MPollBody_option_ended\\"><div class=\\"mx_MPollBody_endedOption\\" data-value=\\"poutine\\"><div class=\\"mx_MPollBody_optionDescription\\"><div class=\\"mx_MPollBody_optionText\\">Poutine</div><div class=\\"mx_MPollBody_optionVoteCount\\">0 votes</div></div></div><div class=\\"mx_MPollBody_popularityBackground\\"><div class=\\"mx_MPollBody_popularityAmount\\" style=\\"width: 0%;\\"></div></div></div><div class=\\"mx_MPollBody_option mx_MPollBody_option_ended\\"><div class=\\"mx_MPollBody_endedOption\\" data-value=\\"italian\\"><div class=\\"mx_MPollBody_optionDescription\\"><div class=\\"mx_MPollBody_optionText\\">Italian</div><div class=\\"mx_MPollBody_optionVoteCount\\">0 votes</div></div></div><div class=\\"mx_MPollBody_popularityBackground\\"><div class=\\"mx_MPollBody_popularityAmount\\" style=\\"width: 0%;\\"></div></div></div><div class=\\"mx_MPollBody_option mx_MPollBody_option_checked mx_MPollBody_option_ended\\"><div class=\\"mx_MPollBody_endedOption mx_MPollBody_endedOptionWinner\\" data-value=\\"wings\\"><div class=\\"mx_MPollBody_optionDescription\\"><div class=\\"mx_MPollBody_optionText\\">Wings</div><div class=\\"mx_MPollBody_optionVoteCount\\">2 votes</div></div></div><div class=\\"mx_MPollBody_popularityBackground\\"><div class=\\"mx_MPollBody_popularityAmount\\" style=\\"width: 50%;\\"></div></div></div></div><div class=\\"mx_MPollBody_totalVotes\\">Final result based on 4 votes</div></div>"`;
|
||||
|
||||
exports[`MPollBody renders an undisclosed, unfinished poll 1`] = `"<div class=\\"mx_MPollBody\\"><h2>What should we order for the party?</h2><div class=\\"mx_MPollBody_allOptions\\"><div class=\\"mx_MPollBody_option\\"><label class=\\"mx_StyledRadioButton mx_MPollBody_live-option mx_StyledRadioButton_enabled\\"><input type=\\"radio\\" name=\\"poll_answer_select-$mypoll\\" value=\\"pizza\\"><div><div></div></div><div class=\\"mx_StyledRadioButton_content\\"><div class=\\"mx_MPollBody_optionDescription\\"><div class=\\"mx_MPollBody_optionText\\">Pizza</div><div class=\\"mx_MPollBody_optionVoteCount\\"></div></div></div><div class=\\"mx_StyledRadioButton_spacer\\"></div></label><div class=\\"mx_MPollBody_popularityBackground\\"><div class=\\"mx_MPollBody_popularityAmount\\" style=\\"width: 0%;\\"></div></div></div><div class=\\"mx_MPollBody_option\\"><label class=\\"mx_StyledRadioButton mx_MPollBody_live-option mx_StyledRadioButton_enabled\\"><input type=\\"radio\\" name=\\"poll_answer_select-$mypoll\\" value=\\"poutine\\"><div><div></div></div><div class=\\"mx_StyledRadioButton_content\\"><div class=\\"mx_MPollBody_optionDescription\\"><div class=\\"mx_MPollBody_optionText\\">Poutine</div><div class=\\"mx_MPollBody_optionVoteCount\\"></div></div></div><div class=\\"mx_StyledRadioButton_spacer\\"></div></label><div class=\\"mx_MPollBody_popularityBackground\\"><div class=\\"mx_MPollBody_popularityAmount\\" style=\\"width: 0%;\\"></div></div></div><div class=\\"mx_MPollBody_option\\"><label class=\\"mx_StyledRadioButton mx_MPollBody_live-option mx_StyledRadioButton_enabled\\"><input type=\\"radio\\" name=\\"poll_answer_select-$mypoll\\" value=\\"italian\\"><div><div></div></div><div class=\\"mx_StyledRadioButton_content\\"><div class=\\"mx_MPollBody_optionDescription\\"><div class=\\"mx_MPollBody_optionText\\">Italian</div><div class=\\"mx_MPollBody_optionVoteCount\\"></div></div></div><div class=\\"mx_StyledRadioButton_spacer\\"></div></label><div class=\\"mx_MPollBody_popularityBackground\\"><div class=\\"mx_MPollBody_popularityAmount\\" style=\\"width: 0%;\\"></div></div></div><div class=\\"mx_MPollBody_option\\"><label class=\\"mx_StyledRadioButton mx_MPollBody_live-option mx_StyledRadioButton_enabled\\"><input type=\\"radio\\" name=\\"poll_answer_select-$mypoll\\" value=\\"wings\\"><div><div></div></div><div class=\\"mx_StyledRadioButton_content\\"><div class=\\"mx_MPollBody_optionDescription\\"><div class=\\"mx_MPollBody_optionText\\">Wings</div><div class=\\"mx_MPollBody_optionVoteCount\\"></div></div></div><div class=\\"mx_StyledRadioButton_spacer\\"></div></label><div class=\\"mx_MPollBody_popularityBackground\\"><div class=\\"mx_MPollBody_popularityAmount\\" style=\\"width: 0%;\\"></div></div></div></div><div class=\\"mx_MPollBody_totalVotes\\">Results will be visible when the poll is ended</div></div>"`;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue