2021-06-02 19:18:32 +00:00
|
|
|
import {
|
|
|
|
dialog,
|
|
|
|
BrowserWindow,
|
|
|
|
HeadersReceivedResponse,
|
|
|
|
WebContents,
|
|
|
|
} from 'electron';
|
|
|
|
jest.mock('loglevel');
|
|
|
|
import { error } from 'loglevel';
|
|
|
|
|
|
|
|
jest.mock('./helpers');
|
2021-06-09 13:49:35 +00:00
|
|
|
import { getCSSToInject } from './helpers';
|
2021-06-02 19:18:32 +00:00
|
|
|
jest.mock('./windowEvents');
|
|
|
|
import { clearAppData, createNewTab, injectCSS } from './windowHelpers';
|
|
|
|
|
|
|
|
describe('clearAppData', () => {
|
|
|
|
let window: BrowserWindow;
|
|
|
|
let mockClearCache: jest.SpyInstance;
|
|
|
|
let mockClearStorageData: jest.SpyInstance;
|
|
|
|
const mockShowDialog: jest.SpyInstance = jest.spyOn(dialog, 'showMessageBox');
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
window = new BrowserWindow();
|
|
|
|
mockClearCache = jest.spyOn(window.webContents.session, 'clearCache');
|
|
|
|
mockClearStorageData = jest.spyOn(
|
|
|
|
window.webContents.session,
|
|
|
|
'clearStorageData',
|
|
|
|
);
|
|
|
|
mockShowDialog.mockReset().mockResolvedValue(undefined);
|
|
|
|
});
|
|
|
|
|
|
|
|
afterAll(() => {
|
|
|
|
mockClearCache.mockRestore();
|
|
|
|
mockClearStorageData.mockRestore();
|
|
|
|
mockShowDialog.mockRestore();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('will not clear app data if dialog canceled', async () => {
|
|
|
|
mockShowDialog.mockResolvedValue(1);
|
|
|
|
|
|
|
|
await clearAppData(window);
|
|
|
|
|
|
|
|
expect(mockShowDialog).toHaveBeenCalledTimes(1);
|
|
|
|
expect(mockClearCache).not.toHaveBeenCalled();
|
|
|
|
expect(mockClearStorageData).not.toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('will clear app data if ok is clicked', async () => {
|
|
|
|
mockShowDialog.mockResolvedValue(0);
|
|
|
|
|
|
|
|
await clearAppData(window);
|
|
|
|
|
|
|
|
expect(mockShowDialog).toHaveBeenCalledTimes(1);
|
|
|
|
expect(mockClearCache).not.toHaveBeenCalledTimes(1);
|
|
|
|
expect(mockClearStorageData).not.toHaveBeenCalledTimes(1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('createNewTab', () => {
|
|
|
|
const window = new BrowserWindow();
|
|
|
|
const options = {};
|
|
|
|
const setupWindow = jest.fn();
|
|
|
|
const url = 'https://github.com/nativefier/nativefier';
|
|
|
|
const mockAddTabbedWindow: jest.SpyInstance = jest.spyOn(
|
|
|
|
BrowserWindow.prototype,
|
|
|
|
'addTabbedWindow',
|
|
|
|
);
|
|
|
|
const mockFocus: jest.SpyInstance = jest.spyOn(
|
|
|
|
BrowserWindow.prototype,
|
|
|
|
'focus',
|
|
|
|
);
|
|
|
|
const mockLoadURL: jest.SpyInstance = jest.spyOn(
|
|
|
|
BrowserWindow.prototype,
|
|
|
|
'loadURL',
|
|
|
|
);
|
|
|
|
|
|
|
|
test('creates new foreground tab', () => {
|
|
|
|
const foreground = true;
|
|
|
|
|
|
|
|
const tab = createNewTab(options, setupWindow, url, foreground, window);
|
|
|
|
|
|
|
|
expect(mockAddTabbedWindow).toHaveBeenCalledWith(tab);
|
|
|
|
expect(setupWindow).toHaveBeenCalledWith(options, tab);
|
|
|
|
expect(mockLoadURL).toHaveBeenCalledWith(url);
|
|
|
|
expect(mockFocus).not.toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('creates new background tab', () => {
|
|
|
|
const foreground = false;
|
|
|
|
|
|
|
|
const tab = createNewTab(options, setupWindow, url, foreground, window);
|
|
|
|
|
|
|
|
expect(mockAddTabbedWindow).toHaveBeenCalledWith(tab);
|
|
|
|
expect(setupWindow).toHaveBeenCalledWith(options, tab);
|
|
|
|
expect(mockLoadURL).toHaveBeenCalledWith(url);
|
|
|
|
expect(mockFocus).toHaveBeenCalledTimes(1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('injectCSS', () => {
|
2021-06-15 13:02:57 +00:00
|
|
|
jest.setTimeout(10000);
|
|
|
|
|
2021-06-02 19:18:32 +00:00
|
|
|
const mockGetCSSToInject: jest.SpyInstance = getCSSToInject as jest.Mock;
|
|
|
|
const mockLogError: jest.SpyInstance = error as jest.Mock;
|
|
|
|
const mockWebContentsInsertCSS: jest.SpyInstance = jest.spyOn(
|
|
|
|
WebContents.prototype,
|
|
|
|
'insertCSS',
|
|
|
|
);
|
|
|
|
|
|
|
|
const css = 'body { color: white; }';
|
2021-06-15 13:02:57 +00:00
|
|
|
let responseHeaders;
|
2021-06-02 19:18:32 +00:00
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
mockGetCSSToInject.mockReset().mockReturnValue('');
|
|
|
|
mockLogError.mockReset();
|
|
|
|
mockWebContentsInsertCSS.mockReset().mockResolvedValue(undefined);
|
2021-06-15 13:02:57 +00:00
|
|
|
responseHeaders = { 'x-header': 'value', 'content-type': ['test/other'] };
|
2021-06-02 19:18:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
afterAll(() => {
|
|
|
|
mockGetCSSToInject.mockRestore();
|
|
|
|
mockLogError.mockRestore();
|
|
|
|
mockWebContentsInsertCSS.mockRestore();
|
|
|
|
});
|
|
|
|
|
2021-06-09 13:49:35 +00:00
|
|
|
test('will not inject if getCSSToInject is empty', () => {
|
2021-06-02 19:18:32 +00:00
|
|
|
const window = new BrowserWindow();
|
|
|
|
|
|
|
|
injectCSS(window);
|
|
|
|
|
2021-06-09 13:49:35 +00:00
|
|
|
expect(mockGetCSSToInject).toHaveBeenCalled();
|
2021-06-02 19:18:32 +00:00
|
|
|
expect(mockWebContentsInsertCSS).not.toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('will inject on did-navigate + onHeadersReceived', (done) => {
|
|
|
|
mockGetCSSToInject.mockReturnValue(css);
|
|
|
|
const window = new BrowserWindow();
|
|
|
|
|
|
|
|
injectCSS(window);
|
|
|
|
|
|
|
|
expect(mockGetCSSToInject).toHaveBeenCalled();
|
|
|
|
|
|
|
|
window.webContents.emit('did-navigate');
|
2021-06-16 02:20:49 +00:00
|
|
|
// @ts-expect-error this function doesn't exist in the actual electron version, but will in our mock
|
2021-06-02 19:18:32 +00:00
|
|
|
window.webContents.session.webRequest.send(
|
|
|
|
'onHeadersReceived',
|
|
|
|
{ responseHeaders, webContents: window.webContents },
|
|
|
|
(result: HeadersReceivedResponse) => {
|
|
|
|
expect(mockWebContentsInsertCSS).toHaveBeenCalledWith(css);
|
|
|
|
expect(result.cancel).toBe(false);
|
|
|
|
expect(result.responseHeaders).toBe(responseHeaders);
|
|
|
|
done();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('will catch errors inserting CSS', (done) => {
|
|
|
|
mockGetCSSToInject.mockReturnValue(css);
|
|
|
|
|
|
|
|
mockWebContentsInsertCSS.mockReturnValue(
|
|
|
|
Promise.reject('css insertion error'),
|
|
|
|
);
|
|
|
|
|
|
|
|
const window = new BrowserWindow();
|
|
|
|
|
|
|
|
injectCSS(window);
|
|
|
|
|
|
|
|
expect(mockGetCSSToInject).toHaveBeenCalled();
|
|
|
|
|
|
|
|
window.webContents.emit('did-navigate');
|
2021-06-16 02:20:49 +00:00
|
|
|
// @ts-expect-error this function doesn't exist in the actual electron version, but will in our mock
|
2021-06-02 19:18:32 +00:00
|
|
|
window.webContents.session.webRequest.send(
|
|
|
|
'onHeadersReceived',
|
|
|
|
{ responseHeaders, webContents: window.webContents },
|
|
|
|
(result: HeadersReceivedResponse) => {
|
|
|
|
expect(mockWebContentsInsertCSS).toHaveBeenCalledWith(css);
|
|
|
|
expect(mockLogError).toHaveBeenCalledWith(
|
2021-06-09 13:49:35 +00:00
|
|
|
'injectCSSIntoResponse ERROR',
|
2021-06-02 19:18:32 +00:00
|
|
|
'css insertion error',
|
|
|
|
);
|
|
|
|
expect(result.cancel).toBe(false);
|
|
|
|
expect(result.responseHeaders).toBe(responseHeaders);
|
|
|
|
done();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
});
|
2021-06-09 13:49:35 +00:00
|
|
|
|
2021-06-15 13:02:57 +00:00
|
|
|
test.each<string | jest.DoneCallback>([
|
|
|
|
'application/json',
|
|
|
|
'font/woff2',
|
|
|
|
'image/png',
|
|
|
|
])(
|
|
|
|
'will not inject for content-type %s',
|
|
|
|
(contentType: string, done: jest.DoneCallback) => {
|
2021-06-09 13:49:35 +00:00
|
|
|
mockGetCSSToInject.mockReturnValue(css);
|
|
|
|
const window = new BrowserWindow();
|
|
|
|
|
2021-06-15 13:02:57 +00:00
|
|
|
responseHeaders['content-type'] = [contentType];
|
|
|
|
|
2021-06-09 13:49:35 +00:00
|
|
|
injectCSS(window);
|
|
|
|
|
|
|
|
expect(mockGetCSSToInject).toHaveBeenCalled();
|
|
|
|
|
2021-06-15 13:02:57 +00:00
|
|
|
expect(window.webContents.emit('did-navigate')).toBe(true);
|
|
|
|
mockWebContentsInsertCSS.mockReset().mockResolvedValue(undefined);
|
2021-06-16 02:20:49 +00:00
|
|
|
// @ts-expect-error this function doesn't exist in the actual electron version, but will in our mock
|
2021-06-09 13:49:35 +00:00
|
|
|
window.webContents.session.webRequest.send(
|
|
|
|
'onHeadersReceived',
|
2021-06-15 13:02:57 +00:00
|
|
|
{
|
|
|
|
responseHeaders,
|
|
|
|
webContents: window.webContents,
|
|
|
|
url: `test-${contentType}`,
|
|
|
|
},
|
2021-06-09 13:49:35 +00:00
|
|
|
(result: HeadersReceivedResponse) => {
|
2021-06-15 13:02:57 +00:00
|
|
|
// insertCSS will still run once for the did-navigate
|
2021-06-09 13:49:35 +00:00
|
|
|
expect(mockWebContentsInsertCSS).not.toHaveBeenCalled();
|
|
|
|
expect(result.cancel).toBe(false);
|
|
|
|
expect(result.responseHeaders).toBe(responseHeaders);
|
|
|
|
done();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2021-06-15 13:02:57 +00:00
|
|
|
test.each<string | jest.DoneCallback>(['text/html'])(
|
|
|
|
'will inject for content-type %s',
|
|
|
|
(contentType: string, done: jest.DoneCallback) => {
|
2021-06-09 13:49:35 +00:00
|
|
|
mockGetCSSToInject.mockReturnValue(css);
|
|
|
|
const window = new BrowserWindow();
|
|
|
|
|
2021-06-15 13:02:57 +00:00
|
|
|
responseHeaders['content-type'] = [contentType];
|
|
|
|
|
2021-06-09 13:49:35 +00:00
|
|
|
injectCSS(window);
|
|
|
|
|
|
|
|
expect(mockGetCSSToInject).toHaveBeenCalled();
|
|
|
|
|
|
|
|
window.webContents.emit('did-navigate');
|
2021-06-15 13:02:57 +00:00
|
|
|
mockWebContentsInsertCSS.mockReset().mockResolvedValue(undefined);
|
2021-06-16 02:20:49 +00:00
|
|
|
// @ts-expect-error this function doesn't exist in the actual electron version, but will in our mock
|
2021-06-09 13:49:35 +00:00
|
|
|
window.webContents.session.webRequest.send(
|
|
|
|
'onHeadersReceived',
|
2021-06-15 13:02:57 +00:00
|
|
|
{
|
|
|
|
responseHeaders,
|
|
|
|
webContents: window.webContents,
|
|
|
|
url: `test-${contentType}`,
|
|
|
|
},
|
2021-06-09 13:49:35 +00:00
|
|
|
(result: HeadersReceivedResponse) => {
|
2021-06-15 13:02:57 +00:00
|
|
|
expect(mockWebContentsInsertCSS).toHaveBeenCalledTimes(1);
|
2021-06-09 13:49:35 +00:00
|
|
|
expect(result.cancel).toBe(false);
|
|
|
|
expect(result.responseHeaders).toBe(responseHeaders);
|
|
|
|
done();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
test.each<string | jest.DoneCallback>([
|
|
|
|
'image',
|
|
|
|
'script',
|
|
|
|
'stylesheet',
|
|
|
|
'xhr',
|
|
|
|
])(
|
|
|
|
'will not inject for resource type %s',
|
|
|
|
(resourceType: string, done: jest.DoneCallback) => {
|
|
|
|
mockGetCSSToInject.mockReturnValue(css);
|
|
|
|
const window = new BrowserWindow();
|
|
|
|
|
|
|
|
injectCSS(window);
|
|
|
|
|
|
|
|
expect(mockGetCSSToInject).toHaveBeenCalled();
|
|
|
|
|
|
|
|
window.webContents.emit('did-navigate');
|
2021-06-15 13:02:57 +00:00
|
|
|
mockWebContentsInsertCSS.mockReset().mockResolvedValue(undefined);
|
2021-06-16 02:20:49 +00:00
|
|
|
// @ts-expect-error this function doesn't exist in the actual electron version, but will in our mock
|
2021-06-09 13:49:35 +00:00
|
|
|
window.webContents.session.webRequest.send(
|
|
|
|
'onHeadersReceived',
|
2021-06-15 13:02:57 +00:00
|
|
|
{
|
|
|
|
responseHeaders,
|
|
|
|
webContents: window.webContents,
|
|
|
|
resourceType,
|
|
|
|
url: `test-${resourceType}`,
|
|
|
|
},
|
2021-06-09 13:49:35 +00:00
|
|
|
(result: HeadersReceivedResponse) => {
|
2021-06-15 13:02:57 +00:00
|
|
|
// insertCSS will still run once for the did-navigate
|
2021-06-09 13:49:35 +00:00
|
|
|
expect(mockWebContentsInsertCSS).not.toHaveBeenCalled();
|
|
|
|
expect(result.cancel).toBe(false);
|
|
|
|
expect(result.responseHeaders).toBe(responseHeaders);
|
|
|
|
done();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
test.each<string | jest.DoneCallback>(['html', 'other'])(
|
|
|
|
'will inject for resource type %s',
|
|
|
|
(resourceType: string, done: jest.DoneCallback) => {
|
|
|
|
mockGetCSSToInject.mockReturnValue(css);
|
|
|
|
const window = new BrowserWindow();
|
|
|
|
|
|
|
|
injectCSS(window);
|
|
|
|
|
|
|
|
expect(mockGetCSSToInject).toHaveBeenCalled();
|
|
|
|
|
|
|
|
window.webContents.emit('did-navigate');
|
2021-06-15 13:02:57 +00:00
|
|
|
mockWebContentsInsertCSS.mockReset().mockResolvedValue(undefined);
|
2021-06-16 02:20:49 +00:00
|
|
|
// @ts-expect-error this function doesn't exist in the actual electron version, but will in our mock
|
2021-06-09 13:49:35 +00:00
|
|
|
window.webContents.session.webRequest.send(
|
|
|
|
'onHeadersReceived',
|
2021-06-15 13:02:57 +00:00
|
|
|
{
|
|
|
|
responseHeaders,
|
|
|
|
webContents: window.webContents,
|
|
|
|
resourceType,
|
|
|
|
url: `test-${resourceType}`,
|
|
|
|
},
|
2021-06-09 13:49:35 +00:00
|
|
|
(result: HeadersReceivedResponse) => {
|
2021-06-15 13:02:57 +00:00
|
|
|
expect(mockWebContentsInsertCSS).toHaveBeenCalledTimes(1);
|
2021-06-09 13:49:35 +00:00
|
|
|
expect(result.cancel).toBe(false);
|
|
|
|
expect(result.responseHeaders).toBe(responseHeaders);
|
|
|
|
done();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
2021-06-02 19:18:32 +00:00
|
|
|
});
|