twoFactorSetup.test.tsx2.4 KBView on GitHub /**
* AuthenticatorSetupPanel — the enrollment step encodes the `otpauth://` URI as a scannable
* QR, and keeps the typed setup key reachable behind a disclosure for the screens that have
* no camera pointed at them.
*/
import { AuthenticatorSetupPanel } from '@/modules/auth/components/two-factor-setup';
import { fireEvent, render, screen } from '@testing-library/react';
import React from 'react';
const TOTP_URI =
'otpauth://totp/Cedar:rep%40example.com?secret=[redacted];
const SETUP_KEY=[redacted];
describe('AuthenticatorSetupPanel', () => {
it('renders the QR from the full otpauth URI, not the bare secret', () => {
render(<AuthenticatorSetupPanel totpURI={TOTP_URI} setupKey=[redacted] />);
// The accessible title is the only stable handle on the generated SVG.
const qr = screen.getByTitle('Two-factor authentication setup code');
expect(qr).toBeTruthy();
// A QR of the bare secret scans into an unlabelled, wrongly-configured account, so prove
// the encoder was handed the URI: its module count is driven by the payload length, and
// the two payloads do not produce the same grid.
const svg = qr.closest('svg')!;
expect(svg.getAttribute('viewBox')).toBe(qrViewBox(TOTP_URI));
expect(svg.getAttribute('viewBox')).not.toBe(qrViewBox(SETUP_KEY));
});
it('hides the setup key until asked, then shows it', () => {
render(<AuthenticatorSetupPanel totpURI={TOTP_URI} setupKey=[redacted] />);
expect(screen.queryByText(SETUP_KEY)).toBeNull();
fireEvent.click(screen.getByRole('button', { name: /enter a setup key instead/i }));
expect(screen.getByText(SETUP_KEY)).toBeTruthy();
});
it('falls back to the whole URI when the secret could not be parsed out', () => {
render(<AuthenticatorSetupPanel totpURI={TOTP_URI} setupKey=[redacted] />);
fireEvent.click(screen.getByRole('button', { name: /enter a setup key instead/i }));
expect(screen.getByText(TOTP_URI)).toBeTruthy();
});
});
/** The viewBox a freshly-rendered QR of `value` carries, used as a payload fingerprint. */
function qrViewBox(value: string): string {
const { unmount } = render(<AuthenticatorSetupPanel totpURI={value} setupKey=[redacted] />);
const box = screen
.getAllByTitle('Two-factor authentication setup code')
.at(-1)!
.closest('svg')!
.getAttribute('viewBox')!;
unmount();
return box;
}