Write more tests (#8799)

This commit is contained in:
Baptiste Devessier 2024-11-28 17:43:15 +01:00 committed by GitHub
parent b857d45182
commit 38b83f0866
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 387 additions and 22 deletions

View File

@ -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();
});

View File

@ -2,6 +2,8 @@ import {
WorkflowDatabaseEventTrigger,
WorkflowTrigger,
} from '@/workflow/types/Workflow';
import { assertUnreachable } from '@/workflow/utils/assertUnreachable';
import { isDefined } from 'twenty-ui';
import { capitalize } from '~/utils/string/capitalize';
export const getTriggerStepName = (trigger: WorkflowTrigger): string => {
@ -9,14 +11,14 @@ export const getTriggerStepName = (trigger: WorkflowTrigger): string => {
case 'DATABASE_EVENT':
return getDatabaseEventTriggerStepName(trigger);
case 'MANUAL':
if (!trigger.settings.objectType) {
if (!isDefined(trigger.settings.objectType)) {
return 'Manual trigger';
}
return 'Manual trigger for ' + capitalize(trigger.settings.objectType);
default:
return '';
}
return assertUnreachable(trigger);
};
const getDatabaseEventTriggerStepName = (

View File

@ -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!');
});

View File

@ -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();
});

View File

@ -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: {},
});
});

View File

@ -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');
});

View File

@ -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');
});

View File

@ -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);
});

View File

@ -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');
});

View File

@ -1,3 +0,0 @@
export const isAnObject = (obj: any): obj is object => {
return typeof obj === 'object' && obj !== null && Object.keys(obj).length > 0;
};

View File

@ -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),
);
});