Implement push notification toggle in device detail (#9308)
Co-authored-by: Travis Ralston <travisr@matrix.org>
This commit is contained in:
parent
ace6591f43
commit
641cf28e4c
13 changed files with 269 additions and 3 deletions
|
@ -19,11 +19,13 @@ import { act } from 'react-dom/test-utils';
|
|||
import { CrossSigningInfo } from 'matrix-js-sdk/src/crypto/CrossSigning';
|
||||
import { DeviceInfo } from 'matrix-js-sdk/src/crypto/deviceinfo';
|
||||
import { sleep } from 'matrix-js-sdk/src/utils';
|
||||
import { PUSHER_DEVICE_ID, PUSHER_ENABLED } from 'matrix-js-sdk/src/@types/event';
|
||||
|
||||
import DevicesPanel from "../../../../src/components/views/settings/DevicesPanel";
|
||||
import {
|
||||
flushPromises,
|
||||
getMockClientWithEventEmitter,
|
||||
mkPusher,
|
||||
mockClientMethodsUser,
|
||||
} from "../../../test-utils";
|
||||
|
||||
|
@ -40,6 +42,8 @@ describe('<DevicesPanel />', () => {
|
|||
getStoredCrossSigningForUser: jest.fn().mockReturnValue(new CrossSigningInfo(userId, {}, {})),
|
||||
getStoredDevice: jest.fn().mockReturnValue(new DeviceInfo('id')),
|
||||
generateClientSecret: jest.fn(),
|
||||
getPushers: jest.fn(),
|
||||
setPusher: jest.fn(),
|
||||
});
|
||||
|
||||
const getComponent = () => <DevicesPanel />;
|
||||
|
@ -50,6 +54,15 @@ describe('<DevicesPanel />', () => {
|
|||
mockClient.getDevices
|
||||
.mockReset()
|
||||
.mockResolvedValue({ devices: [device1, device2, device3] });
|
||||
|
||||
mockClient.getPushers
|
||||
.mockReset()
|
||||
.mockResolvedValue({
|
||||
pushers: [mkPusher({
|
||||
[PUSHER_DEVICE_ID.name]: device1.device_id,
|
||||
[PUSHER_ENABLED.name]: true,
|
||||
})],
|
||||
});
|
||||
});
|
||||
|
||||
it('renders device panel with devices', async () => {
|
||||
|
|
|
@ -40,6 +40,7 @@ describe('<CurrentDeviceSection />', () => {
|
|||
isLoading: false,
|
||||
isSigningOut: false,
|
||||
};
|
||||
|
||||
const getComponent = (props = {}): React.ReactElement =>
|
||||
(<CurrentDeviceSection {...defaultProps} {...props} />);
|
||||
|
||||
|
|
|
@ -15,9 +15,11 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { PUSHER_ENABLED } from 'matrix-js-sdk/src/@types/event';
|
||||
|
||||
import DeviceDetails from '../../../../../src/components/views/settings/devices/DeviceDetails';
|
||||
import { mkPusher } from '../../../../test-utils/test-utils';
|
||||
|
||||
describe('<DeviceDetails />', () => {
|
||||
const baseDevice = {
|
||||
|
@ -26,12 +28,17 @@ describe('<DeviceDetails />', () => {
|
|||
};
|
||||
const defaultProps = {
|
||||
device: baseDevice,
|
||||
pusher: null,
|
||||
isSigningOut: false,
|
||||
isLoading: false,
|
||||
onSignOutDevice: jest.fn(),
|
||||
saveDeviceName: jest.fn(),
|
||||
setPusherEnabled: jest.fn(),
|
||||
supportsMSC3881: true,
|
||||
};
|
||||
|
||||
const getComponent = (props = {}) => <DeviceDetails {...defaultProps} {...props} />;
|
||||
|
||||
// 14.03.2022 16:15
|
||||
const now = 1647270879403;
|
||||
jest.useFakeTimers();
|
||||
|
@ -74,4 +81,82 @@ describe('<DeviceDetails />', () => {
|
|||
getByTestId('device-detail-sign-out-cta').getAttribute('aria-disabled'),
|
||||
).toEqual("true");
|
||||
});
|
||||
|
||||
it('renders the push notification section when a pusher exists', () => {
|
||||
const device = {
|
||||
...baseDevice,
|
||||
};
|
||||
const pusher = mkPusher({
|
||||
device_id: device.device_id,
|
||||
});
|
||||
|
||||
const { getByTestId } = render(getComponent({
|
||||
device,
|
||||
pusher,
|
||||
isSigningOut: true,
|
||||
}));
|
||||
|
||||
expect(getByTestId('device-detail-push-notification')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('hides the push notification section when no pusher', () => {
|
||||
const device = {
|
||||
...baseDevice,
|
||||
};
|
||||
|
||||
const { getByTestId } = render(getComponent({
|
||||
device,
|
||||
pusher: null,
|
||||
isSigningOut: true,
|
||||
}));
|
||||
|
||||
expect(() => getByTestId('device-detail-push-notification')).toThrow();
|
||||
});
|
||||
|
||||
it('disables the checkbox when there is no server support', () => {
|
||||
const device = {
|
||||
...baseDevice,
|
||||
};
|
||||
const pusher = mkPusher({
|
||||
device_id: device.device_id,
|
||||
[PUSHER_ENABLED.name]: false,
|
||||
});
|
||||
|
||||
const { getByTestId } = render(getComponent({
|
||||
device,
|
||||
pusher,
|
||||
isSigningOut: true,
|
||||
supportsMSC3881: false,
|
||||
}));
|
||||
|
||||
const checkbox = getByTestId('device-detail-push-notification-checkbox');
|
||||
|
||||
expect(checkbox.getAttribute('aria-disabled')).toEqual("true");
|
||||
expect(checkbox.getAttribute('aria-checked')).toEqual("false");
|
||||
});
|
||||
|
||||
it('changes the pusher status when clicked', () => {
|
||||
const device = {
|
||||
...baseDevice,
|
||||
};
|
||||
|
||||
const enabled = false;
|
||||
|
||||
const pusher = mkPusher({
|
||||
device_id: device.device_id,
|
||||
[PUSHER_ENABLED.name]: enabled,
|
||||
});
|
||||
|
||||
const { getByTestId } = render(getComponent({
|
||||
device,
|
||||
pusher,
|
||||
isSigningOut: true,
|
||||
}));
|
||||
|
||||
const checkbox = getByTestId('device-detail-push-notification-checkbox');
|
||||
|
||||
fireEvent.click(checkbox);
|
||||
|
||||
expect(defaultProps.setPusherEnabled).toHaveBeenCalledWith(device.device_id, !enabled);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -45,6 +45,7 @@ describe('<FilteredDeviceList />', () => {
|
|||
onDeviceExpandToggle: jest.fn(),
|
||||
onSignOutDevices: jest.fn(),
|
||||
saveDeviceName: jest.fn(),
|
||||
setPusherEnabled: jest.fn(),
|
||||
expandedDeviceIds: [],
|
||||
signingOutDeviceIds: [],
|
||||
devices: {
|
||||
|
@ -54,7 +55,10 @@ describe('<FilteredDeviceList />', () => {
|
|||
[hundredDaysOld.device_id]: hundredDaysOld,
|
||||
[hundredDaysOldUnverified.device_id]: hundredDaysOldUnverified,
|
||||
},
|
||||
pushers: [],
|
||||
supportsMSC3881: true,
|
||||
};
|
||||
|
||||
const getComponent = (props = {}) =>
|
||||
(<FilteredDeviceList {...defaultProps} {...props} />);
|
||||
|
||||
|
|
|
@ -22,13 +22,14 @@ import { logger } from 'matrix-js-sdk/src/logger';
|
|||
import { DeviceTrustLevel } from 'matrix-js-sdk/src/crypto/CrossSigning';
|
||||
import { VerificationRequest } from 'matrix-js-sdk/src/crypto/verification/request/VerificationRequest';
|
||||
import { sleep } from 'matrix-js-sdk/src/utils';
|
||||
import { IMyDevice } from 'matrix-js-sdk/src/matrix';
|
||||
import { IMyDevice, PUSHER_DEVICE_ID, PUSHER_ENABLED } from 'matrix-js-sdk/src/matrix';
|
||||
|
||||
import SessionManagerTab from '../../../../../../src/components/views/settings/tabs/user/SessionManagerTab';
|
||||
import MatrixClientContext from '../../../../../../src/contexts/MatrixClientContext';
|
||||
import {
|
||||
flushPromisesWithFakeTimers,
|
||||
getMockClientWithEventEmitter,
|
||||
mkPusher,
|
||||
mockClientMethodsUser,
|
||||
} from '../../../../../test-utils';
|
||||
import Modal from '../../../../../../src/Modal';
|
||||
|
@ -67,6 +68,9 @@ describe('<SessionManagerTab />', () => {
|
|||
deleteMultipleDevices: jest.fn(),
|
||||
generateClientSecret: jest.fn(),
|
||||
setDeviceDetails: jest.fn(),
|
||||
doesServerSupportUnstableFeature: jest.fn().mockResolvedValue(true),
|
||||
getPushers: jest.fn(),
|
||||
setPusher: jest.fn(),
|
||||
});
|
||||
|
||||
const defaultProps = {};
|
||||
|
@ -101,6 +105,15 @@ describe('<SessionManagerTab />', () => {
|
|||
mockClient.getDevices
|
||||
.mockReset()
|
||||
.mockResolvedValue({ devices: [alicesDevice, alicesMobileDevice] });
|
||||
|
||||
mockClient.getPushers
|
||||
.mockReset()
|
||||
.mockResolvedValue({
|
||||
pushers: [mkPusher({
|
||||
[PUSHER_DEVICE_ID.name]: alicesMobileDevice.device_id,
|
||||
[PUSHER_ENABLED.name]: true,
|
||||
})],
|
||||
});
|
||||
});
|
||||
|
||||
it('renders spinner while devices load', () => {
|
||||
|
@ -668,4 +681,25 @@ describe('<SessionManagerTab />', () => {
|
|||
expect(getByTestId('device-rename-error')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it("lets you change the pusher state", async () => {
|
||||
const { getByTestId } = render(getComponent());
|
||||
|
||||
await act(async () => {
|
||||
await flushPromisesWithFakeTimers();
|
||||
});
|
||||
|
||||
toggleDeviceDetails(getByTestId, alicesMobileDevice.device_id);
|
||||
|
||||
// device details are expanded
|
||||
expect(getByTestId(`device-detail-${alicesMobileDevice.device_id}`)).toBeTruthy();
|
||||
expect(getByTestId('device-detail-push-notification')).toBeTruthy();
|
||||
|
||||
const checkbox = getByTestId('device-detail-push-notification-checkbox');
|
||||
|
||||
expect(checkbox).toBeTruthy();
|
||||
fireEvent.click(checkbox);
|
||||
|
||||
expect(mockClient.setPusher).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -30,6 +30,7 @@ import {
|
|||
EventType,
|
||||
IEventRelation,
|
||||
IUnsigned,
|
||||
IPusher,
|
||||
} from 'matrix-js-sdk/src/matrix';
|
||||
import { normalize } from "matrix-js-sdk/src/utils";
|
||||
import { ReEmitter } from "matrix-js-sdk/src/ReEmitter";
|
||||
|
@ -541,3 +542,14 @@ export const mkSpace = (
|
|||
)));
|
||||
return space;
|
||||
};
|
||||
|
||||
export const mkPusher = (extra: Partial<IPusher> = {}): IPusher => ({
|
||||
app_display_name: "app",
|
||||
app_id: "123",
|
||||
data: {},
|
||||
device_display_name: "name",
|
||||
kind: "http",
|
||||
lang: "en",
|
||||
pushkey: "pushpush",
|
||||
...extra,
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue