Skip to content

Commit 58463b9

Browse files
committed
Fix hasCustomEventTrigger telemetry for workflow list enable/disable
1 parent 2c963b4 commit 58463b9

7 files changed

Lines changed: 179 additions & 1 deletion

File tree

src/platform/plugins/shared/workflows_management/public/common/service/telemetry.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,52 @@ describe('WorkflowsBaseTelemetry', () => {
363363
);
364364
});
365365

366+
it('includes hasCustomEventTrigger on enable/disable when workflowDefinition is provided', () => {
367+
telemetry.reportWorkflowUpdated({
368+
workflowId: 'wf-1',
369+
workflowUpdate: { enabled: true },
370+
workflowDefinition: {
371+
triggers: [{ type: 'scheduled' }, { type: 'cases.created' }],
372+
} as Partial<WorkflowYaml>,
373+
hasValidationErrors: false,
374+
validationErrorCount: 0,
375+
origin: 'workflow_list',
376+
});
377+
378+
expect(mockClient.reportEvent).toHaveBeenCalledWith(
379+
WorkflowLifecycleEventTypes.WorkflowEnabledStateChanged,
380+
expect.objectContaining({
381+
hasCustomEventTrigger: true,
382+
origin: 'workflow_list',
383+
})
384+
);
385+
});
386+
387+
it('does not report hasCustomEventTrigger true on enable/disable when workflowDefinition is omitted', () => {
388+
telemetry.reportWorkflowUpdated({
389+
workflowId: 'wf-1',
390+
workflowUpdate: { enabled: true },
391+
hasValidationErrors: false,
392+
validationErrorCount: 0,
393+
origin: 'workflow_list',
394+
});
395+
396+
expect(mockClient.reportEvent).toHaveBeenCalledWith(
397+
WorkflowLifecycleEventTypes.WorkflowEnabledStateChanged,
398+
expect.objectContaining({
399+
workflowId: 'wf-1',
400+
enabled: true,
401+
origin: 'workflow_list',
402+
})
403+
);
404+
expect(mockClient.reportEvent).toHaveBeenCalledWith(
405+
WorkflowLifecycleEventTypes.WorkflowEnabledStateChanged,
406+
expect.not.objectContaining({
407+
hasCustomEventTrigger: true,
408+
})
409+
);
410+
});
411+
366412
it('determines editorType as yaml when yaml is in the update', () => {
367413
telemetry.reportWorkflowUpdated({
368414
workflowId: 'wf-1',

src/platform/plugins/shared/workflows_management/public/entities/workflows/model/use_workflow_actions.test.ts

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,15 @@
1010
import { act, renderHook, waitFor } from '@testing-library/react';
1111
import React from 'react';
1212
import { QueryClient, QueryClientProvider } from '@kbn/react-query';
13-
import type { WorkflowDetailDto, WorkflowListDto } from '@kbn/workflows';
13+
import type { WorkflowDetailDto, WorkflowListDto, WorkflowYaml } from '@kbn/workflows';
1414
import { createMockWorkflowApi } from '@kbn/workflows-ui/src/api/workflows_api.mock';
1515
import { useWorkflowActions } from './use_workflow_actions';
16+
import {
17+
workflowEventNames,
18+
WorkflowLifecycleEventTypes,
19+
} from '../../../common/lib/telemetry/events/workflows';
20+
import type { TelemetryServiceClient } from '../../../common/lib/telemetry/types';
21+
import { WorkflowsBaseTelemetry } from '../../../common/service/telemetry';
1622
import { parseImportFile } from '../../../features/import_workflows/lib/parse_import_file';
1723
import type { ClientPreflightResult } from '../../../features/import_workflows/lib/parse_import_file';
1824
import { useTelemetry } from '../../../hooks/use_telemetry';
@@ -1000,6 +1006,94 @@ describe('useWorkflowActions – import mutations', () => {
10001006
);
10011007
});
10021008

1009+
it('should pass workflowDefinition to telemetry for enable/disable updates', async () => {
1010+
mockWorkflowApi.updateWorkflow.mockResolvedValueOnce(undefined as never);
1011+
const workflowDefinition = {
1012+
version: '1',
1013+
name: 'Test',
1014+
enabled: false,
1015+
triggers: [{ type: 'cases.created' }],
1016+
steps: [],
1017+
} as unknown as Partial<WorkflowYaml>;
1018+
1019+
const { result } = renderHook(() => useWorkflowActions(), { wrapper });
1020+
1021+
act(() => {
1022+
result.current.updateWorkflow.mutate({
1023+
id: 'wf-1',
1024+
workflow: { enabled: true },
1025+
workflowDefinition,
1026+
});
1027+
});
1028+
1029+
await waitFor(() => expect(result.current.updateWorkflow.isSuccess).toBe(true));
1030+
1031+
expect(mockTelemetry.reportWorkflowUpdated).toHaveBeenCalledWith(
1032+
expect.objectContaining({
1033+
workflowId: 'wf-1',
1034+
workflowDefinition,
1035+
})
1036+
);
1037+
});
1038+
1039+
it('should not pass workflowDefinition to telemetry when mutate omits it', async () => {
1040+
mockWorkflowApi.updateWorkflow.mockResolvedValueOnce(undefined as never);
1041+
1042+
const { result } = renderHook(() => useWorkflowActions(), { wrapper });
1043+
1044+
act(() => {
1045+
result.current.updateWorkflow.mutate({
1046+
id: 'wf-1',
1047+
workflow: { enabled: true },
1048+
});
1049+
});
1050+
1051+
await waitFor(() => expect(result.current.updateWorkflow.isSuccess).toBe(true));
1052+
1053+
const telemetryParams = mockTelemetry.reportWorkflowUpdated.mock.calls[0]?.[0];
1054+
expect(telemetryParams?.workflowDefinition).toBeUndefined();
1055+
});
1056+
1057+
it('reports hasCustomEventTrigger on list enable when workflowDefinition is provided', async () => {
1058+
const reportEvent = jest.fn();
1059+
const telemetryClient: TelemetryServiceClient = { reportEvent };
1060+
const realTelemetry = new WorkflowsBaseTelemetry(telemetryClient);
1061+
mockUseTelemetry.mockReturnValue(realTelemetry as unknown as ReturnType<typeof useTelemetry>);
1062+
1063+
mockWorkflowApi.updateWorkflow.mockResolvedValueOnce(undefined as never);
1064+
1065+
const workflowDefinition = {
1066+
version: '1',
1067+
name: 'Test',
1068+
enabled: false,
1069+
triggers: [{ type: 'cases.created' }],
1070+
steps: [],
1071+
} as unknown as Partial<WorkflowYaml>;
1072+
1073+
const { result } = renderHook(() => useWorkflowActions(), { wrapper });
1074+
1075+
act(() => {
1076+
result.current.updateWorkflow.mutate({
1077+
id: 'wf-1',
1078+
workflow: { enabled: true },
1079+
workflowDefinition,
1080+
});
1081+
});
1082+
1083+
await waitFor(() => expect(result.current.updateWorkflow.isSuccess).toBe(true));
1084+
1085+
expect(reportEvent).toHaveBeenCalledWith(
1086+
WorkflowLifecycleEventTypes.WorkflowEnabledStateChanged,
1087+
expect.objectContaining({
1088+
eventName: workflowEventNames[WorkflowLifecycleEventTypes.WorkflowEnabledStateChanged],
1089+
workflowId: 'wf-1',
1090+
enabled: true,
1091+
hasCustomEventTrigger: true,
1092+
origin: 'workflow_list',
1093+
})
1094+
);
1095+
});
1096+
10031097
it('should optimistically update workflow detail for non-YAML changes', async () => {
10041098
const detailData = createMockWorkflowDetailDto({
10051099
id: 'wf-1',

src/platform/plugins/shared/workflows_management/public/entities/workflows/model/use_workflow_actions.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type {
1717
UpdatedWorkflowResponseDto,
1818
WorkflowDetailDto,
1919
WorkflowListDto,
20+
WorkflowYaml,
2021
} from '@kbn/workflows';
2122
import type { BulkCreateWorkflowsResponse } from '@kbn/workflows-ui';
2223
import { useRunWorkflow, useWorkflowsApi } from '@kbn/workflows-ui';
@@ -34,6 +35,8 @@ type HttpError = IHttpFetchError<ResponseErrorBody>;
3435
export interface UpdateWorkflowParams {
3536
id: string;
3637
workflow: Partial<WorkflowDetailDto>;
38+
/** Workflow definition from list/detail cache; used for enable/disable telemetry metadata. */
39+
workflowDefinition?: Partial<WorkflowYaml> | null;
3740
isBulkAction?: boolean;
3841
bulkActionCount?: number;
3942
/**
@@ -152,6 +155,7 @@ export function useWorkflowActions() {
152155
telemetry.reportWorkflowUpdated({
153156
workflowId: variables.id,
154157
workflowUpdate: variables.workflow,
158+
workflowDefinition: variables.workflowDefinition,
155159
hasValidationErrors: false,
156160
validationErrorCount: 0,
157161
isBulkAction: variables.isBulkAction ?? false,
@@ -168,6 +172,7 @@ export function useWorkflowActions() {
168172
telemetry.reportWorkflowUpdated({
169173
workflowId: variables.id,
170174
workflowUpdate: variables.workflow,
175+
workflowDefinition: variables.workflowDefinition,
171176
hasValidationErrors: false,
172177
validationErrorCount: 0,
173178
isBulkAction: variables.isBulkAction ?? false,

src/platform/plugins/shared/workflows_management/public/features/workflow_list/ui/use_workflow_bulk_actions.test.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ describe('useWorkflowBulkActions', () => {
336336
expect.objectContaining({
337337
id: 'wf-disabled',
338338
workflow: { enabled: true },
339+
workflowDefinition: disabledWorkflow.definition,
339340
}),
340341
expect.any(Object)
341342
);
@@ -372,6 +373,7 @@ describe('useWorkflowBulkActions', () => {
372373
expect.objectContaining({
373374
id: 'wf-enabled',
374375
workflow: { enabled: false },
376+
workflowDefinition: enabledWorkflow.definition,
375377
}),
376378
expect.any(Object)
377379
);

src/platform/plugins/shared/workflows_management/public/features/workflow_list/ui/use_workflow_bulk_actions.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export const useWorkflowBulkActions = ({
136136
{
137137
id: workflow.id,
138138
workflow: updateData,
139+
workflowDefinition: workflow.definition ?? undefined,
139140
isBulkAction: true,
140141
bulkActionCount: totalCount,
141142
skipRefetch: true,

src/platform/plugins/shared/workflows_management/public/features/workflow_list/ui/workflow_list.test.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
import { render, screen, within } from '@testing-library/react';
11+
import userEvent from '@testing-library/user-event';
1112
import React from 'react';
1213
import type { WorkflowListDto, WorkflowListItemDto, WorkflowsSearchParams } from '@kbn/workflows';
1314
import { createMockWorkflowsCapabilities as mockCreateMockWorkflowsCapabilities } from '@kbn/workflows-ui/mocks';
@@ -339,6 +340,34 @@ describe('WorkflowList', () => {
339340
expect(toggle).toBeInTheDocument();
340341
});
341342

343+
it('passes workflow definition when toggling enabled from the list', async () => {
344+
const workflow = createMockWorkflow({
345+
id: 'wf-toggle',
346+
enabled: true,
347+
});
348+
349+
mockUseWorkflows.mockReturnValue({
350+
data: createMockWorkflowListDto([workflow]),
351+
isLoading: false,
352+
error: null,
353+
refetch: mockRefetch,
354+
});
355+
356+
renderComponent();
357+
358+
await userEvent.click(screen.getByTestId('workflowToggleSwitch-wf-toggle'));
359+
360+
expect(mockUpdateWorkflow.mutate).toHaveBeenCalledWith(
361+
expect.objectContaining({
362+
id: 'wf-toggle',
363+
workflow: { enabled: false },
364+
workflowDefinition: workflow.definition,
365+
skipRefetch: true,
366+
}),
367+
expect.any(Object)
368+
);
369+
});
370+
342371
it('renders multiple workflows', () => {
343372
const workflows = [
344373
createMockWorkflow({ id: 'wf-1', name: 'Workflow One' }),

src/platform/plugins/shared/workflows_management/public/features/workflow_list/ui/workflow_list.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ export function WorkflowList({ search, setSearch, onCreateWorkflow }: WorkflowLi
243243
workflow: {
244244
enabled: !item.enabled,
245245
},
246+
workflowDefinition: item.definition ?? undefined,
246247
skipRefetch: true,
247248
},
248249
{

0 commit comments

Comments
 (0)