Conform more of the code base to strict null checking (#10147)

* Conform more of the code base to strict null checking

* More strict fixes

* More strict work

* Fix missing optional type

* Iterate
This commit is contained in:
Michael Telatynski 2023-02-13 17:01:43 +00:00 committed by GitHub
parent fa036a5080
commit da7aa4055e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
380 changed files with 682 additions and 694 deletions

View file

@ -49,7 +49,7 @@ describe("<RoomSearchView/>", () => {
stubClient();
client = MatrixClientPeg.get();
client.supportsThreads = jest.fn().mockReturnValue(true);
room = new Room("!room:server", client, client.getUserId());
room = new Room("!room:server", client, client.getUserId()!);
mocked(client.getRoom).mockReturnValue(room);
permalinkCreator = new RoomPermalinkCreator(room, room.roomId);
@ -92,7 +92,7 @@ describe("<RoomSearchView/>", () => {
result: {
room_id: room.roomId,
event_id: "$2",
sender: client.getUserId(),
sender: client.getUserId()!,
origin_server_ts: 1,
content: { body: "Foo Test Bar", msgtype: "m.text" },
type: EventType.RoomMessage,
@ -103,7 +103,7 @@ describe("<RoomSearchView/>", () => {
{
room_id: room.roomId,
event_id: "$1",
sender: client.getUserId(),
sender: client.getUserId()!,
origin_server_ts: 1,
content: { body: "Before", msgtype: "m.text" },
type: EventType.RoomMessage,
@ -113,7 +113,7 @@ describe("<RoomSearchView/>", () => {
{
room_id: room.roomId,
event_id: "$3",
sender: client.getUserId(),
sender: client.getUserId()!,
origin_server_ts: 1,
content: { body: "After", msgtype: "m.text" },
type: EventType.RoomMessage,
@ -154,7 +154,7 @@ describe("<RoomSearchView/>", () => {
result: {
room_id: room.roomId,
event_id: "$2",
sender: client.getUserId(),
sender: client.getUserId()!,
origin_server_ts: 1,
content: { body: "Foo Test Bar", msgtype: "m.text" },
type: EventType.RoomMessage,
@ -192,7 +192,7 @@ describe("<RoomSearchView/>", () => {
result: {
room_id: room.roomId,
event_id: "$2",
sender: client.getUserId(),
sender: client.getUserId()!,
origin_server_ts: 1,
content: { body: "Foo Test Bar", msgtype: "m.text" },
type: EventType.RoomMessage,
@ -221,7 +221,7 @@ describe("<RoomSearchView/>", () => {
result: {
room_id: room.roomId,
event_id: "$4",
sender: client.getUserId(),
sender: client.getUserId()!,
origin_server_ts: 4,
content: { body: "Potato", msgtype: "m.text" },
type: EventType.RoomMessage,

View file

@ -43,20 +43,20 @@ describe("<TabbedView />", () => {
it("renders first tab as active tab when no initialTabId", () => {
const { container } = render(getComponent());
expect(getActiveTab(container).textContent).toEqual(generalTab.label);
expect(getActiveTabBody(container).textContent).toEqual("general");
expect(getActiveTab(container)?.textContent).toEqual(generalTab.label);
expect(getActiveTabBody(container)?.textContent).toEqual("general");
});
it("renders first tab as active tab when initialTabId is not valid", () => {
const { container } = render(getComponent({ initialTabId: "bad-tab-id" }));
expect(getActiveTab(container).textContent).toEqual(generalTab.label);
expect(getActiveTabBody(container).textContent).toEqual("general");
expect(getActiveTab(container)?.textContent).toEqual(generalTab.label);
expect(getActiveTabBody(container)?.textContent).toEqual("general");
});
it("renders initialTabId tab as active when valid", () => {
const { container } = render(getComponent({ initialTabId: securityTab.id }));
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
expect(getActiveTabBody(container).textContent).toEqual("security");
expect(getActiveTab(container)?.textContent).toEqual(securityTab.label);
expect(getActiveTabBody(container)?.textContent).toEqual("security");
});
it("renders without error when there are no tabs", () => {
@ -71,8 +71,8 @@ describe("<TabbedView />", () => {
fireEvent.click(getByTestId(getTabTestId(securityTab)));
});
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
expect(getActiveTabBody(container).textContent).toEqual("security");
expect(getActiveTab(container)?.textContent).toEqual(securityTab.label);
expect(getActiveTabBody(container)?.textContent).toEqual("security");
});
it("calls onchange on on tab click", () => {
@ -90,29 +90,29 @@ describe("<TabbedView />", () => {
// start with middle tab active
const { container, rerender } = render(getComponent({ initialTabId: labsTab.id }));
expect(getActiveTab(container).textContent).toEqual(labsTab.label);
expect(getActiveTab(container)?.textContent).toEqual(labsTab.label);
rerender(getComponent({ tabs: [labsTab, generalTab, securityTab] }));
// labs tab still active
expect(getActiveTab(container).textContent).toEqual(labsTab.label);
expect(getActiveTab(container)?.textContent).toEqual(labsTab.label);
});
it("does not reactivate inititalTabId on rerender", () => {
const { container, getByTestId, rerender } = render(getComponent());
expect(getActiveTab(container).textContent).toEqual(generalTab.label);
expect(getActiveTab(container)?.textContent).toEqual(generalTab.label);
// make security tab active
act(() => {
fireEvent.click(getByTestId(getTabTestId(securityTab)));
});
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
expect(getActiveTab(container)?.textContent).toEqual(securityTab.label);
// rerender with new tab location
rerender(getComponent({ tabLocation: TabLocation.TOP }));
// still security tab
expect(getActiveTab(container).textContent).toEqual(securityTab.label);
expect(getActiveTab(container)?.textContent).toEqual(securityTab.label);
});
});

View file

@ -101,7 +101,7 @@ describe("<BeaconViewDialog />", () => {
it("renders a map with markers", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
expect(component.find("Map").props()).toEqual(
@ -116,7 +116,7 @@ describe("<BeaconViewDialog />", () => {
it("does not render any own beacon status when user is not live sharing", () => {
// default event belongs to alice, we are bob
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
expect(component.find("DialogOwnBeaconStatus").html()).toBeNull();
@ -125,7 +125,7 @@ describe("<BeaconViewDialog />", () => {
it("renders own beacon status when user is live sharing", () => {
// default event belongs to alice
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
// mock own beacon store to show default event as alice's live beacon
jest.spyOn(OwnBeaconStore.instance, "getLiveBeaconIds").mockReturnValue([beacon.identifier]);
@ -141,7 +141,7 @@ describe("<BeaconViewDialog />", () => {
it("updates markers on changes to beacons", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
expect(component.find("BeaconMarker").length).toEqual(1);
@ -161,7 +161,7 @@ describe("<BeaconViewDialog />", () => {
it("does not update bounds or center on changing beacons", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
expect(component.find("BeaconMarker").length).toEqual(1);
@ -200,7 +200,7 @@ describe("<BeaconViewDialog />", () => {
it("renders map without markers when no live beacons remain", () => {
const onFinished = jest.fn();
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent({ onFinished });
expect(component.find("BeaconMarker").length).toEqual(1);
@ -233,7 +233,7 @@ describe("<BeaconViewDialog />", () => {
describe("sidebar", () => {
it("opens sidebar on view list button click", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();
@ -244,7 +244,7 @@ describe("<BeaconViewDialog />", () => {
it("closes sidebar on close button click", () => {
const room = setupRoom([defaultEvent]);
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent))!;
beacon.addLocations([location1]);
const component = getComponent();

View file

@ -76,9 +76,9 @@ describe("InviteDialog", () => {
});
it("should label with space name", () => {
mockClient.getRoom(roomId).isSpaceRoom = jest.fn().mockReturnValue(true);
mockClient.getRoom(roomId).getType = jest.fn().mockReturnValue(RoomType.Space);
mockClient.getRoom(roomId).name = "Space";
mockClient.getRoom(roomId)!.isSpaceRoom = jest.fn().mockReturnValue(true);
mockClient.getRoom(roomId)!.getType = jest.fn().mockReturnValue(RoomType.Space);
mockClient.getRoom(roomId)!.name = "Space";
render(<InviteDialog kind={KIND_INVITE} roomId={roomId} onFinished={jest.fn()} />);
expect(screen.queryByText("Invite to Space")).toBeTruthy();

View file

@ -80,7 +80,10 @@ describe("<MBeaconBody />", () => {
wrappingComponentProps: { value: mockClient },
});
const modalSpy = jest.spyOn(Modal, "createDialog").mockReturnValue(undefined);
const modalSpy = jest.spyOn(Modal, "createDialog").mockReturnValue({
finished: Promise.resolve([true]),
close: () => {},
});
beforeEach(() => {
jest.clearAllMocks();
@ -169,7 +172,7 @@ describe("<MBeaconBody />", () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo1], { roomId, mockClient });
const component = getComponent({ mxEvent: aliceBeaconInfo1 });
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo1));
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo1))!;
// update alice's beacon with a new edition
// beacon instance emits
act(() => {
@ -190,7 +193,7 @@ describe("<MBeaconBody />", () => {
const aliceBeaconInfo = makeBeaconInfoEvent(aliceId, roomId, { isLive: true }, "$alice-room1-1");
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
const component = getComponent({ mxEvent: aliceBeaconInfo });
act(() => {
@ -240,7 +243,7 @@ describe("<MBeaconBody />", () => {
it("renders a live beacon with a location correctly", () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
beaconInstance.addLocations([location1]);
const component = getComponent({ mxEvent: aliceBeaconInfo });
@ -249,7 +252,7 @@ describe("<MBeaconBody />", () => {
it("opens maximised map view on click when beacon has a live location", () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
beaconInstance.addLocations([location1]);
const component = getComponent({ mxEvent: aliceBeaconInfo });
@ -274,7 +277,7 @@ describe("<MBeaconBody />", () => {
it("renders a live beacon with a location correctly", () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
beaconInstance.addLocations([location1]);
const component = getComponent({ mxEvent: aliceBeaconInfo });
@ -283,7 +286,7 @@ describe("<MBeaconBody />", () => {
it("opens maximised map view on click when beacon has a live location", () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
beaconInstance.addLocations([location1]);
const component = getComponent({ mxEvent: aliceBeaconInfo });
@ -299,7 +302,7 @@ describe("<MBeaconBody />", () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo], { roomId, mockClient });
const component = getComponent({ mxEvent: aliceBeaconInfo });
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo))!;
act(() => {
beaconInstance.addLocations([location1]);
component.setProps({});
@ -345,7 +348,7 @@ describe("<MBeaconBody />", () => {
const setupRoomWithBeacon = (beaconInfoEvent: MatrixEvent, locationEvents: MatrixEvent[] = []) => {
const room = makeRoomWithStateEvents([beaconInfoEvent], { roomId, mockClient });
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(beaconInfoEvent));
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(beaconInfoEvent))!;
beaconInstance.addLocations(locationEvents);
};
const mockGetRelationsForEvent = (locationEvents: MatrixEvent[] = []) => {

View file

@ -69,7 +69,7 @@ describe("<MImageBody/>", () => {
const props = {
onHeightChanged: jest.fn(),
onMessageAllowed: jest.fn(),
permalinkCreator: new RoomPermalinkCreator(new Room(encryptedMediaEvent.getRoomId(), cli, cli.getUserId())),
permalinkCreator: new RoomPermalinkCreator(new Room(encryptedMediaEvent.getRoomId()!, cli, cli.getUserId()!)),
};
it("should show error when encrypted media cannot be downloaded", async () => {

View file

@ -83,7 +83,7 @@ describe("<PinnedMessagesCard />", () => {
};
const mountPins = async (room: Room): Promise<ReactWrapper<ComponentProps<typeof PinnedMessagesCard>>> => {
let pins: ReactWrapper<ComponentProps<typeof PinnedMessagesCard>>;
let pins!: ReactWrapper<ComponentProps<typeof PinnedMessagesCard>>;
await act(async () => {
pins = mount(
<PinnedMessagesCard

View file

@ -53,7 +53,7 @@ describe("NewRoomIntro", () => {
describe("for a DM Room", () => {
beforeEach(() => {
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(userId);
const room = new Room(roomId, client, client.getUserId());
const room = new Room(roomId, client, client.getUserId()!);
room.name = "test_room";
renderNewRoomIntro(client, room);
});
@ -67,7 +67,7 @@ describe("NewRoomIntro", () => {
describe("for a DM LocalRoom", () => {
beforeEach(() => {
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(userId);
const localRoom = new LocalRoom(roomId, client, client.getUserId());
const localRoom = new LocalRoom(roomId, client, client.getUserId()!);
localRoom.name = "test_room";
localRoom.targets.push(new DirectoryMember({ user_id: userId }));
renderNewRoomIntro(client, localRoom);

View file

@ -61,7 +61,7 @@ const setupMainMenu = async (client: MatrixClient, testSpace: Room): Promise<Ren
expect(wrapper.container.textContent).toBe("Test Space");
act(() => {
wrapper.container.querySelector<HTMLElement>('[aria-label="Test Space menu"]').click();
wrapper.container.querySelector<HTMLElement>('[aria-label="Test Space menu"]')?.click();
});
return wrapper;
@ -77,7 +77,7 @@ const setupPlusMenu = async (client: MatrixClient, testSpace: Room): Promise<Ren
expect(wrapper.container.textContent).toBe("Test Space");
act(() => {
wrapper.container.querySelector<HTMLElement>('[aria-label="Add"]').click();
wrapper.container.querySelector<HTMLElement>('[aria-label="Add"]')?.click();
});
return wrapper;
@ -92,7 +92,7 @@ const checkMenuLabels = (items: NodeListOf<Element>, labelArray: Array<string>)
expect(items).toHaveLength(labelArray.length);
const checkLabel = (item: Element, label: string) => {
expect(item.querySelector(".mx_IconizedContextMenu_label").textContent).toBe(label);
expect(item.querySelector(".mx_IconizedContextMenu_label")?.textContent).toBe(label);
};
labelArray.forEach((label, index) => {

View file

@ -84,9 +84,9 @@ describe("<RoomPreviewBar />", () => {
const getActions = (wrapper: RenderResult) =>
wrapper.container.querySelector<HTMLDivElement>(".mx_RoomPreviewBar_actions");
const getPrimaryActionButton = (wrapper: RenderResult) =>
getActions(wrapper).querySelector(".mx_AccessibleButton_kind_primary");
getActions(wrapper)?.querySelector(".mx_AccessibleButton_kind_primary");
const getSecondaryActionButton = (wrapper: RenderResult) =>
getActions(wrapper).querySelector(".mx_AccessibleButton_kind_secondary");
getActions(wrapper)?.querySelector(".mx_AccessibleButton_kind_secondary");
beforeEach(() => {
stubClient();
@ -102,17 +102,17 @@ describe("<RoomPreviewBar />", () => {
const component = getComponent({ joining: true });
expect(isSpinnerRendered(component)).toBeTruthy();
expect(getMessage(component).textContent).toEqual("Joining …");
expect(getMessage(component)?.textContent).toEqual("Joining …");
});
it("renders rejecting message", () => {
const component = getComponent({ rejecting: true });
expect(isSpinnerRendered(component)).toBeTruthy();
expect(getMessage(component).textContent).toEqual("Rejecting invite …");
expect(getMessage(component)?.textContent).toEqual("Rejecting invite …");
});
it("renders loading message", () => {
const component = getComponent({ loading: true });
expect(isSpinnerRendered(component)).toBeTruthy();
expect(getMessage(component).textContent).toEqual("Loading …");
expect(getMessage(component)?.textContent).toEqual("Loading …");
});
it("renders not logged in message", () => {
@ -120,7 +120,7 @@ describe("<RoomPreviewBar />", () => {
const component = getComponent({ loading: true });
expect(isSpinnerRendered(component)).toBeFalsy();
expect(getMessage(component).textContent).toEqual("Join the conversation with an account");
expect(getMessage(component)?.textContent).toEqual("Join the conversation with an account");
});
it("should send room oob data to start login", async () => {
@ -136,8 +136,8 @@ describe("<RoomPreviewBar />", () => {
const dispatcherSpy = jest.fn();
const dispatcherRef = defaultDispatcher.register(dispatcherSpy);
expect(getMessage(component).textContent).toEqual("Join the conversation with an account");
fireEvent.click(getPrimaryActionButton(component));
expect(getMessage(component)?.textContent).toEqual("Join the conversation with an account");
fireEvent.click(getPrimaryActionButton(component)!);
await waitFor(() =>
expect(dispatcherSpy).toHaveBeenCalledWith(
@ -268,14 +268,14 @@ describe("<RoomPreviewBar />", () => {
it("joins room on primary button click", () => {
const component = getComponent({ inviterName, room, onJoinClick, onRejectClick });
fireEvent.click(getPrimaryActionButton(component));
fireEvent.click(getPrimaryActionButton(component)!);
expect(onJoinClick).toHaveBeenCalled();
});
it("rejects invite on secondary button click", () => {
const component = getComponent({ inviterName, room, onJoinClick, onRejectClick });
fireEvent.click(getSecondaryActionButton(component));
fireEvent.click(getSecondaryActionButton(component)!);
expect(onRejectClick).toHaveBeenCalled();
});
@ -331,7 +331,7 @@ describe("<RoomPreviewBar />", () => {
await new Promise(setImmediate);
expect(getPrimaryActionButton(component)).toBeTruthy();
expect(getSecondaryActionButton(component)).toBeFalsy();
fireEvent.click(getPrimaryActionButton(component));
fireEvent.click(getPrimaryActionButton(component)!);
expect(onJoinClick).toHaveBeenCalled();
};

View file

@ -39,11 +39,11 @@ describe("RolesRoomSettingsTab", () => {
};
const getVoiceBroadcastsSelect = (): HTMLElement => {
return renderTab().container.querySelector("select[label='Voice broadcasts']");
return renderTab().container.querySelector("select[label='Voice broadcasts']")!;
};
const getVoiceBroadcastsSelectedOption = (): HTMLElement => {
return renderTab().container.querySelector("select[label='Voice broadcasts'] option:checked");
return renderTab().container.querySelector("select[label='Voice broadcasts'] option:checked")!;
};
beforeEach(() => {
@ -65,7 +65,7 @@ describe("RolesRoomSettingsTab", () => {
state_key: "",
content: {
users: {
[cli.getUserId()]: 100,
[cli.getUserId()!]: 100,
"@admin:server": 100,
},
},
@ -108,19 +108,19 @@ describe("RolesRoomSettingsTab", () => {
};
const getStartCallSelect = (tab: RenderResult): HTMLElement => {
return tab.container.querySelector("select[label='Start Element Call calls']");
return tab.container.querySelector("select[label='Start Element Call calls']")!;
};
const getStartCallSelectedOption = (tab: RenderResult): HTMLElement => {
return tab.container.querySelector("select[label='Start Element Call calls'] option:checked");
return tab.container.querySelector("select[label='Start Element Call calls'] option:checked")!;
};
const getJoinCallSelect = (tab: RenderResult): HTMLElement => {
return tab.container.querySelector("select[label='Join Element Call calls']");
return tab.container.querySelector("select[label='Join Element Call calls']")!;
};
const getJoinCallSelectedOption = (tab: RenderResult): HTMLElement => {
return tab.container.querySelector("select[label='Join Element Call calls'] option:checked");
return tab.container.querySelector("select[label='Join Element Call calls'] option:checked")!;
};
describe("Element Call enabled", () => {