@orchestrator-ui/orchestrator-ui-components
Version:
Library of UI Components used to display the workflow orchestrator frontend
521 lines (449 loc) • 15.5 kB
text/typescript
import { EuiThemeComputed } from '@elastic/eui';
import {
FieldValue,
ProcessStatus,
ProductBlockInstance,
SubscriptionAction,
SubscriptionDetailProcess,
WorkflowTarget,
} from '../../../types';
import {
flattenArrayProps,
getFieldFromProductBlockInstanceValues,
getLastUncompletedProcess,
getLatestTaskDate,
getProductBlockTitle,
getWorkflowTargetColor,
getWorkflowTargetIconContent,
mapProductBlockInstancesToEuiSelectableOptions,
parseErrorDetail,
} from './utils';
describe('getFieldFromProductBlockInstanceValues()', () => {
const instanceValues: FieldValue[] = [
{ field: 'field1', value: 'value1' },
{ field: 'field2', value: 'value2' },
];
it('returns field value when field matches', () => {
const result = getFieldFromProductBlockInstanceValues(
instanceValues,
'field1',
);
expect(result).toEqual('value1');
});
it('returns empty string when field is not found', () => {
const result = getFieldFromProductBlockInstanceValues(
instanceValues,
'unknonw_field',
);
expect(result).toEqual('');
});
});
describe('getProductBlockTitle()', () => {
const instanceValues: FieldValue[] = [
{ field: 'field1', value: 'value1' },
{ field: 'field2', value: 'value2' },
];
it('returns name value there is no title field', () => {
const valuesWithName = [
...instanceValues,
{ field: 'name', value: 'name_value' },
];
expect(getProductBlockTitle(valuesWithName)).toBe('name_value');
});
it('returns title field when there is a title field', () => {
const valuesWithNameAndTitle = [
...instanceValues,
{ field: 'name', value: 'name_value' },
{ field: 'title', value: 'title_value' },
];
expect(getProductBlockTitle(valuesWithNameAndTitle)).toBe(
'title_value',
);
});
it('returns empty string when there are no title or name fields', () => {
expect(getProductBlockTitle(instanceValues)).toBe('');
});
});
describe('flattenArrayProps', () => {
it('should flatten an object with array values into a comma-separated string', () => {
const action: SubscriptionAction = {
name: 'action name',
description: 'action description',
usable_when: ['Status1', 'Status2', 'Status3'],
};
const result = flattenArrayProps(action);
expect(result).toEqual({
name: 'action name',
description: 'action description',
usable_when: 'Status1, Status2, Status3',
});
});
it('should handle an object with non-array values', () => {
const action: SubscriptionAction = {
name: 'action name',
description: 'action description',
};
const result = flattenArrayProps(action);
expect(result).toEqual({
name: 'action name',
description: 'action description',
});
});
});
describe('getWorkflowTargetColor', () => {
it('should return successText color for CREATE', () => {
const theme = {
colors: {
successText: 'successTextColor',
},
} as EuiThemeComputed;
expect(getWorkflowTargetColor(WorkflowTarget.CREATE, theme)).toBe(
'successTextColor',
);
});
it('should return primaryText color for MODIFY', () => {
const theme = {
colors: {
primaryText: 'primaryTextColor',
},
} as EuiThemeComputed;
expect(getWorkflowTargetColor(WorkflowTarget.MODIFY, theme)).toBe(
'primaryTextColor',
);
});
it('should return warning color for SYSTEM', () => {
const theme = {
colors: {
warning: 'warningColor',
},
} as EuiThemeComputed;
expect(getWorkflowTargetColor(WorkflowTarget.SYSTEM, theme)).toBe(
'warningColor',
);
});
it('should return danger color for TERMINATE', () => {
const theme = {
colors: {
danger: 'dangerColor',
},
} as EuiThemeComputed;
expect(getWorkflowTargetColor(WorkflowTarget.TERMINATE, theme)).toBe(
'dangerColor',
);
});
it('should return body color for unknown targets', () => {
const theme = {
colors: {
body: 'bodyColor',
},
} as EuiThemeComputed;
// Test with an unknown target
expect(
getWorkflowTargetColor('UNKNOWN_TARGET' as WorkflowTarget, theme),
).toBe('bodyColor');
});
});
describe('getWorkflowTargetIconContent', () => {
it('should return C for CREATE', () => {
expect(getWorkflowTargetIconContent(WorkflowTarget.CREATE)).toBe('C');
});
it('should return T for SYSTEM', () => {
expect(getWorkflowTargetIconContent(WorkflowTarget.SYSTEM)).toBe('T');
});
it('should return X for TERMINATE', () => {
expect(getWorkflowTargetIconContent(WorkflowTarget.TERMINATE)).toBe(
'X',
);
});
it('should return M for unknown targets', () => {
// Test with an unknown target
expect(
getWorkflowTargetIconContent('UNKNOWN_TARGET' as WorkflowTarget),
).toBe('M');
});
});
const testProcess: SubscriptionDetailProcess = {
workflowName: 'testWorkflow 1',
lastStatus: ProcessStatus.COMPLETED,
workflowTarget: WorkflowTarget.MODIFY,
createdBy: 'testUser 1',
processId: 'testProcessId 1',
startedAt: '2021-01-01T00:00:00Z',
isTask: false,
};
describe('getLastUncompletedProcess', () => {
it('Returns empty string with empty process array', () => {
const processes: SubscriptionDetailProcess[] = [];
const getLastUncompletedProcessResult =
getLastUncompletedProcess(processes);
expect(getLastUncompletedProcessResult).toBe(undefined);
});
it('Return undefined string when there is only completed process', () => {
const completedProcesses = [
{
...testProcess,
lastStatus: ProcessStatus.COMPLETED,
startedAt: '2021-01-01T00:00:00Z',
},
{
...testProcess,
lastStatus: ProcessStatus.COMPLETED,
startedAt: '2021-02-01T00:00:00Z',
},
{
...testProcess,
lastStatus: ProcessStatus.COMPLETED,
startedAt: '2021-03-01T00:00:00Z',
},
];
const lastUncompletedProcess =
getLastUncompletedProcess(completedProcesses);
expect(lastUncompletedProcess).toBe(undefined);
});
it('Returns uncompleted process from list of processes', () => {
const failedProcess = {
...testProcess,
lastStatus: ProcessStatus.FAILED,
processId: 'FAILED_PROCESS_ID',
startedAt: '2021-02-01T00:00:00Z',
};
const failedProcesses = [
{
...testProcess,
lastStatus: ProcessStatus.COMPLETED,
startedAt: '2021-01-01T00:00:00Z',
},
failedProcess,
{
...testProcess,
lastStatus: ProcessStatus.COMPLETED,
startedAt: '2021-03-01T00:00:00Z',
},
];
const lastUncompletedProcess =
getLastUncompletedProcess(failedProcesses);
expect(lastUncompletedProcess?.processId).toBe('FAILED_PROCESS_ID');
});
it('Returns last failed process if there are more uncompleted processes', () => {
const failedProcess = {
...testProcess,
lastStatus: ProcessStatus.FAILED,
processId: 'FAILED_PROCESS_1',
startedAt: '2021-02-01T00:00:00Z',
};
const failedProcess2 = {
...testProcess,
lastStatus: ProcessStatus.SUSPENDED,
processId: 'FAILED_PROCESS_ID_2',
startedAt: '2021-04-01T00:00:00Z',
};
const failedProcesses = [
{
...testProcess,
lastStatus: ProcessStatus.COMPLETED,
startedAt: '2021-01-01T00:00:00Z',
},
failedProcess,
{
...testProcess,
lastStatus: ProcessStatus.COMPLETED,
startedAt: '2021-03-01T00:00:00Z',
},
failedProcess2,
];
const lastUncompletedProcess =
getLastUncompletedProcess(failedProcesses);
expect(lastUncompletedProcess?.processId).toBe('FAILED_PROCESS_ID_2');
});
});
describe('getLatestTaskDate', () => {
it('Returns empty string on empty array', () => {
const tasks: SubscriptionDetailProcess[] = [];
const lastTask = getLatestTaskDate(tasks);
expect(lastTask).toBe('');
});
it('Returns empty string if there are no tasks among the processes', () => {
const workflowsOnly = [
{ ...testProcess, isTask: false },
{ ...testProcess, isTask: false },
];
const lastTask = getLatestTaskDate(workflowsOnly);
expect(lastTask).toBe('');
});
it('Returns date of tasks among the processes', () => {
const workflowsAndTask = [
{ ...testProcess, isTask: false },
{ ...testProcess, isTask: true, startedAt: '2021-01-01T00:00:00Z' },
{ ...testProcess, isTask: false },
];
const lastTaskDate = getLatestTaskDate(workflowsAndTask);
expect(lastTaskDate).toBe('2021-01-01T00:00:00Z');
});
it('Returns date of last task among the processes if there are more tasks', () => {
const workflowsAndTask = [
{
...testProcess,
isTask: false,
startedAt: '2021-01-01T00:00:00Z',
},
{ ...testProcess, isTask: true, startedAt: '2021-02-01T00:00:00Z' },
{
...testProcess,
isTask: false,
startedAt: '2021-03-01T00:00:00Z',
},
{ ...testProcess, isTask: true, startedAt: '2021-04-01T00:00:00Z' },
];
const lastTaskDate = getLatestTaskDate(workflowsAndTask);
expect(lastTaskDate).toBe('2021-04-01T00:00:00Z');
});
});
describe('mapProductBlockInstancesToEuiSelectableOptions', () => {
const baseProductBlockInstance: Omit<
ProductBlockInstance,
'id' | 'productBlockInstanceValues'
> = {
subscriptionInstanceId: '',
parent: null,
inUseByRelations: [],
subscription: {
subscriptionId: '',
description: '',
},
};
it('maps product block instances to EuiSelectableOptions', () => {
// Given
const productBlockInstances: ProductBlockInstance[] = [
{
...baseProductBlockInstance,
id: 0,
productBlockInstanceValues: [
{
field: 'name',
value: 'test1',
},
],
},
{
...baseProductBlockInstance,
id: 1,
productBlockInstanceValues: [
{
field: 'name',
value: 'test2',
},
],
},
];
// When
const result = mapProductBlockInstancesToEuiSelectableOptions(
productBlockInstances,
);
// Then
expect(result).toEqual([
{
label: 'test1',
data: {
ids: [0],
},
},
{
label: 'test2',
data: {
ids: [1],
},
},
]);
});
it('maps product block instances to EuiSelectableOptions and groups ids by name', () => {
// Given
const productBlockInstances: ProductBlockInstance[] = [
{
...baseProductBlockInstance,
id: 0,
productBlockInstanceValues: [
{
field: 'name',
value: 'test1',
},
],
},
{
...baseProductBlockInstance,
id: 1,
productBlockInstanceValues: [
{
field: 'name',
value: 'test2',
},
],
},
{
...baseProductBlockInstance,
id: 2,
productBlockInstanceValues: [
{
field: 'name',
value: 'test1',
},
],
},
];
// When
const result = mapProductBlockInstancesToEuiSelectableOptions(
productBlockInstances,
);
// Then
expect(result).toEqual([
{
label: 'test1',
data: {
ids: [0, 2],
},
},
{
label: 'test2',
data: {
ids: [1],
},
},
]);
});
});
describe('parseErrorDetail', () => {
it('parses a single UUID inside brackets', () => {
const input =
"Subscription 123 has still failed processes with id's: ['11111111-1111-1111-1111-111111111111']";
const { failedIds, filteredInput } = parseErrorDetail(input);
expect(failedIds).toEqual(['11111111-1111-1111-1111-111111111111']);
expect(filteredInput).toBe(
"Subscription 123 has still failed processes with id's:",
);
});
it('parses multiple UUIDs inside brackets', () => {
const input =
"Failed processes: ['11111111-1111-1111-1111-111111111111', '22222222-2222-2222-2222-222222222222']";
const { failedIds, filteredInput } = parseErrorDetail(input);
expect(failedIds).toEqual([
'11111111-1111-1111-1111-111111111111',
'22222222-2222-2222-2222-222222222222',
]);
expect(filteredInput).toBe('Failed processes:');
});
it('returns empty array when no brackets present', () => {
const input = 'No failed processes.';
const { failedIds, filteredInput } = parseErrorDetail(input);
expect(failedIds).toEqual([]);
expect(filteredInput).toBe('No failed processes.');
});
it('ignores extra spaces or commas inside brackets', () => {
const input =
"Errors: [ '11111111-1111-1111-1111-111111111111' , '22222222-2222-2222-2222-222222222222' ]";
const { failedIds, filteredInput } = parseErrorDetail(input);
expect(failedIds).toEqual([
'11111111-1111-1111-1111-111111111111',
'22222222-2222-2222-2222-222222222222',
]);
expect(filteredInput).toBe('Errors:');
});
});