mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-15 20:54:59 +08:00
convert MPollBody tests into rtl (#9906)
* convert MPollBody tests into rtl * strict fixes * more strict * more semantic assertions * update types for extensible events changes
This commit is contained in:
parent
0758b8cdfe
commit
33e8a62dae
@ -448,7 +448,7 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_MPollBody">
|
<div className="mx_MPollBody">
|
||||||
<h2>
|
<h2 data-testid="pollQuestion">
|
||||||
{poll.question.text}
|
{poll.question.text}
|
||||||
{editedSpan}
|
{editedSpan}
|
||||||
</h2>
|
</h2>
|
||||||
@ -471,7 +471,12 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
|||||||
|
|
||||||
const answerPercent = totalVotes === 0 ? 0 : Math.round((100.0 * answerVotes) / totalVotes);
|
const answerPercent = totalVotes === 0 ? 0 : Math.round((100.0 * answerVotes) / totalVotes);
|
||||||
return (
|
return (
|
||||||
<div key={answer.id} className={cls} onClick={() => this.selectOption(answer.id)}>
|
<div
|
||||||
|
data-testid={`pollOption-${answer.id}`}
|
||||||
|
key={answer.id}
|
||||||
|
className={cls}
|
||||||
|
onClick={() => this.selectOption(answer.id)}
|
||||||
|
>
|
||||||
{ended ? (
|
{ended ? (
|
||||||
<EndedPollOption answer={answer} checked={checked} votesText={votesText} />
|
<EndedPollOption answer={answer} checked={checked} votesText={votesText} />
|
||||||
) : (
|
) : (
|
||||||
@ -493,7 +498,9 @@ export default class MPollBody extends React.Component<IBodyProps, IState> {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_MPollBody_totalVotes">{totalText}</div>
|
<div data-testid="totalVotes" className="mx_MPollBody_totalVotes">
|
||||||
|
{totalText}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
// eslint-disable-next-line deprecate/import
|
import { fireEvent, render, RenderResult } from "@testing-library/react";
|
||||||
import { mount, ReactWrapper } from "enzyme";
|
|
||||||
import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||||
import { Relations } from "matrix-js-sdk/src/models/relations";
|
import { Relations } from "matrix-js-sdk/src/models/relations";
|
||||||
import { RelatedRelations } from "matrix-js-sdk/src/models/related-relations";
|
import { RelatedRelations } from "matrix-js-sdk/src/models/related-relations";
|
||||||
@ -44,6 +43,8 @@ import { IBodyProps } from "../../../../src/components/views/messages/IBodyProps
|
|||||||
import { getMockClientWithEventEmitter } from "../../../test-utils";
|
import { getMockClientWithEventEmitter } from "../../../test-utils";
|
||||||
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||||
import MPollBody from "../../../../src/components/views/messages/MPollBody";
|
import MPollBody from "../../../../src/components/views/messages/MPollBody";
|
||||||
|
import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks";
|
||||||
|
import { MediaEventHelper } from "../../../../src/utils/MediaEventHelper";
|
||||||
|
|
||||||
const CHECKED = "mx_MPollBody_option_checked";
|
const CHECKED = "mx_MPollBody_option_checked";
|
||||||
|
|
||||||
@ -85,13 +86,13 @@ describe("MPollBody", () => {
|
|||||||
new RelatedRelations([newEndRelations([])]),
|
new RelatedRelations([newEndRelations([])]),
|
||||||
),
|
),
|
||||||
).toEqual([
|
).toEqual([
|
||||||
new UserVote(ev1.getTs(), ev1.getSender(), ev1.getContent()[M_POLL_RESPONSE.name].answers),
|
new UserVote(ev1.getTs(), ev1.getSender()!, ev1.getContent()[M_POLL_RESPONSE.name].answers),
|
||||||
new UserVote(
|
new UserVote(
|
||||||
badEvent.getTs(),
|
badEvent.getTs(),
|
||||||
badEvent.getSender(),
|
badEvent.getSender()!,
|
||||||
[], // should be spoiled
|
[], // should be spoiled
|
||||||
),
|
),
|
||||||
new UserVote(ev2.getTs(), ev2.getSender(), ev2.getContent()[M_POLL_RESPONSE.name].answers),
|
new UserVote(ev2.getTs(), ev2.getSender()!, ev2.getContent()[M_POLL_RESPONSE.name].answers),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -146,14 +147,14 @@ describe("MPollBody", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("renders no votes if none were made", () => {
|
it("renders no votes if none were made", () => {
|
||||||
const votes = [];
|
const votes: MatrixEvent[] = [];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(votesCount(body, "pizza")).toBe("");
|
expect(votesCount(renderResult, "pizza")).toBe("");
|
||||||
expect(votesCount(body, "poutine")).toBe("");
|
expect(votesCount(renderResult, "poutine")).toBe("");
|
||||||
expect(votesCount(body, "italian")).toBe("");
|
expect(votesCount(renderResult, "italian")).toBe("");
|
||||||
expect(votesCount(body, "wings")).toBe("");
|
expect(votesCount(renderResult, "wings")).toBe("");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("No votes cast");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("No votes cast");
|
||||||
expect(body.find("h2").html()).toEqual("<h2>What should we order for the party?</h2>");
|
expect(renderResult.getByText("What should we order for the party?")).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("finds votes from multiple people", () => {
|
it("finds votes from multiple people", () => {
|
||||||
@ -163,12 +164,12 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@catrd:example.com", "poutine"),
|
responseEvent("@catrd:example.com", "poutine"),
|
||||||
responseEvent("@dune2:example.com", "wings"),
|
responseEvent("@dune2:example.com", "wings"),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(votesCount(body, "pizza")).toBe("2 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("2 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("1 vote");
|
expect(votesCount(renderResult, "poutine")).toBe("1 vote");
|
||||||
expect(votesCount(body, "italian")).toBe("0 votes");
|
expect(votesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(votesCount(body, "wings")).toBe("1 vote");
|
expect(votesCount(renderResult, "wings")).toBe("1 vote");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 4 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 4 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("ignores end poll events from unauthorised users", () => {
|
it("ignores end poll events from unauthorised users", () => {
|
||||||
@ -179,15 +180,15 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@dune2:example.com", "wings"),
|
responseEvent("@dune2:example.com", "wings"),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@notallowed:example.com", 12)];
|
const ends = [endEvent("@notallowed:example.com", 12)];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
|
|
||||||
// Even though an end event was sent, we render the poll as unfinished
|
// Even though an end event was sent, we render the poll as unfinished
|
||||||
// because this person is not allowed to send these events
|
// because this person is not allowed to send these events
|
||||||
expect(votesCount(body, "pizza")).toBe("2 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("2 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("1 vote");
|
expect(votesCount(renderResult, "poutine")).toBe("1 vote");
|
||||||
expect(votesCount(body, "italian")).toBe("0 votes");
|
expect(votesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(votesCount(body, "wings")).toBe("1 vote");
|
expect(votesCount(renderResult, "wings")).toBe("1 vote");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 4 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 4 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("hides scores if I have not voted", () => {
|
it("hides scores if I have not voted", () => {
|
||||||
@ -197,22 +198,22 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@catrd:example.com", "poutine"),
|
responseEvent("@catrd:example.com", "poutine"),
|
||||||
responseEvent("@dune2:example.com", "wings"),
|
responseEvent("@dune2:example.com", "wings"),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(votesCount(body, "pizza")).toBe("");
|
expect(votesCount(renderResult, "pizza")).toBe("");
|
||||||
expect(votesCount(body, "poutine")).toBe("");
|
expect(votesCount(renderResult, "poutine")).toBe("");
|
||||||
expect(votesCount(body, "italian")).toBe("");
|
expect(votesCount(renderResult, "italian")).toBe("");
|
||||||
expect(votesCount(body, "wings")).toBe("");
|
expect(votesCount(renderResult, "wings")).toBe("");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("4 votes cast. Vote to see the results");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("4 votes cast. Vote to see the results");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("hides a single vote if I have not voted", () => {
|
it("hides a single vote if I have not voted", () => {
|
||||||
const votes = [responseEvent("@alice:example.com", "pizza")];
|
const votes = [responseEvent("@alice:example.com", "pizza")];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(votesCount(body, "pizza")).toBe("");
|
expect(votesCount(renderResult, "pizza")).toBe("");
|
||||||
expect(votesCount(body, "poutine")).toBe("");
|
expect(votesCount(renderResult, "poutine")).toBe("");
|
||||||
expect(votesCount(body, "italian")).toBe("");
|
expect(votesCount(renderResult, "italian")).toBe("");
|
||||||
expect(votesCount(body, "wings")).toBe("");
|
expect(votesCount(renderResult, "wings")).toBe("");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("1 vote cast. Vote to see the results");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("1 vote cast. Vote to see the results");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("takes someone's most recent vote if they voted several times", () => {
|
it("takes someone's most recent vote if they voted several times", () => {
|
||||||
@ -223,12 +224,12 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@qbert:example.com", "poutine", 16), // latest qbert
|
responseEvent("@qbert:example.com", "poutine", 16), // latest qbert
|
||||||
responseEvent("@qbert:example.com", "wings", 15),
|
responseEvent("@qbert:example.com", "wings", 15),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(votesCount(body, "pizza")).toBe("0 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("0 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("1 vote");
|
expect(votesCount(renderResult, "poutine")).toBe("1 vote");
|
||||||
expect(votesCount(body, "italian")).toBe("0 votes");
|
expect(votesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(votesCount(body, "wings")).toBe("1 vote");
|
expect(votesCount(renderResult, "wings")).toBe("1 vote");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 2 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 2 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("uses my local vote", () => {
|
it("uses my local vote", () => {
|
||||||
@ -238,18 +239,18 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@fg:example.com", "pizza", 15),
|
responseEvent("@fg:example.com", "pizza", 15),
|
||||||
responseEvent("@hi:example.com", "pizza", 15),
|
responseEvent("@hi:example.com", "pizza", 15),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
|
|
||||||
// When I vote for Italian
|
// When I vote for Italian
|
||||||
clickRadio(body, "italian");
|
clickOption(renderResult, "italian");
|
||||||
|
|
||||||
// My vote is counted
|
// My vote is counted
|
||||||
expect(votesCount(body, "pizza")).toBe("3 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("3 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("0 votes");
|
expect(votesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(votesCount(body, "italian")).toBe("1 vote");
|
expect(votesCount(renderResult, "italian")).toBe("1 vote");
|
||||||
expect(votesCount(body, "wings")).toBe("0 votes");
|
expect(votesCount(renderResult, "wings")).toBe("0 votes");
|
||||||
|
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 4 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 4 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("overrides my other votes with my local vote", () => {
|
it("overrides my other votes with my local vote", () => {
|
||||||
@ -260,53 +261,66 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@me:example.com", "italian", 14),
|
responseEvent("@me:example.com", "italian", 14),
|
||||||
responseEvent("@nf:example.com", "italian", 15),
|
responseEvent("@nf:example.com", "italian", 15),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
|
|
||||||
// When I click Wings
|
// When I click Wings
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
|
|
||||||
// Then my vote is counted for Wings, and not for Italian
|
// Then my vote is counted for Wings, and not for Italian
|
||||||
expect(votesCount(body, "pizza")).toBe("0 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("0 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("0 votes");
|
expect(votesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(votesCount(body, "italian")).toBe("1 vote");
|
expect(votesCount(renderResult, "italian")).toBe("1 vote");
|
||||||
expect(votesCount(body, "wings")).toBe("1 vote");
|
expect(votesCount(renderResult, "wings")).toBe("1 vote");
|
||||||
|
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 2 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 2 votes");
|
||||||
|
|
||||||
// And my vote is highlighted
|
// And my vote is highlighted
|
||||||
expect(voteButton(body, "wings").hasClass(CHECKED)).toBe(true);
|
expect(voteButton(renderResult, "wings").className.includes(CHECKED)).toBe(true);
|
||||||
expect(voteButton(body, "italian").hasClass(CHECKED)).toBe(false);
|
expect(voteButton(renderResult, "italian").className.includes(CHECKED)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("cancels my local vote if another comes in", () => {
|
it("cancels my local vote if another comes in", () => {
|
||||||
// Given I voted locally
|
// Given I voted locally
|
||||||
const votes = [responseEvent("@me:example.com", "pizza", 100)];
|
const votes = [responseEvent("@me:example.com", "pizza", 100)];
|
||||||
const body = newMPollBody(votes);
|
const mxEvent = new MatrixEvent({
|
||||||
const props: IBodyProps = body.instance().props as IBodyProps;
|
type: M_POLL_START.name,
|
||||||
|
event_id: "$mypoll",
|
||||||
|
room_id: "#myroom:example.com",
|
||||||
|
content: newPollStart(undefined, undefined, true),
|
||||||
|
});
|
||||||
|
const props = getMPollBodyPropsFromEvent(mxEvent, votes);
|
||||||
|
const renderResult = renderMPollBodyWithWrapper(props);
|
||||||
const voteRelations = props!.getRelationsForEvent!("$mypoll", "m.reference", M_POLL_RESPONSE.name);
|
const voteRelations = props!.getRelationsForEvent!("$mypoll", "m.reference", M_POLL_RESPONSE.name);
|
||||||
expect(voteRelations).toBeDefined();
|
expect(voteRelations).toBeDefined();
|
||||||
clickRadio(body, "pizza");
|
clickOption(renderResult, "pizza");
|
||||||
|
|
||||||
// When a new vote from me comes in
|
// When a new vote from me comes in
|
||||||
voteRelations!.addEvent(responseEvent("@me:example.com", "wings", 101));
|
voteRelations!.addEvent(responseEvent("@me:example.com", "wings", 101));
|
||||||
|
|
||||||
// Then the new vote is counted, not the old one
|
// Then the new vote is counted, not the old one
|
||||||
expect(votesCount(body, "pizza")).toBe("0 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("0 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("0 votes");
|
expect(votesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(votesCount(body, "italian")).toBe("0 votes");
|
expect(votesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(votesCount(body, "wings")).toBe("1 vote");
|
expect(votesCount(renderResult, "wings")).toBe("1 vote");
|
||||||
|
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 1 vote");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 1 vote");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("doesn't cancel my local vote if someone else votes", () => {
|
it("doesn't cancel my local vote if someone else votes", () => {
|
||||||
// Given I voted locally
|
// Given I voted locally
|
||||||
const votes = [responseEvent("@me:example.com", "pizza")];
|
const votes = [responseEvent("@me:example.com", "pizza")];
|
||||||
const body = newMPollBody(votes);
|
const mxEvent = new MatrixEvent({
|
||||||
const props: IBodyProps = body.instance().props as IBodyProps;
|
type: M_POLL_START.name,
|
||||||
|
event_id: "$mypoll",
|
||||||
|
room_id: "#myroom:example.com",
|
||||||
|
content: newPollStart(undefined, undefined, true),
|
||||||
|
});
|
||||||
|
const props = getMPollBodyPropsFromEvent(mxEvent, votes);
|
||||||
|
const renderResult = renderMPollBodyWithWrapper(props);
|
||||||
|
|
||||||
const voteRelations = props!.getRelationsForEvent!("$mypoll", "m.reference", M_POLL_RESPONSE.name);
|
const voteRelations = props!.getRelationsForEvent!("$mypoll", "m.reference", M_POLL_RESPONSE.name);
|
||||||
expect(voteRelations).toBeDefined();
|
expect(voteRelations).toBeDefined();
|
||||||
clickRadio(body, "pizza");
|
clickOption(renderResult, "pizza");
|
||||||
|
|
||||||
// When a new vote from someone else comes in
|
// When a new vote from someone else comes in
|
||||||
voteRelations!.addEvent(responseEvent("@xx:example.com", "wings", 101));
|
voteRelations!.addEvent(responseEvent("@xx:example.com", "wings", 101));
|
||||||
@ -315,39 +329,39 @@ describe("MPollBody", () => {
|
|||||||
// NOTE: the new event does not affect the counts for other people -
|
// NOTE: the new event does not affect the counts for other people -
|
||||||
// that is handled through the Relations, not by listening to
|
// that is handled through the Relations, not by listening to
|
||||||
// these timeline events.
|
// these timeline events.
|
||||||
expect(votesCount(body, "pizza")).toBe("1 vote");
|
expect(votesCount(renderResult, "pizza")).toBe("1 vote");
|
||||||
expect(votesCount(body, "poutine")).toBe("0 votes");
|
expect(votesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(votesCount(body, "italian")).toBe("0 votes");
|
expect(votesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(votesCount(body, "wings")).toBe("1 vote");
|
expect(votesCount(renderResult, "wings")).toBe("1 vote");
|
||||||
|
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 2 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 2 votes");
|
||||||
|
|
||||||
// And my vote is highlighted
|
// And my vote is highlighted
|
||||||
expect(voteButton(body, "pizza").hasClass(CHECKED)).toBe(true);
|
expect(voteButton(renderResult, "pizza").className.includes(CHECKED)).toBe(true);
|
||||||
expect(voteButton(body, "wings").hasClass(CHECKED)).toBe(false);
|
expect(voteButton(renderResult, "wings").className.includes(CHECKED)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("highlights my vote even if I did it on another device", () => {
|
it("highlights my vote even if I did it on another device", () => {
|
||||||
// Given I voted italian
|
// Given I voted italian
|
||||||
const votes = [responseEvent("@me:example.com", "italian"), responseEvent("@nf:example.com", "wings")];
|
const votes = [responseEvent("@me:example.com", "italian"), responseEvent("@nf:example.com", "wings")];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
|
|
||||||
// But I didn't click anything locally
|
// But I didn't click anything locally
|
||||||
|
|
||||||
// Then my vote is highlighted, and others are not
|
// Then my vote is highlighted, and others are not
|
||||||
expect(voteButton(body, "italian").hasClass(CHECKED)).toBe(true);
|
expect(voteButton(renderResult, "italian").className.includes(CHECKED)).toBe(true);
|
||||||
expect(voteButton(body, "wings").hasClass(CHECKED)).toBe(false);
|
expect(voteButton(renderResult, "wings").className.includes(CHECKED)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("ignores extra answers", () => {
|
it("ignores extra answers", () => {
|
||||||
// When cb votes for 2 things, we consider the first only
|
// When cb votes for 2 things, we consider the first only
|
||||||
const votes = [responseEvent("@cb:example.com", ["pizza", "wings"]), responseEvent("@me:example.com", "wings")];
|
const votes = [responseEvent("@cb:example.com", ["pizza", "wings"]), responseEvent("@me:example.com", "wings")];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(votesCount(body, "pizza")).toBe("1 vote");
|
expect(votesCount(renderResult, "pizza")).toBe("1 vote");
|
||||||
expect(votesCount(body, "poutine")).toBe("0 votes");
|
expect(votesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(votesCount(body, "italian")).toBe("0 votes");
|
expect(votesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(votesCount(body, "wings")).toBe("1 vote");
|
expect(votesCount(renderResult, "wings")).toBe("1 vote");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 2 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 2 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("allows un-voting by passing an empty vote", () => {
|
it("allows un-voting by passing an empty vote", () => {
|
||||||
@ -356,12 +370,12 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@nc:example.com", [], 13),
|
responseEvent("@nc:example.com", [], 13),
|
||||||
responseEvent("@me:example.com", "italian"),
|
responseEvent("@me:example.com", "italian"),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(votesCount(body, "pizza")).toBe("0 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("0 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("0 votes");
|
expect(votesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(votesCount(body, "italian")).toBe("1 vote");
|
expect(votesCount(renderResult, "italian")).toBe("1 vote");
|
||||||
expect(votesCount(body, "wings")).toBe("0 votes");
|
expect(votesCount(renderResult, "wings")).toBe("0 votes");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 1 vote");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 1 vote");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("allows re-voting after un-voting", () => {
|
it("allows re-voting after un-voting", () => {
|
||||||
@ -371,12 +385,12 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@op:example.com", "italian", 14),
|
responseEvent("@op:example.com", "italian", 14),
|
||||||
responseEvent("@me:example.com", "italian"),
|
responseEvent("@me:example.com", "italian"),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(votesCount(body, "pizza")).toBe("0 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("0 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("0 votes");
|
expect(votesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(votesCount(body, "italian")).toBe("2 votes");
|
expect(votesCount(renderResult, "italian")).toBe("2 votes");
|
||||||
expect(votesCount(body, "wings")).toBe("0 votes");
|
expect(votesCount(renderResult, "wings")).toBe("0 votes");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 2 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 2 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("treats any invalid answer as a spoiled ballot", () => {
|
it("treats any invalid answer as a spoiled ballot", () => {
|
||||||
@ -389,12 +403,12 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@uy:example.com", "italian", 14),
|
responseEvent("@uy:example.com", "italian", 14),
|
||||||
responseEvent("@uy:example.com", "doesntexist", 15),
|
responseEvent("@uy:example.com", "doesntexist", 15),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(votesCount(body, "pizza")).toBe("0 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("0 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("0 votes");
|
expect(votesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(votesCount(body, "italian")).toBe("0 votes");
|
expect(votesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(votesCount(body, "wings")).toBe("0 votes");
|
expect(votesCount(renderResult, "wings")).toBe("0 votes");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 0 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 0 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("allows re-voting after a spoiled ballot", () => {
|
it("allows re-voting after a spoiled ballot", () => {
|
||||||
@ -405,31 +419,31 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@uy:example.com", "doesntexist", 15),
|
responseEvent("@uy:example.com", "doesntexist", 15),
|
||||||
responseEvent("@uy:example.com", "poutine", 16),
|
responseEvent("@uy:example.com", "poutine", 16),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
expect(body.find('input[type="radio"]')).toHaveLength(4);
|
expect(renderResult.container.querySelectorAll('input[type="radio"]')).toHaveLength(4);
|
||||||
expect(votesCount(body, "pizza")).toBe("0 votes");
|
expect(votesCount(renderResult, "pizza")).toBe("0 votes");
|
||||||
expect(votesCount(body, "poutine")).toBe("1 vote");
|
expect(votesCount(renderResult, "poutine")).toBe("1 vote");
|
||||||
expect(votesCount(body, "italian")).toBe("0 votes");
|
expect(votesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(votesCount(body, "wings")).toBe("0 votes");
|
expect(votesCount(renderResult, "wings")).toBe("0 votes");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 1 vote");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Based on 1 vote");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders nothing if poll has no answers", () => {
|
it("renders nothing if poll has no answers", () => {
|
||||||
const answers = [];
|
const answers: PollAnswer[] = [];
|
||||||
const votes = [];
|
const votes: MatrixEvent[] = [];
|
||||||
const ends = [];
|
const ends: MatrixEvent[] = [];
|
||||||
const body = newMPollBody(votes, ends, answers);
|
const { container } = newMPollBody(votes, ends, answers);
|
||||||
expect(body.html()).toBeNull();
|
expect(container.childElementCount).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders the first 20 answers if 21 were given", () => {
|
it("renders the first 20 answers if 21 were given", () => {
|
||||||
const answers = Array.from(Array(21).keys()).map((i) => {
|
const answers = Array.from(Array(21).keys()).map((i) => {
|
||||||
return { id: `id${i}`, [M_TEXT.name]: `Name ${i}` };
|
return { id: `id${i}`, [M_TEXT.name]: `Name ${i}` };
|
||||||
});
|
});
|
||||||
const votes = [];
|
const votes: MatrixEvent[] = [];
|
||||||
const ends = [];
|
const ends: MatrixEvent[] = [];
|
||||||
const body = newMPollBody(votes, ends, answers);
|
const { container } = newMPollBody(votes, ends, answers);
|
||||||
expect(body.find(".mx_MPollBody_option").length).toBe(20);
|
expect(container.querySelectorAll(".mx_MPollBody_option").length).toBe(20);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("hides scores if I voted but the poll is undisclosed", () => {
|
it("hides scores if I voted but the poll is undisclosed", () => {
|
||||||
@ -440,12 +454,12 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@catrd:example.com", "poutine"),
|
responseEvent("@catrd:example.com", "poutine"),
|
||||||
responseEvent("@dune2:example.com", "wings"),
|
responseEvent("@dune2:example.com", "wings"),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes, [], undefined, false);
|
const renderResult = newMPollBody(votes, [], undefined, false);
|
||||||
expect(votesCount(body, "pizza")).toBe("");
|
expect(votesCount(renderResult, "pizza")).toBe("");
|
||||||
expect(votesCount(body, "poutine")).toBe("");
|
expect(votesCount(renderResult, "poutine")).toBe("");
|
||||||
expect(votesCount(body, "italian")).toBe("");
|
expect(votesCount(renderResult, "italian")).toBe("");
|
||||||
expect(votesCount(body, "wings")).toBe("");
|
expect(votesCount(renderResult, "wings")).toBe("");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Results will be visible when the poll is ended");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Results will be visible when the poll is ended");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("highlights my vote if the poll is undisclosed", () => {
|
it("highlights my vote if the poll is undisclosed", () => {
|
||||||
@ -456,13 +470,13 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@catrd:example.com", "poutine"),
|
responseEvent("@catrd:example.com", "poutine"),
|
||||||
responseEvent("@dune2:example.com", "wings"),
|
responseEvent("@dune2:example.com", "wings"),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes, [], undefined, false);
|
const { container } = newMPollBody(votes, [], undefined, false);
|
||||||
|
|
||||||
// My vote is marked
|
// My vote is marked
|
||||||
expect(body.find('input[value="pizza"]').prop("checked")).toBeTruthy();
|
expect(container.querySelector('input[value="pizza"]')!).toBeChecked();
|
||||||
|
|
||||||
// Sanity: other items are not checked
|
// Sanity: other items are not checked
|
||||||
expect(body.find('input[value="poutine"]').prop("checked")).toBeFalsy();
|
expect(container.querySelector('input[value="poutine"]')!).not.toBeChecked();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("shows scores if the poll is undisclosed but ended", () => {
|
it("shows scores if the poll is undisclosed but ended", () => {
|
||||||
@ -474,47 +488,47 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@dune2:example.com", "wings"),
|
responseEvent("@dune2:example.com", "wings"),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@me:example.com", 12)];
|
const ends = [endEvent("@me:example.com", 12)];
|
||||||
const body = newMPollBody(votes, ends, undefined, false);
|
const renderResult = newMPollBody(votes, ends, undefined, false);
|
||||||
expect(endedVotesCount(body, "pizza")).toBe("3 votes");
|
expect(endedVotesCount(renderResult, "pizza")).toBe("3 votes");
|
||||||
expect(endedVotesCount(body, "poutine")).toBe("1 vote");
|
expect(endedVotesCount(renderResult, "poutine")).toBe("1 vote");
|
||||||
expect(endedVotesCount(body, "italian")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "wings")).toBe("1 vote");
|
expect(endedVotesCount(renderResult, "wings")).toBe("1 vote");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Final result based on 5 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends a vote event when I choose an option", () => {
|
it("sends a vote event when I choose an option", () => {
|
||||||
const votes = [];
|
const votes: MatrixEvent[] = [];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledWith(...expectedResponseEventCall("wings"));
|
expect(mockClient.sendEvent).toHaveBeenCalledWith(...expectedResponseEventCall("wings"));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends only one vote event when I click several times", () => {
|
it("sends only one vote event when I click several times", () => {
|
||||||
const votes = [];
|
const votes: MatrixEvent[] = [];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledWith(...expectedResponseEventCall("wings"));
|
expect(mockClient.sendEvent).toHaveBeenCalledWith(...expectedResponseEventCall("wings"));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends no vote event when I click what I already chose", () => {
|
it("sends no vote event when I click what I already chose", () => {
|
||||||
const votes = [responseEvent("@me:example.com", "wings")];
|
const votes = [responseEvent("@me:example.com", "wings")];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
expect(mockClient.sendEvent).not.toHaveBeenCalled();
|
expect(mockClient.sendEvent).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends several events when I click different options", () => {
|
it("sends several events when I click different options", () => {
|
||||||
const votes = [];
|
const votes: MatrixEvent[] = [];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
clickRadio(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
clickRadio(body, "italian");
|
clickOption(renderResult, "italian");
|
||||||
clickRadio(body, "poutine");
|
clickOption(renderResult, "poutine");
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledTimes(3);
|
expect(mockClient.sendEvent).toHaveBeenCalledTimes(3);
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledWith(...expectedResponseEventCall("wings"));
|
expect(mockClient.sendEvent).toHaveBeenCalledWith(...expectedResponseEventCall("wings"));
|
||||||
expect(mockClient.sendEvent).toHaveBeenCalledWith(...expectedResponseEventCall("italian"));
|
expect(mockClient.sendEvent).toHaveBeenCalledWith(...expectedResponseEventCall("italian"));
|
||||||
@ -524,10 +538,10 @@ describe("MPollBody", () => {
|
|||||||
it("sends no events when I click in an ended poll", () => {
|
it("sends no events when I click in an ended poll", () => {
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const votes = [responseEvent("@uy:example.com", "wings", 15), responseEvent("@uy:example.com", "poutine", 15)];
|
const votes = [responseEvent("@uy:example.com", "wings", 15), responseEvent("@uy:example.com", "poutine", 15)];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
clickEndedOption(body, "wings");
|
clickOption(renderResult, "wings");
|
||||||
clickEndedOption(body, "italian");
|
clickOption(renderResult, "italian");
|
||||||
clickEndedOption(body, "poutine");
|
clickOption(renderResult, "poutine");
|
||||||
expect(mockClient.sendEvent).not.toHaveBeenCalled();
|
expect(mockClient.sendEvent).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -577,9 +591,9 @@ describe("MPollBody", () => {
|
|||||||
|
|
||||||
it("shows non-radio buttons if the poll is ended", () => {
|
it("shows non-radio buttons if the poll is ended", () => {
|
||||||
const events = [endEvent()];
|
const events = [endEvent()];
|
||||||
const body = newMPollBody([], events);
|
const { container } = newMPollBody([], events);
|
||||||
expect(body.find(".mx_StyledRadioButton")).toHaveLength(0);
|
expect(container.querySelector(".mx_StyledRadioButton")).not.toBeInTheDocument();
|
||||||
expect(body.find('input[type="radio"]')).toHaveLength(0);
|
expect(container.querySelector('input[type="radio"]')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("counts votes as normal if the poll is ended", () => {
|
it("counts votes as normal if the poll is ended", () => {
|
||||||
@ -591,23 +605,23 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@qbert:example.com", "wings", 15),
|
responseEvent("@qbert:example.com", "wings", 15),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
expect(endedVotesCount(body, "pizza")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "pizza")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "poutine")).toBe("1 vote");
|
expect(endedVotesCount(renderResult, "poutine")).toBe("1 vote");
|
||||||
expect(endedVotesCount(body, "italian")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "wings")).toBe("1 vote");
|
expect(endedVotesCount(renderResult, "wings")).toBe("1 vote");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Final result based on 2 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 2 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("counts a single vote as normal if the poll is ended", () => {
|
it("counts a single vote as normal if the poll is ended", () => {
|
||||||
const votes = [responseEvent("@qbert:example.com", "poutine", 16)];
|
const votes = [responseEvent("@qbert:example.com", "poutine", 16)];
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
expect(endedVotesCount(body, "pizza")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "pizza")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "poutine")).toBe("1 vote");
|
expect(endedVotesCount(renderResult, "poutine")).toBe("1 vote");
|
||||||
expect(endedVotesCount(body, "italian")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "wings")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "wings")).toBe("0 votes");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Final result based on 1 vote");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 1 vote");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("shows ended vote counts of different numbers", () => {
|
it("shows ended vote counts of different numbers", () => {
|
||||||
@ -619,15 +633,15 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@hi:example.com", "pizza", 15),
|
responseEvent("@hi:example.com", "pizza", 15),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
|
|
||||||
expect(body.find(".mx_StyledRadioButton")).toHaveLength(0);
|
expect(renderResult.container.querySelectorAll(".mx_StyledRadioButton")).toHaveLength(0);
|
||||||
expect(body.find('input[type="radio"]')).toHaveLength(0);
|
expect(renderResult.container.querySelectorAll('input[type="radio"]')).toHaveLength(0);
|
||||||
expect(endedVotesCount(body, "pizza")).toBe("2 votes");
|
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||||
expect(endedVotesCount(body, "poutine")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "italian")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "wings")).toBe("3 votes");
|
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Final result based on 5 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("ignores votes that arrived after poll ended", () => {
|
it("ignores votes that arrived after poll ended", () => {
|
||||||
@ -641,13 +655,13 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@ld:example.com", "pizza", 15),
|
responseEvent("@ld:example.com", "pizza", 15),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
|
|
||||||
expect(endedVotesCount(body, "pizza")).toBe("2 votes");
|
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||||
expect(endedVotesCount(body, "poutine")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "italian")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "wings")).toBe("3 votes");
|
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Final result based on 5 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("counts votes that arrived after an unauthorised poll end event", () => {
|
it("counts votes that arrived after an unauthorised poll end event", () => {
|
||||||
@ -664,13 +678,13 @@ describe("MPollBody", () => {
|
|||||||
endEvent("@unauthorised:example.com", 5), // Should be ignored
|
endEvent("@unauthorised:example.com", 5), // Should be ignored
|
||||||
endEvent("@me:example.com", 25),
|
endEvent("@me:example.com", 25),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
|
|
||||||
expect(endedVotesCount(body, "pizza")).toBe("2 votes");
|
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||||
expect(endedVotesCount(body, "poutine")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "italian")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "wings")).toBe("3 votes");
|
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Final result based on 5 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("ignores votes that arrived after the first end poll event", () => {
|
it("ignores votes that arrived after the first end poll event", () => {
|
||||||
@ -691,13 +705,13 @@ describe("MPollBody", () => {
|
|||||||
endEvent("@me:example.com", 25),
|
endEvent("@me:example.com", 25),
|
||||||
endEvent("@me:example.com", 75),
|
endEvent("@me:example.com", 75),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
|
|
||||||
expect(endedVotesCount(body, "pizza")).toBe("2 votes");
|
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||||
expect(endedVotesCount(body, "poutine")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "italian")).toBe("0 votes");
|
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||||
expect(endedVotesCount(body, "wings")).toBe("3 votes");
|
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||||
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Final result based on 5 votes");
|
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("highlights the winning vote in an ended poll", () => {
|
it("highlights the winning vote in an ended poll", () => {
|
||||||
@ -708,15 +722,15 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@xy:example.com", "wings", 15),
|
responseEvent("@xy:example.com", "wings", 15),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
|
|
||||||
// Then the winner is highlighted
|
// Then the winner is highlighted
|
||||||
expect(endedVoteChecked(body, "wings")).toBe(true);
|
expect(endedVoteChecked(renderResult, "wings")).toBe(true);
|
||||||
expect(endedVoteChecked(body, "pizza")).toBe(false);
|
expect(endedVoteChecked(renderResult, "pizza")).toBe(false);
|
||||||
|
|
||||||
// Double-check by looking for the endedOptionWinner class
|
// Double-check by looking for the endedOptionWinner class
|
||||||
expect(endedVoteDiv(body, "wings").hasClass("mx_MPollBody_endedOptionWinner")).toBe(true);
|
expect(endedVoteDiv(renderResult, "wings").className.includes("mx_MPollBody_endedOptionWinner")).toBe(true);
|
||||||
expect(endedVoteDiv(body, "pizza").hasClass("mx_MPollBody_endedOptionWinner")).toBe(false);
|
expect(endedVoteDiv(renderResult, "pizza").className.includes("mx_MPollBody_endedOptionWinner")).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("highlights multiple winning votes", () => {
|
it("highlights multiple winning votes", () => {
|
||||||
@ -726,23 +740,23 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@fg:example.com", "poutine", 15),
|
responseEvent("@fg:example.com", "poutine", 15),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody(votes, ends);
|
const renderResult = newMPollBody(votes, ends);
|
||||||
|
|
||||||
expect(endedVoteChecked(body, "pizza")).toBe(true);
|
expect(endedVoteChecked(renderResult, "pizza")).toBe(true);
|
||||||
expect(endedVoteChecked(body, "wings")).toBe(true);
|
expect(endedVoteChecked(renderResult, "wings")).toBe(true);
|
||||||
expect(endedVoteChecked(body, "poutine")).toBe(true);
|
expect(endedVoteChecked(renderResult, "poutine")).toBe(true);
|
||||||
expect(endedVoteChecked(body, "italian")).toBe(false);
|
expect(endedVoteChecked(renderResult, "italian")).toBe(false);
|
||||||
expect(body.find(".mx_MPollBody_option_checked")).toHaveLength(3);
|
expect(renderResult.container.getElementsByClassName("mx_MPollBody_option_checked")).toHaveLength(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("highlights nothing if poll has no votes", () => {
|
it("highlights nothing if poll has no votes", () => {
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody([], ends);
|
const renderResult = newMPollBody([], ends);
|
||||||
expect(body.find(".mx_MPollBody_option_checked")).toHaveLength(0);
|
expect(renderResult.container.getElementsByClassName("mx_MPollBody_option_checked")).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("says poll is not ended if there is no end event", () => {
|
it("says poll is not ended if there is no end event", () => {
|
||||||
const ends = [];
|
const ends: MatrixEvent[] = [];
|
||||||
expect(runIsPollEnded(ends)).toBe(false);
|
expect(runIsPollEnded(ends)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -810,26 +824,26 @@ describe("MPollBody", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
pollEvent.makeReplaced(replacingEvent);
|
pollEvent.makeReplaced(replacingEvent);
|
||||||
const body = newMPollBodyFromEvent(pollEvent, []);
|
const { getByTestId, container } = newMPollBodyFromEvent(pollEvent, []);
|
||||||
expect(body.find("h2").html()).toEqual(
|
expect(getByTestId("pollQuestion").innerHTML).toEqual(
|
||||||
"<h2>new question" + '<span class="mx_MPollBody_edited"> (edited)</span>' + "</h2>",
|
'new question<span class="mx_MPollBody_edited"> (edited)</span>',
|
||||||
);
|
);
|
||||||
const inputs = body.find('input[type="radio"]');
|
const inputs = container.querySelectorAll('input[type="radio"]');
|
||||||
expect(inputs).toHaveLength(3);
|
expect(inputs).toHaveLength(3);
|
||||||
expect(inputs.at(0).prop("value")).toEqual("n1");
|
expect(inputs[0].getAttribute("value")).toEqual("n1");
|
||||||
expect(inputs.at(1).prop("value")).toEqual("n2");
|
expect(inputs[1].getAttribute("value")).toEqual("n2");
|
||||||
expect(inputs.at(2).prop("value")).toEqual("n3");
|
expect(inputs[2].getAttribute("value")).toEqual("n3");
|
||||||
const options = body.find(".mx_MPollBody_optionText");
|
const options = container.querySelectorAll(".mx_MPollBody_optionText");
|
||||||
expect(options).toHaveLength(3);
|
expect(options).toHaveLength(3);
|
||||||
expect(options.at(0).text()).toEqual("new answer 1");
|
expect(options[0].innerHTML).toEqual("new answer 1");
|
||||||
expect(options.at(1).text()).toEqual("new answer 2");
|
expect(options[1].innerHTML).toEqual("new answer 2");
|
||||||
expect(options.at(2).text()).toEqual("new answer 3");
|
expect(options[2].innerHTML).toEqual("new answer 3");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders a poll with no votes", () => {
|
it("renders a poll with no votes", () => {
|
||||||
const votes = [];
|
const votes: MatrixEvent[] = [];
|
||||||
const body = newMPollBody(votes);
|
const { container } = newMPollBody(votes);
|
||||||
expect(body).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders a poll with only non-local votes", () => {
|
it("renders a poll with only non-local votes", () => {
|
||||||
@ -840,8 +854,8 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@me:example.com", "wings", 15),
|
responseEvent("@me:example.com", "wings", 15),
|
||||||
responseEvent("@qr:example.com", "italian", 16),
|
responseEvent("@qr:example.com", "italian", 16),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const { container } = newMPollBody(votes);
|
||||||
expect(body).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders a poll with local, non-local and invalid votes", () => {
|
it("renders a poll with local, non-local and invalid votes", () => {
|
||||||
@ -853,9 +867,9 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@e:example.com", "wings", 15),
|
responseEvent("@e:example.com", "wings", 15),
|
||||||
responseEvent("@me:example.com", "italian", 16),
|
responseEvent("@me:example.com", "italian", 16),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const renderResult = newMPollBody(votes);
|
||||||
clickRadio(body, "italian");
|
clickOption(renderResult, "italian");
|
||||||
expect(body).toMatchSnapshot();
|
expect(renderResult.container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders a poll that I have not voted in", () => {
|
it("renders a poll that I have not voted in", () => {
|
||||||
@ -866,14 +880,14 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@yo:example.com", "wings", 15),
|
responseEvent("@yo:example.com", "wings", 15),
|
||||||
responseEvent("@qr:example.com", "italian", 16),
|
responseEvent("@qr:example.com", "italian", 16),
|
||||||
];
|
];
|
||||||
const body = newMPollBody(votes);
|
const { container } = newMPollBody(votes);
|
||||||
expect(body).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders a finished poll with no votes", () => {
|
it("renders a finished poll with no votes", () => {
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody([], ends);
|
const { container } = newMPollBody([], ends);
|
||||||
expect(body).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders a finished poll", () => {
|
it("renders a finished poll", () => {
|
||||||
@ -885,8 +899,8 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@qr:example.com", "italian", 16),
|
responseEvent("@qr:example.com", "italian", 16),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody(votes, ends);
|
const { container } = newMPollBody(votes, ends);
|
||||||
expect(body).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders a finished poll with multiple winners", () => {
|
it("renders a finished poll with multiple winners", () => {
|
||||||
@ -899,8 +913,8 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@yh:example.com", "poutine", 14),
|
responseEvent("@yh:example.com", "poutine", 14),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody(votes, ends);
|
const { container } = newMPollBody(votes, ends);
|
||||||
expect(body).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders an undisclosed, unfinished poll", () => {
|
it("renders an undisclosed, unfinished poll", () => {
|
||||||
@ -912,9 +926,9 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@th:example.com", "poutine", 13),
|
responseEvent("@th:example.com", "poutine", 13),
|
||||||
responseEvent("@yh:example.com", "poutine", 14),
|
responseEvent("@yh:example.com", "poutine", 14),
|
||||||
];
|
];
|
||||||
const ends = [];
|
const ends: MatrixEvent[] = [];
|
||||||
const body = newMPollBody(votes, ends, undefined, false);
|
const { container } = newMPollBody(votes, ends, undefined, false);
|
||||||
expect(body.html()).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders an undisclosed, finished poll", () => {
|
it("renders an undisclosed, finished poll", () => {
|
||||||
@ -927,8 +941,8 @@ describe("MPollBody", () => {
|
|||||||
responseEvent("@yh:example.com", "poutine", 14),
|
responseEvent("@yh:example.com", "poutine", 14),
|
||||||
];
|
];
|
||||||
const ends = [endEvent("@me:example.com", 25)];
|
const ends = [endEvent("@me:example.com", 25)];
|
||||||
const body = newMPollBody(votes, ends, undefined, false);
|
const { container } = newMPollBody(votes, ends, undefined, false);
|
||||||
expect(body.html()).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -941,7 +955,7 @@ function newEndRelations(relationEvents: Array<MatrixEvent>): Relations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function newRelations(relationEvents: Array<MatrixEvent>, eventType: string): Relations {
|
function newRelations(relationEvents: Array<MatrixEvent>, eventType: string): Relations {
|
||||||
const voteRelations = new Relations("m.reference", eventType, null);
|
const voteRelations = new Relations("m.reference", eventType, mockClient);
|
||||||
for (const ev of relationEvents) {
|
for (const ev of relationEvents) {
|
||||||
voteRelations.addEvent(ev);
|
voteRelations.addEvent(ev);
|
||||||
}
|
}
|
||||||
@ -953,84 +967,88 @@ function newMPollBody(
|
|||||||
endEvents: Array<MatrixEvent> = [],
|
endEvents: Array<MatrixEvent> = [],
|
||||||
answers?: PollAnswer[],
|
answers?: PollAnswer[],
|
||||||
disclosed = true,
|
disclosed = true,
|
||||||
): ReactWrapper {
|
): RenderResult {
|
||||||
const mxEvent = new MatrixEvent({
|
const mxEvent = new MatrixEvent({
|
||||||
type: M_POLL_START.name,
|
type: M_POLL_START.name,
|
||||||
event_id: "$mypoll",
|
event_id: "$mypoll",
|
||||||
room_id: "#myroom:example.com",
|
room_id: "#myroom:example.com",
|
||||||
content: newPollStart(answers, null, disclosed),
|
content: newPollStart(answers, undefined, disclosed),
|
||||||
});
|
});
|
||||||
return newMPollBodyFromEvent(mxEvent, relationEvents, endEvents);
|
return newMPollBodyFromEvent(mxEvent, relationEvents, endEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMPollBodyPropsFromEvent(
|
||||||
|
mxEvent: MatrixEvent,
|
||||||
|
relationEvents: Array<MatrixEvent>,
|
||||||
|
endEvents: Array<MatrixEvent> = [],
|
||||||
|
): IBodyProps {
|
||||||
|
const voteRelations = newVoteRelations(relationEvents);
|
||||||
|
const endRelations = newEndRelations(endEvents);
|
||||||
|
|
||||||
|
const getRelationsForEvent = (eventId: string, relationType: string, eventType: string) => {
|
||||||
|
expect(eventId).toBe("$mypoll");
|
||||||
|
expect(relationType).toBe("m.reference");
|
||||||
|
if (M_POLL_RESPONSE.matches(eventType)) {
|
||||||
|
return voteRelations;
|
||||||
|
} else if (M_POLL_END.matches(eventType)) {
|
||||||
|
return endRelations;
|
||||||
|
} else {
|
||||||
|
fail("Unexpected eventType: " + eventType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
mxEvent,
|
||||||
|
getRelationsForEvent,
|
||||||
|
// We don't use any of these props, but they're required.
|
||||||
|
highlightLink: "unused",
|
||||||
|
highlights: [],
|
||||||
|
mediaEventHelper: {} as unknown as MediaEventHelper,
|
||||||
|
onHeightChanged: () => {},
|
||||||
|
onMessageAllowed: () => {},
|
||||||
|
permalinkCreator: {} as unknown as RoomPermalinkCreator,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderMPollBodyWithWrapper(props: IBodyProps): RenderResult {
|
||||||
|
return render(<MPollBody {...props} />, {
|
||||||
|
wrapper: ({ children }) => (
|
||||||
|
<MatrixClientContext.Provider value={mockClient}>{children}</MatrixClientContext.Provider>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function newMPollBodyFromEvent(
|
function newMPollBodyFromEvent(
|
||||||
mxEvent: MatrixEvent,
|
mxEvent: MatrixEvent,
|
||||||
relationEvents: Array<MatrixEvent>,
|
relationEvents: Array<MatrixEvent>,
|
||||||
endEvents: Array<MatrixEvent> = [],
|
endEvents: Array<MatrixEvent> = [],
|
||||||
): ReactWrapper {
|
): RenderResult {
|
||||||
const voteRelations = newVoteRelations(relationEvents);
|
const props = getMPollBodyPropsFromEvent(mxEvent, relationEvents, endEvents);
|
||||||
const endRelations = newEndRelations(endEvents);
|
return renderMPollBodyWithWrapper(props);
|
||||||
return mount(
|
|
||||||
<MPollBody
|
|
||||||
mxEvent={mxEvent}
|
|
||||||
getRelationsForEvent={(eventId: string, relationType: string, eventType: string) => {
|
|
||||||
expect(eventId).toBe("$mypoll");
|
|
||||||
expect(relationType).toBe("m.reference");
|
|
||||||
if (M_POLL_RESPONSE.matches(eventType)) {
|
|
||||||
return voteRelations;
|
|
||||||
} else if (M_POLL_END.matches(eventType)) {
|
|
||||||
return endRelations;
|
|
||||||
} else {
|
|
||||||
fail("Unexpected eventType: " + eventType);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
// We don't use any of these props, but they're required.
|
|
||||||
highlightLink="unused"
|
|
||||||
highlights={[]}
|
|
||||||
mediaEventHelper={null}
|
|
||||||
onHeightChanged={() => {}}
|
|
||||||
onMessageAllowed={() => {}}
|
|
||||||
permalinkCreator={null}
|
|
||||||
/>,
|
|
||||||
{
|
|
||||||
wrappingComponent: MatrixClientContext.Provider,
|
|
||||||
wrappingComponentProps: {
|
|
||||||
value: mockClient,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickRadio(wrapper: ReactWrapper, value: string) {
|
function clickOption({ getByTestId }: RenderResult, value: string) {
|
||||||
const div = wrapper.find(`StyledRadioButton[value="${value}"]`);
|
fireEvent.click(getByTestId(`pollOption-${value}`));
|
||||||
expect(div).toHaveLength(1);
|
|
||||||
div.simulate("click");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickEndedOption(wrapper: ReactWrapper, value: string) {
|
function voteButton({ getByTestId }: RenderResult, value: string): Element {
|
||||||
const div = wrapper.find(`div[data-value="${value}"]`);
|
return getByTestId(`pollOption-${value}`);
|
||||||
expect(div).toHaveLength(1);
|
|
||||||
div.simulate("click");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function voteButton(wrapper: ReactWrapper, value: string): ReactWrapper {
|
function votesCount({ getByTestId }: RenderResult, value: string): string {
|
||||||
return wrapper.find(`div.mx_MPollBody_option`).findWhere((w) => w.key() === value);
|
return getByTestId(`pollOption-${value}`).querySelector(".mx_MPollBody_optionVoteCount")!.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
function votesCount(wrapper: ReactWrapper, value: string): string {
|
function endedVoteChecked({ getByTestId }: RenderResult, value: string): boolean {
|
||||||
return wrapper.find(`StyledRadioButton[value="${value}"] .mx_MPollBody_optionVoteCount`).text();
|
return getByTestId(`pollOption-${value}`).className.includes("mx_MPollBody_option_checked");
|
||||||
}
|
}
|
||||||
|
|
||||||
function endedVoteChecked(wrapper: ReactWrapper, value: string): boolean {
|
function endedVoteDiv({ getByTestId }: RenderResult, value: string): Element {
|
||||||
return endedVoteDiv(wrapper, value).closest(".mx_MPollBody_option").hasClass("mx_MPollBody_option_checked");
|
return getByTestId(`pollOption-${value}`).firstElementChild!;
|
||||||
}
|
}
|
||||||
|
|
||||||
function endedVoteDiv(wrapper: ReactWrapper, value: string): ReactWrapper {
|
function endedVotesCount(renderResult: RenderResult, value: string): string {
|
||||||
return wrapper.find(`div[data-value="${value}"]`);
|
return votesCount(renderResult, value);
|
||||||
}
|
|
||||||
|
|
||||||
function endedVotesCount(wrapper: ReactWrapper, value: string): string {
|
|
||||||
return wrapper.find(`div[data-value="${value}"] .mx_MPollBody_optionVoteCount`).text();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function newPollStart(answers?: PollAnswer[], question?: string, disclosed = true): PollStartEventContent {
|
function newPollStart(answers?: PollAnswer[], question?: string, disclosed = true): PollStartEventContent {
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user