mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Reporting/improve request handler path testing (#162926)
## Summary Addresses https://github.com/elastic/kibana/issues/152870 When clients request a report is generated, the JSON payload they receive in response contains a path string that helps automate downloading the report job once it is finished. This is an important piece of our public APIs. When reviewing some code to research [this issue](https://github.com/elastic/kibana/issues/152870), I found a few areas where the validity of this field was not properly documented and tested. This PR updates types and a test to fix the issue.
This commit is contained in:
parent
70676ccbed
commit
787454a146
3 changed files with 46 additions and 47 deletions
|
@ -5,6 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
jest.mock(
|
||||
'puid',
|
||||
() =>
|
||||
class MockPuid {
|
||||
generate() {
|
||||
return 'mock-report-id';
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
import { KibanaRequest, KibanaResponseFactory } from '@kbn/core/server';
|
||||
import rison from '@kbn/rison';
|
||||
import { coreMock, httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
|
@ -12,11 +22,13 @@ import { ReportingCore } from '../../..';
|
|||
import { TaskPayloadPDFV2 } from '../../../../common/types/export_types/printable_pdf_v2';
|
||||
import { JobParamsPDFDeprecated } from '../../../export_types/printable_pdf/types';
|
||||
import { Report, ReportingStore } from '../../../lib/store';
|
||||
import { ReportApiJSON } from '../../../lib/store/report';
|
||||
import { createMockConfigSchema, createMockReportingCore } from '../../../test_helpers';
|
||||
import { ReportingRequestHandlerContext, ReportingSetup } from '../../../types';
|
||||
import {
|
||||
ReportingJobResponse,
|
||||
ReportingRequestHandlerContext,
|
||||
ReportingSetup,
|
||||
} from '../../../types';
|
||||
import { RequestHandler } from './request_handler';
|
||||
|
||||
jest.mock('../../../lib/crypto', () => ({
|
||||
cryptoFactory: () => ({
|
||||
encrypt: () => `hello mock cypher text`,
|
||||
|
@ -246,47 +258,12 @@ describe('Handle request to generate', () => {
|
|||
});
|
||||
|
||||
test('generates the download path', async () => {
|
||||
const response = (await requestHandler.handleGenerateRequest(
|
||||
const { body } = (await requestHandler.handleGenerateRequest(
|
||||
'csv_searchsource',
|
||||
mockJobParams
|
||||
)) as unknown as { body: { job: ReportApiJSON } };
|
||||
const { id, created_at: _created_at, ...snapObj } = response.body.job;
|
||||
expect(snapObj).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"attempts": 0,
|
||||
"completed_at": undefined,
|
||||
"created_by": "testymcgee",
|
||||
"execution_time_ms": undefined,
|
||||
"index": ".reporting-foo-index-234",
|
||||
"jobtype": "csv_searchsource",
|
||||
"kibana_id": undefined,
|
||||
"kibana_name": undefined,
|
||||
"max_attempts": undefined,
|
||||
"meta": Object {
|
||||
"isDeprecated": undefined,
|
||||
"layout": "preserve_layout",
|
||||
"objectType": "cool_object_type",
|
||||
},
|
||||
"metrics": undefined,
|
||||
"migration_version": "7.14.0",
|
||||
"output": Object {},
|
||||
"payload": Object {
|
||||
"browserTimezone": "UTC",
|
||||
"layout": Object {
|
||||
"id": "preserve_layout",
|
||||
},
|
||||
"objectType": "cool_object_type",
|
||||
"relativeUrls": Array [],
|
||||
"spaceId": undefined,
|
||||
"title": "cool_title",
|
||||
"version": "7.14.0",
|
||||
},
|
||||
"queue_time_ms": undefined,
|
||||
"started_at": undefined,
|
||||
"status": "pending",
|
||||
"timeout": undefined,
|
||||
}
|
||||
`);
|
||||
)) as unknown as { body: ReportingJobResponse };
|
||||
|
||||
expect(body.path).toMatch('/mock-server-basepath/api/reporting/jobs/download/mock-report-id');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,7 +16,12 @@ import type { ReportingCore } from '../../..';
|
|||
import { PUBLIC_ROUTES } from '../../../../common/constants';
|
||||
import { checkParamsVersion, cryptoFactory } from '../../../lib';
|
||||
import { Report } from '../../../lib/store';
|
||||
import type { BaseParams, ReportingRequestHandlerContext, ReportingUser } from '../../../types';
|
||||
import type {
|
||||
BaseParams,
|
||||
ReportingJobResponse,
|
||||
ReportingRequestHandlerContext,
|
||||
ReportingUser,
|
||||
} from '../../../types';
|
||||
|
||||
export const handleUnavailable = (res: KibanaResponseFactory) => {
|
||||
return res.custom({ statusCode: 503, body: 'Not Available' });
|
||||
|
@ -203,7 +208,7 @@ export class RequestHandler {
|
|||
// return task manager's task information and the download URL
|
||||
counters.usageCounter();
|
||||
|
||||
return this.res.ok({
|
||||
return this.res.ok<ReportingJobResponse>({
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: {
|
||||
path: `${publicDownloadPath}/${report._id}`,
|
||||
|
|
|
@ -11,6 +11,7 @@ import { DiscoverServerPluginStart } from '@kbn/discover-plugin/server';
|
|||
import type { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server';
|
||||
import { FieldFormatsStart } from '@kbn/field-formats-plugin/server';
|
||||
import type { LicensingPluginStart } from '@kbn/licensing-plugin/server';
|
||||
import type { CancellationToken, TaskRunResult } from '@kbn/reporting-common';
|
||||
import type { ScreenshotModePluginSetup } from '@kbn/screenshot-mode-plugin/server';
|
||||
import type {
|
||||
PdfScreenshotOptions as BasePdfScreenshotOptions,
|
||||
|
@ -29,11 +30,10 @@ import type {
|
|||
} from '@kbn/task-manager-plugin/server';
|
||||
import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
|
||||
import type { Writable } from 'stream';
|
||||
import type { CancellationToken, TaskRunResult } from '@kbn/reporting-common';
|
||||
import type { BaseParams, BasePayload, UrlOrUrlLocatorTuple } from '../common/types';
|
||||
import type { BaseParams, BasePayload, ReportApiJSON, UrlOrUrlLocatorTuple } from '../common/types';
|
||||
import type { ReportingConfigType } from './config';
|
||||
import { ExportTypesRegistry } from './lib';
|
||||
import { ReportingCore } from './core';
|
||||
import { ExportTypesRegistry } from './lib';
|
||||
|
||||
/**
|
||||
* Plugin Setup Contract
|
||||
|
@ -56,6 +56,23 @@ export type ReportingUser = { username: AuthenticatedUser['username'] } | false;
|
|||
|
||||
export type ScrollConfig = ReportingConfigType['csv']['scroll'];
|
||||
|
||||
/**
|
||||
* Interface of a response to an HTTP request for our plugin to generate a report.
|
||||
* @public
|
||||
*/
|
||||
export interface ReportingJobResponse {
|
||||
/**
|
||||
* Contractual field with Watcher: used to automate download of the report once it is finished
|
||||
* @public
|
||||
*/
|
||||
path: string;
|
||||
/**
|
||||
* Details of a new report job that was requested
|
||||
* @public
|
||||
*/
|
||||
job: ReportApiJSON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal Types
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue