diff --git a/packages/kbn-generate-csv/src/generate_csv.test.ts b/packages/kbn-generate-csv/src/generate_csv.test.ts index faba0a8425e9e..f39cf51352a58 100644 --- a/packages/kbn-generate-csv/src/generate_csv.test.ts +++ b/packages/kbn-generate-csv/src/generate_csv.test.ts @@ -47,7 +47,7 @@ const getMockConfig = (opts: Partial = {}): CsvConfigType => ({ maxSizeBytes: 180000, useByteOrderMarkEncoding: false, scroll: { size: 500, duration: '30s', strategy: 'pit' }, - enablePanelActionDownload: true, + enablePanelActionDownload: false, maxConcurrentShardRequests: 5, ...opts, }); diff --git a/packages/kbn-generate-csv/src/generate_csv_esql.test.ts b/packages/kbn-generate-csv/src/generate_csv_esql.test.ts index 4e85431448e45..9ae0b2b711c19 100644 --- a/packages/kbn-generate-csv/src/generate_csv_esql.test.ts +++ b/packages/kbn-generate-csv/src/generate_csv_esql.test.ts @@ -98,7 +98,7 @@ describe('CsvESQLGenerator', () => { maxSizeBytes: 180000, useByteOrderMarkEncoding: false, scroll: { size: 500, duration: '30s', strategy: 'pit' }, - enablePanelActionDownload: true, + enablePanelActionDownload: false, maxConcurrentShardRequests: 5, }; @@ -569,7 +569,7 @@ describe('CsvESQLGenerator', () => { maxSizeBytes: 180000, useByteOrderMarkEncoding: false, scroll: { size: 500, duration: '30s', strategy: 'pit' }, - enablePanelActionDownload: true, + enablePanelActionDownload: false, maxConcurrentShardRequests: 5, }; mockSearchResponse({ diff --git a/packages/kbn-generate-csv/src/lib/get_export_settings.test.ts b/packages/kbn-generate-csv/src/lib/get_export_settings.test.ts index 9b14636081233..05a321aa1a255 100644 --- a/packages/kbn-generate-csv/src/lib/get_export_settings.test.ts +++ b/packages/kbn-generate-csv/src/lib/get_export_settings.test.ts @@ -39,7 +39,7 @@ describe('getExportSettings', () => { scroll: { size: 500, duration: '30s', strategy: 'pit' }, useByteOrderMarkEncoding: false, maxConcurrentShardRequests: 5, - enablePanelActionDownload: true, + enablePanelActionDownload: false, }; taskInstanceFields = { startedAt: null, retryAt: null }; diff --git a/packages/kbn-reporting/common/routes.ts b/packages/kbn-reporting/common/routes.ts index 77d126b94e08a..dc01746fcc8db 100644 --- a/packages/kbn-reporting/common/routes.ts +++ b/packages/kbn-reporting/common/routes.ts @@ -24,7 +24,6 @@ export const INTERNAL_ROUTES = { DELETE_PREFIX: prefixInternalPath + '/jobs/delete', // docId is added to the final path DOWNLOAD_PREFIX: prefixInternalPath + '/jobs/download', // docId is added to the final path }, - DOWNLOAD_CSV: prefixInternalPath + '/generate/immediate/csv_searchsource', // DEPRECATED GENERATE_PREFIX: prefixInternalPath + '/generate', // exportTypeId is added to the final path }; diff --git a/packages/kbn-reporting/export_types/csv/csv_searchsource_immediate.test.ts b/packages/kbn-reporting/export_types/csv/csv_searchsource_immediate.test.ts deleted file mode 100644 index 417cc782a54cb..0000000000000 --- a/packages/kbn-reporting/export_types/csv/csv_searchsource_immediate.test.ts +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { CsvGenerator } from '@kbn/generate-csv'; - -jest.mock('@kbn/generate-csv', () => { - return { - CsvGenerator: jest.fn().mockImplementation(() => { - return { generateData: jest.fn() }; - }), - }; -}); - -import { httpServerMock } from '@kbn/core-http-server-mocks'; -import type { CoreStart, KibanaRequest } from '@kbn/core/server'; -import { coreMock, elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mocks'; -import { dataPluginMock } from '@kbn/data-plugin/server/mocks'; -import { discoverPluginMock } from '@kbn/discover-plugin/server/mocks'; -import { createFieldFormatsStartMock } from '@kbn/field-formats-plugin/server/mocks'; -import { createMockConfigSchema } from '@kbn/reporting-mocks-server'; -import { setFieldFormats } from '@kbn/reporting-server'; -import type { Writable } from 'stream'; - -import { CsvSearchSourceImmediateExportType } from '.'; -import { ReportingRequestHandlerContext } from './types'; - -const mockLogger = loggingSystemMock.createLogger(); -const encryptionKey = 'tetkey'; -let stream: jest.Mocked; -let mockCsvSearchSourceImmediateExportType: CsvSearchSourceImmediateExportType; -let mockCoreStart: CoreStart; -let mockRequest: KibanaRequest; -let mockRequestHandlerContext: ReportingRequestHandlerContext; - -beforeEach(async () => { - // use fieldFormats plugin for csv formats - // normally, this is done in the Reporting plugin - setFieldFormats(createFieldFormatsStartMock()); - stream = {} as typeof stream; - - const configType = createMockConfigSchema({ - encryptionKey, - csv: { - checkForFormulas: true, - escapeFormulaValues: true, - maxSizeBytes: 180000, - scroll: { size: 500, duration: 'auto' }, - }, - }); - const mockCoreSetup = coreMock.createSetup(); - mockCoreStart = coreMock.createStart(); - const context = coreMock.createPluginInitializerContext(configType); - mockRequest = httpServerMock.createKibanaRequest(); - - mockCsvSearchSourceImmediateExportType = new CsvSearchSourceImmediateExportType( - mockCoreSetup, - configType, - mockLogger, - context - ); - - mockRequestHandlerContext = { - core: Promise.resolve(mockCoreStart), - } as unknown as ReportingRequestHandlerContext; - - mockCsvSearchSourceImmediateExportType.setup({ - basePath: { set: jest.fn() }, - }); - - mockCsvSearchSourceImmediateExportType.start({ - esClient: elasticsearchServiceMock.createClusterClient(), - savedObjects: mockCoreStart.savedObjects, - uiSettings: mockCoreStart.uiSettings, - discover: discoverPluginMock.createStartContract(), - data: dataPluginMock.createStartContract(), - }); - - jest.useFakeTimers(); - jest.setSystemTime(1630526670000); -}); - -afterEach(() => { - jest.useRealTimers(); -}); - -test('allows csv.scroll.duration to be "auto"', async () => { - const mockGenerateData = jest.fn().mockResolvedValue(() => ({ csv_contains_formulas: false })); - (CsvGenerator as jest.Mock).mockImplementationOnce(() => { - return { generateData: mockGenerateData }; - }); - - await mockCsvSearchSourceImmediateExportType.runTask( - 'cool-job-id', - { browserTimezone: 'US/Alaska', searchSource: {}, title: 'Test Search' }, - mockRequestHandlerContext, - stream, - mockRequest - ); - - expect(CsvGenerator).toBeCalledWith( - { - browserTimezone: 'US/Alaska', - objectType: 'immediate-search', - searchSource: {}, - title: 'Test Search', - }, - { - checkForFormulas: true, - escapeFormulaValues: true, - maxSizeBytes: 180000, - scroll: { duration: 'auto', size: 500 }, - }, - { - retryAt: new Date('2021-09-01T20:06:30.000Z'), - startedAt: new Date('2021-09-01T20:04:30.000Z'), - }, - expect.anything(), - expect.anything(), - expect.anything(), - expect.anything(), - expect.anything() - ); - - expect(mockGenerateData).toBeCalled(); -}); diff --git a/packages/kbn-reporting/export_types/csv/csv_searchsource_immediate.ts b/packages/kbn-reporting/export_types/csv/csv_searchsource_immediate.ts deleted file mode 100644 index 5ca85cb27e540..0000000000000 --- a/packages/kbn-reporting/export_types/csv/csv_searchsource_immediate.ts +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { Writable } from 'stream'; - -import { KibanaRequest } from '@kbn/core-http-server'; -import { DataPluginStart } from '@kbn/data-plugin/server/plugin'; -import { DiscoverServerPluginStart } from '@kbn/discover-plugin/server'; -import { CsvGenerator } from '@kbn/generate-csv'; -import { - CancellationToken, - LICENSE_TYPE_BASIC, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_TRIAL, - durationToNumber, -} from '@kbn/reporting-common'; -import type { TaskRunResult } from '@kbn/reporting-common/types'; -import { - CSV_SEARCHSOURCE_IMMEDIATE_TYPE, - JobParamsDownloadCSV, -} from '@kbn/reporting-export-types-csv-common'; -import type { BaseExportTypeSetupDeps, BaseExportTypeStartDeps } from '@kbn/reporting-server'; -import { ExportType, getFieldFormats } from '@kbn/reporting-server'; - -import { ReportingRequestHandlerContext } from './types'; - -type CsvSearchSourceImmediateExportTypeSetupDeps = BaseExportTypeSetupDeps; -interface CsvSearchSourceImmediateExportTypeStartDeps extends BaseExportTypeStartDeps { - discover: DiscoverServerPluginStart; - data: DataPluginStart; -} - -/* - * ImmediateExecuteFn receives the job doc payload because the payload was - * generated in the ScheduleFn - */ -export type ImmediateExecuteFn = ( - jobId: null, - job: JobParamsDownloadCSV, - context: ReportingRequestHandlerContext, - stream: Writable, - req: KibanaRequest -) => Promise; - -/** - * @deprecated - * Requires `xpack.reporting.csv.enablePanelActionDownload` set to `true` (default is false) - */ -export class CsvSearchSourceImmediateExportType extends ExportType< - JobParamsDownloadCSV, - ImmediateExecuteFn, - CsvSearchSourceImmediateExportTypeSetupDeps, - CsvSearchSourceImmediateExportTypeStartDeps -> { - id = CSV_SEARCHSOURCE_IMMEDIATE_TYPE; - name = CSV_SEARCHSOURCE_IMMEDIATE_TYPE; - jobType = CSV_SEARCHSOURCE_IMMEDIATE_TYPE; - jobContentEncoding = 'base64' as const; - jobContentExtension = 'csv' as const; - validLicenses = [ - LICENSE_TYPE_TRIAL, - LICENSE_TYPE_BASIC, - LICENSE_TYPE_CLOUD_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - ]; - - constructor(...args: ConstructorParameters) { - super(...args); - this.logger = this.logger.get('csv-searchsource-export'); - } - - public createJob = async () => { - throw new Error(`immediate download has no create job handler!`); - }; - // @ts-ignore expected type failure from deprecated export type - public runTask = async ( - _jobId: string | null, - immediateJobParams: JobParamsDownloadCSV, - context: ReportingRequestHandlerContext, - stream: Writable, - req: KibanaRequest - ) => { - const job = { - objectType: 'immediate-search', - ...immediateJobParams, - }; - - const dataPluginStart = this.startDeps.data; - const savedObjectsClient = (await context.core).savedObjects.client; - const uiSettings = this.getUiSettingsServiceFactory(savedObjectsClient); - const fieldFormatsRegistry = await getFieldFormats().fieldFormatServiceFactory(uiSettings); - - const es = this.startDeps.esClient.asScoped(req); - const searchSourceStart = await dataPluginStart.search.searchSource.asScoped(req); - const clients = { - uiSettings, - data: dataPluginStart.search.asScoped(req), - es, - }; - const dependencies = { - fieldFormatsRegistry, - searchSourceStart, - }; - const cancellationToken = new CancellationToken(); - const csvConfig = this.config.csv; - const taskInstanceFields = - csvConfig.scroll.duration === 'auto' - ? { - startedAt: new Date(), - retryAt: new Date(Date.now() + durationToNumber(this.config.queue.timeout)), - } - : { - startedAt: null, - retryAt: null, - }; - - const csv = new CsvGenerator( - job, - csvConfig, - taskInstanceFields, - clients, - dependencies, - cancellationToken, - this.logger, - stream - ); - const result = await csv.generateData(); - - if (result.csv_contains_formulas) { - this.logger.warn(`CSV may contain formulas whose values have been escaped`); - } - - if (result.max_size_reached) { - this.logger.warn(`Max size reached: CSV output truncated`); - } - - const { warnings } = result; - if (warnings) { - warnings.forEach((warning) => { - this.logger.warn(warning); - }); - } - - return result; - }; -} diff --git a/packages/kbn-reporting/export_types/csv/index.ts b/packages/kbn-reporting/export_types/csv/index.ts index 5910d17926c06..8ad8d200f6b77 100644 --- a/packages/kbn-reporting/export_types/csv/index.ts +++ b/packages/kbn-reporting/export_types/csv/index.ts @@ -9,4 +9,3 @@ export { CsvSearchSourceExportType } from './csv_searchsource'; export { CsvV2ExportType } from './csv_v2'; -export { CsvSearchSourceImmediateExportType } from './csv_searchsource_immediate'; diff --git a/packages/kbn-reporting/export_types/csv/tsconfig.json b/packages/kbn-reporting/export_types/csv/tsconfig.json index 2fef9b63fda79..a5ee79e9b52c4 100644 --- a/packages/kbn-reporting/export_types/csv/tsconfig.json +++ b/packages/kbn-reporting/export_types/csv/tsconfig.json @@ -21,12 +21,10 @@ "@kbn/discover-plugin", "@kbn/data-plugin", "@kbn/generate-csv", - "@kbn/core-http-server", "@kbn/reporting-server", "@kbn/reporting-export-types-csv-common", "@kbn/reporting-mocks-server", "@kbn/core-http-request-handler-context-server", "@kbn/field-formats-plugin", - "@kbn/core-http-server-mocks", ] } diff --git a/packages/kbn-reporting/export_types/csv_common/index.ts b/packages/kbn-reporting/export_types/csv_common/index.ts index 1a2b175347484..259f4a917783a 100644 --- a/packages/kbn-reporting/export_types/csv_common/index.ts +++ b/packages/kbn-reporting/export_types/csv_common/index.ts @@ -18,17 +18,6 @@ import type { export * from './constants'; -/** - * @deprecated - * Requires `xpack.reporting.csv.enablePanelActionDownload` set to `true` (default is false) - */ -export interface JobParamsDownloadCSV { - browserTimezone: string; - title: string; - searchSource: SerializedSearchSourceFields; - columns?: string[]; -} - interface BaseParamsCSV { searchSource: SerializedSearchSourceFields; columns?: string[]; @@ -62,12 +51,6 @@ export interface TaskPayloadCsvFromSavedObject extends CsvFromSavedObjectBase, B export const CSV_REPORTING_ACTION = 'generateCsvReport'; -/** - * @deprecated - * Requires `xpack.reporting.csv.enablePanelActionDownload` set to `true` (default is false) - */ -export const CSV_SEARCHSOURCE_IMMEDIATE_TYPE = 'csv_searchsource_immediate'; - /** * @deprecated * Supported in case older reports exist in storage diff --git a/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.test.ts b/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.test.ts index 72da136ba9223..6eaa3e933980b 100644 --- a/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.test.ts +++ b/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.test.ts @@ -61,7 +61,6 @@ describe('GetCsvReportPanelAction', () => { beforeEach(() => { csvConfig = { scroll: {} as ClientConfigType['csv']['scroll'], - enablePanelActionDownload: false, }; apiClient = new ReportingAPIClient(core.http, core.uiSettings, '7.15.0'); @@ -285,58 +284,4 @@ describe('GetCsvReportPanelAction', () => { expect(await plugin.isCompatible(context)).toEqual(true); }); }); - - describe('download csv', () => { - beforeEach(() => { - csvConfig = { - scroll: {} as ClientConfigType['csv']['scroll'], - enablePanelActionDownload: true, - }; - - core.http.post.mockResolvedValue({}); - }); - - it('shows a success toast when the download successfully starts', async () => { - const panel = new ReportingCsvPanelAction({ - core, - apiClient, - startServices$: mockStartServices$, - usesUiCapabilities: true, - csvConfig, - }); - - await Rx.firstValueFrom(mockStartServices$); - - await panel.execute(context); - - expect(core.notifications.toasts.addSuccess).toHaveBeenCalledWith({ - 'data-test-subj': 'csvDownloadStarted', - text: expect.any(Function), - title: 'CSV download started', - }); - expect(core.notifications.toasts.addDanger).not.toHaveBeenCalled(); - }); - - it('shows a bad old toastie when it unsuccessfully fails', async () => { - apiClient.createImmediateReport = jest.fn().mockRejectedValue('No more ram!'); - const panel = new ReportingCsvPanelAction({ - core, - apiClient, - startServices$: mockStartServices$, - usesUiCapabilities: true, - csvConfig, - }); - - await Rx.firstValueFrom(mockStartServices$); - - await panel.execute(context); - - expect(core.notifications.toasts.addSuccess).toHaveBeenCalled(); - expect(core.notifications.toasts.addDanger).toHaveBeenCalledWith({ - 'data-test-subj': 'downloadCsvFail', - text: "We couldn't download your CSV at this time.", - title: 'CSV download failed', - }); - }); - }); }); diff --git a/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.tsx b/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.tsx index 7be14579523bd..65712496519f7 100644 --- a/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.tsx +++ b/packages/kbn-reporting/get_csv_panel_actions/panel_actions/get_csv_panel_action.tsx @@ -102,7 +102,6 @@ export class ReportingCsvPanelAction implements ActionDefinition; private readonly notifications: NotificationsSetup; private readonly apiClient: ReportingAPIClient; - private readonly enablePanelActionDownload: boolean; private readonly theme: ThemeServiceSetup; private readonly startServices$: Params['startServices$']; private readonly usesUiCapabilities: boolean; @@ -110,7 +109,6 @@ export class ReportingCsvPanelAction implements ActionDefinition { - const { searchSource, columns, title, analytics, i18nStart } = params; - const immediateJobParams = this.apiClient.getDecoratedJobParams({ - searchSource, - columns, - title, - objectType: 'downloadCsv', // FIXME: added for typescript, but immediate download job does not need objectType - }); - - this.isDownloading = true; - - this.notifications.toasts.addSuccess({ - title: this.i18nStrings.download.toasts.success.title, - text: toMountPoint(this.i18nStrings.download.toasts.success.body, { - analytics, - i18n: i18nStart, - theme: this.theme, - }), - 'data-test-subj': 'csvDownloadStarted', - }); - - await this.apiClient - .createImmediateReport(immediateJobParams) - .then(({ body, response }) => { - this.isDownloading = false; - - const download = `${title}.csv`; - const blob = new Blob([body as BlobPart], { - type: response?.headers.get('content-type') || undefined, - }); - - // Hack for IE11 Support - // @ts-expect-error - if (window.navigator.msSaveOrOpenBlob) { - // @ts-expect-error - return window.navigator.msSaveOrOpenBlob(blob, download); - } - - const a = window.document.createElement('a'); - const downloadObject = window.URL.createObjectURL(blob); - - a.href = downloadObject; - a.download = download; - document.body.appendChild(a); - a.click(); - window.URL.revokeObjectURL(downloadObject); - document.body.removeChild(a); - }) - .catch((error: unknown) => { - // eslint-disable-next-line no-console - console.error(error); - this.isDownloading = false; - this.notifications.toasts.addDanger({ - title: this.i18nStrings.download.toasts.error.title, - text: this.i18nStrings.download.toasts.error.body, - 'data-test-subj': 'downloadCsvFail', - }); - }); - }; - private executeGenerate = async (params: ExecutionParams) => { const { searchSource, columns, title, analytics, i18nStart } = params; const csvJobParams = this.apiClient.getDecoratedJobParams({ @@ -278,9 +210,6 @@ export class ReportingCsvPanelAction implements ActionDefinition => ({ - download: { - displayName: i18n.translate('reporting.share.panelAction.downloadCsvPanelTitle', { - defaultMessage: 'Download CSV', - }), - toasts: { - error: { - title: i18n.translate('reporting.share.panelAction.failedCsvReportTitle', { - defaultMessage: `CSV download failed`, - }), - body: i18n.translate('reporting.share.panelAction.failedCsvReportMessage', { - defaultMessage: `We couldn't download your CSV at this time.`, - }), - }, - success: { - title: i18n.translate('reporting.share.panelAction.csvDownloadStartedTitle', { - defaultMessage: `CSV download started`, - }), - body: ( - - ), - }, - }, - }, +export const getI18nStrings = (apiClient: ReportingAPIClient): Record<'generate', I18nStrings> => ({ generate: { displayName: i18n.translate('reporting.share.panelAction.generateCsvPanelTitle', { defaultMessage: 'Generate CSV report', diff --git a/packages/kbn-reporting/public/reporting_api_client.test.ts b/packages/kbn-reporting/public/reporting_api_client.test.ts index c1da4b46ae27a..3504ed87956d4 100644 --- a/packages/kbn-reporting/public/reporting_api_client.test.ts +++ b/packages/kbn-reporting/public/reporting_api_client.test.ts @@ -214,32 +214,6 @@ describe('ReportingAPIClient', () => { }); }); - describe('createImmediateReport', () => { - beforeEach(() => { - httpClient.post.mockResolvedValueOnce({ job: { payload: {} } }); - }); - - it('should send a post request', async () => { - await apiClient.createImmediateReport({ - browserTimezone: 'UTC', - objectType: 'something', - title: 'some title', - version: 'some version', - }); - - expect(httpClient.post).toHaveBeenCalledWith( - expect.any(String), - expect.objectContaining({ - body: JSON.stringify({ - browserTimezone: 'UTC', - title: 'some title', - version: 'some version', - }), - }) - ); - }); - }); - describe('getDecoratedJobParams', () => { beforeEach(() => { jest.spyOn(tz, 'guess').mockReturnValue('UTC'); diff --git a/packages/kbn-reporting/public/reporting_api_client.ts b/packages/kbn-reporting/public/reporting_api_client.ts index 48931fee1cf51..66f5daa0c520a 100644 --- a/packages/kbn-reporting/public/reporting_api_client.ts +++ b/packages/kbn-reporting/public/reporting_api_client.ts @@ -215,18 +215,6 @@ export class ReportingAPIClient implements IReportingAPI { } } - /** - * @deprecated - * Requires `xpack.reporting.csv.enablePanelActionDownload` set to `true` (default is false) - */ - public async createImmediateReport(baseParams: BaseParams) { - const { objectType: _objectType, ...params } = baseParams; // objectType is not needed for immediate download api - return this.http.post(INTERNAL_ROUTES.DOWNLOAD_CSV, { - asResponse: true, - body: JSON.stringify(params), - }); - } - /** * Adds the browserTimezone and kibana version to report job params */ diff --git a/packages/kbn-reporting/public/types.ts b/packages/kbn-reporting/public/types.ts index 2579ee42fe0dd..e01a1b55b0a1f 100644 --- a/packages/kbn-reporting/public/types.ts +++ b/packages/kbn-reporting/public/types.ts @@ -25,7 +25,6 @@ export interface ReportingPublicPluginStartDependencies { export interface ClientConfigType { csv: { - enablePanelActionDownload: boolean; scroll: { duration: string; size: number; diff --git a/packages/kbn-reporting/server/config_schema.ts b/packages/kbn-reporting/server/config_schema.ts index 7d831f95fc006..a4117341d27ca 100644 --- a/packages/kbn-reporting/server/config_schema.ts +++ b/packages/kbn-reporting/server/config_schema.ts @@ -60,7 +60,7 @@ const CaptureSchema = schema.object({ const CsvSchema = schema.object({ checkForFormulas: schema.boolean({ defaultValue: true }), escapeFormulaValues: schema.boolean({ defaultValue: false }), - enablePanelActionDownload: schema.boolean({ defaultValue: false }), + enablePanelActionDownload: schema.boolean({ defaultValue: false }), // unused as of 9.0 maxSizeBytes: schema.oneOf([schema.number(), schema.byteSize()], { defaultValue: ByteSizeValue.parse('250mb'), }), diff --git a/packages/kbn-reporting/server/export_type.ts b/packages/kbn-reporting/server/export_type.ts index 8ccf69f5073da..2ddd69b826b60 100644 --- a/packages/kbn-reporting/server/export_type.ts +++ b/packages/kbn-reporting/server/export_type.ts @@ -100,7 +100,6 @@ export abstract class ExportType< } } - // needed to be protected vs private for the csv search source immediate export type protected getUiSettingsServiceFactory(savedObjectsClient: SavedObjectsClientContract) { const { uiSettings: uiSettingsService } = this.startDeps; const scopedUiSettingsService = uiSettingsService.asScopedToClient(savedObjectsClient); diff --git a/x-pack/plugins/reporting/README.md b/x-pack/plugins/reporting/README.md index f9d6fe4e3db40..7e4d1beefde19 100644 --- a/x-pack/plugins/reporting/README.md +++ b/x-pack/plugins/reporting/README.md @@ -4,8 +4,6 @@ An awesome Kibana reporting plugin ## csv_searchsource. This is the endpoint used in the Discover UI. It must be replaced by csv_v2 at some point, when we have more capacity in reporting. https://github.com/elastic/kibana/issues/151190 -## csv_searchsource_immediate. -This is deprecated. This export type provides users with the means to download a CSV export of a saved search without creating a report. It is only available to users when `xpack.reporting.csv.enablePanelActionDownload` is set to `true` in kibana.yml. The default is `false`, which provides users with the means to generate a normal CSV report. ## csv_v2. This new endpoint is designed to have a more automation-friendly signature. It will replace csv_searchsource in the UI at some point, when there is more capacity in reporting. It will need a little more work to have parity: it needs to be able to export "unsaved" searches. diff --git a/x-pack/plugins/reporting/public/management/__test__/report_listing.test.helpers.tsx b/x-pack/plugins/reporting/public/management/__test__/report_listing.test.helpers.tsx index 97c5fae9cc5aa..19337a6f46deb 100644 --- a/x-pack/plugins/reporting/public/management/__test__/report_listing.test.helpers.tsx +++ b/x-pack/plugins/reporting/public/management/__test__/report_listing.test.helpers.tsx @@ -55,7 +55,6 @@ export const mockConfig: ClientConfigType = { duration: '10m', size: 500, }, - enablePanelActionDownload: false, }, poll: { jobsRefresh: { diff --git a/x-pack/plugins/reporting/server/config/index.ts b/x-pack/plugins/reporting/server/config/index.ts index a44a51d7d9ae4..709d072a9035a 100644 --- a/x-pack/plugins/reporting/server/config/index.ts +++ b/x-pack/plugins/reporting/server/config/index.ts @@ -24,6 +24,7 @@ export const config: PluginConfigDescriptor = { }, schema: ConfigSchema, deprecations: ({ unused }) => [ + unused('csv.enablePanelActionDownload', { level: 'warning' }), // unused since 9.0 unused('queue.indexInterval', { level: 'warning' }), // unused since 8.15 unused('capture.browser.chromium.maxScreenshotDimension', { level: 'warning' }), // unused since 7.8 unused('capture.browser.type', { level: 'warning' }), diff --git a/x-pack/plugins/reporting/server/core.ts b/x-pack/plugins/reporting/server/core.ts index 794cb5180ea09..283488dd5a973 100644 --- a/x-pack/plugins/reporting/server/core.ts +++ b/x-pack/plugins/reporting/server/core.ts @@ -29,11 +29,7 @@ import type { FeaturesPluginSetup } from '@kbn/features-plugin/server'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/server'; import type { LicensingPluginStart } from '@kbn/licensing-plugin/server'; import type { ReportingServerInfo } from '@kbn/reporting-common/types'; -import { - CsvSearchSourceExportType, - CsvSearchSourceImmediateExportType, - CsvV2ExportType, -} from '@kbn/reporting-export-types-csv'; +import { CsvSearchSourceExportType, CsvV2ExportType } from '@kbn/reporting-export-types-csv'; import { PdfExportType, PdfV1ExportType } from '@kbn/reporting-export-types-pdf'; import { PngExportType } from '@kbn/reporting-export-types-png'; import type { ReportingConfigType } from '@kbn/reporting-server'; @@ -383,22 +379,4 @@ export class ReportingCore { const ReportingEventLogger = reportingEventLoggerFactory(this.logger); return new ReportingEventLogger(report, task); } - - /** - * @deprecated - * Requires `xpack.reporting.csv.enablePanelActionDownload` set to `true` (default is false) - */ - public async getCsvSearchSourceImmediate() { - const startDeps = await this.getPluginStartDeps(); - - const csvImmediateExport = new CsvSearchSourceImmediateExportType( - this.core, - this.config, - this.logger, - this.context - ); - csvImmediateExport.setup(this.getPluginSetupDeps()); - csvImmediateExport.start({ ...startDeps }); - return csvImmediateExport; - } } diff --git a/x-pack/plugins/reporting/server/lib/event_logger/types.ts b/x-pack/plugins/reporting/server/lib/event_logger/types.ts index 8a6725eb33a4d..4b792446ff4c7 100644 --- a/x-pack/plugins/reporting/server/lib/event_logger/types.ts +++ b/x-pack/plugins/reporting/server/lib/event_logger/types.ts @@ -20,7 +20,7 @@ export interface ReportingAction extends LogMeta { kibana: { reporting: { actionType: A; - id?: string; // "immediate download" exports have no ID + id: string; jobType: string; byteSize?: number; } & TaskRunMetrics; diff --git a/x-pack/plugins/reporting/server/routes/index.ts b/x-pack/plugins/reporting/server/routes/index.ts index 750cd0d5cd6fb..3473f660f647f 100644 --- a/x-pack/plugins/reporting/server/routes/index.ts +++ b/x-pack/plugins/reporting/server/routes/index.ts @@ -9,7 +9,6 @@ import type { Logger } from '@kbn/core/server'; import { ReportingCore } from '..'; import { registerDeprecationsRoutes } from './internal/deprecations/deprecations'; import { registerDiagnosticRoutes } from './internal/diagnostic'; -import { registerGenerateCsvFromSavedObjectImmediate } from './internal/generate/csv_searchsource_immediate'; import { registerGenerationRoutesInternal } from './internal/generate/generate_from_jobparams'; import { registerJobInfoRoutesInternal } from './internal/management/jobs'; import { registerGenerationRoutesPublic } from './public/generate_from_jobparams'; @@ -22,10 +21,4 @@ export function registerRoutes(reporting: ReportingCore, logger: Logger) { registerJobInfoRoutesInternal(reporting); registerGenerationRoutesPublic(reporting, logger); registerJobInfoRoutesPublic(reporting); - - // (deprecated) allow users to download CSV without generating a report - const config = reporting.getConfig(); - if (config.csv.enablePanelActionDownload) { - registerGenerateCsvFromSavedObjectImmediate(reporting, logger); - } } diff --git a/x-pack/plugins/reporting/server/routes/internal/generate/csv_searchsource_immediate.ts b/x-pack/plugins/reporting/server/routes/internal/generate/csv_searchsource_immediate.ts deleted file mode 100644 index cc9ad946d84ef..0000000000000 --- a/x-pack/plugins/reporting/server/routes/internal/generate/csv_searchsource_immediate.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import Boom from '@hapi/boom'; -import moment from 'moment'; - -import { schema } from '@kbn/config-schema'; -import type { KibanaRequest, Logger } from '@kbn/core/server'; -import { INTERNAL_ROUTES } from '@kbn/reporting-common'; -import { - CSV_SEARCHSOURCE_IMMEDIATE_TYPE, - JobParamsDownloadCSV, -} from '@kbn/reporting-export-types-csv-common'; -import type { ReportingCore } from '../../..'; -import { PassThroughStream } from '../../../lib'; -import { authorizedUserPreRouting, getCounters } from '../../common'; - -const path = INTERNAL_ROUTES.DOWNLOAD_CSV; - -export type CsvFromSavedObjectRequest = KibanaRequest; - -/* - * This function registers API Endpoints for immediate Reporting jobs. The API inputs are: - * - saved object type and ID - * - time range and time zone - * - application state: - * - filters - * - query bar - * - local (transient) changes the user made to the saved object - */ -export function registerGenerateCsvFromSavedObjectImmediate( - reporting: ReportingCore, - parentLogger: Logger -) { - const setupDeps = reporting.getPluginSetupDeps(); - const { router } = setupDeps; - - const useKibanaAccessControl = reporting.getDeprecatedAllowedRoles() === false; // true if deprecated config is turned off - const kibanaAccessControlTags = useKibanaAccessControl ? ['access:downloadCsv'] : []; - - // This API calls run the SearchSourceImmediate export type's runTaskFn directly - router.post( - { - path, - validate: { - body: schema.object({ - columns: schema.maybe(schema.arrayOf(schema.string())), - searchSource: schema.object({}, { unknowns: 'allow' }), - browserTimezone: schema.string({ - defaultValue: 'UTC', - validate: (value) => - moment.tz.zone(value) ? undefined : `Invalid timezone "${typeof value}".`, - }), - title: schema.string(), - version: schema.maybe(schema.string()), - }), - }, - options: { tags: kibanaAccessControlTags, access: 'internal' }, - }, - authorizedUserPreRouting( - reporting, - async (user, context, req: CsvFromSavedObjectRequest, res) => { - const counters = getCounters(req.route.method, path, reporting.getUsageCounter()); - - const logger = parentLogger.get(CSV_SEARCHSOURCE_IMMEDIATE_TYPE); - const csvSearchSourceImmediateExport = await reporting.getCsvSearchSourceImmediate(); - - const stream = new PassThroughStream(); - const eventLog = reporting.getEventLogger({ - jobtype: CSV_SEARCHSOURCE_IMMEDIATE_TYPE, - created_by: user && user.username, - payload: { browserTimezone: req.body.browserTimezone }, - }); - const logError = (error: Error) => { - logger.error(error); - eventLog.logError(error); - }; - - try { - eventLog.logExecutionStart(); - - const taskPromise = csvSearchSourceImmediateExport - .runTask(null, req.body, context, stream, req) - .then((output) => { - logger.info(`Job output size: ${stream.bytesWritten} bytes.`); - - if (!stream.bytesWritten) { - logger.warn('CSV Job Execution created empty content result'); - } - - eventLog.logExecutionComplete({ - ...(output.metrics ?? {}), - byteSize: stream.bytesWritten, - }); - }) - .finally(() => stream.end()); - - await Promise.race([stream.firstBytePromise, taskPromise]); - - taskPromise.catch(logError); - - counters.usageCounter(); - - return res.ok({ - body: stream, - headers: { - 'content-type': 'text/csv;charset=utf-8', - 'accept-ranges': 'none', - }, - }); - } catch (error) { - logError(error); - - if (error instanceof Boom.Boom) { - const statusCode = error.output.statusCode; - counters.errorCounter(undefined, statusCode); - - return res.customError({ - statusCode, - body: error.output.payload.message, - }); - } - - counters.errorCounter(undefined, 500); - - return res.customError({ - statusCode: 500, - }); - } - } - ) - ); -} diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 1521e3e251702..b59c2fb18f4b3 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -6074,12 +6074,7 @@ "reporting.share.modalContent.notification.reportingErrorTitle": "Impossible de créer le rapport", "reporting.share.modalContent.successfullyQueuedReportNotificationDescription": "Suivre sa progression dans {path}", "reporting.share.modalContent.successfullyQueuedReportNotificationTitle": "Rapport mis en file d'attente pour {objectType}", - "reporting.share.panelAction.csvDownloadStartedMessage": "Votre CSV sera téléchargé dans un instant.", - "reporting.share.panelAction.csvDownloadStartedTitle": "Téléchargement du CSV démarré", "reporting.share.panelAction.csvReportStartedTitle": "Rapport mis en file d'attente pour CSV", - "reporting.share.panelAction.downloadCsvPanelTitle": "Télécharger CSV", - "reporting.share.panelAction.failedCsvReportMessage": "Nous n'avons pas pu télécharger votre CSV pour le moment.", - "reporting.share.panelAction.failedCsvReportTitle": "Le téléchargement du CSV a échoué", "reporting.share.panelAction.failedGenerateCsvReportMessage": "Nous n'avons pas pu générer votre CSV pour le moment.", "reporting.share.panelAction.failedGenerateCsvReportTitle": "Échec du rapport CSV", "reporting.share.panelAction.generateCsvPanelTitle": "Générer des rapports CSV", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index e10155c086e64..c8b181bea9ffb 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -5828,12 +5828,7 @@ "reporting.share.modalContent.notification.reportingErrorTitle": "レポートを作成できません", "reporting.share.modalContent.successfullyQueuedReportNotificationDescription": "{path}で進捗状況を追跡します。", "reporting.share.modalContent.successfullyQueuedReportNotificationTitle": "{objectType} のレポートキュー", - "reporting.share.panelAction.csvDownloadStartedMessage": "間もなく CSV がダウンロードされます。", - "reporting.share.panelAction.csvDownloadStartedTitle": "CSVダウンロードが開始しました", "reporting.share.panelAction.csvReportStartedTitle": "CSVのキューにあるレポート", - "reporting.share.panelAction.downloadCsvPanelTitle": "CSV をダウンロード", - "reporting.share.panelAction.failedCsvReportMessage": "現在、CSVをダウンロードできませんでした。", - "reporting.share.panelAction.failedCsvReportTitle": "CSV のダウンロードに失敗", "reporting.share.panelAction.failedGenerateCsvReportMessage": "現在 CSV を生成できません。", "reporting.share.panelAction.failedGenerateCsvReportTitle": "CSVレポート失敗", "reporting.share.panelAction.generateCsvPanelTitle": "CSVレポートを生成", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 0ed330ec41630..6d89cd0ffd4f0 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -5841,12 +5841,7 @@ "reporting.share.modalContent.notification.reportingErrorTitle": "无法创建报告", "reporting.share.modalContent.successfullyQueuedReportNotificationDescription": "在 {path} 中跟踪其进度。", "reporting.share.modalContent.successfullyQueuedReportNotificationTitle": "已为 {objectType} 排队报告", - "reporting.share.panelAction.csvDownloadStartedMessage": "您的 CSV 将很快下载。", - "reporting.share.panelAction.csvDownloadStartedTitle": "CSV 下载已开始", "reporting.share.panelAction.csvReportStartedTitle": "已为 CSV 排队报告", - "reporting.share.panelAction.downloadCsvPanelTitle": "下载 CSV", - "reporting.share.panelAction.failedCsvReportMessage": "此时无法下载 CSV。", - "reporting.share.panelAction.failedCsvReportTitle": "CSV 下载失败。", "reporting.share.panelAction.failedGenerateCsvReportMessage": "我们此次无法生成 CSV。", "reporting.share.panelAction.failedGenerateCsvReportTitle": "CSV 报告失败", "reporting.share.panelAction.generateCsvPanelTitle": "生成 CSV 报告", diff --git a/x-pack/test/functional/apps/dashboard/group3/reporting/__snapshots__/download_csv.snap b/x-pack/test/functional/apps/dashboard/group3/reporting/__snapshots__/download_csv.snap deleted file mode 100644 index c062cae2f66bd..0000000000000 --- a/x-pack/test/functional/apps/dashboard/group3/reporting/__snapshots__/download_csv.snap +++ /dev/null @@ -1,35 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`dashboard Reporting Dashboard Generate CSV Default Saved Search Data Downloads a filtered CSV export of a saved search panel 1`] = ` -"\\"order_date\\",category,currency,\\"customer_id\\",\\"order_id\\",\\"day_of_week_i\\",\\"products.created_on\\",sku -\\"Jun 22, 2019 @ 00:00:00.000\\",\\"Men's Clothing, Men's Shoes\\",EUR,13,715752,6,\\"Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000\\",\\"ZO0130801308, ZO0402604026, ZO0630506305, ZO0297402974\\" -\\"Jun 22, 2019 @ 00:00:00.000\\",\\"Men's Shoes, Men's Clothing\\",EUR,50,565284,6,\\"Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000\\",\\"ZO0687206872, ZO0422304223\\" -\\"Jun 22, 2019 @ 00:00:00.000\\",\\"Men's Shoes, Men's Accessories\\",EUR,49,565266,6,\\"Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000\\",\\"ZO0255602556, ZO0468304683\\"" -`; - -exports[`dashboard Reporting Dashboard Generate CSV Default Saved Search Data Downloads a saved search panel with a custom time range that does not intersect with dashboard time range 1`] = ` -"\\"order_date\\",category,currency,\\"customer_id\\",\\"order_id\\",\\"day_of_week_i\\",\\"products.created_on\\",sku -\\"Jun 15, 2019 @ 00:00:00.000\\",\\"Women's Clothing, Women's Shoes\\",EUR,27,732985,6,\\"Dec 4, 2016 @ 00:00:00.000, Dec 4, 2016 @ 00:00:00.000, Dec 4, 2016 @ 00:00:00.000, Dec 4, 2016 @ 00:00:00.000\\",\\"ZO0048100481, ZO0133401334, ZO0153201532, ZO0381603816\\" -\\"Jun 15, 2019 @ 00:00:00.000\\",\\"Women's Accessories, Women's Clothing, Women's Shoes\\",EUR,5,731613,6,\\"Dec 4, 2016 @ 00:00:00.000, Dec 4, 2016 @ 00:00:00.000, Dec 4, 2016 @ 00:00:00.000, Dec 4, 2016 @ 00:00:00.000\\",\\"ZO0203502035, ZO0706807068, ZO0072000720, ZO0011200112\\" -\\"Jun 15, 2019 @ 00:00:00.000\\",\\"Women's Clothing, Women's Shoes, Women's Accessories\\",EUR,5,731534,6,\\"Dec 4, 2016 @ 00:00:00.000, Dec 4, 2016 @ 00:00:00.000, Dec 4, 2016 @ 00:00:00.000, Dec 4, 2016 @ 00:00:00.000\\",\\"ZO0032800328, ZO0026900269, ZO0220602206, ZO0209802098\\"" -`; - -exports[`dashboard Reporting Dashboard Generate CSV Default Saved Search Data Generate CSV export of a saved search panel 1`] = ` -"\\"order_date\\",category,currency,\\"customer_id\\",\\"order_id\\",\\"day_of_week_i\\",\\"products.created_on\\",sku -\\"Jun 22, 2019 @ 00:00:00.000\\",\\"Women's Clothing, Women's Shoes\\",EUR,27,731788,6,\\"Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000\\",\\"ZO0486004860, ZO0177901779, ZO0680506805, ZO0340503405\\" -\\"Jun 22, 2019 @ 00:00:00.000\\",\\"Women's Accessories, Women's Shoes\\",EUR,17,730663,6,\\"Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000\\",\\"ZO0697406974, ZO0370303703, ZO0368103681, ZO0013800138\\" -\\"Jun 22, 2019 @ 00:00:00.000\\",\\"Women's Accessories, Women's Clothing\\",EUR,5,727071,6,\\"Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000, Dec 11, 2016 @ 00:00:00.000\\",\\"ZO0091900919, ZO0660006600, ZO0197001970, ZO0074600746\\"" -`; - -exports[`dashboard Reporting Dashboard Generate CSV Field Formatters and Scripted Fields Generate CSV export of a saved search panel 1`] = ` -"date,\\"_id\\",name,gender,value,year,\\"years_ago\\",\\"date_informal\\" -\\"Jan 1, 1982 @ 00:00:00.000\\",\\"1982-Fethany-F\\",Fethany,F,780,1982,\\"37.00000000000000000000\\",\\"Jan 1st 82\\" -" -`; - -exports[`dashboard Reporting Dashboard Generate CSV Filtered Saved Search Downloads filtered Discover saved search report 1`] = ` -"\\"order_date\\",category,\\"order_id\\",\\"customer_full_name\\",\\"taxful_total_price\\",currency -\\"Jun 25, 2019 @ 00:00:00.000\\",\\"Women's Clothing\\",569144,\\"Betty Perkins\\",\\"61.969\\",EUR -\\"Jun 25, 2019 @ 00:00:00.000\\",\\"Women's Clothing, Women's Shoes\\",568503,\\"Betty Bryant\\",68,EUR -\\"Jun 25, 2019 @ 00:00:00.000\\",\\"Women's Accessories\\",568229,\\"Betty Reese\\",\\"22.984\\",EUR" -`; diff --git a/x-pack/test/functional/apps/dashboard/group3/reporting/download_csv.ts b/x-pack/test/functional/apps/dashboard/group3/reporting/download_csv.ts deleted file mode 100644 index ea2a66028ada5..0000000000000 --- a/x-pack/test/functional/apps/dashboard/group3/reporting/download_csv.ts +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import expect from '@kbn/expect'; -import { WebElementWrapper } from '@kbn/ftr-common-functional-ui-services'; -import { FtrProviderContext } from '../../../../ftr_provider_context'; - -export default function ({ getService, getPageObjects }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); - const kibanaServer = getService('kibanaServer'); - const dashboardPanelActions = getService('dashboardPanelActions'); - const log = getService('log'); - const testSubjects = getService('testSubjects'); - const reportingService = getService('reporting'); - const dashboardAddPanel = getService('dashboardAddPanel'); - const filterBar = getService('filterBar'); - const retry = getService('retry'); - const toasts = getService('toasts'); - const { reporting, common, dashboard, timePicker } = getPageObjects([ - 'reporting', - 'common', - 'dashboard', - 'timePicker', - ]); - - const navigateToDashboardApp = async () => { - log.debug('in navigateToDashboardApp'); - await dashboard.navigateToApp(); - await retry.tryForTime(10000, async () => { - expect(await dashboard.onDashboardLandingPage()).to.be(true); - }); - }; - - const getCsvReportData = async () => { - await toasts.dismissAll(); - const url = await reporting.getReportURL(60000); - const res = await reporting.getResponse(url ?? ''); - - expect(res.status).to.equal(200); - expect(res.get('content-type')).to.equal('text/csv; charset=utf-8'); - return res.text; - }; - - const clickDownloadCsv = async (wrapper?: WebElementWrapper) => { - log.debug('click "Generate CSV"'); - await dashboardPanelActions.clickPanelAction( - 'embeddablePanelAction-generateCsvReport', - wrapper - ); - await testSubjects.existOrFail('csvReportStarted'); // validate toast panel - }; - - const clickDownloadCsvByTitle = async (title?: string) => { - log.debug(`click "Generate CSV" on "${title}"`); - await dashboardPanelActions.clickPanelActionByTitle( - 'embeddablePanelAction-generateCsvReport', - title - ); - await testSubjects.existOrFail('csvReportStarted'); // validate toast panel - }; - - const createPartialCsv = (csvFile: unknown) => { - const partialCsvFile = (csvFile as string).split('\n').slice(0, 4); - return partialCsvFile.join('\n'); - }; - - /* - * Tests - */ - describe('Dashboard Generate CSV', () => { - describe('Default Saved Search Data', () => { - before(async () => { - await esArchiver.emptyKibanaIndex(); - await reportingService.initEcommerce(); - await kibanaServer.uiSettings.update({ 'dateFormat:tz': 'UTC' }); - }); - - beforeEach(async () => { - await navigateToDashboardApp(); - }); - - after(async () => { - await reportingService.teardownEcommerce(); - }); - - it('Generate CSV export of a saved search panel', async function () { - await dashboard.loadSavedDashboard('Ecom Dashboard - 3 Day Period'); - await clickDownloadCsvByTitle('EcommerceData'); - - const csvFile = await getCsvReportData(); - expect(csvFile.length).to.be(76137); - expectSnapshot(createPartialCsv(csvFile)).toMatch(); - }); - - it('Downloads a filtered CSV export of a saved search panel', async function () { - await dashboard.loadSavedDashboard('Ecom Dashboard - 3 Day Period'); - - // add a filter - await filterBar.addFilter({ field: 'category', operation: 'is', value: `Men's Shoes` }); - await clickDownloadCsvByTitle('EcommerceData'); - - const csvFile = await getCsvReportData(); - expect(csvFile.length).to.be(17106); - expectSnapshot(createPartialCsv(csvFile)).toMatch(); - }); - - it('Downloads a saved search panel with a custom time range that does not intersect with dashboard time range', async function () { - await dashboard.loadSavedDashboard('Ecom Dashboard - 3 Day Period - custom time range'); - await clickDownloadCsvByTitle('EcommerceData'); - - const csvFile = await getCsvReportData(); - expect(csvFile.length).to.be(23277); - expectSnapshot(createPartialCsv(csvFile)).toMatch(); - }); - - it('Gets the correct filename if panel titles are hidden', async () => { - await dashboard.loadSavedDashboard('Ecom Dashboard Hidden Panel Titles'); - const savedSearchPanel = await dashboardPanelActions.getPanelWrapperById( - '94eab06f-60ac-4a85-b771-3a8ed475c9bb' - ); // panel title is hidden - - await clickDownloadCsv(savedSearchPanel); - await testSubjects.existOrFail('csvReportStarted'); - - const csvFile = await getCsvReportData(); - expect(csvFile).to.not.be(null); - }); - }); - - describe('Filtered Saved Search', () => { - const TEST_SEARCH_TITLE = 'Customer Betty'; - const TEST_DASHBOARD_TITLE = 'Filtered Search Data'; - const from = 'Jun 20, 2019 @ 23:56:51.374'; - const to = 'Jun 25, 2019 @ 16:18:51.821'; - - before(async () => { - await esArchiver.emptyKibanaIndex(); - await reportingService.initEcommerce(); - await kibanaServer.uiSettings.update({ 'dateFormat:tz': 'UTC' }); - }); - - beforeEach(async () => { - await navigateToDashboardApp(); - log.info(`Creating empty dashboard`); - await dashboard.clickNewDashboard(); - await timePicker.setAbsoluteRange(from, to); - log.info(`Adding "${TEST_SEARCH_TITLE}" to dashboard`); - await dashboardAddPanel.addSavedSearch(TEST_SEARCH_TITLE); - await dashboard.saveDashboard(TEST_DASHBOARD_TITLE); - }); - - after(async () => { - await reportingService.teardownEcommerce(); - await common.unsetTime(); - }); - - it('Downloads filtered Discover saved search report', async () => { - await clickDownloadCsvByTitle(TEST_SEARCH_TITLE); - - const csvFile = await getCsvReportData(); - expect(csvFile.length).to.be(2446); - expectSnapshot(createPartialCsv(csvFile)).toMatch(); - }); - }); - - describe('Field Formatters and Scripted Fields', () => { - const dashboardWithScriptedFieldsSearch = 'names dashboard'; - - before(async () => { - await esArchiver.emptyKibanaIndex(); - await reportingService.initLogs(); - await esArchiver.load('x-pack/test/functional/es_archives/reporting/hugedata'); - await kibanaServer.uiSettings.update({ 'dateFormat:tz': 'UTC' }); - }); - - beforeEach(async () => { - await navigateToDashboardApp(); - await dashboard.loadSavedDashboard(dashboardWithScriptedFieldsSearch); - await timePicker.setAbsoluteRange( - 'Nov 26, 1981 @ 21:54:15.526', - 'Mar 5, 1982 @ 18:17:44.821' - ); - - await common.sleep(1000); - await filterBar.addFilter({ field: 'name.keyword', operation: 'is', value: 'Fethany' }); - await common.sleep(1000); - }); - - after(async () => { - await reportingService.teardownLogs(); - await esArchiver.unload('x-pack/test/functional/es_archives/reporting/hugedata'); - }); - - it('Generate CSV export of a saved search panel', async () => { - await clickDownloadCsvByTitle('namessearch'); - - const csvFile = await getCsvReportData(); - expect(csvFile.length).to.be(166); - expectSnapshot(createPartialCsv(csvFile)).toMatch(); - }); - }); - }); -} diff --git a/x-pack/test/functional/apps/dashboard/group3/reporting/index.ts b/x-pack/test/functional/apps/dashboard/group3/reporting/index.ts index ef9821a544b3a..9dfbd61473302 100644 --- a/x-pack/test/functional/apps/dashboard/group3/reporting/index.ts +++ b/x-pack/test/functional/apps/dashboard/group3/reporting/index.ts @@ -10,6 +10,5 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('Reporting', function () { loadTestFile(require.resolve('./screenshots')); - loadTestFile(require.resolve('./download_csv')); }); } diff --git a/x-pack/test/functional/apps/reporting/README.md b/x-pack/test/functional/apps/reporting/README.md index 5d47804fef284..ed2402e9d9d58 100644 --- a/x-pack/test/functional/apps/reporting/README.md +++ b/x-pack/test/functional/apps/reporting/README.md @@ -9,7 +9,6 @@ Functional tests on report generation are under the applications that use report - `x-pack/test/functional/apps/visualize/reporting.ts` **CSV Report testing:** - - `x-pack/test/functional/apps/dashboard/reporting/download_csv.ts` - `x-pack/test/functional/apps/discover/reporting.ts` Reporting Management app tests are in `functional/apps/reporting_management`.