Skip to content

Commit

Permalink
[Reporting] convert all server unit tests to TypeScript (#62873) (#63304
Browse files Browse the repository at this point in the history
)

* [Reporting] convert all server unit tests to TypeScript

* fix ts

* revert unrelated change
  • Loading branch information
tsullivan authored Apr 11, 2020
1 parent 3665dfb commit fdb501d
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 168 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -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(() => ({
Expand All @@ -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',
Expand All @@ -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);
Expand All @@ -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
);

Expand All @@ -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');
Expand All @@ -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
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => ({
Expand All @@ -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',
Expand All @@ -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);
Expand All @@ -60,37 +67,46 @@ 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',
{ objects: [], timeRange: {}, headers: encryptedHeaders }, // 7.x and below only
getJobDocPayload({ objects: [], timeRange: {}, headers: encryptedHeaders }), // 7.x and below only
cancellationToken
);
expect(contentType).toBe('application/pdf');
});

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',
{ objects: [], timeRange: {}, headers: encryptedHeaders }, // 7.x and below only
getJobDocPayload({ objects: [], timeRange: {}, headers: encryptedHeaders }), // 7.x and below only
cancellationToken
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: () => () => ({}),
Expand All @@ -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 } } });
Expand All @@ -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())),
};
Expand All @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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)),
};
Expand Down Expand Up @@ -194,6 +201,7 @@ describe(`when job is completed`, () => {
title,
},
});
// @ts-ignore
mockPlugins.elasticsearch.adminClient = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(hits)),
};
Expand Down
Loading

0 comments on commit fdb501d

Please sign in to comment.