From c3e26657e9fb3368b1a204ea8d51bae274115a12 Mon Sep 17 00:00:00 2001 From: Tharun Rajendran Date: Tue, 29 Jun 2021 19:38:50 +0530 Subject: [PATCH] LoginPage: add tests (#36226) * added tests for LoginPage component * addressed review changes and removed snapshot --- .../app/core/components/Login/LoginCtrl.tsx | 6 +- .../core/components/Login/LoginPage.test.tsx | 91 +++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 public/app/core/components/Login/LoginPage.test.tsx diff --git a/public/app/core/components/Login/LoginCtrl.tsx b/public/app/core/components/Login/LoginCtrl.tsx index ac63eedd19c..aa969a8d729 100644 --- a/public/app/core/components/Login/LoginCtrl.tsx +++ b/public/app/core/components/Login/LoginCtrl.tsx @@ -115,12 +115,12 @@ export class LoginCtrl extends PureComponent { // Use window.location.href to force page reload if (this.result.redirectUrl) { if (config.appSubUrl !== '' && !this.result.redirectUrl.startsWith(config.appSubUrl)) { - window.location.href = config.appSubUrl + this.result.redirectUrl; + window.location.assign(config.appSubUrl + this.result.redirectUrl); } else { - window.location.href = this.result.redirectUrl; + window.location.assign(this.result.redirectUrl); } } else { - window.location.href = config.appSubUrl + '/'; + window.location.assign(config.appSubUrl + '/'); } }; diff --git a/public/app/core/components/Login/LoginPage.test.tsx b/public/app/core/components/Login/LoginPage.test.tsx new file mode 100644 index 00000000000..e6047ea5753 --- /dev/null +++ b/public/app/core/components/Login/LoginPage.test.tsx @@ -0,0 +1,91 @@ +import React from 'react'; +import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { LoginPage } from './LoginPage'; + +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: () => ({ + appSubUrl: '', + verifyEmailEnabled: false, + }), + }; +}); + +describe('Login Page', () => { + it('renders correctly', () => { + render(); + + expect(screen.getByRole('heading', { name: 'Welcome to Grafana' })).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'Username input field' })).toBeInTheDocument(); + expect(screen.getByLabelText('Password input field')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Login button' })).toBeInTheDocument(); + + expect(screen.getByRole('link', { name: 'Forgot your password?' })).toBeInTheDocument(); + expect(screen.getByRole('link', { name: 'Forgot your password?' })).toHaveAttribute( + 'href', + '/user/password/send-reset-email' + ); + + expect(screen.getByRole('link', { name: 'Sign up' })).toBeInTheDocument(); + expect(screen.getByRole('link', { name: 'Sign up' })).toHaveAttribute('href', '/signup'); + }); + it('should pass validation checks for username field', async () => { + render(); + + fireEvent.click(screen.getByRole('button', { name: 'Login button' })); + expect(await screen.findByText('Email or username is required')).toBeInTheDocument(); + + await act(async () => { + await userEvent.type(screen.getByRole('textbox', { name: 'Username input field' }), 'admin'); + expect(screen.queryByText('Email or username is required')).not.toBeInTheDocument(); + }); + }); + it('should pass validation checks for password field', async () => { + render(); + + fireEvent.click(screen.getByRole('button', { name: 'Login button' })); + expect(await screen.findByText('Password is required')).toBeInTheDocument(); + + await act(async () => { + await userEvent.type(screen.getByLabelText('Password input field'), 'admin'); + expect(screen.queryByText('Password is required')).not.toBeInTheDocument(); + }); + }); + it('should navigate to default url if credentials is valid', async () => { + Object.defineProperty(window, 'location', { + value: { + assign: jest.fn(), + }, + }); + postMock.mockResolvedValueOnce({ message: 'Logged in' }); + render(); + + await userEvent.type(screen.getByLabelText('Username input field'), 'admin'); + await userEvent.type(screen.getByLabelText('Password input field'), 'test'); + fireEvent.click(screen.getByLabelText('Login button')); + + await waitFor(() => expect(postMock).toHaveBeenCalledWith('/login', { password: 'test', user: 'admin' })); + expect(window.location.assign).toHaveBeenCalledWith('/'); + }); +});