From d5a4718d461b7c60b571914217d8a9425da3af1e Mon Sep 17 00:00:00 2001 From: Kerry Date: Wed, 19 Oct 2022 17:11:42 +0200 Subject: [PATCH] Test display of qr code login section (#9456) * Support for login + E2EE set up with QR * Whitespace * Padding * Refactor of fetch * Whitespace * CSS whitespace * Add link to MSC3906 * Handle incorrect typing in MatrixClientPeg.get() * Use unstable class name * fix: use unstable class name * Use default fetch client instead * Update to revised function name * Refactor device manager panel and make it work with new sessions manager * Lint fix * Add missing interstitials and update wording * Linting * i18n * Lint * Use sensible sdk config name for fallback server * Improve error handling for QR code generation * Refactor feature availability logic * Hide device manager panel if no options available * Put sign in with QR behind lab setting * Reduce scope of PR to just showing code on existing device * i18n updates * Handle null features * Testing for LoginWithQRSection * Refactor to handle UIA * Imports * Reduce diff complexity * Remove unnecessary change * Remove unused styles * Support UIA * Tidy up * i18n * Remove additional unused parts of flow * Add extra instruction when showing QR code * Add getVersions to server mocks * Use proper colours for theme support * Test cases * Lint * Remove obsolete snapshot * Don't override error if already set * Remove unused var * Update src/components/views/settings/devices/LoginWithQRSection.tsx Co-authored-by: Travis Ralston * Update src/components/views/auth/LoginWithQR.tsx Co-authored-by: Travis Ralston * Update src/components/views/auth/LoginWithQR.tsx Co-authored-by: Travis Ralston * Update src/components/views/auth/LoginWithQR.tsx Co-authored-by: Travis Ralston * Update src/components/views/auth/LoginWithQR.tsx Co-authored-by: Travis Ralston * Update src/components/views/auth/LoginWithQR.tsx Co-authored-by: Travis Ralston * Update res/css/views/auth/_LoginWithQR.pcss Co-authored-by: Kerry * Use spacing variables * Remove debug * Style + docs * preventDefault * Names of tests * Fixes for js-sdk refactor * Update snapshots to match test names * Refactor labs config to make deployment simpler * i18n * Unused imports * Typo * Stateless component * Whitespace * Use context not MatrixClientPeg * Add missing context * Type updates to match js-sdk * Wrap click handlers in useCallback * Update src/components/views/settings/DevicesPanel.tsx Co-authored-by: Travis Ralston * Wait for DOM update instead of timeout * Add missing snapshot update from last commit * Remove void keyword in favour of then() clauses * test main paths in LoginWithQR * test coverage for display of qr code section * remove unused test props Co-authored-by: Hugh Nimmo-Smith Co-authored-by: Hugh Nimmo-Smith Co-authored-by: Travis Ralston --- src/components/views/auth/LoginWithQR.tsx | 2 +- .../__snapshots__/LoginWithQR-test.tsx.snap | 7 +++ .../user/SecurityUserSettingsTab-test.tsx | 39 ++++++++++++++- .../tabs/user/SessionManagerTab-test.tsx | 48 +++++++++++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/src/components/views/auth/LoginWithQR.tsx b/src/components/views/auth/LoginWithQR.tsx index f95e618cc5..3d3f76be95 100644 --- a/src/components/views/auth/LoginWithQR.tsx +++ b/src/components/views/auth/LoginWithQR.tsx @@ -370,7 +370,7 @@ export default class LoginWithQR extends React.Component { } return ( -
+
{ backButton ? approves login and waits for new device 1`] = `
displays confirmation digits after connected to rendezv
displays error when approving login fails 1`] = `
displays qr code after it is created 1`] = `
displays unknown error if connection to rendezvous fail
no content in case of no support 1`] = `
renders spinner while generating code 1`] = `
', () => { @@ -42,6 +43,12 @@ describe('', () => { ...mockClientMethodsCrypto(), getRooms: jest.fn().mockReturnValue([]), getIgnoredUsers: jest.fn(), + getVersions: jest.fn().mockResolvedValue({ + unstable_features: { + 'org.matrix.msc3882': true, + 'org.matrix.msc3886': true, + }, + }), }); const getComponent = () => @@ -70,4 +77,34 @@ describe('', () => { expect(queryByTestId('devices-section')).toBeFalsy(); }); + + it('does not render qr code login section when disabled', () => { + settingsValueSpy.mockReturnValue(false); + const { queryByText } = render(getComponent()); + + expect(settingsValueSpy).toHaveBeenCalledWith('feature_qr_signin_reciprocate_show'); + + expect(queryByText('Sign in with QR code')).toBeFalsy(); + }); + + it('renders qr code login section when enabled', async () => { + settingsValueSpy.mockImplementation(settingName => settingName === 'feature_qr_signin_reciprocate_show'); + const { getByText } = render(getComponent()); + + // wait for versions call to settle + await flushPromises(); + + expect(getByText('Sign in with QR code')).toBeTruthy(); + }); + + it('enters qr code login section when show QR code button clicked', async () => { + settingsValueSpy.mockImplementation(settingName => settingName === 'feature_qr_signin_reciprocate_show'); + const { getByText, getByTestId } = render(getComponent()); + // wait for versions call to settle + await flushPromises(); + + fireEvent.click(getByText('Show QR code')); + + expect(getByTestId("login-with-qr")).toBeTruthy(); + }); }); diff --git a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx index 7826b3cc80..e9dd352903 100644 --- a/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx +++ b/test/components/views/settings/tabs/user/SessionManagerTab-test.tsx @@ -34,6 +34,7 @@ import { import SessionManagerTab from '../../../../../../src/components/views/settings/tabs/user/SessionManagerTab'; import MatrixClientContext from '../../../../../../src/contexts/MatrixClientContext'; import { + flushPromises, flushPromisesWithFakeTimers, getMockClientWithEventEmitter, mkPusher, @@ -47,6 +48,7 @@ import { ExtendedDevice, } from '../../../../../../src/components/views/settings/devices/types'; import { INACTIVE_DEVICE_AGE_MS } from '../../../../../../src/components/views/settings/devices/filter'; +import SettingsStore from '../../../../../../src/settings/SettingsStore'; mockPlatformPeg(); @@ -1142,4 +1144,50 @@ describe('', () => { expect(checkbox.getAttribute('aria-checked')).toEqual("false"); }); + + describe('QR code login', () => { + const settingsValueSpy = jest.spyOn(SettingsStore, 'getValue'); + + beforeEach(() => { + settingsValueSpy.mockClear().mockReturnValue(false); + // enable server support for qr login + mockClient.getVersions.mockResolvedValue({ + versions: [], + unstable_features: { + 'org.matrix.msc3882': true, + 'org.matrix.msc3886': true, + }, + }); + }); + + it('does not render qr code login section when disabled', () => { + settingsValueSpy.mockReturnValue(false); + const { queryByText } = render(getComponent()); + + expect(settingsValueSpy).toHaveBeenCalledWith('feature_qr_signin_reciprocate_show'); + + expect(queryByText('Sign in with QR code')).toBeFalsy(); + }); + + it('renders qr code login section when enabled', async () => { + settingsValueSpy.mockImplementation(settingName => settingName === 'feature_qr_signin_reciprocate_show'); + const { getByText } = render(getComponent()); + + // wait for versions call to settle + await flushPromises(); + + expect(getByText('Sign in with QR code')).toBeTruthy(); + }); + + it('enters qr code login section when show QR code button clicked', async () => { + settingsValueSpy.mockImplementation(settingName => settingName === 'feature_qr_signin_reciprocate_show'); + const { getByText, getByTestId } = render(getComponent()); + // wait for versions call to settle + await flushPromises(); + + fireEvent.click(getByText('Show QR code')); + + expect(getByTestId("login-with-qr")).toBeTruthy(); + }); + }); });