From a00bf5ba671621882885e2d65ca3fbda664f2226 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Wed, 8 Sep 2021 13:04:03 +0500 Subject: [PATCH] test(AuthManager): specs added for redirected login --- src/auth/AuthManager.ts | 12 ++ src/auth/spec/AuthManager.spec.ts | 267 ++++++++++++++++++++---------- src/auth/verifySas9Login.ts | 4 +- src/auth/verifySasViyaLogin.ts | 4 +- 4 files changed, 193 insertions(+), 94 deletions(-) diff --git a/src/auth/AuthManager.ts b/src/auth/AuthManager.ts index 7ab854d..3c1c0fb 100644 --- a/src/auth/AuthManager.ts +++ b/src/auth/AuthManager.ts @@ -31,6 +31,18 @@ export class AuthManager { public async redirectedLogIn({ onLoggedOut }: LoginOptions): Promise { + const { isLoggedIn: isLoggedInAlready, userName: currentSessionUsername } = + await this.fetchUserName() + + if (isLoggedInAlready) { + await this.loginCallback() + + return { + isLoggedIn: true, + userName: currentSessionUsername + } + } + const loginPopup = await openWebPage( this.loginPreventRedirectUrl, 'SASLogon', diff --git a/src/auth/spec/AuthManager.spec.ts b/src/auth/spec/AuthManager.spec.ts index 5b2e5fc..ae04e3c 100644 --- a/src/auth/spec/AuthManager.spec.ts +++ b/src/auth/spec/AuthManager.spec.ts @@ -8,6 +8,8 @@ import { mockLoginSuccessResponse } from './mockResponses' import { serialize } from '../../utils' +import * as openWebPageModule from '../openWebPage' +import * as verifySasViyaLoginModule from '../verifySasViyaLogin' import { RequestClient } from '../../request/RequestClient' jest.mock('axios') const mockedAxios = axios as jest.Mocked @@ -58,107 +60,188 @@ describe('AuthManager', () => { expect((authManager as any).logoutUrl).toEqual('/SASLogon/logout?') }) - it('should call the auth callback and return when already logged in', async () => { - const authManager = new AuthManager( - serverUrl, - serverType, - requestClient, - authCallback - ) - jest.spyOn(authManager, 'checkSession').mockImplementation(() => - Promise.resolve({ - isLoggedIn: true, - userName, - loginForm: 'test' - }) - ) + describe('login - default mechanism', () => { + it('should call the auth callback and return when already logged in', async () => { + const authManager = new AuthManager( + serverUrl, + serverType, + requestClient, + authCallback + ) + jest.spyOn(authManager, 'checkSession').mockImplementation(() => + Promise.resolve({ + isLoggedIn: true, + userName, + loginForm: 'test' + }) + ) - const loginResponse = await authManager.logIn(userName, password) + const loginResponse = await authManager.logIn(userName, password) - expect(loginResponse.isLoggedIn).toBeTruthy() - expect(loginResponse.userName).toEqual(userName) - expect(authCallback).toHaveBeenCalledTimes(1) - }) - - it('should post a login request to the server if not logged in', async () => { - const authManager = new AuthManager( - serverUrl, - serverType, - requestClient, - authCallback - ) - jest.spyOn(authManager, 'checkSession').mockImplementation(() => - Promise.resolve({ - isLoggedIn: false, - userName: '', - loginForm: { name: 'test' } - }) - ) - mockedAxios.post.mockImplementation(() => - Promise.resolve({ data: mockLoginSuccessResponse }) - ) - - const loginResponse = await authManager.logIn(userName, password) - - expect(loginResponse.isLoggedIn).toBeTruthy() - expect(loginResponse.userName).toEqual(userName) - - const loginParams = serialize({ - _service: 'default', - username: userName, - password, - name: 'test' + expect(loginResponse.isLoggedIn).toBeTruthy() + expect(loginResponse.userName).toEqual(userName) + expect(authCallback).toHaveBeenCalledTimes(1) }) - expect(mockedAxios.post).toHaveBeenCalledWith( - `/SASLogon/login`, - loginParams, - { - withCredentials: true, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Accept: '*/*' + + it('should post a login request to the server if not logged in', async () => { + const authManager = new AuthManager( + serverUrl, + serverType, + requestClient, + authCallback + ) + jest.spyOn(authManager, 'checkSession').mockImplementation(() => + Promise.resolve({ + isLoggedIn: false, + userName: '', + loginForm: { name: 'test' } + }) + ) + mockedAxios.post.mockImplementation(() => + Promise.resolve({ data: mockLoginSuccessResponse }) + ) + + const loginResponse = await authManager.logIn(userName, password) + + expect(loginResponse.isLoggedIn).toBeTruthy() + expect(loginResponse.userName).toEqual(userName) + + const loginParams = serialize({ + _service: 'default', + username: userName, + password, + name: 'test' + }) + expect(mockedAxios.post).toHaveBeenCalledWith( + `/SASLogon/login`, + loginParams, + { + withCredentials: true, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Accept: '*/*' + } } - } - ) - expect(authCallback).toHaveBeenCalledTimes(1) + ) + expect(authCallback).toHaveBeenCalledTimes(1) + }) + + it('should parse and submit the authorisation form when necessary', async () => { + const authManager = new AuthManager( + serverUrl, + serverType, + requestClient, + authCallback + ) + jest + .spyOn(requestClient, 'authorize') + .mockImplementation(() => Promise.resolve()) + jest.spyOn(authManager, 'checkSession').mockImplementation(() => + Promise.resolve({ + isLoggedIn: false, + userName: 'test', + loginForm: { name: 'test' } + }) + ) + mockedAxios.post.mockImplementationOnce(() => + Promise.resolve({ + data: mockLoginAuthoriseRequiredResponse, + config: { url: 'https://test.com/SASLogon/login' }, + request: { responseURL: 'https://test.com/OAuth/authorize' } + }) + ) + + mockedAxios.get.mockImplementationOnce(() => + Promise.resolve({ + data: mockLoginAuthoriseRequiredResponse + }) + ) + + await authManager.logIn(userName, password) + + expect(requestClient.authorize).toHaveBeenCalledWith( + mockLoginAuthoriseRequiredResponse + ) + }) }) - it('should parse and submit the authorisation form when necessary', async () => { - const authManager = new AuthManager( - serverUrl, - serverType, - requestClient, - authCallback - ) - jest - .spyOn(requestClient, 'authorize') - .mockImplementation(() => Promise.resolve()) - jest.spyOn(authManager, 'checkSession').mockImplementation(() => - Promise.resolve({ - isLoggedIn: false, - userName: 'test', - loginForm: { name: 'test' } - }) - ) - mockedAxios.post.mockImplementationOnce(() => - Promise.resolve({ - data: mockLoginAuthoriseRequiredResponse, - config: { url: 'https://test.com/SASLogon/login' }, - request: { responseURL: 'https://test.com/OAuth/authorize' } - }) - ) + describe('login - redirect mechanism', () => { + beforeAll(() => { + jest.mock('../openWebPage') + jest + .spyOn(openWebPageModule, 'openWebPage') + .mockImplementation(() => + Promise.resolve({ close: jest.fn() } as unknown as Window) + ) + jest.mock('../verifySasViyaLogin') + jest + .spyOn(verifySasViyaLoginModule, 'verifySasViyaLogin') + .mockImplementation(() => Promise.resolve({ isLoggedIn: true })) + }) - mockedAxios.get.mockImplementationOnce(() => - Promise.resolve({ - data: mockLoginAuthoriseRequiredResponse - }) - ) + it('should call the auth callback and return when already logged in', async () => { + const authManager = new AuthManager( + serverUrl, + serverType, + requestClient, + authCallback + ) + jest + .spyOn(authManager, 'fetchUserName') + .mockImplementation(() => + Promise.resolve({ + isLoggedIn: true, + userName + }) + ) - await authManager.logIn(userName, password) + const loginResponse = await authManager.redirectedLogIn({}) - expect(requestClient.authorize).toHaveBeenCalledWith( - mockLoginAuthoriseRequiredResponse - ) + expect(loginResponse.isLoggedIn).toBeTruthy() + expect(loginResponse.userName).toEqual(userName) + expect(authCallback).toHaveBeenCalledTimes(1) + }) + + it('should open pop up if not logged in', async () => { + const authManager = new AuthManager( + serverUrl, + serverType, + requestClient, + authCallback + ) + jest + .spyOn(authManager, 'fetchUserName') + .mockImplementationOnce(() => + Promise.resolve({ + isLoggedIn: false, + userName: '' + }) + ) + .mockImplementationOnce(() => + Promise.resolve({ + isLoggedIn: true, + userName + }) + ) + + const loginResponse = await authManager.redirectedLogIn({}) + + expect(loginResponse.isLoggedIn).toBeTruthy() + expect(loginResponse.userName).toEqual(userName) + + expect(openWebPageModule.openWebPage).toHaveBeenCalledWith( + `/SASLogon/home`, + 'SASLogon', + { + width: 500, + height: 600 + }, + undefined + ) + expect(authManager['fetchUserName']).toHaveBeenCalledTimes(2) + + expect(authCallback).toHaveBeenCalledTimes(1) + }) }) it('should check and return session information if logged in', async () => { diff --git a/src/auth/verifySas9Login.ts b/src/auth/verifySas9Login.ts index 2907d67..cf350f7 100644 --- a/src/auth/verifySas9Login.ts +++ b/src/auth/verifySas9Login.ts @@ -1,6 +1,8 @@ import { delay } from '../utils' -export async function verifySas9Login(loginPopup: Window) { +export async function verifySas9Login(loginPopup: Window): Promise<{ + isLoggedIn: boolean +}> { let isLoggedIn = false let startTime = new Date() let elapsedSeconds = 0 diff --git a/src/auth/verifySasViyaLogin.ts b/src/auth/verifySasViyaLogin.ts index 1c9105e..6715ae9 100644 --- a/src/auth/verifySasViyaLogin.ts +++ b/src/auth/verifySasViyaLogin.ts @@ -1,6 +1,8 @@ import { delay } from '../utils' -export async function verifySasViyaLogin(loginPopup: Window) { +export async function verifySasViyaLogin(loginPopup: Window): Promise<{ + isLoggedIn: boolean +}> { let isLoggedIn = false let startTime = new Date() let elapsedSeconds = 0