Device manager - current session context menu (#9386)
* add destructive option and close on interaction options * add kebab context menu wrapper * use kebab context menu in current device section * use named export * lint * sessionman tests
This commit is contained in:
parent
8b54be6f48
commit
776ffa4764
14 changed files with 468 additions and 108 deletions
|
@ -285,47 +285,6 @@ describe('<SessionManagerTab />', () => {
|
|||
expect(queryByTestId('device-detail-metadata-application')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('renders current session section with an unverified session', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
|
||||
const { getByTestId } = render(getComponent());
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
expect(getByTestId('current-session-section')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('opens encryption setup dialog when verifiying current session', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
|
||||
const { getByTestId } = render(getComponent());
|
||||
const modalSpy = jest.spyOn(Modal, 'createDialog');
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
// click verify button from current session section
|
||||
fireEvent.click(getByTestId(`verification-status-button-${alicesDevice.device_id}`));
|
||||
|
||||
expect(modalSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders current session section with a verified session', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
|
||||
mockClient.getStoredDevice.mockImplementation(() => new DeviceInfo(alicesDevice.device_id));
|
||||
mockCrossSigningInfo.checkDeviceTrust
|
||||
.mockReturnValue(new DeviceTrustLevel(true, true, false, false));
|
||||
|
||||
const { getByTestId } = render(getComponent());
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
expect(getByTestId('current-session-section')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('does not render other sessions section when user has only one device', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice] });
|
||||
const { queryByTestId } = render(getComponent());
|
||||
|
@ -367,6 +326,64 @@ describe('<SessionManagerTab />', () => {
|
|||
expect(container.querySelector('.mx_FilteredDeviceListHeader')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('current session section', () => {
|
||||
it('disables current session context menu while devices are loading', () => {
|
||||
const { getByTestId } = render(getComponent());
|
||||
expect(getByTestId('current-session-menu').getAttribute('aria-disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('disables current session context menu when there is no current device', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [] });
|
||||
const { getByTestId } = render(getComponent());
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
expect(getByTestId('current-session-menu').getAttribute('aria-disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('renders current session section with an unverified session', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
|
||||
const { getByTestId } = render(getComponent());
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
expect(getByTestId('current-session-section')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('opens encryption setup dialog when verifiying current session', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
|
||||
const { getByTestId } = render(getComponent());
|
||||
const modalSpy = jest.spyOn(Modal, 'createDialog');
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
// click verify button from current session section
|
||||
fireEvent.click(getByTestId(`verification-status-button-${alicesDevice.device_id}`));
|
||||
|
||||
expect(modalSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders current session section with a verified session', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
|
||||
mockClient.getStoredDevice.mockImplementation(() => new DeviceInfo(alicesDevice.device_id));
|
||||
mockCrossSigningInfo.checkDeviceTrust
|
||||
.mockReturnValue(new DeviceTrustLevel(true, true, false, false));
|
||||
|
||||
const { getByTestId } = render(getComponent());
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
expect(getByTestId('current-session-section')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('device detail expansion', () => {
|
||||
it('renders no devices expanded by default', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({
|
||||
|
@ -520,6 +537,53 @@ describe('<SessionManagerTab />', () => {
|
|||
expect(modalSpy).toHaveBeenCalledWith(LogoutDialog, {}, undefined, false, true);
|
||||
});
|
||||
|
||||
it('Signs out of current device from kebab menu', async () => {
|
||||
const modalSpy = jest.spyOn(Modal, 'createDialog');
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice] });
|
||||
const { getByTestId, getByLabelText } = render(getComponent());
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
fireEvent.click(getByTestId('current-session-menu'));
|
||||
fireEvent.click(getByLabelText('Sign out'));
|
||||
|
||||
// logout dialog opened
|
||||
expect(modalSpy).toHaveBeenCalledWith(LogoutDialog, {}, undefined, false, true);
|
||||
});
|
||||
|
||||
it('does not render sign out other devices option when only one device', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [alicesDevice] });
|
||||
const { getByTestId, queryByLabelText } = render(getComponent());
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
fireEvent.click(getByTestId('current-session-menu'));
|
||||
expect(queryByLabelText('Sign out all other sessions')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('signs out of all other devices from current session context menu', async () => {
|
||||
mockClient.getDevices.mockResolvedValue({ devices: [
|
||||
alicesDevice, alicesMobileDevice, alicesOlderMobileDevice,
|
||||
] });
|
||||
const { getByTestId, getByLabelText } = render(getComponent());
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
fireEvent.click(getByTestId('current-session-menu'));
|
||||
fireEvent.click(getByLabelText('Sign out all other sessions'));
|
||||
|
||||
// other devices deleted, excluding current device
|
||||
expect(mockClient.deleteMultipleDevices).toHaveBeenCalledWith([
|
||||
alicesMobileDevice.device_id, alicesOlderMobileDevice.device_id,
|
||||
], undefined);
|
||||
});
|
||||
|
||||
describe('other devices', () => {
|
||||
const interactiveAuthError = { httpStatus: 401, data: { flows: [{ stages: ["m.login.password"] }] } };
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue