import {mountWithTheme} from 'sentry-test/enzyme'; import {act} from 'sentry-test/reactTestingLibrary'; import {Client} from 'sentry/api'; import ConfigStore from 'sentry/stores/configStore'; import App from 'sentry/views/app'; describe('Sudo Modal', function () { const setHasPasswordAuth = hasPasswordAuth => act(() => ConfigStore.set('user', {...ConfigStore.get('user'), hasPasswordAuth})); beforeEach(function () { Client.clearMockResponses(); Client.addMockResponse({ url: '/internal/health/', body: { problems: [], }, }); Client.addMockResponse({ url: '/assistant/', body: [], }); Client.addMockResponse({ url: '/organizations/', body: [TestStubs.Organization()], }); Client.addMockResponse({ url: '/organizations/org-slug/', method: 'DELETE', statusCode: 401, body: { detail: { code: 'sudo-required', username: 'test@test.com', }, }, }); Client.addMockResponse({ url: '/authenticators/', body: [], }); }); it('can delete an org with sudo flow', async function () { setHasPasswordAuth(true); const wrapper = mountWithTheme({
placeholder content
}
); const api = new Client(); const successCb = jest.fn(); const errorCb = jest.fn(); // No Modal expect(wrapper.find('GlobalModal[visible=true]').exists()).toBe(false); // Should return w/ `sudoRequired` api.request('/organizations/org-slug/', { method: 'DELETE', success: successCb, error: errorCb, }); await tick(); await tick(); wrapper.update(); // Should have Modal + input expect(wrapper.find('Modal input')).toHaveLength(1); // Original callbacks should not have been called expect(successCb).not.toHaveBeenCalled(); expect(errorCb).not.toHaveBeenCalled(); // Clear mocks and allow DELETE Client.clearMockResponses(); const orgDeleteMock = Client.addMockResponse({ url: '/organizations/org-slug/', method: 'DELETE', statusCode: 200, }); const sudoMock = Client.addMockResponse({ url: '/auth/', method: 'PUT', statusCode: 200, }); expect(sudoMock).not.toHaveBeenCalled(); // "Sudo" auth wrapper .find('Modal input[name="password"]') .simulate('change', {target: {value: 'password'}}); wrapper.find('Modal form').simulate('submit'); wrapper.find('Modal Button[type="submit"]').simulate('click'); await tick(); wrapper.update(); expect(sudoMock).toHaveBeenCalledWith( '/auth/', expect.objectContaining({ method: 'PUT', data: {isSuperuserModal: false, password: 'password'}, }) ); // Retry API request expect(successCb).toHaveBeenCalled(); expect(orgDeleteMock).toHaveBeenCalledWith( '/organizations/org-slug/', expect.objectContaining({ method: 'DELETE', }) ); await tick(); wrapper.update(); // Sudo Modal should be closed expect(wrapper.find('GlobalModal[visible=true]').exists()).toBe(false); }); it('shows button to redirect if user does not have password auth', async function () { setHasPasswordAuth(false); const wrapper = mountWithTheme({
placeholder content
}
); const api = new Client(); const successCb = jest.fn(); const errorCb = jest.fn(); // No Modal expect(wrapper.find('GlobalModal[visible=true]').exists()).toBe(false); // Should return w/ `sudoRequired` api.request('/organizations/org-slug/', { method: 'DELETE', success: successCb, error: errorCb, }); await tick(); await tick(); wrapper.update(); // Should have Modal + input expect(wrapper.find('Modal input')).toHaveLength(0); expect(wrapper.find('Button[href]').prop('href')).toMatch('/auth/login/?next=%2F'); }); });