use Poll model with relations API in poll rendering (#9877)
* wip * remove dupe * use poll model relations in all cases * update mpollbody tests to use poll instance * update poll fetching login in pinned messages card * add pinned polls to room polls state * add spinner while relations are still loading * handle no poll in end poll dialog * strict errors * strict fix * more strict fix
This commit is contained in:
parent
b45b933a65
commit
544baa30ed
9 changed files with 350 additions and 670 deletions
File diff suppressed because it is too large
Load diff
|
@ -456,6 +456,8 @@ exports[`MPollBody renders a finished poll with no votes 1`] = `
|
|||
</div>
|
||||
`;
|
||||
|
||||
exports[`MPollBody renders a loader while responses are still loading 1`] = `"Based on 4 votes<div class="mx_Spinner"><div class="mx_Spinner_icon" style="width: 16px; height: 16px;" aria-label="Loading..." role="progressbar" data-testid="spinner"></div></div>"`;
|
||||
|
||||
exports[`MPollBody renders a poll that I have not voted in 1`] = `
|
||||
<div>
|
||||
<div
|
||||
|
@ -769,7 +771,6 @@ exports[`MPollBody renders a poll with local, non-local and invalid votes 1`] =
|
|||
class="mx_StyledRadioButton mx_MPollBody_live-option mx_StyledRadioButton_enabled mx_StyledRadioButton_checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
name="poll_answer_select-$mypoll"
|
||||
type="radio"
|
||||
value="italian"
|
||||
|
@ -1224,7 +1225,6 @@ exports[`MPollBody renders a poll with only non-local votes 1`] = `
|
|||
class="mx_StyledRadioButton mx_MPollBody_live-option mx_StyledRadioButton_enabled mx_StyledRadioButton_checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
name="poll_answer_select-$mypoll"
|
||||
type="radio"
|
||||
value="wings"
|
||||
|
|
|
@ -23,12 +23,12 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
|||
import { EventType, RelationType, MsgType } from "matrix-js-sdk/src/@types/event";
|
||||
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
|
||||
import { IEvent, Room, EventTimelineSet, IMinimalEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { M_POLL_RESPONSE, M_POLL_END, M_POLL_KIND_DISCLOSED } from "matrix-js-sdk/src/@types/polls";
|
||||
import { M_POLL_KIND_DISCLOSED } from "matrix-js-sdk/src/@types/polls";
|
||||
import { PollStartEvent } from "matrix-js-sdk/src/extensible_events_v1/PollStartEvent";
|
||||
import { PollResponseEvent } from "matrix-js-sdk/src/extensible_events_v1/PollResponseEvent";
|
||||
import { PollEndEvent } from "matrix-js-sdk/src/extensible_events_v1/PollEndEvent";
|
||||
|
||||
import { stubClient, mkStubRoom, mkEvent, mkMessage } from "../../../test-utils";
|
||||
import { stubClient, mkEvent, mkMessage, flushPromises } from "../../../test-utils";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import PinnedMessagesCard from "../../../../src/components/views/right_panel/PinnedMessagesCard";
|
||||
import PinnedEventTile from "../../../../src/components/views/rooms/PinnedEventTile";
|
||||
|
@ -40,16 +40,16 @@ describe("<PinnedMessagesCard />", () => {
|
|||
stubClient();
|
||||
const cli = mocked(MatrixClientPeg.get());
|
||||
cli.getUserId.mockReturnValue("@alice:example.org");
|
||||
cli.setRoomAccountData.mockReturnValue(undefined);
|
||||
cli.setRoomAccountData.mockResolvedValue({});
|
||||
cli.relations.mockResolvedValue({ originalEvent: {} as unknown as MatrixEvent, events: [] });
|
||||
|
||||
const mkRoom = (localPins: MatrixEvent[], nonLocalPins: MatrixEvent[]): Room => {
|
||||
const room = mkStubRoom("!room:example.org", "room", cli);
|
||||
const room = new Room("!room:example.org", cli, "@me:example.org");
|
||||
// Deferred since we may be adding or removing pins later
|
||||
const pins = () => [...localPins, ...nonLocalPins];
|
||||
|
||||
// Insert pin IDs into room state
|
||||
mocked(room.currentState).getStateEvents.mockImplementation((): any =>
|
||||
jest.spyOn(room.currentState, "getStateEvents").mockImplementation((): any =>
|
||||
mkEvent({
|
||||
event: true,
|
||||
type: EventType.RoomPinnedEvents,
|
||||
|
@ -61,6 +61,8 @@ describe("<PinnedMessagesCard />", () => {
|
|||
}),
|
||||
);
|
||||
|
||||
jest.spyOn(room.currentState, "on");
|
||||
|
||||
// Insert local pins into local timeline set
|
||||
room.getUnfilteredTimelineSet = () =>
|
||||
({
|
||||
|
@ -75,6 +77,8 @@ describe("<PinnedMessagesCard />", () => {
|
|||
return Promise.resolve(event as IMinimalEvent);
|
||||
});
|
||||
|
||||
cli.getRoom.mockReturnValue(room);
|
||||
|
||||
return room;
|
||||
};
|
||||
|
||||
|
@ -131,8 +135,8 @@ describe("<PinnedMessagesCard />", () => {
|
|||
|
||||
it("updates when messages are pinned", async () => {
|
||||
// Start with nothing pinned
|
||||
const localPins = [];
|
||||
const nonLocalPins = [];
|
||||
const localPins: MatrixEvent[] = [];
|
||||
const nonLocalPins: MatrixEvent[] = [];
|
||||
const pins = await mountPins(mkRoom(localPins, nonLocalPins));
|
||||
expect(pins.find(PinnedEventTile).length).toBe(0);
|
||||
|
||||
|
@ -240,31 +244,27 @@ describe("<PinnedMessagesCard />", () => {
|
|||
["@eve:example.org", 1],
|
||||
].map(([user, option], i) =>
|
||||
mkEvent({
|
||||
...PollResponseEvent.from([answers[option].id], poll.getId()).serialize(),
|
||||
...PollResponseEvent.from([answers[option as number].id], poll.getId()!).serialize(),
|
||||
event: true,
|
||||
room: "!room:example.org",
|
||||
user: user as string,
|
||||
}),
|
||||
);
|
||||
|
||||
const end = mkEvent({
|
||||
...PollEndEvent.from(poll.getId(), "Closing the poll").serialize(),
|
||||
...PollEndEvent.from(poll.getId()!, "Closing the poll").serialize(),
|
||||
event: true,
|
||||
room: "!room:example.org",
|
||||
user: "@alice:example.org",
|
||||
});
|
||||
|
||||
// Make the responses available
|
||||
cli.relations.mockImplementation(async (roomId, eventId, relationType, eventType, { from }) => {
|
||||
cli.relations.mockImplementation(async (roomId, eventId, relationType, eventType, opts) => {
|
||||
if (eventId === poll.getId() && relationType === RelationType.Reference) {
|
||||
switch (eventType) {
|
||||
case M_POLL_RESPONSE.name:
|
||||
// Paginate the results, for added challenge
|
||||
return from === "page2"
|
||||
? { originalEvent: poll, events: responses.slice(2) }
|
||||
: { originalEvent: poll, events: responses.slice(0, 2), nextBatch: "page2" };
|
||||
case M_POLL_END.name:
|
||||
return { originalEvent: null, events: [end] };
|
||||
}
|
||||
// Paginate the results, for added challenge
|
||||
return opts?.from === "page2"
|
||||
? { originalEvent: poll, events: responses.slice(2) }
|
||||
: { originalEvent: poll, events: [...responses.slice(0, 2), end], nextBatch: "page2" };
|
||||
}
|
||||
// type does not allow originalEvent to be falsy
|
||||
// but code seems to
|
||||
|
@ -272,8 +272,20 @@ describe("<PinnedMessagesCard />", () => {
|
|||
return { originalEvent: undefined as unknown as MatrixEvent, events: [] };
|
||||
});
|
||||
|
||||
const pins = await mountPins(mkRoom([], [poll]));
|
||||
const room = mkRoom([], [poll]);
|
||||
// poll end event validates against this
|
||||
jest.spyOn(room.currentState, "maySendRedactionForEvent").mockReturnValue(true);
|
||||
|
||||
const pins = await mountPins(room);
|
||||
// two pages of results
|
||||
await flushPromises();
|
||||
await flushPromises();
|
||||
|
||||
const pollInstance = room.polls.get(poll.getId()!);
|
||||
expect(pollInstance).toBeTruthy();
|
||||
|
||||
const pinTile = pins.find(MPollBody);
|
||||
|
||||
expect(pinTile.length).toEqual(1);
|
||||
expect(pinTile.find(".mx_MPollBody_option_ended").length).toEqual(2);
|
||||
expect(pinTile.find(".mx_MPollBody_optionVoteCount").first().text()).toEqual("2 votes");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue