[Reporting] convert all server unit tests to TypeScript (#62873)

* [Reporting] convert all server unit tests to TypeScript

* fix ts

* revert unrelated change
This commit is contained in:
Tim Sullivan 2020-04-10 09:57:59 -07:00 committed by GitHub
parent 9d2ecc7c06
commit aed5253b53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 273 additions and 167 deletions

View file

@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
// @ts-ignore
import Puid from 'puid';
import sinon from 'sinon';
import nodeCrypto from '@elastic/node-crypto';
@ -13,36 +14,40 @@ import { createMockReportingCore } from '../../../test_helpers';
import { LevelLogger } from '../../../server/lib/level_logger';
import { setFieldFormats } from '../../../server/services';
import { executeJobFactory } from './execute_job';
import { JobDocPayloadDiscoverCsv } from '../types';
import { CSV_BOM_CHARS } from '../../../common/constants';
const delay = ms => new Promise(resolve => setTimeout(() => resolve(), ms));
const delay = (ms: number) => new Promise(resolve => setTimeout(() => resolve(), ms));
const puid = new Puid();
const getRandomScrollId = () => {
return puid.generate();
};
const getJobDocPayload = (baseObj: any) => baseObj as JobDocPayloadDiscoverCsv;
describe('CSV Execute Job', function() {
const encryptionKey = 'testEncryptionKey';
const headers = {
sid: 'test',
};
const mockLogger = new LevelLogger({
get: () => ({
debug: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
}),
get: () =>
({
debug: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
} as any),
});
let defaultElasticsearchResponse;
let encryptedHeaders;
let defaultElasticsearchResponse: any;
let encryptedHeaders: any;
let clusterStub;
let configGetStub;
let mockReportingConfig;
let mockReportingPlugin;
let callAsCurrentUserStub;
let cancellationToken;
let clusterStub: any;
let configGetStub: any;
let mockReportingConfig: any;
let mockReportingPlugin: any;
let callAsCurrentUserStub: any;
let cancellationToken: any;
const mockElasticsearch = {
dataClient: {
@ -78,7 +83,7 @@ describe('CSV Execute Job', function() {
_scroll_id: 'defaultScrollId',
};
clusterStub = {
callAsCurrentUser: function() {},
callAsCurrentUser() {},
};
callAsCurrentUserStub = sinon
@ -89,17 +94,19 @@ describe('CSV Execute Job', function() {
mockUiSettingsClient.get.withArgs('csv:quoteValues').returns(true);
setFieldFormats({
fieldFormatServiceFactory: function() {
fieldFormatServiceFactory() {
const uiConfigMock = {};
uiConfigMock['format:defaultTypeMap'] = {
(uiConfigMock as any)['format:defaultTypeMap'] = {
_default_: { id: 'string', params: {} },
};
const fieldFormatsRegistry = new fieldFormats.FieldFormatsRegistry();
fieldFormatsRegistry.init(key => uiConfigMock[key], {}, [fieldFormats.StringFormat]);
fieldFormatsRegistry.init(key => (uiConfigMock as any)[key], {}, [
fieldFormats.StringFormat,
]);
return fieldFormatsRegistry;
return Promise.resolve(fieldFormatsRegistry);
},
});
});
@ -109,7 +116,11 @@ describe('CSV Execute Job', function() {
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
await executeJob(
'job456',
{ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null } },
getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
}),
cancellationToken
);
expect(callAsCurrentUserStub.called).toBe(true);
@ -123,14 +134,14 @@ describe('CSV Execute Job', function() {
};
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const job = {
const job = getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: {
index,
body,
},
};
});
await executeJob('job777', job, cancellationToken);
@ -152,7 +163,11 @@ describe('CSV Execute Job', function() {
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
await executeJob(
'job456',
{ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null } },
getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
}),
cancellationToken
);
@ -166,7 +181,11 @@ describe('CSV Execute Job', function() {
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
await executeJob(
'job456',
{ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null } },
getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
}),
cancellationToken
);
@ -196,7 +215,11 @@ describe('CSV Execute Job', function() {
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
await executeJob(
'job456',
{ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null } },
getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
}),
cancellationToken
);
@ -231,7 +254,11 @@ describe('CSV Execute Job', function() {
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
await executeJob(
'job456',
{ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null } },
getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
}),
cancellationToken
);
@ -257,12 +284,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: undefined,
searchRequest: { index: null, body: null },
};
});
await expect(
executeJob('job123', jobParams, cancellationToken)
).rejects.toMatchInlineSnapshot(`[TypeError: Cannot read property 'indexOf' of undefined]`);
@ -284,12 +311,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
const { csv_contains_formulas: csvContainsFormulas } = await executeJob(
'job123',
jobParams,
@ -309,12 +336,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['=SUM(A1:A2)', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
const { csv_contains_formulas: csvContainsFormulas } = await executeJob(
'job123',
jobParams,
@ -334,12 +361,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
const { csv_contains_formulas: csvContainsFormulas } = await executeJob(
'job123',
jobParams,
@ -359,12 +386,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
const { csv_contains_formulas: csvContainsFormulas } = await executeJob(
'job123',
jobParams,
@ -386,12 +413,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
expect(content).toEqual(`${CSV_BOM_CHARS}one,two\none,bar\n`);
@ -407,12 +434,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
expect(content).toEqual('one,two\none,bar\n');
@ -423,11 +450,11 @@ describe('CSV Execute Job', function() {
it('should reject Promise if search call errors out', async function() {
callAsCurrentUserStub.rejects(new Error());
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
};
});
await expect(
executeJob('job123', jobParams, cancellationToken)
).rejects.toMatchInlineSnapshot(`[Error]`);
@ -442,11 +469,11 @@ describe('CSV Execute Job', function() {
});
callAsCurrentUserStub.onSecondCall().rejects(new Error());
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
};
});
await expect(
executeJob('job123', jobParams, cancellationToken)
).rejects.toMatchInlineSnapshot(`[Error]`);
@ -463,11 +490,11 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
};
});
await expect(
executeJob('job123', jobParams, cancellationToken)
).rejects.toMatchInlineSnapshot(
@ -484,11 +511,11 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
};
});
await expect(
executeJob('job123', jobParams, cancellationToken)
).rejects.toMatchInlineSnapshot(
@ -512,11 +539,11 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
};
});
await expect(
executeJob('job123', jobParams, cancellationToken)
).rejects.toMatchInlineSnapshot(
@ -540,11 +567,11 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
};
});
await expect(
executeJob('job123', jobParams, cancellationToken)
).rejects.toMatchInlineSnapshot(
@ -578,7 +605,11 @@ describe('CSV Execute Job', function() {
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
executeJob(
'job345',
{ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null } },
getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
}),
cancellationToken
);
@ -593,13 +624,17 @@ describe('CSV Execute Job', function() {
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
executeJob(
'job345',
{ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null } },
getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
}),
cancellationToken
);
cancellationToken.cancel();
for (let i = 0; i < callAsCurrentUserStub.callCount; ++i) {
expect(callAsCurrentUserStub.getCall(i).args[1]).to.not.be('clearScroll');
expect(callAsCurrentUserStub.getCall(i).args[1]).not.toBe('clearScroll'); // dead code?
}
});
@ -607,7 +642,11 @@ describe('CSV Execute Job', function() {
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
executeJob(
'job345',
{ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null } },
getJobDocPayload({
headers: encryptedHeaders,
fields: [],
searchRequest: { index: null, body: null },
}),
cancellationToken
);
await delay(100);
@ -623,11 +662,11 @@ describe('CSV Execute Job', function() {
describe('csv content', function() {
it('should write column headers to output, even if there are no results', async function() {
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
searchRequest: { index: null, body: null },
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
expect(content).toBe(`one,two\n`);
});
@ -635,11 +674,11 @@ describe('CSV Execute Job', function() {
it('should use custom uiSettings csv:separator for header', async function() {
mockUiSettingsClient.get.withArgs('csv:separator').returns(';');
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
searchRequest: { index: null, body: null },
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
expect(content).toBe(`one;two\n`);
});
@ -647,11 +686,11 @@ describe('CSV Execute Job', function() {
it('should escape column headers if uiSettings csv:quoteValues is true', async function() {
mockUiSettingsClient.get.withArgs('csv:quoteValues').returns(true);
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one and a half', 'two', 'three-and-four', 'five & six'],
searchRequest: { index: null, body: null },
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
expect(content).toBe(`"one and a half",two,"three-and-four","five & six"\n`);
});
@ -659,11 +698,11 @@ describe('CSV Execute Job', function() {
it(`shouldn't escape column headers if uiSettings csv:quoteValues is false`, async function() {
mockUiSettingsClient.get.withArgs('csv:quoteValues').returns(false);
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one and a half', 'two', 'three-and-four', 'five & six'],
searchRequest: { index: null, body: null },
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
expect(content).toBe(`one and a half,two,three-and-four,five & six\n`);
});
@ -677,11 +716,11 @@ describe('CSV Execute Job', function() {
_scroll_id: 'scrollId',
});
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
searchRequest: { index: null, body: null },
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
const lines = content.split('\n');
const headerLine = lines[0];
@ -697,12 +736,12 @@ describe('CSV Execute Job', function() {
_scroll_id: 'scrollId',
});
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
const lines = content.split('\n');
const valuesLine = lines[1];
@ -724,12 +763,12 @@ describe('CSV Execute Job', function() {
_scroll_id: 'scrollId',
});
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
const lines = content.split('\n');
@ -746,7 +785,7 @@ describe('CSV Execute Job', function() {
_scroll_id: 'scrollId',
});
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
@ -760,7 +799,7 @@ describe('CSV Execute Job', function() {
fieldFormatMap: '{"one":{"id":"string","params":{"transform": "upper"}}}',
},
},
};
});
const { content } = await executeJob('job123', jobParams, cancellationToken);
const lines = content.split('\n');
@ -774,18 +813,18 @@ describe('CSV Execute Job', function() {
// tests use these 'simple' characters to make the math easier
describe('when only the headers exceed the maxSizeBytes', function() {
let content;
let maxSizeReached;
let content: string;
let maxSizeReached: boolean;
beforeEach(async function() {
configGetStub.withArgs('csv', 'maxSizeBytes').returns(1);
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
searchRequest: { index: null, body: null },
};
});
({ content, max_size_reached: maxSizeReached } = await executeJob(
'job123',
@ -804,18 +843,18 @@ describe('CSV Execute Job', function() {
});
describe('when headers are equal to maxSizeBytes', function() {
let content;
let maxSizeReached;
let content: string;
let maxSizeReached: boolean;
beforeEach(async function() {
configGetStub.withArgs('csv', 'maxSizeBytes').returns(9);
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
searchRequest: { index: null, body: null },
};
});
({ content, max_size_reached: maxSizeReached } = await executeJob(
'job123',
@ -834,8 +873,8 @@ describe('CSV Execute Job', function() {
});
describe('when the data exceeds the maxSizeBytes', function() {
let content;
let maxSizeReached;
let content: string;
let maxSizeReached: boolean;
beforeEach(async function() {
configGetStub.withArgs('csv', 'maxSizeBytes').returns(9);
@ -848,12 +887,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
({ content, max_size_reached: maxSizeReached } = await executeJob(
'job123',
@ -872,8 +911,8 @@ describe('CSV Execute Job', function() {
});
describe('when headers and data equal the maxSizeBytes', function() {
let content;
let maxSizeReached;
let content: string;
let maxSizeReached: boolean;
beforeEach(async function() {
mockReportingPlugin.getUiSettingsServiceFactory = () => mockUiSettingsClient;
@ -887,12 +926,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
({ content, max_size_reached: maxSizeReached } = await executeJob(
'job123',
@ -924,12 +963,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
await executeJob('job123', jobParams, cancellationToken);
@ -950,12 +989,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
await executeJob('job123', jobParams, cancellationToken);
@ -976,12 +1015,12 @@ describe('CSV Execute Job', function() {
});
const executeJob = await executeJobFactory(mockReportingPlugin, mockLogger);
const jobParams = {
const jobParams = getJobDocPayload({
headers: encryptedHeaders,
fields: ['one', 'two'],
conflictedTypesFields: [],
searchRequest: { index: null, body: null },
};
});
await executeJob('job123', jobParams, cancellationToken);

View file

@ -5,19 +5,22 @@
*/
import * as Rx from 'rxjs';
import { createMockReportingCore } from '../../../../test_helpers';
import { createMockReportingCore, createMockBrowserDriverFactory } from '../../../../test_helpers';
import { cryptoFactory } from '../../../../server/lib/crypto';
import { executeJobFactory } from './index';
import { generatePngObservableFactory } from '../lib/generate_png';
import { CancellationToken } from '../../../../common/cancellation_token';
import { LevelLogger } from '../../../../server/lib';
import { ReportingCore, CaptureConfig } from '../../../../server/types';
import { JobDocPayloadPNG } from '../../types';
jest.mock('../lib/generate_png', () => ({ generatePngObservableFactory: jest.fn() }));
let mockReporting;
let mockReporting: ReportingCore;
const cancellationToken = {
const cancellationToken = ({
on: jest.fn(),
};
} as unknown) as CancellationToken;
const mockLoggerFactory = {
get: jest.fn().mockImplementation(() => ({
@ -28,12 +31,16 @@ const mockLoggerFactory = {
};
const getMockLogger = () => new LevelLogger(mockLoggerFactory);
const captureConfig = {} as CaptureConfig;
const mockEncryptionKey = 'abcabcsecuresecret';
const encryptHeaders = async headers => {
const encryptHeaders = async (headers: Record<string, string>) => {
const crypto = cryptoFactory(mockEncryptionKey);
return await crypto.encrypt(headers);
};
const getJobDocPayload = (baseObj: any) => baseObj as JobDocPayloadPNG;
beforeEach(async () => {
const kbnConfig = {
'server.basePath': '/sbp',
@ -45,8 +52,8 @@ beforeEach(async () => {
'kibanaServer.protocol': 'http',
};
const mockReportingConfig = {
get: (...keys) => reportingConfig[keys.join('.')],
kbnConfig: { get: (...keys) => kbnConfig[keys.join('.')] },
get: (...keys: string[]) => (reportingConfig as any)[keys.join('.')],
kbnConfig: { get: (...keys: string[]) => (kbnConfig as any)[keys.join('.')] },
};
mockReporting = await createMockReportingCore(mockReportingConfig);
@ -60,22 +67,30 @@ beforeEach(async () => {
mockGetElasticsearch.mockImplementation(() => Promise.resolve(mockElasticsearch));
mockReporting.getElasticsearchService = mockGetElasticsearch;
generatePngObservableFactory.mockReturnValue(jest.fn());
(generatePngObservableFactory as jest.Mock).mockReturnValue(jest.fn());
});
afterEach(() => generatePngObservableFactory.mockReset());
afterEach(() => (generatePngObservableFactory as jest.Mock).mockReset());
test(`passes browserTimezone to generatePng`, async () => {
const encryptedHeaders = await encryptHeaders({});
const mockBrowserDriverFactory = await createMockBrowserDriverFactory(getMockLogger());
const generatePngObservable = generatePngObservableFactory();
generatePngObservable.mockReturnValue(Rx.of(Buffer.from('')));
const generatePngObservable = generatePngObservableFactory(
captureConfig,
mockBrowserDriverFactory
);
(generatePngObservable as jest.Mock).mockReturnValue(Rx.of(Buffer.from('')));
const executeJob = await executeJobFactory(mockReporting, getMockLogger());
const browserTimezone = 'UTC';
await executeJob(
'pngJobId',
{ relativeUrl: '/app/kibana#/something', browserTimezone, headers: encryptedHeaders },
getJobDocPayload({
relativeUrl: '/app/kibana#/something',
browserTimezone,
headers: encryptedHeaders,
}),
cancellationToken
);
@ -92,12 +107,17 @@ test(`returns content_type of application/png`, async () => {
const executeJob = await executeJobFactory(mockReporting, getMockLogger());
const encryptedHeaders = await encryptHeaders({});
const generatePngObservable = generatePngObservableFactory();
generatePngObservable.mockReturnValue(Rx.of(Buffer.from('')));
const mockBrowserDriverFactory = await createMockBrowserDriverFactory(getMockLogger());
const generatePngObservable = generatePngObservableFactory(
captureConfig,
mockBrowserDriverFactory
);
(generatePngObservable as jest.Mock).mockReturnValue(Rx.of(Buffer.from('')));
const { content_type: contentType } = await executeJob(
'pngJobId',
{ relativeUrl: '/app/kibana#/something', timeRange: {}, headers: encryptedHeaders },
getJobDocPayload({ relativeUrl: '/app/kibana#/something', headers: encryptedHeaders }),
cancellationToken
);
expect(contentType).toBe('image/png');
@ -106,14 +126,19 @@ test(`returns content_type of application/png`, async () => {
test(`returns content of generatePng getBuffer base64 encoded`, async () => {
const testContent = 'test content';
const generatePngObservable = generatePngObservableFactory();
generatePngObservable.mockReturnValue(Rx.of({ buffer: Buffer.from(testContent) }));
const mockBrowserDriverFactory = await createMockBrowserDriverFactory(getMockLogger());
const generatePngObservable = generatePngObservableFactory(
captureConfig,
mockBrowserDriverFactory
);
(generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from(testContent) }));
const executeJob = await executeJobFactory(mockReporting, getMockLogger());
const encryptedHeaders = await encryptHeaders({});
const { content } = await executeJob(
'pngJobId',
{ relativeUrl: '/app/kibana#/something', timeRange: {}, headers: encryptedHeaders },
getJobDocPayload({ relativeUrl: '/app/kibana#/something', headers: encryptedHeaders }),
cancellationToken
);

View file

@ -5,19 +5,24 @@
*/
import * as Rx from 'rxjs';
import { createMockReportingCore } from '../../../../test_helpers';
import { createMockReportingCore, createMockBrowserDriverFactory } from '../../../../test_helpers';
import { cryptoFactory } from '../../../../server/lib/crypto';
import { executeJobFactory } from './index';
import { generatePdfObservableFactory } from '../lib/generate_pdf';
import { LevelLogger } from '../../../../server/lib';
import { CancellationToken } from '../../../../types';
import { ReportingCore, CaptureConfig } from '../../../../server/types';
import { generatePdfObservableFactory } from '../lib/generate_pdf';
import { JobDocPayloadPDF } from '../../types';
import { executeJobFactory } from './index';
jest.mock('../lib/generate_pdf', () => ({ generatePdfObservableFactory: jest.fn() }));
let mockReporting;
let mockReporting: ReportingCore;
const cancellationToken = {
const cancellationToken = ({
on: jest.fn(),
};
} as unknown) as CancellationToken;
const captureConfig = {} as CaptureConfig;
const mockLoggerFactory = {
get: jest.fn().mockImplementation(() => ({
@ -29,11 +34,13 @@ const mockLoggerFactory = {
const getMockLogger = () => new LevelLogger(mockLoggerFactory);
const mockEncryptionKey = 'testencryptionkey';
const encryptHeaders = async headers => {
const encryptHeaders = async (headers: Record<string, string>) => {
const crypto = cryptoFactory(mockEncryptionKey);
return await crypto.encrypt(headers);
};
const getJobDocPayload = (baseObj: any) => baseObj as JobDocPayloadPDF;
beforeEach(async () => {
const kbnConfig = {
'server.basePath': '/sbp',
@ -45,8 +52,8 @@ beforeEach(async () => {
'kibanaServer.protocol': 'http',
};
const mockReportingConfig = {
get: (...keys) => reportingConfig[keys.join('.')],
kbnConfig: { get: (...keys) => kbnConfig[keys.join('.')] },
get: (...keys: string[]) => (reportingConfig as any)[keys.join('.')],
kbnConfig: { get: (...keys: string[]) => (kbnConfig as any)[keys.join('.')] },
};
mockReporting = await createMockReportingCore(mockReportingConfig);
@ -60,21 +67,26 @@ beforeEach(async () => {
mockGetElasticsearch.mockImplementation(() => Promise.resolve(mockElasticsearch));
mockReporting.getElasticsearchService = mockGetElasticsearch;
generatePdfObservableFactory.mockReturnValue(jest.fn());
(generatePdfObservableFactory as jest.Mock).mockReturnValue(jest.fn());
});
afterEach(() => generatePdfObservableFactory.mockReset());
afterEach(() => (generatePdfObservableFactory as jest.Mock).mockReset());
test(`returns content_type of application/pdf`, async () => {
const executeJob = await executeJobFactory(mockReporting, getMockLogger());
const logger = getMockLogger();
const executeJob = await executeJobFactory(mockReporting, logger);
const mockBrowserDriverFactory = await createMockBrowserDriverFactory(logger);
const encryptedHeaders = await encryptHeaders({});
const generatePdfObservable = generatePdfObservableFactory();
generatePdfObservable.mockReturnValue(Rx.of(Buffer.from('')));
const generatePdfObservable = generatePdfObservableFactory(
captureConfig,
mockBrowserDriverFactory
);
(generatePdfObservable as jest.Mock).mockReturnValue(Rx.of(Buffer.from('')));
const { content_type: contentType } = await executeJob(
'pdfJobId',
{ relativeUrls: [], timeRange: {}, headers: encryptedHeaders },
getJobDocPayload({ relativeUrls: [], headers: encryptedHeaders }),
cancellationToken
);
expect(contentType).toBe('application/pdf');
@ -82,15 +94,19 @@ test(`returns content_type of application/pdf`, async () => {
test(`returns content of generatePdf getBuffer base64 encoded`, async () => {
const testContent = 'test content';
const mockBrowserDriverFactory = await createMockBrowserDriverFactory(getMockLogger());
const generatePdfObservable = generatePdfObservableFactory();
generatePdfObservable.mockReturnValue(Rx.of({ buffer: Buffer.from(testContent) }));
const generatePdfObservable = generatePdfObservableFactory(
captureConfig,
mockBrowserDriverFactory
);
(generatePdfObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from(testContent) }));
const executeJob = await executeJobFactory(mockReporting, getMockLogger());
const encryptedHeaders = await encryptHeaders({});
const { content } = await executeJob(
'pdfJobId',
{ relativeUrls: [], timeRange: {}, headers: encryptedHeaders },
getJobDocPayload({ relativeUrls: [], headers: encryptedHeaders }),
cancellationToken
);

View file

@ -27,7 +27,7 @@ const describeWithContext = describe.each([
describeWithContext('config schema with context %j', context => {
it('produces correct config', async () => {
const schema = await getConfigSchema(reporting);
const value = await schema.validate({}, { context });
const value: any = await schema.validate({}, { context });
value.capture.browser.chromium.disableSandbox = '<platform dependent>';
await expect(value).toMatchSnapshot();
});

View file

@ -6,7 +6,10 @@
import Hapi from 'hapi';
import { createMockReportingCore } from '../../test_helpers';
import { ExportTypeDefinition } from '../../types';
import { ExportTypesRegistry } from '../lib/export_types_registry';
import { LevelLogger } from '../lib/level_logger';
import { ReportingConfig, ReportingCore, ReportingSetupDeps } from '../types';
jest.mock('./lib/authorized_user_pre_routing', () => ({
authorizedUserPreRoutingFactory: () => () => ({}),
@ -19,14 +22,14 @@ jest.mock('./lib/reporting_feature_pre_routing', () => ({
import { registerJobInfoRoutes } from './jobs';
let mockServer;
let exportTypesRegistry;
let mockReportingPlugin;
let mockReportingConfig;
const mockLogger = {
let mockServer: any;
let exportTypesRegistry: ExportTypesRegistry;
let mockReportingPlugin: ReportingCore;
let mockReportingConfig: ReportingConfig;
const mockLogger = ({
error: jest.fn(),
debug: jest.fn(),
};
} as unknown) as LevelLogger;
beforeEach(async () => {
mockServer = new Hapi.Server({ debug: false, port: 8080, routes: { log: { collect: true } } });
@ -35,38 +38,39 @@ beforeEach(async () => {
id: 'unencoded',
jobType: 'unencodedJobType',
jobContentExtension: 'csv',
});
} as ExportTypeDefinition<unknown, unknown, unknown, unknown>);
exportTypesRegistry.register({
id: 'base64Encoded',
jobType: 'base64EncodedJobType',
jobContentEncoding: 'base64',
jobContentExtension: 'pdf',
});
} as ExportTypeDefinition<unknown, unknown, unknown, unknown>);
mockReportingConfig = { get: jest.fn(), kbnConfig: { get: jest.fn() } };
mockReportingPlugin = await createMockReportingCore(mockReportingConfig);
mockReportingPlugin.getExportTypesRegistry = () => exportTypesRegistry;
});
const mockPlugins = {
const mockPlugins = ({
elasticsearch: {
adminClient: { callAsInternalUser: jest.fn() },
},
security: null,
};
} as unknown) as ReportingSetupDeps;
const getHits = (...sources) => {
const getHits = (...sources: any) => {
return {
hits: {
hits: sources.map(source => ({ _source: source })),
hits: sources.map((source: object) => ({ _source: source })),
},
};
};
const getErrorsFromRequest = request =>
request.logs.filter(log => log.tags.includes('error')).map(log => log.error);
const getErrorsFromRequest = (request: any) =>
request.logs.filter((log: any) => log.tags.includes('error')).map((log: any) => log.error);
test(`returns 404 if job not found`, async () => {
// @ts-ignore
mockPlugins.elasticsearch.adminClient = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(getHits())),
};
@ -84,6 +88,7 @@ test(`returns 404 if job not found`, async () => {
});
test(`returns 401 if not valid job type`, async () => {
// @ts-ignore
mockPlugins.elasticsearch.adminClient = {
callAsInternalUser: jest
.fn()
@ -103,6 +108,7 @@ test(`returns 401 if not valid job type`, async () => {
describe(`when job is incomplete`, () => {
const getIncompleteResponse = async () => {
// @ts-ignore
mockPlugins.elasticsearch.adminClient = {
callAsInternalUser: jest
.fn()
@ -149,6 +155,7 @@ describe(`when job is failed`, () => {
status: 'failed',
output: { content: 'job failure message' },
});
// @ts-ignore
mockPlugins.elasticsearch.adminClient = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(hits)),
};
@ -194,6 +201,7 @@ describe(`when job is completed`, () => {
title,
},
});
// @ts-ignore
mockPlugins.elasticsearch.adminClient = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(hits)),
};

View file

@ -11,18 +11,21 @@ import {
registerReportingUsageCollector,
getReportingUsageCollector,
} from './reporting_usage_collector';
import { ReportingConfig } from '../types';
const exportTypesRegistry = getExportTypesRegistry();
function getMockUsageCollection() {
class MockUsageCollector {
constructor(_server, { fetch }) {
// @ts-ignore fetch is not used
private fetch: any;
constructor(_server: any, { fetch }: any) {
this.fetch = fetch;
}
}
return {
makeUsageCollector: options => {
return new MockUsageCollector(this, options);
makeUsageCollector: (options: any) => {
return new MockUsageCollector(null, options);
},
registerCollector: sinon.stub(),
};
@ -51,7 +54,7 @@ function getPluginsMock(
xpack_main: mockXpackMain,
},
},
};
} as any;
}
const getMockReportingConfig = () => ({
@ -61,13 +64,13 @@ const getMockReportingConfig = () => ({
const getResponseMock = (customization = {}) => customization;
describe('license checks', () => {
let mockConfig;
let mockConfig: ReportingConfig;
beforeAll(async () => {
mockConfig = getMockReportingConfig();
});
describe('with a basic license', () => {
let usageStats;
let usageStats: any;
beforeAll(async () => {
const plugins = getPluginsMock({ license: 'basic' });
const callClusterMock = jest.fn(() => Promise.resolve(getResponseMock()));
@ -75,9 +78,12 @@ describe('license checks', () => {
mockConfig,
plugins.usageCollection,
plugins.__LEGACY.plugins.xpack_main.info,
exportTypesRegistry
exportTypesRegistry,
function isReady() {
return Promise.resolve(true);
}
);
usageStats = await fetch(callClusterMock, exportTypesRegistry);
usageStats = await fetch(callClusterMock as any);
});
test('sets enables to true', async () => {
@ -94,7 +100,7 @@ describe('license checks', () => {
});
describe('with no license', () => {
let usageStats;
let usageStats: any;
beforeAll(async () => {
const plugins = getPluginsMock({ license: 'none' });
const callClusterMock = jest.fn(() => Promise.resolve(getResponseMock()));
@ -102,9 +108,12 @@ describe('license checks', () => {
mockConfig,
plugins.usageCollection,
plugins.__LEGACY.plugins.xpack_main.info,
exportTypesRegistry
exportTypesRegistry,
function isReady() {
return Promise.resolve(true);
}
);
usageStats = await fetch(callClusterMock, exportTypesRegistry);
usageStats = await fetch(callClusterMock as any);
});
test('sets enables to true', async () => {
@ -121,7 +130,7 @@ describe('license checks', () => {
});
describe('with platinum license', () => {
let usageStats;
let usageStats: any;
beforeAll(async () => {
const plugins = getPluginsMock({ license: 'platinum' });
const callClusterMock = jest.fn(() => Promise.resolve(getResponseMock()));
@ -129,9 +138,12 @@ describe('license checks', () => {
mockConfig,
plugins.usageCollection,
plugins.__LEGACY.plugins.xpack_main.info,
exportTypesRegistry
exportTypesRegistry,
function isReady() {
return Promise.resolve(true);
}
);
usageStats = await fetch(callClusterMock, exportTypesRegistry);
usageStats = await fetch(callClusterMock as any);
});
test('sets enables to true', async () => {
@ -148,7 +160,7 @@ describe('license checks', () => {
});
describe('with no usage data', () => {
let usageStats;
let usageStats: any;
beforeAll(async () => {
const plugins = getPluginsMock({ license: 'basic' });
const callClusterMock = jest.fn(() => Promise.resolve({}));
@ -156,9 +168,12 @@ describe('license checks', () => {
mockConfig,
plugins.usageCollection,
plugins.__LEGACY.plugins.xpack_main.info,
exportTypesRegistry
exportTypesRegistry,
function isReady() {
return Promise.resolve(true);
}
);
usageStats = await fetch(callClusterMock, exportTypesRegistry);
usageStats = await fetch(callClusterMock as any);
});
test('sets enables to true', async () => {
@ -179,7 +194,10 @@ describe('data modeling', () => {
mockConfig,
plugins.usageCollection,
plugins.__LEGACY.plugins.xpack_main.info,
exportTypesRegistry
exportTypesRegistry,
function isReady() {
return Promise.resolve(true);
}
);
const callClusterMock = jest.fn(() =>
Promise.resolve(
@ -303,7 +321,7 @@ describe('data modeling', () => {
)
);
const usageStats = await fetch(callClusterMock);
const usageStats = await fetch(callClusterMock as any);
expect(usageStats).toMatchInlineSnapshot(`
Object {
"PNG": Object {
@ -406,7 +424,7 @@ describe('Ready for collection observable', () => {
const makeCollectorSpy = sinon.spy();
usageCollection.makeUsageCollector = makeCollectorSpy;
const plugins = getPluginsMock({ usageCollection });
const plugins = getPluginsMock({ usageCollection } as any);
registerReportingUsageCollector(mockReporting, plugins);
const [args] = makeCollectorSpy.firstCall.args;

View file

@ -92,7 +92,7 @@ const defaultOpts: CreateMockBrowserDriverFactoryOpts = {
export const createMockBrowserDriverFactory = async (
logger: Logger,
opts: Partial<CreateMockBrowserDriverFactoryOpts>
opts: Partial<CreateMockBrowserDriverFactoryOpts> = {}
): Promise<HeadlessChromiumDriverFactory> => {
const captureConfig = {
timeouts: { openUrl: 30000, waitForElements: 30000, renderComplete: 30000 },

View file

@ -186,7 +186,7 @@ export type ESQueueWorkerExecuteFn<JobDocPayloadType> = (
jobId: string,
job: JobDocPayloadType,
cancellationToken?: CancellationToken
) => void;
) => Promise<any>;
/*
* ImmediateExecuteFn receives the job doc payload because the payload was