123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- import {AccountEmailsFixture} from 'sentry-fixture/accountEmails';
- import {
- AllAuthenticatorsFixture,
- AuthenticatorsFixture,
- } from 'sentry-fixture/authenticators';
- import {OrganizationsFixture} from 'sentry-fixture/organizations';
- import {initializeOrg} from 'sentry-test/initializeOrg';
- import {
- render,
- renderGlobalModal,
- screen,
- userEvent,
- } from 'sentry-test/reactTestingLibrary';
- import AccountSecurityDetails from 'sentry/views/settings/account/accountSecurity/accountSecurityDetails';
- import AccountSecurityWrapper from 'sentry/views/settings/account/accountSecurity/accountSecurityWrapper';
- const ENDPOINT = '/users/me/authenticators/';
- const ACCOUNT_EMAILS_ENDPOINT = '/users/me/emails/';
- const ORG_ENDPOINT = '/organizations/';
- describe('AccountSecurityDetails', function () {
- beforeEach(() => {
- MockApiClient.clearMockResponses();
- });
- describe('Totp', function () {
- beforeEach(function () {
- MockApiClient.addMockResponse({
- url: ENDPOINT,
- body: AllAuthenticatorsFixture(),
- });
- MockApiClient.addMockResponse({
- url: ORG_ENDPOINT,
- body: OrganizationsFixture(),
- });
- MockApiClient.addMockResponse({
- url: `${ENDPOINT}15/`,
- body: AuthenticatorsFixture().Totp(),
- });
- MockApiClient.addMockResponse({
- url: ACCOUNT_EMAILS_ENDPOINT,
- body: AccountEmailsFixture(),
- });
- });
- it('has enrolled circle indicator', async function () {
- const params = {
- authId: '15',
- };
- const {routerProps, routerContext} = initializeOrg({
- router: {
- params,
- },
- });
- render(
- <AccountSecurityWrapper {...routerProps}>
- <AccountSecurityDetails
- {...routerProps}
- onRegenerateBackupCodes={jest.fn()}
- deleteDisabled={false}
- />
- </AccountSecurityWrapper>,
- {context: routerContext}
- );
- expect(await screen.findByTestId('auth-status-enabled')).toBeInTheDocument();
- // has created and last used dates
- expect(screen.getByText('Created at')).toBeInTheDocument();
- expect(screen.getByText('Last used')).toBeInTheDocument();
- });
- it('can remove method', async function () {
- const deleteMock = MockApiClient.addMockResponse({
- url: `${ENDPOINT}15/`,
- method: 'DELETE',
- });
- const params = {
- authId: '15',
- };
- const {routerProps, routerContext} = initializeOrg({
- router: {
- params,
- },
- });
- render(
- <AccountSecurityWrapper {...routerProps}>
- <AccountSecurityDetails
- {...routerProps}
- onRegenerateBackupCodes={jest.fn()}
- deleteDisabled={false}
- />
- </AccountSecurityWrapper>,
- {context: routerContext}
- );
- await userEvent.click(await screen.findByRole('button', {name: 'Remove'}));
- renderGlobalModal();
- await userEvent.click(await screen.findByRole('button', {name: 'Confirm'}));
- expect(deleteMock).toHaveBeenCalled();
- });
- it('can remove one of multiple 2fa methods when org requires 2fa', async function () {
- MockApiClient.addMockResponse({
- url: ORG_ENDPOINT,
- body: OrganizationsFixture({require2FA: true}),
- });
- const deleteMock = MockApiClient.addMockResponse({
- url: `${ENDPOINT}15/`,
- method: 'DELETE',
- });
- const params = {
- authId: '15',
- };
- const {routerProps, routerContext} = initializeOrg({
- router: {
- params,
- },
- });
- render(
- <AccountSecurityWrapper {...routerProps}>
- <AccountSecurityDetails
- {...routerProps}
- onRegenerateBackupCodes={jest.fn()}
- deleteDisabled={false}
- />
- </AccountSecurityWrapper>,
- {context: routerContext}
- );
- await userEvent.click(await screen.findByRole('button', {name: 'Remove'}));
- renderGlobalModal();
- await userEvent.click(await screen.findByRole('button', {name: 'Confirm'}));
- expect(deleteMock).toHaveBeenCalled();
- });
- it('can not remove last 2fa method when org requires 2fa', async function () {
- MockApiClient.addMockResponse({
- url: ORG_ENDPOINT,
- body: OrganizationsFixture({require2FA: true}),
- });
- MockApiClient.addMockResponse({
- url: ENDPOINT,
- body: [AuthenticatorsFixture().Totp()],
- });
- const params = {
- authId: '15',
- };
- const {routerContext, routerProps} = initializeOrg({
- router: {
- params,
- },
- });
- render(
- <AccountSecurityWrapper {...routerProps}>
- <AccountSecurityDetails
- {...routerProps}
- onRegenerateBackupCodes={jest.fn()}
- deleteDisabled={false}
- />
- </AccountSecurityWrapper>,
- {context: routerContext}
- );
- expect(await screen.findByRole('button', {name: 'Remove'})).toBeDisabled();
- });
- });
- describe('Recovery', function () {
- beforeEach(function () {
- MockApiClient.addMockResponse({
- url: ENDPOINT,
- body: AllAuthenticatorsFixture(),
- });
- MockApiClient.addMockResponse({
- url: ORG_ENDPOINT,
- body: OrganizationsFixture(),
- });
- MockApiClient.addMockResponse({
- url: `${ENDPOINT}16/`,
- body: AuthenticatorsFixture().Recovery(),
- });
- MockApiClient.addMockResponse({
- url: ACCOUNT_EMAILS_ENDPOINT,
- body: AccountEmailsFixture(),
- });
- });
- it('has enrolled circle indicator', async function () {
- const params = {
- authId: '16',
- };
- const {routerProps, routerContext} = initializeOrg({
- router: {
- params,
- },
- });
- render(
- <AccountSecurityWrapper {...routerProps}>
- <AccountSecurityDetails
- {...routerProps}
- onRegenerateBackupCodes={jest.fn()}
- deleteDisabled={false}
- />
- </AccountSecurityWrapper>,
- {context: routerContext}
- );
- expect(await screen.findByTestId('auth-status-enabled')).toBeInTheDocument();
- // does not have remove button
- expect(screen.queryByRole('button', {name: 'Remove'})).not.toBeInTheDocument();
- });
- it('regenerates codes', async function () {
- const deleteMock = MockApiClient.addMockResponse({
- url: `${ENDPOINT}16/`,
- method: 'PUT',
- });
- const params = {
- authId: '16',
- };
- const {routerProps, routerContext} = initializeOrg({
- router: {
- params,
- },
- });
- render(
- <AccountSecurityWrapper {...routerProps}>
- <AccountSecurityDetails
- {...routerProps}
- onRegenerateBackupCodes={jest.fn()}
- deleteDisabled={false}
- />
- </AccountSecurityWrapper>,
- {context: routerContext}
- );
- await userEvent.click(
- await screen.findByRole('button', {name: 'Regenerate Codes'})
- );
- renderGlobalModal();
- expect(
- await screen.findByText(
- 'Are you sure you want to regenerate recovery codes? Your old codes will no longer work.'
- )
- ).toBeInTheDocument();
- await userEvent.click(screen.getByRole('button', {name: 'Confirm'}));
- expect(deleteMock).toHaveBeenCalled();
- });
- it('has copy, print and download buttons', async function () {
- const params = {
- authId: '16',
- };
- const {routerProps, routerContext} = initializeOrg({
- router: {
- params,
- },
- });
- Object.defineProperty(document, 'queryCommandSupported', {
- value: () => true,
- });
- render(
- <AccountSecurityWrapper {...routerProps}>
- <AccountSecurityDetails
- {...routerProps}
- onRegenerateBackupCodes={jest.fn()}
- deleteDisabled={false}
- />
- </AccountSecurityWrapper>,
- {context: routerContext}
- );
- expect(await screen.findByRole('button', {name: 'print'})).toBeInTheDocument();
- expect(screen.getByRole('button', {name: 'download'})).toHaveAttribute(
- 'href',
- 'data:text/plain;charset=utf-8,ABCD-1234 \nEFGH-5678'
- );
- expect(screen.getByTestId('frame')).toBeInTheDocument();
- expect(screen.getByRole('button', {name: 'Copy'})).toBeInTheDocument();
- });
- });
- });
|