Poll history - read only list of polls in current timeline (#10055)

* add settings while under development

* very basic tests for roomsummarycard

* empty poll history dialog and option in room summary

* pollS history in settings

* render an ugly list of polls in current timeline

* readonly poll history list items

* fix scroll window

* use short year code in date format, tidy

* no results message + tests

* strict fix

* mock intldatetimeformat for stable date formatting

* extract date format fn into date-utils

* jsdoc
This commit is contained in:
Kerry 2023-02-03 10:39:23 +13:00 committed by GitHub
parent 544baa30ed
commit ebb8408f28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 572 additions and 7 deletions

View file

@ -0,0 +1,86 @@
/*
Copyright 2023 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import { render } from "@testing-library/react";
import { MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import { PollHistoryDialog } from "../../../../../src/components/views/dialogs/polls/PollHistoryDialog";
import {
getMockClientWithEventEmitter,
makePollStartEvent,
mockClientMethodsUser,
mockIntlDateTimeFormat,
unmockIntlDateTimeFormat,
} from "../../../../test-utils";
describe("<PollHistoryDialog />", () => {
const userId = "@alice:domain.org";
const roomId = "!room:domain.org";
const mockClient = getMockClientWithEventEmitter({
...mockClientMethodsUser(userId),
getRoom: jest.fn(),
});
const room = new Room(roomId, mockClient, userId);
const defaultProps = {
roomId,
matrixClient: mockClient,
onFinished: jest.fn(),
};
const getComponent = () => render(<PollHistoryDialog {...defaultProps} />);
beforeAll(() => {
mockIntlDateTimeFormat();
});
beforeEach(() => {
mockClient.getRoom.mockReturnValue(room);
const timeline = room.getLiveTimeline();
jest.spyOn(timeline, "getEvents").mockReturnValue([]);
});
afterAll(() => {
unmockIntlDateTimeFormat();
});
it("throws when room is not found", () => {
mockClient.getRoom.mockReturnValue(null);
expect(() => getComponent()).toThrow("Cannot find room");
});
it("renders a no polls message when there are no polls in the timeline", () => {
const { getByText } = getComponent();
expect(getByText("There are no polls in this room")).toBeTruthy();
});
it("renders a list of polls when there are polls in the timeline", () => {
const pollStart1 = makePollStartEvent("Question?", userId, undefined, 1675300825090, "$1");
const pollStart2 = makePollStartEvent("Where?", userId, undefined, 1675300725090, "$2");
const pollStart3 = makePollStartEvent("What?", userId, undefined, 1675200725090, "$3");
const message = new MatrixEvent({
type: "m.room.message",
content: {},
});
const timeline = room.getLiveTimeline();
jest.spyOn(timeline, "getEvents").mockReturnValue([pollStart1, pollStart2, pollStart3, message]);
const { container } = getComponent();
expect(container).toMatchSnapshot();
});
});

View file

@ -0,0 +1,53 @@
/*
Copyright 2023 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import { render } from "@testing-library/react";
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import PollListItem from "../../../../../src/components/views/dialogs/polls/PollListItem";
import { makePollStartEvent, mockIntlDateTimeFormat, unmockIntlDateTimeFormat } from "../../../../test-utils";
describe("<PollListItem />", () => {
const event = makePollStartEvent("Question?", "@me:domain.org");
event.getContent().origin;
const defaultProps = { event };
const getComponent = (props = {}) => render(<PollListItem {...defaultProps} {...props} />);
beforeAll(() => {
// mock default locale to en-GB and set timezone
// so these tests run the same everywhere
mockIntlDateTimeFormat();
});
afterAll(() => {
unmockIntlDateTimeFormat();
});
it("renders a poll", () => {
const { container } = getComponent();
expect(container).toMatchSnapshot();
});
it("renders null when event does not have an extensible poll start event", () => {
const event = new MatrixEvent({
type: "m.room.message",
content: {},
});
const { container } = getComponent({ event });
expect(container.firstElementChild).toBeFalsy();
});
});

View file

@ -0,0 +1,99 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<PollHistoryDialog /> renders a list of polls when there are polls in the timeline 1`] = `
<div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
<div
aria-labelledby="mx_BaseDialog_title"
class="undefined mx_Dialog_fixedWidth"
data-focus-lock-disabled="false"
role="dialog"
>
<div
class="mx_Dialog_header mx_Dialog_headerWithCancel"
>
<h2
class="mx_Heading_h2 mx_Dialog_title"
id="mx_BaseDialog_title"
>
Polls history
</h2>
<div
aria-label="Close dialog"
class="mx_AccessibleButton mx_Dialog_cancelButton"
role="button"
tabindex="0"
/>
</div>
<div
class="mx_PollHistoryDialog_content"
>
<div
class="mx_PollHistoryList"
>
<ol
class="mx_PollHistoryList_list"
>
<li
class="mx_PollListItem"
data-testid="pollListItem-$1"
>
<span>
02/02/23
</span>
<div
class="mx_PollListItem_icon"
/>
<span
class="mx_PollListItem_question"
>
Question?
</span>
</li>
<li
class="mx_PollListItem"
data-testid="pollListItem-$2"
>
<span>
02/02/23
</span>
<div
class="mx_PollListItem_icon"
/>
<span
class="mx_PollListItem_question"
>
Where?
</span>
</li>
<li
class="mx_PollListItem"
data-testid="pollListItem-$3"
>
<span>
31/01/23
</span>
<div
class="mx_PollListItem_icon"
/>
<span
class="mx_PollListItem_question"
>
What?
</span>
</li>
</ol>
</div>
</div>
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
</div>
`;

View file

@ -0,0 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<PollListItem /> renders a poll 1`] = `
<div>
<li
class="mx_PollListItem"
data-testid="pollListItem-$mypoll"
>
<span>
01/01/70
</span>
<div
class="mx_PollListItem_icon"
/>
<span
class="mx_PollListItem_question"
>
Question?
</span>
</li>
</div>
`;

View file

@ -145,7 +145,7 @@ describe("<RoomSummaryCard />", () => {
fireEvent.click(getByText("Polls history"));
expect(modalSpy).toHaveBeenCalledWith(PollHistoryDialog, { roomId });
expect(modalSpy).toHaveBeenCalledWith(PollHistoryDialog, { roomId, matrixClient: mockClient });
});
});

View file

@ -92,6 +92,7 @@ exports[`<RoomSummaryCard /> renders the room summary 1`] = `
</div>
<div
class="mx_AccessibleButton mx_BaseCard_Button mx_RoomSummaryCard_Button mx_RoomSummaryCard_icon_share"
data-testid="shareRoomButton"
role="button"
tabindex="0"
>