[MM-40146][MM-40147] Unit tests for authManager and certificateManager (#1874)
This commit is contained in:
parent
d358369ff9
commit
d0e1936b2c
|
@ -59,6 +59,7 @@
|
|||
"check-types": "tsc"
|
||||
},
|
||||
"jest": {
|
||||
"clearMocks": true,
|
||||
"moduleDirectories": [
|
||||
"",
|
||||
"node_modules"
|
||||
|
|
283
src/main/authManager.test.js
Normal file
283
src/main/authManager.test.js
Normal file
|
@ -0,0 +1,283 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
'use strict';
|
||||
|
||||
import {AuthManager} from 'main/authManager';
|
||||
import WindowManager from 'main/windows/windowManager';
|
||||
import ModalManager from 'main/views/modalManager';
|
||||
|
||||
jest.mock('common/utils/url', () => {
|
||||
const actualUrl = jest.requireActual('common/utils/url');
|
||||
return {
|
||||
...actualUrl.default,
|
||||
getView: (url) => {
|
||||
if (url.toString() === 'http://badurl.com/') {
|
||||
return null;
|
||||
}
|
||||
return {name: 'test', url};
|
||||
},
|
||||
isTrustedURL: (url) => {
|
||||
return url.toString() === 'http://trustedurl.com/';
|
||||
},
|
||||
isCustomLoginURL: (url) => {
|
||||
return url.toString() === 'http://customloginurl.com/';
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('electron-log', () => ({
|
||||
error: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('main/windows/windowManager', () => ({
|
||||
getMainWindow: jest.fn().mockImplementation(() => ({})),
|
||||
}));
|
||||
|
||||
jest.mock('main/views/modalManager', () => ({
|
||||
addModal: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('main/utils', () => ({
|
||||
getLocalPreload: (file) => file,
|
||||
getLocalURLString: (file) => file,
|
||||
}));
|
||||
|
||||
const config = {
|
||||
teams: [{
|
||||
name: 'example',
|
||||
url: 'http://example.com',
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
name: 'TAB_MESSAGING',
|
||||
order: 0,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_FOCALBOARD',
|
||||
order: 1,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_PLAYBOOKS',
|
||||
order: 2,
|
||||
isOpen: true,
|
||||
},
|
||||
],
|
||||
lastActiveTab: 0,
|
||||
}, {
|
||||
name: 'github',
|
||||
url: 'https://github.com/',
|
||||
order: 1,
|
||||
tabs: [
|
||||
{
|
||||
name: 'TAB_MESSAGING',
|
||||
order: 0,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_FOCALBOARD',
|
||||
order: 1,
|
||||
isOpen: true,
|
||||
},
|
||||
{
|
||||
name: 'TAB_PLAYBOOKS',
|
||||
order: 2,
|
||||
isOpen: true,
|
||||
},
|
||||
],
|
||||
lastActiveTab: 0,
|
||||
}],
|
||||
};
|
||||
|
||||
const trustedOriginsStore = {
|
||||
addPermission: jest.fn(),
|
||||
checkPermission: (url) => {
|
||||
return url.toString() === 'http://haspermissionurl.com/';
|
||||
},
|
||||
save: jest.fn(),
|
||||
};
|
||||
|
||||
describe('main/authManager', () => {
|
||||
describe('handleAppLogin', () => {
|
||||
const authManager = new AuthManager(config, trustedOriginsStore);
|
||||
authManager.popLoginModal = jest.fn();
|
||||
authManager.popPermissionModal = jest.fn();
|
||||
|
||||
it('should not pop any modal on null url', () => {
|
||||
authManager.handleAppLogin({preventDefault: jest.fn()}, null, {url: null}, null, jest.fn());
|
||||
expect(authManager.popLoginModal).not.toBeCalled();
|
||||
expect(authManager.popPermissionModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should not pop any modal on null server', () => {
|
||||
authManager.handleAppLogin({preventDefault: jest.fn()}, null, {url: 'http://badurl.com/'}, null, jest.fn());
|
||||
expect(authManager.popLoginModal).not.toBeCalled();
|
||||
expect(authManager.popPermissionModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should popLoginModal when isTrustedURL', () => {
|
||||
authManager.handleAppLogin({preventDefault: jest.fn()}, null, {url: 'http://trustedurl.com/'}, null, jest.fn());
|
||||
expect(authManager.popLoginModal).toBeCalled();
|
||||
expect(authManager.popPermissionModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should popLoginModal when isCustomLoginURL', () => {
|
||||
authManager.handleAppLogin({preventDefault: jest.fn()}, null, {url: 'http://customloginurl.com/'}, null, jest.fn());
|
||||
expect(authManager.popLoginModal).toBeCalled();
|
||||
expect(authManager.popPermissionModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should popLoginModal when has permission', () => {
|
||||
authManager.handleAppLogin({preventDefault: jest.fn()}, null, {url: 'http://haspermissionurl.com/'}, null, jest.fn());
|
||||
expect(authManager.popLoginModal).toBeCalled();
|
||||
expect(authManager.popPermissionModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should popPermissionModal when anything else is true', () => {
|
||||
authManager.handleAppLogin({preventDefault: jest.fn()}, null, {url: 'http://someotherurl.com/'}, null, jest.fn());
|
||||
expect(authManager.popLoginModal).not.toBeCalled();
|
||||
expect(authManager.popPermissionModal).toBeCalled();
|
||||
});
|
||||
|
||||
it('should set login callback when logging in', () => {
|
||||
const callback = jest.fn();
|
||||
authManager.handleAppLogin({preventDefault: jest.fn()}, null, {url: 'http://someotherurl.com/'}, null, callback);
|
||||
expect(authManager.loginCallbackMap.get('http://someotherurl.com/')).toEqual(callback);
|
||||
});
|
||||
});
|
||||
|
||||
describe('popLoginModal', () => {
|
||||
const authManager = new AuthManager(config, trustedOriginsStore);
|
||||
|
||||
it('should not pop modal when no main window exists', () => {
|
||||
WindowManager.getMainWindow.mockImplementationOnce(() => null);
|
||||
authManager.popLoginModal({url: 'http://anormalurl.com'}, {
|
||||
isProxy: false,
|
||||
host: 'anormalurl',
|
||||
});
|
||||
expect(ModalManager.addModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should call with prefix based on proxy setting', () => {
|
||||
authManager.popLoginModal({url: 'http://anormalurl.com'},
|
||||
{
|
||||
isProxy: true,
|
||||
host: 'anormalurl',
|
||||
});
|
||||
expect(ModalManager.addModal).toBeCalledWith(
|
||||
'proxy-anormalurl',
|
||||
expect.any(String),
|
||||
expect.any(String),
|
||||
expect.any(Object),
|
||||
expect.any(Object),
|
||||
);
|
||||
|
||||
authManager.popLoginModal({url: 'http://anormalurl.com'},
|
||||
{
|
||||
isProxy: false,
|
||||
host: 'anormalurl',
|
||||
});
|
||||
expect(ModalManager.addModal).toBeCalledWith(
|
||||
'login-http://anormalurl.com',
|
||||
expect.any(String),
|
||||
expect.any(String),
|
||||
expect.any(Object),
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
|
||||
it('should return login credentials when modal resolves', async () => {
|
||||
authManager.handleLoginCredentialsEvent = jest.fn();
|
||||
const promise = Promise.resolve({username: 'test', password: 'password'});
|
||||
ModalManager.addModal.mockImplementationOnce(() => promise);
|
||||
authManager.popLoginModal({url: 'http://anormalurl.com'},
|
||||
{
|
||||
isProxy: false,
|
||||
host: 'anormalurl',
|
||||
});
|
||||
await promise;
|
||||
expect(authManager.handleLoginCredentialsEvent).toBeCalledWith({url: 'http://anormalurl.com'}, 'test', 'password');
|
||||
});
|
||||
|
||||
it('should cancel the login event when modal rejects', async () => {
|
||||
authManager.handleCancelLoginEvent = jest.fn();
|
||||
const error = new Error('oops');
|
||||
const promise = Promise.reject(error);
|
||||
ModalManager.addModal.mockImplementationOnce(() => promise);
|
||||
authManager.popLoginModal({url: 'http://anormalurl.com'},
|
||||
{
|
||||
isProxy: false,
|
||||
host: 'anormalurl',
|
||||
});
|
||||
await expect(promise).rejects.toThrow(error);
|
||||
expect(authManager.handleCancelLoginEvent).toBeCalledWith({url: 'http://anormalurl.com'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('popPermissionModal', () => {
|
||||
const authManager = new AuthManager(config, trustedOriginsStore);
|
||||
|
||||
it('should not pop modal when no main window exists', () => {
|
||||
WindowManager.getMainWindow.mockImplementationOnce(() => null);
|
||||
authManager.popPermissionModal({url: 'http://anormalurl.com'}, {
|
||||
isProxy: false,
|
||||
host: 'anormalurl',
|
||||
}, 'canBasicAuth');
|
||||
expect(ModalManager.addModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should call the login event when modal resolves', async () => {
|
||||
authManager.popLoginModal = jest.fn();
|
||||
authManager.handlePermissionGranted = jest.fn();
|
||||
const promise = Promise.resolve();
|
||||
ModalManager.addModal.mockImplementationOnce(() => promise);
|
||||
authManager.popPermissionModal({url: 'http://anormalurl.com'},
|
||||
{
|
||||
isProxy: false,
|
||||
host: 'anormalurl',
|
||||
}, 'canBasicAuth');
|
||||
await promise;
|
||||
expect(authManager.handlePermissionGranted).toBeCalledWith('http://anormalurl.com', 'canBasicAuth');
|
||||
expect(authManager.popLoginModal).toBeCalledWith({url: 'http://anormalurl.com'}, {
|
||||
isProxy: false,
|
||||
host: 'anormalurl',
|
||||
});
|
||||
});
|
||||
|
||||
it('should cancel the login event when modal rejects', async () => {
|
||||
authManager.handleCancelLoginEvent = jest.fn();
|
||||
const error = new Error('oops');
|
||||
const promise = Promise.reject(error);
|
||||
ModalManager.addModal.mockImplementationOnce(() => promise);
|
||||
authManager.popPermissionModal({url: 'http://anormalurl.com'},
|
||||
{
|
||||
isProxy: false,
|
||||
host: 'anormalurl',
|
||||
}, 'canBasicAuth');
|
||||
await expect(promise).rejects.toThrow(error);
|
||||
expect(authManager.handleCancelLoginEvent).toBeCalledWith({url: 'http://anormalurl.com'});
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleLoginCredentialsEvent', () => {
|
||||
const authManager = new AuthManager(config, trustedOriginsStore);
|
||||
const callback = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
authManager.loginCallbackMap.set('http://someurl.com', callback);
|
||||
});
|
||||
|
||||
it('should fire callback on successful login', () => {
|
||||
authManager.handleLoginCredentialsEvent({url: 'http://someurl.com'}, 'test', 'password');
|
||||
expect(callback).toBeCalledWith('test', 'password');
|
||||
expect(authManager.loginCallbackMap.get('http://someurl.com')).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should fail gracefully on no callback found', () => {
|
||||
authManager.handleLoginCredentialsEvent({url: 'http://someotherurl.com'}, 'test', 'password');
|
||||
expect(callback).not.toBeCalled();
|
||||
expect(authManager.loginCallbackMap.get('http://someurl.com')).toBe(callback);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -8,13 +8,12 @@ import {PermissionType} from 'types/trustedOrigin';
|
|||
import {LoginModalData} from 'types/auth';
|
||||
|
||||
import {BASIC_AUTH_PERMISSION} from 'common/permissions';
|
||||
|
||||
import urlUtils from 'common/utils/url';
|
||||
|
||||
import * as WindowManager from './windows/windowManager';
|
||||
import * as WindowManager from 'main/windows/windowManager';
|
||||
import {addModal} from 'main/views/modalManager';
|
||||
import {getLocalURLString, getLocalPreload} from 'main/utils';
|
||||
|
||||
import {addModal} from './views/modalManager';
|
||||
import {getLocalURLString, getLocalPreload} from './utils';
|
||||
import TrustedOriginsStore from './trustedOrigins';
|
||||
|
||||
const modalPreload = getLocalPreload('modalPreload.js');
|
||||
|
@ -43,7 +42,10 @@ export class AuthManager {
|
|||
|
||||
handleAppLogin = (event: Event, webContents: WebContents, request: AuthenticationResponseDetails, authInfo: AuthInfo, callback?: (username?: string, password?: string) => void) => {
|
||||
event.preventDefault();
|
||||
const parsedURL = new URL(request.url);
|
||||
const parsedURL = urlUtils.parseURL(request.url);
|
||||
if (!parsedURL) {
|
||||
return;
|
||||
}
|
||||
const server = urlUtils.getView(parsedURL, this.config.teams);
|
||||
if (!server) {
|
||||
return;
|
||||
|
|
109
src/main/certificateManager.test.js
Normal file
109
src/main/certificateManager.test.js
Normal file
|
@ -0,0 +1,109 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
'use strict';
|
||||
|
||||
import WindowManager from 'main/windows/windowManager';
|
||||
import ModalManager from 'main/views/modalManager';
|
||||
import {CertificateManager} from 'main/certificateManager';
|
||||
|
||||
jest.mock('electron-log', () => ({
|
||||
info: jest.fn(),
|
||||
error: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('main/windows/windowManager', () => ({
|
||||
getMainWindow: jest.fn().mockImplementation(() => ({})),
|
||||
}));
|
||||
|
||||
jest.mock('main/views/modalManager', () => ({
|
||||
addModal: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('main/utils', () => ({
|
||||
getLocalPreload: (file) => file,
|
||||
getLocalURLString: (file) => file,
|
||||
}));
|
||||
|
||||
describe('main/certificateManager', () => {
|
||||
describe('handleSelectCertificate', () => {
|
||||
const certificateManager = new CertificateManager();
|
||||
certificateManager.popCertificateModal = jest.fn();
|
||||
|
||||
it('should not pop modal on no certificates', () => {
|
||||
certificateManager.handleSelectCertificate({preventDefault: jest.fn()}, null, 'http://someurl.com/', [], jest.fn());
|
||||
expect(certificateManager.popCertificateModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should not pop modal on one certificate', () => {
|
||||
certificateManager.handleSelectCertificate({preventDefault: jest.fn()}, null, 'http://someurl.com/', [{}], jest.fn());
|
||||
expect(certificateManager.popCertificateModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should pop modal on two certificates', () => {
|
||||
certificateManager.handleSelectCertificate({preventDefault: jest.fn()}, null, 'http://someurl.com/', [{}, {}], jest.fn());
|
||||
expect(certificateManager.popCertificateModal).toBeCalled();
|
||||
});
|
||||
|
||||
it('should set callback when checking for cert', () => {
|
||||
const callback = jest.fn();
|
||||
certificateManager.handleSelectCertificate({preventDefault: jest.fn()}, null, 'http://someurl.com/', [{}, {}], callback);
|
||||
expect(certificateManager.certificateRequestCallbackMap.get('http://someurl.com/')).toEqual(callback);
|
||||
});
|
||||
});
|
||||
|
||||
describe('popCertificateModal', () => {
|
||||
const certificateManager = new CertificateManager();
|
||||
|
||||
it('should not pop modal when no main window exists', () => {
|
||||
WindowManager.getMainWindow.mockImplementationOnce(() => null);
|
||||
certificateManager.popCertificateModal('http://anormalurl.com', [{data: 'test 1'}, {data: 'test 2'}, {data: 'test 3'}]);
|
||||
expect(ModalManager.addModal).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should return the chosen certificate when modal resolves', async () => {
|
||||
certificateManager.handleSelectedCertificate = jest.fn();
|
||||
const promise = Promise.resolve({cert: {data: 'test 2'}});
|
||||
ModalManager.addModal.mockImplementationOnce(() => promise);
|
||||
certificateManager.popCertificateModal('http://anormalurl.com', [{data: 'test 1'}, {data: 'test 2'}, {data: 'test 3'}]);
|
||||
await promise;
|
||||
expect(certificateManager.handleSelectedCertificate).toBeCalledWith('http://anormalurl.com', {data: 'test 2'});
|
||||
});
|
||||
|
||||
it('should call with no cert when modal rejects', async () => {
|
||||
certificateManager.handleSelectCertificate = jest.fn();
|
||||
const error = new Error('oops');
|
||||
const promise = Promise.reject(error);
|
||||
ModalManager.addModal.mockImplementationOnce(() => promise);
|
||||
certificateManager.popCertificateModal('http://anormalurl.com', [{data: 'test 1'}, {data: 'test 2'}, {data: 'test 3'}]);
|
||||
await expect(promise).rejects.toThrow(error);
|
||||
expect(certificateManager.handleSelectedCertificate).toBeCalledWith('http://anormalurl.com');
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleSelectedCertificate', () => {
|
||||
const certificateManager = new CertificateManager();
|
||||
const callback = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
certificateManager.certificateRequestCallbackMap.set('http://someurl.com', callback);
|
||||
});
|
||||
|
||||
it('should fire callback on successful selection', () => {
|
||||
certificateManager.handleSelectedCertificate('http://someurl.com', {data: 'test'});
|
||||
expect(callback).toBeCalledWith({data: 'test'});
|
||||
expect(certificateManager.certificateRequestCallbackMap.get('http://someurl.com')).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should fail gracefully on no callback found', () => {
|
||||
certificateManager.handleSelectedCertificate('http://someotherurl.com', {data: 'test'});
|
||||
expect(callback).not.toBeCalled();
|
||||
expect(certificateManager.certificateRequestCallbackMap.get('http://someurl.com')).toBe(callback);
|
||||
});
|
||||
|
||||
it('should fail gracefully on no certificate', () => {
|
||||
certificateManager.handleSelectedCertificate('http://someurl.com');
|
||||
expect(callback).not.toBeCalled();
|
||||
expect(certificateManager.certificateRequestCallbackMap.get('http://someurl.com')).toBe(undefined);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -70,5 +70,6 @@ export class CertificateManager {
|
|||
log.error(`There was a problem using the selected certificate: ${e}`);
|
||||
}
|
||||
}
|
||||
this.certificateRequestCallbackMap.delete(server);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue