Moprh-integration-delete (#13165)

Intergartion test dedicated to the delete method
This commit is contained in:
Guillim
2025-07-15 11:16:19 +02:00
committed by GitHub
parent ff3f3d4661
commit 1a81e43286
5 changed files with 222 additions and 40 deletions

View File

@ -74,24 +74,17 @@ describe('createOne FieldMetadataService morph relation fields', () => {
});
type EachTestingContextArray = EachTestingContext<
| {
relationType: RelationType;
objectMetadataId: string;
firstTargetObjectMetadataId: string;
secondTargetObjectMetadataId: string;
type: FieldMetadataType;
}
| ((args: {
objectMetadataId: string;
firstTargetObjectMetadataId: string;
secondTargetObjectMetadataId: string;
}) => {
relationType: RelationType;
objectMetadataId: string;
firstTargetObjectMetadataId: string;
secondTargetObjectMetadataId: string;
type: FieldMetadataType;
})
(args: {
objectMetadataId: string;
firstTargetObjectMetadataId: string;
secondTargetObjectMetadataId: string;
}) => {
relationType: RelationType;
objectMetadataId: string;
firstTargetObjectMetadataId: string;
secondTargetObjectMetadataId: string;
type: FieldMetadataType;
}
>[];
const eachTestingContextArray: EachTestingContextArray = [

View File

@ -57,18 +57,12 @@ describe('createOne FieldMetadataService relation fields', () => {
});
type EachTestingContextArray = EachTestingContext<
| {
relationType: RelationType;
objectMetadataId: string;
targetObjectMetadataId: string;
type: FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION;
}
| ((args: { objectMetadataId: string; targetObjectMetadataId: string }) => {
relationType: RelationType;
objectMetadataId: string;
targetObjectMetadataId: string;
type: FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION;
})
(args: { objectMetadataId: string; targetObjectMetadataId: string }) => {
relationType: RelationType;
objectMetadataId: string;
targetObjectMetadataId: string;
type: FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION;
}
>[];
const eachTestingContextArray: EachTestingContextArray = [
@ -93,15 +87,14 @@ describe('createOne FieldMetadataService relation fields', () => {
];
it.each(eachTestingContextArray)('$title', async ({ context }) => {
const contextPayload =
typeof context === 'function'
? context({
objectMetadataId: createdObjectMetadataOpportunityId,
targetObjectMetadataId: createdObjectMetadataPersonId,
})
: context;
const contextPayload = context({
objectMetadataId: createdObjectMetadataOpportunityId,
targetObjectMetadataId: createdObjectMetadataPersonId,
});
const createdField = await createRelationBetweenObjects({
const createdField = await createRelationBetweenObjects<
typeof contextPayload.type
>({
objectMetadataId: contextPayload.objectMetadataId,
targetObjectMetadataId: contextPayload.targetObjectMetadataId,
type: contextPayload.type,

View File

@ -0,0 +1,5 @@
describe('Delete Object metadata with morph relation should succeed', () => {
it('should succeed', () => {
// 'TODO guillim : once delete is implemented'
});
});

View File

@ -0,0 +1,189 @@
import { deleteOneFieldMetadata } from 'test/integration/metadata/suites/field-metadata/utils/delete-one-field-metadata.util';
import { findManyFieldsMetadataQueryFactory } from 'test/integration/metadata/suites/field-metadata/utils/find-many-fields-metadata-query-factory.util';
import { createOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/create-one-object-metadata.util';
import { createRelationBetweenObjects } from 'test/integration/metadata/suites/object-metadata/utils/create-relation-between-objects.util';
import { deleteOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/delete-one-object-metadata.util';
import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util';
import { EachTestingContext } from 'twenty-shared/testing';
import { FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata.interface';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
type DeleteOneObjectMetadataItemTestingContext = EachTestingContext<
(args: { objectMetadataIdToDelete: string; relationFieldId: string }) => {
objectMetadataIdToDelete: string;
relationFieldId: string;
}
>[];
const successfulDeleteSourceUseCase: DeleteOneObjectMetadataItemTestingContext =
[
{
title:
'When deleting source object, the relation on the target should be deleted',
context: ({ objectMetadataIdToDelete, relationFieldId }) => ({
objectMetadataIdToDelete,
relationFieldId,
}),
},
];
const successfulDeleteTargetUseCase: DeleteOneObjectMetadataItemTestingContext =
[
{
title:
'When deleting target object, the relation on the source should be deleted',
context: ({ objectMetadataIdToDelete, relationFieldId }) => ({
objectMetadataIdToDelete,
relationFieldId,
}),
},
];
describe('Delete Object metadata with relation should succeed', () => {
let createdObjectMetadataPersonId = '';
let createdObjectMetadataOpportunityId = '';
let createdRelationField: FieldMetadataInterface<FieldMetadataType.RELATION>;
let globalTestContext: {
opportunityMetadataId: string;
personMetadataId: string;
relationField: FieldMetadataInterface<FieldMetadataType.RELATION>;
};
beforeEach(async () => {
const {
data: {
createOneObject: { id: objectMetadataPersonId },
},
} = await createOneObjectMetadata({
input: {
nameSingular: 'personForRelation',
namePlural: 'peopleForRelation',
labelSingular: 'Person For Relation',
labelPlural: 'People For Relation',
icon: 'IconPerson',
},
});
createdObjectMetadataPersonId = objectMetadataPersonId;
const {
data: {
createOneObject: { id: objectMetadataOpportunityId },
},
} = await createOneObjectMetadata({
input: {
nameSingular: 'opportunityForRelation',
namePlural: 'opportunitiesForRelation',
labelSingular: 'Opportunity For Relation',
labelPlural: 'Opportunities For Relation',
icon: 'IconOpportunity',
},
});
createdObjectMetadataOpportunityId = objectMetadataOpportunityId;
createdRelationField =
await createRelationBetweenObjects<FieldMetadataType.RELATION>({
objectMetadataId: createdObjectMetadataOpportunityId,
targetObjectMetadataId: createdObjectMetadataPersonId,
type: FieldMetadataType.RELATION,
relationType: RelationType.MANY_TO_ONE,
});
globalTestContext = {
opportunityMetadataId: createdObjectMetadataOpportunityId,
personMetadataId: createdObjectMetadataPersonId,
relationField: createdRelationField,
};
});
afterEach(async () => {
await deleteOneFieldMetadata({
input: { idToDelete: createdRelationField.id },
});
await deleteOneObjectMetadata({
input: { idToDelete: createdObjectMetadataPersonId },
});
await deleteOneObjectMetadata({
input: { idToDelete: createdObjectMetadataOpportunityId },
});
});
it.each(successfulDeleteSourceUseCase)('$title', async ({ context }) => {
const computedContext = context({
objectMetadataIdToDelete: globalTestContext.personMetadataId,
relationFieldId: globalTestContext.relationField.id,
});
await deleteOneObjectMetadata({
input: { idToDelete: computedContext.objectMetadataIdToDelete },
});
const opportunityFieldOnPersonAfterDeletion = await findFieldMetadata({
fieldMetadataId: computedContext.relationFieldId,
});
expect(opportunityFieldOnPersonAfterDeletion).toBeUndefined();
});
it.each(successfulDeleteTargetUseCase)('$title', async ({ context }) => {
if (!isDefined(globalTestContext.relationField.relation)) {
throw new Error('Relation field relation is undefined');
}
const computedContext = context({
objectMetadataIdToDelete: globalTestContext.opportunityMetadataId,
relationFieldId:
globalTestContext.relationField.relation.targetFieldMetadata.id,
});
await deleteOneObjectMetadata({
input: { idToDelete: computedContext.objectMetadataIdToDelete },
});
const personFieldOnOpportunityAfterDeletion = await findFieldMetadata({
fieldMetadataId: computedContext.relationFieldId,
});
expect(personFieldOnOpportunityAfterDeletion).toBeUndefined();
});
});
const findFieldMetadata = async ({
fieldMetadataId,
}: {
fieldMetadataId: string;
}) => {
const operation = findManyFieldsMetadataQueryFactory({
gqlFields: `
id
name
object {
id
nameSingular
}
relation {
type
targetFieldMetadata {
id
}
targetObjectMetadata {
id
}
}
settings
`,
input: {
filter: {
id: { eq: fieldMetadataId },
},
paging: { first: 1 },
},
});
const fields = await makeMetadataAPIRequest(operation);
const field = fields.body.data.fields.edges?.[0]?.node;
return field;
};

View File

@ -4,7 +4,9 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
export const createRelationBetweenObjects = async ({
export const createRelationBetweenObjects = async <
T extends FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION,
>({
objectMetadataId,
targetObjectMetadataId,
type,
@ -17,7 +19,7 @@ export const createRelationBetweenObjects = async ({
}: {
objectMetadataId: string;
targetObjectMetadataId: string;
type: FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION;
type: T;
relationType: RelationType;
name?: string;
label?: string;