Poll history - extract poll option display components (#10107)
* 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 * render a poll body that errors for poll end events * add fetching logic to pollend tile * extract poll testing utilities * test mpollend * strict fix * more strict fix * strict fix for forwardref * add filter component * update poll test utils * add unstyled filter tab group * filtertabgroup snapshot * lint * update test util setupRoomWithPollEvents to allow testing multiple polls in one room * style filter tabs * test error message for past polls * sort polls list by latest * extract poll option display components * strict fixes
This commit is contained in:
parent
18ab325eaf
commit
1c6b06bb58
13 changed files with 597 additions and 494 deletions
|
@ -42,7 +42,7 @@ 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_PollOption_checked";
|
||||
const userId = "@me:example.com";
|
||||
|
||||
const mockClient = getMockClientWithEventEmitter({
|
||||
|
@ -383,7 +383,7 @@ describe("MPollBody", () => {
|
|||
const votes: MatrixEvent[] = [];
|
||||
const ends: MatrixEvent[] = [];
|
||||
const { container } = await newMPollBody(votes, ends, answers);
|
||||
expect(container.querySelectorAll(".mx_MPollBody_option").length).toBe(20);
|
||||
expect(container.querySelectorAll(".mx_PollOption").length).toBe(20);
|
||||
});
|
||||
|
||||
it("hides scores if I voted but the poll is undisclosed", async () => {
|
||||
|
@ -429,7 +429,7 @@ describe("MPollBody", () => {
|
|||
];
|
||||
const ends = [newPollEndEvent("@me:example.com", 12)];
|
||||
const renderResult = await newMPollBody(votes, ends, undefined, false);
|
||||
expect(endedVotesCount(renderResult, "pizza")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "pizza")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("1 vote");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("1 vote");
|
||||
|
@ -531,9 +531,9 @@ describe("MPollBody", () => {
|
|||
const ends = [newPollEndEvent("@me:example.com", 25)];
|
||||
const renderResult = await newMPollBody(votes, ends);
|
||||
expect(endedVotesCount(renderResult, "pizza")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("1 vote");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe('<div class="mx_PollOption_winnerIcon"></div>1 vote');
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("1 vote");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>1 vote');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 2 votes");
|
||||
});
|
||||
|
||||
|
@ -542,7 +542,7 @@ describe("MPollBody", () => {
|
|||
const ends = [newPollEndEvent("@me:example.com", 25)];
|
||||
const renderResult = await newMPollBody(votes, ends);
|
||||
expect(endedVotesCount(renderResult, "pizza")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("1 vote");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe('<div class="mx_PollOption_winnerIcon"></div>1 vote');
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("0 votes");
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 1 vote");
|
||||
|
@ -564,7 +564,7 @@ describe("MPollBody", () => {
|
|||
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||
});
|
||||
|
||||
|
@ -584,7 +584,7 @@ describe("MPollBody", () => {
|
|||
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||
});
|
||||
|
||||
|
@ -607,7 +607,7 @@ describe("MPollBody", () => {
|
|||
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||
});
|
||||
|
||||
|
@ -634,7 +634,7 @@ describe("MPollBody", () => {
|
|||
expect(endedVotesCount(renderResult, "pizza")).toBe("2 votes");
|
||||
expect(endedVotesCount(renderResult, "poutine")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "italian")).toBe("0 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe("3 votes");
|
||||
expect(endedVotesCount(renderResult, "wings")).toBe('<div class="mx_PollOption_winnerIcon"></div>3 votes');
|
||||
expect(renderResult.getByTestId("totalVotes").innerHTML).toBe("Final result based on 5 votes");
|
||||
});
|
||||
|
||||
|
@ -653,8 +653,8 @@ describe("MPollBody", () => {
|
|||
expect(endedVoteChecked(renderResult, "pizza")).toBe(false);
|
||||
|
||||
// Double-check by looking for the endedOptionWinner class
|
||||
expect(endedVoteDiv(renderResult, "wings").className.includes("mx_MPollBody_endedOptionWinner")).toBe(true);
|
||||
expect(endedVoteDiv(renderResult, "pizza").className.includes("mx_MPollBody_endedOptionWinner")).toBe(false);
|
||||
expect(endedVoteDiv(renderResult, "wings").className.includes("mx_PollOption_endedOptionWinner")).toBe(true);
|
||||
expect(endedVoteDiv(renderResult, "pizza").className.includes("mx_PollOption_endedOptionWinner")).toBe(false);
|
||||
});
|
||||
|
||||
it("highlights multiple winning votes", async () => {
|
||||
|
@ -670,13 +670,13 @@ describe("MPollBody", () => {
|
|||
expect(endedVoteChecked(renderResult, "wings")).toBe(true);
|
||||
expect(endedVoteChecked(renderResult, "poutine")).toBe(true);
|
||||
expect(endedVoteChecked(renderResult, "italian")).toBe(false);
|
||||
expect(renderResult.container.getElementsByClassName("mx_MPollBody_option_checked")).toHaveLength(3);
|
||||
expect(renderResult.container.getElementsByClassName(CHECKED)).toHaveLength(3);
|
||||
});
|
||||
|
||||
it("highlights nothing if poll has no votes", async () => {
|
||||
const ends = [newPollEndEvent("@me:example.com", 25)];
|
||||
const renderResult = await newMPollBody([], ends);
|
||||
expect(renderResult.container.getElementsByClassName("mx_MPollBody_option_checked")).toHaveLength(0);
|
||||
expect(renderResult.container.getElementsByClassName(CHECKED)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("says poll is not ended if there is no end event", async () => {
|
||||
|
@ -745,7 +745,7 @@ describe("MPollBody", () => {
|
|||
expect(inputs[0].getAttribute("value")).toEqual("n1");
|
||||
expect(inputs[1].getAttribute("value")).toEqual("n2");
|
||||
expect(inputs[2].getAttribute("value")).toEqual("n3");
|
||||
const options = container.querySelectorAll(".mx_MPollBody_optionText");
|
||||
const options = container.querySelectorAll(".mx_PollOption_optionText");
|
||||
expect(options).toHaveLength(3);
|
||||
expect(options[0].innerHTML).toEqual("new answer 1");
|
||||
expect(options[1].innerHTML).toEqual("new answer 2");
|
||||
|
@ -934,11 +934,11 @@ function voteButton({ getByTestId }: RenderResult, value: string): Element {
|
|||
}
|
||||
|
||||
function votesCount({ getByTestId }: RenderResult, value: string): string {
|
||||
return getByTestId(`pollOption-${value}`).querySelector(".mx_MPollBody_optionVoteCount")!.innerHTML;
|
||||
return getByTestId(`pollOption-${value}`).querySelector(".mx_PollOption_optionVoteCount")!.innerHTML;
|
||||
}
|
||||
|
||||
function endedVoteChecked({ getByTestId }: RenderResult, value: string): boolean {
|
||||
return getByTestId(`pollOption-${value}`).className.includes("mx_MPollBody_option_checked");
|
||||
return getByTestId(`pollOption-${value}`).className.includes(CHECKED);
|
||||
}
|
||||
|
||||
function endedVoteDiv({ getByTestId }: RenderResult, value: string): Element {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,65 +22,65 @@ exports[`<MPollEndBody /> when poll start event exists in current timeline rende
|
|||
class="mx_MPollBody_allOptions"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_option mx_MPollBody_option_ended"
|
||||
class="mx_PollOption mx_PollOption_ended"
|
||||
data-testid="pollOption-socks"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_endedOption"
|
||||
class="mx_PollOption_endedOption"
|
||||
data-value="socks"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_optionDescription"
|
||||
class="mx_PollOption_content"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_optionText"
|
||||
class="mx_PollOption_optionText"
|
||||
>
|
||||
Socks
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_optionVoteCount"
|
||||
class="mx_PollOption_optionVoteCount"
|
||||
>
|
||||
0 votes
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_popularityBackground"
|
||||
class="mx_PollOption_popularityBackground"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_popularityAmount"
|
||||
class="mx_PollOption_popularityAmount"
|
||||
style="width: 0%;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_option mx_MPollBody_option_ended"
|
||||
class="mx_PollOption mx_PollOption_ended"
|
||||
data-testid="pollOption-shoes"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_endedOption"
|
||||
class="mx_PollOption_endedOption"
|
||||
data-value="shoes"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_optionDescription"
|
||||
class="mx_PollOption_content"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_optionText"
|
||||
class="mx_PollOption_optionText"
|
||||
>
|
||||
Shoes
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_optionVoteCount"
|
||||
class="mx_PollOption_optionVoteCount"
|
||||
>
|
||||
0 votes
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MPollBody_popularityBackground"
|
||||
class="mx_PollOption_popularityBackground"
|
||||
>
|
||||
<div
|
||||
class="mx_MPollBody_popularityAmount"
|
||||
class="mx_PollOption_popularityAmount"
|
||||
style="width: 0%;"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -287,8 +287,8 @@ describe("<PinnedMessagesCard />", () => {
|
|||
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");
|
||||
expect(pinTile.find(".mx_MPollBody_optionVoteCount").last().text()).toEqual("1 vote");
|
||||
expect(pinTile.find(".mx_PollOption_ended").length).toEqual(2);
|
||||
expect(pinTile.find(".mx_PollOption_optionVoteCount").first().text()).toEqual("2 votes");
|
||||
expect(pinTile.find(".mx_PollOption_optionVoteCount").last().text()).toEqual("1 vote");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,6 +26,9 @@ mockPlatformPeg();
|
|||
|
||||
const MS_DAY = 86400000;
|
||||
describe("<FilteredDeviceList />", () => {
|
||||
// 14.03.2022 16:15
|
||||
const now = 1647270879403;
|
||||
jest.spyOn(global.Date, "now").mockReturnValue(now);
|
||||
const newDevice = {
|
||||
device_id: "new",
|
||||
last_seen_ts: Date.now() - 500,
|
||||
|
@ -81,6 +84,10 @@ describe("<FilteredDeviceList />", () => {
|
|||
|
||||
const getComponent = (props = {}) => <FilteredDeviceList {...defaultProps} {...props} />;
|
||||
|
||||
afterAll(() => {
|
||||
jest.spyOn(global.Date, "now").mockRestore();
|
||||
});
|
||||
|
||||
it("renders devices in correct order", () => {
|
||||
const { container } = render(getComponent());
|
||||
const tiles = container.querySelectorAll(".mx_DeviceTile");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue