Write more tests (#8799)
This commit is contained in:
committed by
GitHub
parent
b857d45182
commit
38b83f0866
@ -0,0 +1,53 @@
|
|||||||
|
import { getTriggerStepName } from '../getTriggerStepName';
|
||||||
|
|
||||||
|
it('returns the expected name for a DATABASE_EVENT trigger', () => {
|
||||||
|
expect(
|
||||||
|
getTriggerStepName({
|
||||||
|
type: 'DATABASE_EVENT',
|
||||||
|
name: '',
|
||||||
|
settings: {
|
||||||
|
eventName: 'company.created',
|
||||||
|
outputSchema: {},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toBe('Company is Created');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the expected name for a MANUAL trigger without a defined objectType', () => {
|
||||||
|
expect(
|
||||||
|
getTriggerStepName({
|
||||||
|
type: 'MANUAL',
|
||||||
|
name: '',
|
||||||
|
settings: {
|
||||||
|
objectType: undefined,
|
||||||
|
outputSchema: {},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toBe('Manual trigger');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the expected name for a MANUAL trigger with a defined objectType', () => {
|
||||||
|
expect(
|
||||||
|
getTriggerStepName({
|
||||||
|
type: 'MANUAL',
|
||||||
|
name: '',
|
||||||
|
settings: {
|
||||||
|
objectType: 'company',
|
||||||
|
outputSchema: {},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toBe('Manual trigger for Company');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when an unknown trigger type is provided', () => {
|
||||||
|
expect(() => {
|
||||||
|
getTriggerStepName({
|
||||||
|
type: 'unknown' as any,
|
||||||
|
name: '',
|
||||||
|
settings: {
|
||||||
|
objectType: 'company',
|
||||||
|
outputSchema: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
@ -2,6 +2,8 @@ import {
|
|||||||
WorkflowDatabaseEventTrigger,
|
WorkflowDatabaseEventTrigger,
|
||||||
WorkflowTrigger,
|
WorkflowTrigger,
|
||||||
} from '@/workflow/types/Workflow';
|
} from '@/workflow/types/Workflow';
|
||||||
|
import { assertUnreachable } from '@/workflow/utils/assertUnreachable';
|
||||||
|
import { isDefined } from 'twenty-ui';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
import { capitalize } from '~/utils/string/capitalize';
|
||||||
|
|
||||||
export const getTriggerStepName = (trigger: WorkflowTrigger): string => {
|
export const getTriggerStepName = (trigger: WorkflowTrigger): string => {
|
||||||
@ -9,14 +11,14 @@ export const getTriggerStepName = (trigger: WorkflowTrigger): string => {
|
|||||||
case 'DATABASE_EVENT':
|
case 'DATABASE_EVENT':
|
||||||
return getDatabaseEventTriggerStepName(trigger);
|
return getDatabaseEventTriggerStepName(trigger);
|
||||||
case 'MANUAL':
|
case 'MANUAL':
|
||||||
if (!trigger.settings.objectType) {
|
if (!isDefined(trigger.settings.objectType)) {
|
||||||
return 'Manual trigger';
|
return 'Manual trigger';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Manual trigger for ' + capitalize(trigger.settings.objectType);
|
return 'Manual trigger for ' + capitalize(trigger.settings.objectType);
|
||||||
default:
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return assertUnreachable(trigger);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDatabaseEventTriggerStepName = (
|
const getDatabaseEventTriggerStepName = (
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
import { assertUnreachable } from '@/workflow/utils/assertUnreachable';
|
||||||
|
|
||||||
|
it('throws when argument is not never', () => {
|
||||||
|
expect(() => {
|
||||||
|
assertUnreachable(42 as never);
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws with the provided error message when argument is not never', () => {
|
||||||
|
expect(() => {
|
||||||
|
assertUnreachable(42 as never, 'Custom error!');
|
||||||
|
}).toThrow('Custom error!');
|
||||||
|
});
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
import { WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
|
||||||
|
import { assertWorkflowWithCurrentVersionIsDefined } from '../assertWorkflowWithCurrentVersionIsDefined';
|
||||||
|
|
||||||
|
it('throws when provided workflow is undefined', () => {
|
||||||
|
expect(() => {
|
||||||
|
assertWorkflowWithCurrentVersionIsDefined(undefined);
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throws when provided workflow's current version is undefined", () => {
|
||||||
|
expect(() => {
|
||||||
|
assertWorkflowWithCurrentVersionIsDefined(
|
||||||
|
{} as unknown as WorkflowWithCurrentVersion,
|
||||||
|
);
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||||
|
import { getManualTriggerDefaultSettings } from '../getManualTriggerDefaultSettings';
|
||||||
|
|
||||||
|
it('returns settings for a manual trigger that can be activated from any where', () => {
|
||||||
|
expect(
|
||||||
|
getManualTriggerDefaultSettings({
|
||||||
|
availability: 'EVERYWHERE',
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
}),
|
||||||
|
).toStrictEqual({
|
||||||
|
objectType: undefined,
|
||||||
|
outputSchema: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns settings for a manual trigger that can be activated from any where', () => {
|
||||||
|
expect(
|
||||||
|
getManualTriggerDefaultSettings({
|
||||||
|
availability: 'WHEN_RECORD_SELECTED',
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
}),
|
||||||
|
).toStrictEqual({
|
||||||
|
objectType: generatedMockObjectMetadataItems[0].nameSingular,
|
||||||
|
outputSchema: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||||
|
import { getStepDefaultDefinition } from '../getStepDefaultDefinition';
|
||||||
|
|
||||||
|
it('returns a valid definition for CODE actions', () => {
|
||||||
|
expect(
|
||||||
|
getStepDefaultDefinition({
|
||||||
|
type: 'CODE',
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
}),
|
||||||
|
).toStrictEqual({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: 'Code',
|
||||||
|
type: 'CODE',
|
||||||
|
valid: false,
|
||||||
|
settings: {
|
||||||
|
input: {
|
||||||
|
serverlessFunctionId: '',
|
||||||
|
serverlessFunctionVersion: '',
|
||||||
|
serverlessFunctionInput: {},
|
||||||
|
},
|
||||||
|
outputSchema: {},
|
||||||
|
errorHandlingOptions: {
|
||||||
|
continueOnFailure: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
retryOnFailure: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a valid definition for SEND_EMAIL actions', () => {
|
||||||
|
expect(
|
||||||
|
getStepDefaultDefinition({
|
||||||
|
type: 'SEND_EMAIL',
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
}),
|
||||||
|
).toStrictEqual({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: 'Send Email',
|
||||||
|
type: 'SEND_EMAIL',
|
||||||
|
valid: false,
|
||||||
|
settings: {
|
||||||
|
input: {
|
||||||
|
connectedAccountId: '',
|
||||||
|
email: '',
|
||||||
|
subject: '',
|
||||||
|
body: '',
|
||||||
|
},
|
||||||
|
outputSchema: {},
|
||||||
|
errorHandlingOptions: {
|
||||||
|
continueOnFailure: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
retryOnFailure: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a valid definition for RECORD_CRUD.CREATE actions', () => {
|
||||||
|
expect(
|
||||||
|
getStepDefaultDefinition({
|
||||||
|
type: 'RECORD_CRUD.CREATE',
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
}),
|
||||||
|
).toStrictEqual({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: 'Create Record',
|
||||||
|
type: 'RECORD_CRUD',
|
||||||
|
valid: false,
|
||||||
|
settings: {
|
||||||
|
input: {
|
||||||
|
type: 'CREATE',
|
||||||
|
objectName: generatedMockObjectMetadataItems[0].nameSingular,
|
||||||
|
objectRecord: {},
|
||||||
|
},
|
||||||
|
outputSchema: {},
|
||||||
|
errorHandlingOptions: {
|
||||||
|
continueOnFailure: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
retryOnFailure: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throws for RECORD_CRUD.DELETE actions as it's not implemented yet", () => {
|
||||||
|
expect(() => {
|
||||||
|
getStepDefaultDefinition({
|
||||||
|
type: 'RECORD_CRUD.DELETE',
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
});
|
||||||
|
}).toThrow('Not implemented yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throws for RECORD_CRUD.UPDATE actions as it's not implemented yet", () => {
|
||||||
|
expect(() => {
|
||||||
|
getStepDefaultDefinition({
|
||||||
|
type: 'RECORD_CRUD.UPDATE',
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
});
|
||||||
|
}).toThrow('Not implemented yet');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when providing an unknown type', () => {
|
||||||
|
expect(() => {
|
||||||
|
getStepDefaultDefinition({
|
||||||
|
type: 'unknown' as any,
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
});
|
||||||
|
}).toThrow('Unknown type: unknown');
|
||||||
|
});
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
||||||
|
import { getTriggerDefaultDefinition } from '../getTriggerDefaultDefinition';
|
||||||
|
|
||||||
|
it('throws if the activeObjectMetadataItems list is empty', () => {
|
||||||
|
expect(() => {
|
||||||
|
getTriggerDefaultDefinition({
|
||||||
|
type: 'DATABASE_EVENT',
|
||||||
|
activeObjectMetadataItems: [],
|
||||||
|
});
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a valid configuration for DATABASE_EVENT trigger type', () => {
|
||||||
|
expect(
|
||||||
|
getTriggerDefaultDefinition({
|
||||||
|
type: 'DATABASE_EVENT',
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
}),
|
||||||
|
).toStrictEqual({
|
||||||
|
type: 'DATABASE_EVENT',
|
||||||
|
settings: {
|
||||||
|
eventName: `${generatedMockObjectMetadataItems[0].nameSingular}.created`,
|
||||||
|
outputSchema: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns a valid configuration for MANUAL trigger type', () => {
|
||||||
|
expect(
|
||||||
|
getTriggerDefaultDefinition({
|
||||||
|
type: 'MANUAL',
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
}),
|
||||||
|
).toStrictEqual({
|
||||||
|
type: 'MANUAL',
|
||||||
|
settings: {
|
||||||
|
objectType: generatedMockObjectMetadataItems[0].nameSingular,
|
||||||
|
outputSchema: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when providing an unknown trigger type', () => {
|
||||||
|
expect(() => {
|
||||||
|
getTriggerDefaultDefinition({
|
||||||
|
type: 'unknown' as any,
|
||||||
|
activeObjectMetadataItems: generatedMockObjectMetadataItems,
|
||||||
|
});
|
||||||
|
}).toThrow('Unknown type: unknown');
|
||||||
|
});
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
import {
|
||||||
|
WorkflowCodeAction,
|
||||||
|
WorkflowRecordCRUDAction,
|
||||||
|
} from '@/workflow/types/Workflow';
|
||||||
|
import { isWorkflowRecordCreateAction } from '../isWorkflowRecordCreateAction';
|
||||||
|
|
||||||
|
it('returns false when providing an action that is not Record Create', () => {
|
||||||
|
const codeAction: WorkflowCodeAction = {
|
||||||
|
type: 'CODE',
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
settings: {
|
||||||
|
errorHandlingOptions: {
|
||||||
|
continueOnFailure: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
retryOnFailure: {
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
serverlessFunctionId: '',
|
||||||
|
serverlessFunctionVersion: '',
|
||||||
|
serverlessFunctionInput: {},
|
||||||
|
},
|
||||||
|
outputSchema: {},
|
||||||
|
},
|
||||||
|
valid: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isWorkflowRecordCreateAction(codeAction)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false for Record Update', () => {
|
||||||
|
const codeAction: WorkflowRecordCRUDAction = {
|
||||||
|
type: 'RECORD_CRUD',
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
settings: {
|
||||||
|
errorHandlingOptions: {
|
||||||
|
continueOnFailure: { value: false },
|
||||||
|
retryOnFailure: { value: false },
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
type: 'UPDATE',
|
||||||
|
objectName: '',
|
||||||
|
objectRecord: {},
|
||||||
|
objectRecordId: '',
|
||||||
|
},
|
||||||
|
outputSchema: {},
|
||||||
|
},
|
||||||
|
valid: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isWorkflowRecordCreateAction(codeAction)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns true for Record Create', () => {
|
||||||
|
const codeAction: WorkflowRecordCRUDAction = {
|
||||||
|
type: 'RECORD_CRUD',
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
settings: {
|
||||||
|
errorHandlingOptions: {
|
||||||
|
continueOnFailure: { value: false },
|
||||||
|
retryOnFailure: { value: false },
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
type: 'CREATE',
|
||||||
|
objectName: '',
|
||||||
|
objectRecord: {},
|
||||||
|
},
|
||||||
|
outputSchema: {},
|
||||||
|
},
|
||||||
|
valid: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(isWorkflowRecordCreateAction(codeAction)).toBe(true);
|
||||||
|
});
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import { castToString } from '../castToString';
|
||||||
|
|
||||||
|
it('returns an empty string when undefined is provided', () => {
|
||||||
|
expect(castToString(undefined)).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns an empty string when null is provided', () => {
|
||||||
|
expect(castToString(undefined)).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns an empty string when an empty string is provided', () => {
|
||||||
|
expect(castToString('')).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves strings', () => {
|
||||||
|
expect(castToString('test')).toBe('test');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('casts numbers to strings', () => {
|
||||||
|
expect(castToString(21)).toBe('21');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('casts booleans to strings', () => {
|
||||||
|
expect(castToString(true)).toBe('true');
|
||||||
|
});
|
||||||
@ -1,3 +0,0 @@
|
|||||||
export const isAnObject = (obj: any): obj is object => {
|
|
||||||
return typeof obj === 'object' && obj !== null && Object.keys(obj).length > 0;
|
|
||||||
};
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import { Observable } from '@apollo/client';
|
|
||||||
|
|
||||||
export const promiseToObservable = <T>(promise: Promise<T>) =>
|
|
||||||
new Observable<T>((subscriber) => {
|
|
||||||
promise.then(
|
|
||||||
(value) => {
|
|
||||||
if (subscriber.closed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
subscriber.next(value);
|
|
||||||
subscriber.complete();
|
|
||||||
},
|
|
||||||
(err) => subscriber.error(err),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user