chore: Signup Page Component tests (#36279)

* added tests for SignupPage component

* added tests for VerifyEmailPage component

* addressed review changes

* removed id for button and followed consistent id naming pattern
This commit is contained in:
Tharun Rajendran 2021-06-30 20:41:27 +05:30 committed by GitHub
parent 1ab4ffb03d
commit 3b4916853c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 214 additions and 8 deletions

View File

@ -0,0 +1,119 @@
import React from 'react';
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { getRouteComponentProps } from 'app/core/navigation/__mocks__/routeProps';
import { SignupPage } from './SignupPage';
const postMock = jest.fn();
jest.mock('@grafana/runtime', () => ({
getBackendSrv: () => ({
post: postMock,
}),
}));
jest.mock('app/core/config', () => {
return {
loginError: false,
buildInfo: {
version: 'v1.0',
commit: '1',
env: 'production',
edition: 'Open Source',
isEnterprise: false,
},
licenseInfo: {
stateInfo: '',
licenseUrl: '',
},
appSubUrl: '',
getConfig: () => ({
autoAssignOrg: false,
verifyEmailEnabled: true,
appSubUrl: '',
}),
};
});
const props = {
email: '',
code: '',
...getRouteComponentProps(),
};
describe('Signup Page', () => {
it('renders correctly', () => {
render(<SignupPage {...props} />);
expect(screen.getByRole('heading', { name: 'Welcome to Grafana' })).toBeInTheDocument();
expect(screen.getByRole('textbox', { name: 'Your name' })).toBeInTheDocument();
expect(screen.getByRole('textbox', { name: 'Email' })).toBeInTheDocument();
expect(screen.getByRole('textbox', { name: 'Org. name' })).toBeInTheDocument();
expect(screen.getByRole('textbox', { name: /Email verification code/i })).toBeInTheDocument();
expect(screen.getByLabelText('Password')).toBeInTheDocument();
expect(screen.getByLabelText('Confirm password')).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Submit' })).toBeInTheDocument();
expect(screen.getByRole('link', { name: 'Back to login' })).toBeInTheDocument();
expect(screen.getByRole('link', { name: 'Back to login' })).toHaveAttribute('href', '/login');
});
it('should pass validation checks for email field', async () => {
render(<SignupPage {...props} />);
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
expect(await screen.findByText('Email is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test');
expect(screen.queryByText('Email is invalid')).toBeInTheDocument();
await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument();
});
});
it('should pass validation checks for password and confirm password field', async () => {
render(<SignupPage {...props} />);
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
expect(await screen.findByText('Password is required')).toBeInTheDocument();
expect(await screen.findByText('Confirmed password is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByLabelText('Password'), 'admin');
await userEvent.type(screen.getByLabelText('Confirm password'), 'a');
expect(screen.queryByText('Passwords must match!')).toBeInTheDocument();
await userEvent.type(screen.getByLabelText('Confirm password'), 'dmin');
expect(screen.queryByText('Passwords must match!')).not.toBeInTheDocument();
});
});
it('should navigate to default url if signup is successful', async () => {
Object.defineProperty(window, 'location', {
value: {
assign: jest.fn(),
},
});
postMock.mockResolvedValueOnce({ message: 'Logged in' });
render(<SignupPage {...props} />);
await userEvent.type(screen.getByRole('textbox', { name: 'Your name' }), 'test-user');
await userEvent.type(screen.getByRole('textbox', { name: 'Email' }), 'test@gmail.com');
await userEvent.type(screen.getByLabelText('Password'), 'admin');
await userEvent.type(screen.getByLabelText('Confirm password'), 'admin');
fireEvent.click(screen.getByRole('button', { name: 'Submit' }));
await waitFor(() =>
expect(postMock).toHaveBeenCalledWith('/api/user/signup/step2', {
code: '',
email: 'test@gmail.com',
name: 'test-user',
orgName: '',
password: 'admin',
username: 'test@gmail.com',
})
);
expect(window.location.assign).toHaveBeenCalledWith('/');
});
});

View File

@ -46,9 +46,9 @@ export const SignupPage: FC<Props> = (props) => {
});
if (response.code === 'redirect-to-select-org') {
window.location.href = getConfig().appSubUrl + '/profile/select-org?signup=1';
window.location.assign(getConfig().appSubUrl + '/profile/select-org?signup=1');
}
window.location.href = getConfig().appSubUrl + '/';
window.location.assign(getConfig().appSubUrl + '/');
};
const defaultValues = {
@ -63,10 +63,11 @@ export const SignupPage: FC<Props> = (props) => {
{({ errors, register, getValues }: FormAPI<SignupDTO>) => (
<>
<Field label="Your name">
<Input {...register('name')} placeholder="(optional)" />
<Input id="user-name" {...register('name')} placeholder="(optional)" />
</Field>
<Field label="Email" invalid={!!errors.email} error={errors.email?.message}>
<Input
id="email"
{...register('email', {
required: 'Email is required',
pattern: {
@ -80,16 +81,17 @@ export const SignupPage: FC<Props> = (props) => {
</Field>
{!getConfig().autoAssignOrg && (
<Field label="Org. name">
<Input {...register('orgName')} placeholder="Org. name" />
<Input id="org-name" {...register('orgName')} placeholder="Org. name" />
</Field>
)}
{getConfig().verifyEmailEnabled && (
<Field label="Email verification code (sent to your email)">
<Input {...register('code')} placeholder="Code" />
<Input id="verification-code" {...register('code')} placeholder="Code" />
</Field>
)}
<Field label="Password" invalid={!!errors.password} error={errors?.password?.message}>
<Input
id="new-password"
{...register('password', {
required: 'Password is required',
})}
@ -99,6 +101,7 @@ export const SignupPage: FC<Props> = (props) => {
</Field>
<Field label="Confirm password" invalid={!!errors.confirm} error={errors?.confirm?.message}>
<Input
id="confirm-new-password"
{...register('confirm', {
required: 'Confirmed password is required',
validate: (v) => v === getValues().password || 'Passwords must match!',

View File

@ -44,10 +44,20 @@ export const VerifyEmail: FC = () => {
<Field
label="Email"
description="Enter your email address to get a verification link sent to you"
invalid={!!(errors as any).email}
error={(errors as any).email?.message}
invalid={!!errors.email}
error={errors.email?.message}
>
<Input {...register('email', { required: true })} placeholder="Email" />
<Input
id="email"
{...register('email', {
required: 'Email is required',
pattern: {
value: /^\S+@\S+$/,
message: 'Email is invalid',
},
})}
placeholder="Email"
/>
</Field>
<HorizontalGroup>
<Button>Send verification email</Button>

View File

@ -0,0 +1,74 @@
import React from 'react';
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { VerifyEmailPage } from './VerifyEmailPage';
const postMock = jest.fn();
jest.mock('@grafana/runtime', () => ({
getBackendSrv: () => ({
post: postMock,
}),
}));
jest.mock('app/core/config', () => {
return {
buildInfo: {
version: 'v1.0',
commit: '1',
env: 'production',
edition: 'Open Source',
isEnterprise: false,
},
licenseInfo: {
stateInfo: '',
licenseUrl: '',
},
getConfig: () => ({
verifyEmailEnabled: true,
appSubUrl: '',
}),
};
});
describe('VerifyEmail Page', () => {
it('renders correctly', () => {
render(<VerifyEmailPage />);
expect(screen.getByText('Verify Email')).toBeInTheDocument();
expect(screen.getByRole('textbox', { name: /Email/i })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Send verification email' })).toBeInTheDocument();
expect(screen.getByRole('link', { name: 'Back to login' })).toBeInTheDocument();
expect(screen.getByRole('link', { name: 'Back to login' })).toHaveAttribute('href', '/login');
});
it('should pass validation checks for email field', async () => {
render(<VerifyEmailPage />);
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
expect(await screen.findByText('Email is required')).toBeInTheDocument();
await act(async () => {
await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test');
expect(screen.queryByText('Email is invalid')).toBeInTheDocument();
await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
expect(screen.queryByText('Email is invalid')).not.toBeInTheDocument();
});
});
it('should show complete signup if email-verification is successful', async () => {
postMock.mockResolvedValueOnce({ message: 'SignUpCreated' });
render(<VerifyEmailPage />);
await userEvent.type(screen.getByRole('textbox', { name: /Email/i }), 'test@gmail.com');
fireEvent.click(screen.getByRole('button', { name: 'Send verification email' }));
await waitFor(() =>
expect(postMock).toHaveBeenCalledWith('/api/user/signup', {
email: 'test@gmail.com',
})
);
expect(screen.getByRole('link', { name: 'Complete Signup' })).toBeInTheDocument();
expect(screen.getByRole('link', { name: 'Complete Signup' })).toHaveAttribute('href', '/signup');
});
});