Ensure my votes from a different device show up (#7233)

Co-authored-by: Travis Ralston <travpc@gmail.com>
This commit is contained in:
Andy Balaam 2021-12-02 17:12:18 +00:00 committed by GitHub
parent 25c119dd5a
commit 141950d9e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 101 additions and 23 deletions

View file

@ -23,9 +23,10 @@ import * as TestUtils from "../../../test-utils";
import { Callback, IContent, MatrixEvent } from "matrix-js-sdk";
import { ISendEventResponse } from "matrix-js-sdk/src/@types/requests";
import { Relations } from "matrix-js-sdk/src/models/relations";
import { IPollAnswer, IPollContent } from "../../../../src/polls/consts";
import { IPollAnswer, IPollContent, POLL_RESPONSE_EVENT_TYPE } from "../../../../src/polls/consts";
import { UserVote, allVotes } from "../../../../src/components/views/messages/MPollBody";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import { IBodyProps } from "../../../../src/components/views/messages/IBodyProps";
const CHECKED = "mx_MPollBody_option_checked";
@ -52,12 +53,12 @@ describe("MPollBody", () => {
new UserVote(
ev1.getTs(),
ev1.getSender(),
ev1.getContent()["org.matrix.msc3381.poll.response"].answers,
ev1.getContent()[POLL_RESPONSE_EVENT_TYPE.name].answers,
),
new UserVote(
ev2.getTs(),
ev2.getSender(),
ev2.getContent()["org.matrix.msc3381.poll.response"].answers,
ev2.getContent()[POLL_RESPONSE_EVENT_TYPE.name].answers,
),
]);
});
@ -150,6 +151,55 @@ describe("MPollBody", () => {
expect(voteButton(body, "italian").hasClass(CHECKED)).toBe(false);
});
it("cancels my local vote if another comes in", () => {
// Given I voted locally
const votes = [responseEvent("@me:example.com", "pizza", 100)];
const body = newMPollBody(votes);
const props: IBodyProps = body.instance().props as IBodyProps;
const pollRelations: Relations = props.getRelationsForEvent(
"$mypoll", "m.reference", POLL_RESPONSE_EVENT_TYPE.name);
clickRadio(body, "pizza");
// When a new vote from me comes in
pollRelations.addEvent(responseEvent("@me:example.com", "wings", 101));
// Then the new vote is counted, not the old one
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("1 vote");
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 1 vote");
});
it("doesn't cancel my local vote if someone else votes", () => {
// Given I voted locally
const votes = [responseEvent("@me:example.com", "pizza")];
const body = newMPollBody(votes);
const props: IBodyProps = body.instance().props as IBodyProps;
const pollRelations: Relations = props.getRelationsForEvent(
"$mypoll", "m.reference", POLL_RESPONSE_EVENT_TYPE.name);
clickRadio(body, "pizza");
// When a new vote from someone else comes in
pollRelations.addEvent(responseEvent("@xx:example.com", "wings", 101));
// Then my vote is still for pizza
// NOTE: the new event does not affect the counts for other people -
// that is handled through the Relations, not by listening to
// these timeline events.
expect(votesCount(body, "pizza")).toBe("1 vote");
expect(votesCount(body, "poutine")).toBe("0 votes");
expect(votesCount(body, "italian")).toBe("0 votes");
expect(votesCount(body, "wings")).toBe("1 vote");
expect(body.find(".mx_MPollBody_totalVotes").text()).toBe("Based on 2 votes");
// And my vote is highlighted
expect(voteButton(body, "pizza").hasClass(CHECKED)).toBe(true);
expect(voteButton(body, "wings").hasClass(CHECKED)).toBe(false);
});
it("highlights my vote even if I did it on another device", () => {
// Given I voted italian
const votes = [
@ -363,7 +413,7 @@ describe("MPollBody", () => {
function newPollRelations(relationEvents: Array<MatrixEvent>): Relations {
const pollRelations = new Relations(
"m.reference", "org.matrix.msc3381.poll.response", null);
"m.reference", POLL_RESPONSE_EVENT_TYPE.name, null);
for (const ev of relationEvents) {
pollRelations.addEvent(ev);
}
@ -375,7 +425,7 @@ function newMPollBody(
answers?: IPollAnswer[],
): ReactWrapper {
const pollRelations = new Relations(
"m.reference", "org.matrix.msc3381.poll.response", null);
"m.reference", POLL_RESPONSE_EVENT_TYPE.name, null);
for (const ev of relationEvents) {
pollRelations.addEvent(ev);
}
@ -390,7 +440,7 @@ function newMPollBody(
(eventId: string, relationType: string, eventType: string) => {
expect(eventId).toBe("$mypoll");
expect(relationType).toBe("m.reference");
expect(eventType).toBe("org.matrix.msc3381.poll.response");
expect(eventType).toBe(POLL_RESPONSE_EVENT_TYPE.name);
return pollRelations;
}
}
@ -440,7 +490,7 @@ function badResponseEvent(): MatrixEvent {
return new MatrixEvent(
{
"event_id": nextId(),
"type": "org.matrix.msc3381.poll.response",
"type": POLL_RESPONSE_EVENT_TYPE.name,
"content": {
"m.relates_to": {
"rel_type": "m.reference",
@ -463,14 +513,14 @@ function responseEvent(
"event_id": nextId(),
"room_id": "#myroom:example.com",
"origin_server_ts": ts,
"type": "org.matrix.msc3381.poll.response",
"type": POLL_RESPONSE_EVENT_TYPE.name,
"sender": sender,
"content": {
"m.relates_to": {
"rel_type": "m.reference",
"event_id": "$mypoll",
},
"org.matrix.msc3381.poll.response": {
[POLL_RESPONSE_EVENT_TYPE.name]: {
"answers": ans,
},
},
@ -481,7 +531,7 @@ function responseEvent(
function expectedResponseEvent(answer: string) {
return {
"content": {
"org.matrix.msc3381.poll.response": {
[POLL_RESPONSE_EVENT_TYPE.name]: {
"answers": [answer],
},
"m.relates_to": {
@ -489,7 +539,7 @@ function expectedResponseEvent(answer: string) {
"rel_type": "m.reference",
},
},
"eventType": "org.matrix.msc3381.poll.response",
"eventType": POLL_RESPONSE_EVENT_TYPE.name,
"roomId": "#myroom:example.com",
"txnId": undefined,
"callback": undefined,