import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; import config from 'app/core/config'; import { getNavModel } from '../../core/selectors/navModel'; import { backendSrv } from '../../core/services/backend_srv'; import { Props, ChangePasswordPage } from './ChangePasswordPage'; import { initialUserState } from './state/reducers'; const defaultProps: Props = { ...initialUserState, user: { id: 1, name: 'Test User', email: 'test@test.com', login: 'test', isDisabled: false, isGrafanaAdmin: false, orgId: 0, authLabels: ['github'], }, navModel: getNavModel( { 'profile-settings': { icon: 'sliders-v-alt', id: 'profile-settings', parentItem: { id: 'profile', text: 'Test User', img: '/avatar/46d229b033af06a191ff2267bca9ae56', url: '/profile', }, text: 'Preferences', url: '/profile', }, }, 'profile-settings' ), loadUser: jest.fn(), changePassword: jest.fn(), }; async function getTestContext(overrides: Partial = {}) { jest.clearAllMocks(); jest.spyOn(backendSrv, 'get').mockResolvedValue({ id: 1, name: 'Test User', email: 'test@test.com', login: 'test', isDisabled: false, isGrafanaAdmin: false, orgId: 0, }); const props = { ...defaultProps, ...overrides }; const { rerender } = render(); await waitFor(() => expect(props.loadUser).toHaveBeenCalledTimes(1)); return { rerender, props }; } describe('ChangePasswordPage', () => { it('should show loading placeholder', async () => { await getTestContext({ user: null }); expect(screen.getByText(/loading \.\.\./i)).toBeInTheDocument(); }); it('should show change password form when user has loaded', async () => { await getTestContext(); expect(screen.getByText('Change Your Password')).toBeInTheDocument(); expect(screen.getByLabelText('Old password')).toBeInTheDocument(); expect(screen.getByLabelText('New password')).toBeInTheDocument(); expect(screen.getByLabelText('Confirm password')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Change Password' })).toBeInTheDocument(); expect(screen.getByRole('link', { name: 'Cancel' })).toBeInTheDocument(); expect(screen.getByRole('link', { name: 'Cancel' })).toHaveAttribute('href', '/profile'); }); it('should call changePassword if change password is valid', async () => { const { props } = await getTestContext(); await userEvent.type(screen.getByLabelText('Old password'), 'test'); await userEvent.type(screen.getByLabelText('New password'), 'admin'); await userEvent.type(screen.getByLabelText('Confirm password'), 'admin'); fireEvent.click(screen.getByRole('button', { name: 'Change Password' })); await waitFor(() => { expect(props.changePassword).toHaveBeenCalledTimes(1); expect(props.changePassword).toHaveBeenCalledWith( { confirmNew: 'admin', newPassword: 'admin', oldPassword: 'test', }, expect.anything() ); }); }); it('should cannot change password form if ldap or authProxy enabled', async () => { config.ldapEnabled = true; const { rerender } = await getTestContext(); expect( screen.getByText('You cannot change password when LDAP or auth proxy authentication is enabled.') ).toBeInTheDocument(); config.ldapEnabled = false; config.authProxyEnabled = true; rerender(); expect( screen.getByText('You cannot change password when LDAP or auth proxy authentication is enabled.') ).toBeInTheDocument(); config.authProxyEnabled = false; }); it('should show cannot change password if disableLoginForm is true and auth', async () => { config.disableLoginForm = true; await getTestContext(); expect(screen.getByText('Password cannot be changed here.')).toBeInTheDocument(); config.disableLoginForm = false; }); });