From 5daef283288fbbd219d4dcac98b87d9526334bd8 Mon Sep 17 00:00:00 2001 From: Guillim Date: Thu, 11 Dec 2025 10:10:30 +0100 Subject: [PATCH] Morph INPUT integration test (#16464) - Adding a new target to the test setup suite - We add the MORPH_RELATION to the list of types we wanna test in the current test suites Important: I noticed the REST API was not working well with Morph relations. I created [an issue](https://github.com/twentyhq/core-team-issues/issues/2002) to work on that. Within that timeframe, I `xdescribed` the related tests Fixes https://github.com/twentyhq/core-team-issues/issues/1327 --- .../test-object-gql-fields.constant.ts | 6 + ...-input-validation.integration-spec.ts.snap | 11 ++ ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...e-input-by-field-metadata-type.constant.ts | 28 ++++ ...e-input-by-field-metadata-type.constant.ts | 27 +++- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 115 +++++++++++++++++ ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...reate-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...r-input-by-field-metadata-type.constant.ts | 21 +++ ...r-input-by-field-metadata-type.constant.ts | 120 ++++++++++++++++++ ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 117 +++++++++++++++++ ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- ...ilter-input-validation.integration-spec.ts | 9 +- .../types/field-metadata-type-to-test.ts | 2 - ...get-field-metadata-creation-inputs.util.ts | 42 +++++- ...-test-objects-with-all-field-types.util.ts | 75 +++++++---- .../perform-create-many-operation.utils.ts | 5 +- 50 files changed, 766 insertions(+), 145 deletions(-) create mode 100644 packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/__snapshots__/morph-relation-field-create-input-validation.integration-spec.ts.snap create mode 100644 packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/morph-relation-field-create-input-validation.integration-spec.ts create mode 100644 packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/morph-relation-field-filter-input-validation.integration-spec.ts diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/constants/test-object-gql-fields.constant.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/constants/test-object-gql-fields.constant.ts index 4cb8d065a6..7440fdec2c 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/constants/test-object-gql-fields.constant.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/constants/test-object-gql-fields.constant.ts @@ -1,9 +1,15 @@ +import { joinColumnNameForManyToOneMorphRelationField1 } from 'test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util'; + export const TEST_OBJECT_GQL_FIELDS = ` id manyToOneRelationFieldId manyToOneRelationField { id } + ${joinColumnNameForManyToOneMorphRelationField1} + ${joinColumnNameForManyToOneMorphRelationField1.replace('Id', '')}{ + id + } uuidField textField phonesField { diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/__snapshots__/morph-relation-field-create-input-validation.integration-spec.ts.snap b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/__snapshots__/morph-relation-field-create-input-validation.integration-spec.ts.snap new file mode 100644 index 0000000000..6b51d232cf --- /dev/null +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/__snapshots__/morph-relation-field-create-input-validation.integration-spec.ts.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Create input validation - MORPH_RELATION Gql create input - failure MORPH_RELATION - should fail with : {"manyToOneMorphRelationFieldApiInputValidationTargetTestObject1Id":"not-a-morph-relation"} 1`] = `"Invalid UUID value 'not-a-morph-relation' for field "manyToOneMorphRelationFieldApiInputValidationTargetTestObject1Id""`; + +exports[`Create input validation - MORPH_RELATION Gql create input - failure MORPH_RELATION - should fail with : {"manyToOneMorphRelationFieldApiInputValidationTargetTestObject1Id":[]} 1`] = `"ID cannot represent value: []"`; + +exports[`Create input validation - MORPH_RELATION Gql create input - failure MORPH_RELATION - should fail with : {"manyToOneMorphRelationFieldApiInputValidationTargetTestObject1Id":{}} 1`] = `"ID cannot represent value: {}"`; + +exports[`Create input validation - MORPH_RELATION Gql create input - failure MORPH_RELATION - should fail with : {"manyToOneMorphRelationFieldApiInputValidationTargetTestObject1Id":1} 1`] = `"Invalid UUID value '1' for field "manyToOneMorphRelationFieldApiInputValidationTargetTestObject1Id""`; + +exports[`Create input validation - MORPH_RELATION Gql create input - failure MORPH_RELATION - should fail with : {"manyToOneMorphRelationFieldApiInputValidationTargetTestObject1Id":true} 1`] = `"ID cannot represent value: true"`; diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/address-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/address-field-create-input-validation.integration-spec.ts index 397c89b9bf..8cb60cdc3a 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/address-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/address-field-create-input-validation.integration-spec.ts @@ -20,7 +20,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -28,13 +29,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/array-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/array-field-create-input-validation.integration-spec.ts index 32c4bfee5d..568189c37d 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/array-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/array-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/boolean-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/boolean-field-create-input-validation.integration-spec.ts index 0c72ddc6d0..721d4c237e 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/boolean-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/boolean-field-create-input-validation.integration-spec.ts @@ -14,7 +14,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -22,13 +23,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/failing-create-input-by-field-metadata-type.constant.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/failing-create-input-by-field-metadata-type.constant.ts index 4cd5737704..8786db92a8 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/failing-create-input-by-field-metadata-type.constant.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/failing-create-input-by-field-metadata-type.constant.ts @@ -1,4 +1,5 @@ import { type FieldMetadataTypesToTestForCreateInputValidation } from 'test/integration/graphql/suites/inputs-validation/types/field-metadata-type-to-test'; +import { joinColumnNameForManyToOneMorphRelationField1 } from 'test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util'; import { FieldMetadataType } from 'twenty-shared/types'; export const failingCreateInputByFieldMetadataType: { @@ -160,6 +161,33 @@ export const failingCreateInputByFieldMetadataType: { }, }, ], + [FieldMetadataType.MORPH_RELATION]: [ + { + input: { + [joinColumnNameForManyToOneMorphRelationField1]: 'not-a-morph-relation', + }, + }, + { + input: { + [joinColumnNameForManyToOneMorphRelationField1]: {}, + }, + }, + { + input: { + [joinColumnNameForManyToOneMorphRelationField1]: [], + }, + }, + { + input: { + [joinColumnNameForManyToOneMorphRelationField1]: true, + }, + }, + { + input: { + [joinColumnNameForManyToOneMorphRelationField1]: 1, + }, + }, + ], [FieldMetadataType.RATING]: [ { input: { diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/successful-create-input-by-field-metadata-type.constant.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/successful-create-input-by-field-metadata-type.constant.ts index c36beb5455..baa37d494e 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/successful-create-input-by-field-metadata-type.constant.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/constants/successful-create-input-by-field-metadata-type.constant.ts @@ -1,5 +1,8 @@ import { type FieldMetadataTypesToTestForCreateInputValidation } from 'test/integration/graphql/suites/inputs-validation/types/field-metadata-type-to-test'; -import { TEST_TARGET_OBJECT_RECORD_ID_FIELD_VALUE } from 'test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util'; +import { + joinColumnNameForManyToOneMorphRelationField1, + TEST_TARGET_OBJECT_RECORD_ID_FIELD_VALUE, +} from 'test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util'; import { FieldMetadataType } from 'twenty-shared/types'; export const successfulCreateInputByFieldMetadataType: { @@ -120,6 +123,28 @@ export const successfulCreateInputByFieldMetadataType: { }, }, ], + [FieldMetadataType.MORPH_RELATION]: [ + { + input: { + [joinColumnNameForManyToOneMorphRelationField1]: + TEST_TARGET_OBJECT_RECORD_ID_FIELD_VALUE, + }, + validateInput: (record: Record) => { + return ( + record[joinColumnNameForManyToOneMorphRelationField1] === + TEST_TARGET_OBJECT_RECORD_ID_FIELD_VALUE + ); + }, + }, + { + input: { + [joinColumnNameForManyToOneMorphRelationField1]: null, + }, + validateInput: (record: Record) => { + return record[joinColumnNameForManyToOneMorphRelationField1] === null; + }, + }, + ], [FieldMetadataType.RAW_JSON]: [ { input: { diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/currency-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/currency-field-create-input-validation.integration-spec.ts index 19206f79e9..e943e00f88 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/currency-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/currency-field-create-input-validation.integration-spec.ts @@ -20,7 +20,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -28,13 +29,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/date-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/date-field-create-input-validation.integration-spec.ts index 275a382ada..3e213833b3 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/date-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/date-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/date-time-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/date-time-field-create-input-validation.integration-spec.ts index e5dd711823..85cccdda59 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/date-time-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/date-time-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/emails-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/emails-field-create-input-validation.integration-spec.ts index da2c7fd787..797422024a 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/emails-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/emails-field-create-input-validation.integration-spec.ts @@ -20,7 +20,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -28,13 +29,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/full-name-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/full-name-field-create-input-validation.integration-spec.ts index 8c73606720..92f5683e6b 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/full-name-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/full-name-field-create-input-validation.integration-spec.ts @@ -20,7 +20,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -28,13 +29,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/links-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/links-field-create-input-validation.integration-spec.ts index f0db6d3722..4caa15a392 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/links-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/links-field-create-input-validation.integration-spec.ts @@ -20,7 +20,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -28,13 +29,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/morph-relation-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/morph-relation-field-create-input-validation.integration-spec.ts new file mode 100644 index 0000000000..b3aaaca8e1 --- /dev/null +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/morph-relation-field-create-input-validation.integration-spec.ts @@ -0,0 +1,115 @@ +import { failingCreateInputByFieldMetadataType } from 'test/integration/graphql/suites/inputs-validation/create-validation/constants/failing-create-input-by-field-metadata-type.constant'; +import { successfulCreateInputByFieldMetadataType } from 'test/integration/graphql/suites/inputs-validation/create-validation/constants/successful-create-input-by-field-metadata-type.constant'; +import { expectGqlCreateInputValidationError } from 'test/integration/graphql/suites/inputs-validation/create-validation/utils/expect-gql-create-input-validation-error.util'; +import { expectGqlCreateInputValidationSuccess } from 'test/integration/graphql/suites/inputs-validation/create-validation/utils/expect-gql-create-input-validation-success.util'; +import { expectRestCreateInputValidationError } from 'test/integration/graphql/suites/inputs-validation/create-validation/utils/expect-rest-create-input-validation-error.util'; +import { expectRestCreateInputValidationSuccess } from 'test/integration/graphql/suites/inputs-validation/create-validation/utils/expect-rest-create-input-validation-success.util'; +import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/inputs-validation/utils/destroy-many-objects-metadata'; +import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util'; +import { FieldMetadataType } from 'twenty-shared/types'; + +const FIELD_METADATA_TYPE = FieldMetadataType.MORPH_RELATION; + +const failingTestCases = + failingCreateInputByFieldMetadataType[FIELD_METADATA_TYPE]; +const successfulTestCases = + successfulCreateInputByFieldMetadataType[FIELD_METADATA_TYPE]; + +describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { + let objectMetadataId: string; + let objectMetadataSingularName: string; + let objectMetadataPluralName: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; + + beforeAll(async () => { + const setupTest = await setupTestObjectsWithAllFieldTypes(); + + objectMetadataId = setupTest.objectMetadataId; + objectMetadataSingularName = setupTest.objectMetadataSingularName; + objectMetadataPluralName = setupTest.objectMetadataPluralName; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; + }); + + afterAll(async () => { + await destroyManyObjectsMetadata([ + objectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, + ]); + }); + + describe('Gql create input - failure', () => { + it.each( + failingTestCases.map((testCase) => ({ + ...testCase, + stringifiedInput: JSON.stringify(testCase.input), + })), + )( + `${FIELD_METADATA_TYPE} - should fail with : $stringifiedInput`, + async ({ input }) => { + await expectGqlCreateInputValidationError( + objectMetadataSingularName, + input, + ); + }, + ); + }); + + // TODO - add when REST API can handle morph relations + xdescribe('Rest create input - failure', () => { + it.each( + failingTestCases.map((testCase) => ({ + ...testCase, + stringifiedInput: JSON.stringify(testCase.input), + })), + )( + `${FIELD_METADATA_TYPE} - should fail with : $stringifiedInput`, + async ({ input }) => { + await expectRestCreateInputValidationError( + objectMetadataPluralName, + input, + ); + }, + ); + }); + + describe('Gql create input - success', () => { + it.each( + successfulTestCases.map((testCase) => ({ + ...testCase, + stringifiedInput: JSON.stringify(testCase.input), + })), + )( + `${FIELD_METADATA_TYPE} - should succeed with : $stringifiedInput`, + async ({ input, validateInput }) => { + await expectGqlCreateInputValidationSuccess( + objectMetadataSingularName, + input, + validateInput, + ); + }, + ); + }); + + // TODO - add when REST API can handle morph relations + xdescribe('Rest create input - success', () => { + it.each( + successfulTestCases.map((testCase) => ({ + ...testCase, + stringifiedInput: JSON.stringify(testCase.input), + })), + )( + `${FIELD_METADATA_TYPE} - should succeed with : $stringifiedInput`, + async ({ input, validateInput }) => { + await expectRestCreateInputValidationSuccess( + objectMetadataPluralName, + objectMetadataSingularName, + input, + validateInput, + ); + }, + ); + }); +}); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/multi-select-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/multi-select-field-create-input-validation.integration-spec.ts index 8aa78735fb..e7b3a70221 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/multi-select-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/multi-select-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/number-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/number-field-create-input-validation.integration-spec.ts index 31a65c04ff..ed51d0b8d5 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/number-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/number-field-create-input-validation.integration-spec.ts @@ -14,7 +14,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -22,13 +23,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/phones-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/phones-field-create-input-validation.integration-spec.ts index d89d991d03..4d81cd6885 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/phones-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/phones-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rating-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rating-field-create-input-validation.integration-spec.ts index c066ce4ba9..a7c3eaaf57 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rating-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rating-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/raw-json-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/raw-json-field-create-input-validation.integration-spec.ts index 2411b0df0c..3c6e877722 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/raw-json-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/raw-json-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/relation-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/relation-field-create-input-validation.integration-spec.ts index 412dc237af..f9245a0177 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/relation-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/relation-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rich-text-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rich-text-field-create-input-validation.integration-spec.ts index fa1c75b520..fc0c6c7ccc 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rich-text-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rich-text-field-create-input-validation.integration-spec.ts @@ -14,7 +14,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -22,13 +23,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rich-text-v2-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rich-text-v2-field-create-input-validation.integration-spec.ts index 6248325c02..2317fc0062 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rich-text-v2-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/rich-text-v2-field-create-input-validation.integration-spec.ts @@ -20,7 +20,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -28,13 +29,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/select-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/select-field-create-input-validation.integration-spec.ts index 6697123c40..76c3668dac 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/select-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/select-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/text-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/text-field-create-input-validation.integration-spec.ts index e751c8404c..2143dc0553 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/text-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/text-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/uuid-field-create-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/uuid-field-create-input-validation.integration-spec.ts index be9456c545..31019b7df0 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/uuid-field-create-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/create-validation/uuid-field-create-input-validation.integration-spec.ts @@ -19,7 +19,8 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -27,13 +28,15 @@ describe(`Create input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/address-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/address-field-filter-input-validation.integration-spec.ts index 46e917cdc7..0ddaa3a89d 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/address-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/address-field-filter-input-validation.integration-spec.ts @@ -13,7 +13,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -21,13 +22,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/array-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/array-field-filter-input-validation.integration-spec.ts index a28cdc85a8..a78368b711 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/array-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/array-field-filter-input-validation.integration-spec.ts @@ -15,7 +15,8 @@ describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -23,13 +24,15 @@ describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/boolean-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/boolean-field-filter-input-validation.integration-spec.ts index 1da007caed..44288747f6 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/boolean-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/boolean-field-filter-input-validation.integration-spec.ts @@ -14,7 +14,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -22,13 +23,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant.ts index 7749cc4d59..0a36286dd3 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant.ts @@ -1,4 +1,5 @@ import { type FieldMetadataTypesToTestForFilterInputValidation } from 'test/integration/graphql/suites/inputs-validation/types/field-metadata-type-to-test'; +import { joinColumnNameForManyToOneMorphRelationField1 } from 'test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util'; import { FieldMetadataType } from 'twenty-shared/types'; import { type CompositeFieldMetadataType } from 'src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory'; @@ -60,6 +61,26 @@ export const failingFilterInputByFieldMetadataType: { // restErrorMessage: "'oneToManyRelationFieldId' does not exist", // }, ], + [FieldMetadataType.MORPH_RELATION]: [ + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { eq: 'invalid-uuid' }, + }, + gqlErrorMessage: 'Invalid UUID', + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[eq]:"invalid-uuid"`, + restErrorMessage: 'invalid input syntax for type uuid', + }, + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1.replace('Id', '')]: { + eq: '6dd71a46-68fe-4420-82b3-0d5b00ad2642', + }, + }, + gqlErrorMessage: 'is not defined by type', + restFilterInput: `${[joinColumnNameForManyToOneMorphRelationField1.replace('Id', '')]}[eq]:"6dd71a46-68fe-4420-82b3-0d5b00ad2642"`, + restErrorMessage: `column apiInputValidationTestObject.${joinColumnNameForManyToOneMorphRelationField1.replace('Id', '')} does not exist`, + }, + ], [FieldMetadataType.UUID]: [ { gqlFilterInput: { uuidField: { eq: 'invalid-uuid' } }, diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant.ts index bfc90aef18..e9e74fbedd 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant.ts @@ -1,5 +1,6 @@ import { type FieldMetadataTypesToTestForFilterInputValidation } from 'test/integration/graphql/suites/inputs-validation/types/field-metadata-type-to-test'; import { + joinColumnNameForManyToOneMorphRelationField1, TEST_TARGET_OBJECT_RECORD_ID, TEST_UUID_FIELD_VALUE, } from 'test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util'; @@ -138,6 +139,125 @@ export const successfulFilterInputByFieldMetadataType: { }, }, ], + [FieldMetadataType.MORPH_RELATION]: [ + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { + neq: '00000000-0000-4000-8000-000000000000', + }, + }, + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[neq]:"00000000-0000-4000-8000-000000000000"`, + validateFilter: (record: Record) => { + return ( + record[joinColumnNameForManyToOneMorphRelationField1] !== + '00000000-0000-4000-8000-000000000000' + ); + }, + }, + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { + eq: TEST_TARGET_OBJECT_RECORD_ID, + }, + }, + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[eq]:"${TEST_TARGET_OBJECT_RECORD_ID}"`, + validateFilter: (record: Record) => { + return ( + record[joinColumnNameForManyToOneMorphRelationField1] === + TEST_TARGET_OBJECT_RECORD_ID + ); + }, + }, + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { + gt: '00000000-0000-4000-8000-000000000000', + }, + }, + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[gt]:"00000000-0000-4000-8000-000000000000"`, + validateFilter: (record: Record) => { + // Morph relation join column is a UUID stored as string + return ( + record[joinColumnNameForManyToOneMorphRelationField1] > + '00000000-0000-4000-8000-000000000000' + ); + }, + }, + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { + gte: '00000000-0000-4000-8000-000000000000', + }, + }, + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[gte]:"00000000-0000-4000-8000-000000000000"`, + validateFilter: (record: Record) => { + return ( + record[joinColumnNameForManyToOneMorphRelationField1] >= + '00000000-0000-4000-8000-000000000000' + ); + }, + }, + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { + lt: 'ffffffff-ffff-4fff-bfff-ffffffffffff', + }, + }, + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[lt]:"ffffffff-ffff-4fff-bfff-ffffffffffff"`, + validateFilter: (record: Record) => { + return ( + record[joinColumnNameForManyToOneMorphRelationField1] < + 'ffffffff-ffff-4fff-bfff-ffffffffffff' + ); + }, + }, + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { + lte: 'ffffffff-ffff-4fff-bfff-ffffffffffff', + }, + }, + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[lte]:"ffffffff-ffff-4fff-bfff-ffffffffffff"`, + validateFilter: (record: Record) => { + return ( + record[joinColumnNameForManyToOneMorphRelationField1] <= + 'ffffffff-ffff-4fff-bfff-ffffffffffff' + ); + }, + }, + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { + in: [TEST_TARGET_OBJECT_RECORD_ID], + }, + }, + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[in]:["${TEST_TARGET_OBJECT_RECORD_ID}"]`, + validateFilter: (record: Record) => { + return ( + record[joinColumnNameForManyToOneMorphRelationField1] === + TEST_TARGET_OBJECT_RECORD_ID + ); + }, + }, + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { is: 'NULL' }, + }, + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[is]:NULL`, + validateFilter: (record: Record) => { + return record[joinColumnNameForManyToOneMorphRelationField1] === null; + }, + }, + { + gqlFilterInput: { + [joinColumnNameForManyToOneMorphRelationField1]: { is: 'NOT_NULL' }, + }, + restFilterInput: `${joinColumnNameForManyToOneMorphRelationField1}[is]:"NOT_NULL"`, + validateFilter: (record: Record) => { + return isDefined(record[joinColumnNameForManyToOneMorphRelationField1]); + }, + }, + ], [FieldMetadataType.UUID]: [ { gqlFilterInput: { diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/currency-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/currency-field-filter-input-validation.integration-spec.ts index b1f10daf24..9c71502f25 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/currency-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/currency-field-filter-input-validation.integration-spec.ts @@ -13,7 +13,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -21,13 +22,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/date-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/date-field-filter-input-validation.integration-spec.ts index 2c7d1625a3..ba312264c2 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/date-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/date-field-filter-input-validation.integration-spec.ts @@ -18,7 +18,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -26,13 +27,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/date-time-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/date-time-field-filter-input-validation.integration-spec.ts index 52e1691abc..9abd0df4c7 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/date-time-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/date-time-field-filter-input-validation.integration-spec.ts @@ -18,7 +18,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -26,13 +27,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/emails-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/emails-field-filter-input-validation.integration-spec.ts index 655262ad4b..1e6d5a4b4e 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/emails-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/emails-field-filter-input-validation.integration-spec.ts @@ -13,7 +13,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -21,13 +22,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/full-name-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/full-name-field-filter-input-validation.integration-spec.ts index 954c41246b..1757c70bec 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/full-name-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/full-name-field-filter-input-validation.integration-spec.ts @@ -13,7 +13,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -21,13 +22,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/links-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/links-field-filter-input-validation.integration-spec.ts index 032dda274a..13846efe8b 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/links-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/links-field-filter-input-validation.integration-spec.ts @@ -13,7 +13,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -21,13 +22,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/morph-relation-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/morph-relation-field-filter-input-validation.integration-spec.ts new file mode 100644 index 0000000000..100de12b7f --- /dev/null +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/morph-relation-field-filter-input-validation.integration-spec.ts @@ -0,0 +1,117 @@ +import { failingFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/inputs-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant'; +import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/inputs-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant'; +import { testGqlFailingScenario } from 'test/integration/graphql/suites/inputs-validation/filter-validation/utils/test-gql-failing-scenario.util'; +import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/inputs-validation/filter-validation/utils/test-gql-successful-scenario.util'; +import { testRestFailingScenario } from 'test/integration/graphql/suites/inputs-validation/filter-validation/utils/test-rest-failing-scenario.util'; +import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/inputs-validation/filter-validation/utils/test-rest-successful-scenario.util'; +import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/inputs-validation/utils/destroy-many-objects-metadata'; +import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util'; +import { FieldMetadataType } from 'twenty-shared/types'; + +const FIELD_METADATA_TYPE = FieldMetadataType.MORPH_RELATION; +const failingTestCases = + failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE]; +const successfulTestCases = + successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE]; + +describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { + let objectMetadataId: string; + let objectMetadataSingularName: string; + let objectMetadataPluralName: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; + + beforeAll(async () => { + const setupTest = await setupTestObjectsWithAllFieldTypes(); + + objectMetadataId = setupTest.objectMetadataId; + objectMetadataSingularName = setupTest.objectMetadataSingularName; + objectMetadataPluralName = setupTest.objectMetadataPluralName; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; + }); + + afterAll(async () => { + await destroyManyObjectsMetadata([ + objectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, + ]); + }); + + describe('Gql filter input - failure', () => { + it.each( + failingTestCases.map((testCase) => ({ + ...testCase, + stringifiedFilter: JSON.stringify(testCase.gqlFilterInput), + })), + )( + `${FIELD_METADATA_TYPE} field type - should fail with filter : $stringifiedFilter`, + async ({ gqlFilterInput: filter, gqlErrorMessage: errorMessage }) => { + await testGqlFailingScenario( + objectMetadataSingularName, + objectMetadataPluralName, + filter, + errorMessage, + ); + }, + ); + }); + + // TODO : Refacto-common - Uncomment this + describe('Rest filter input - failure', () => { + it.each( + failingTestCases.map((testCase) => ({ + ...testCase, + stringifiedFilter: JSON.stringify(testCase.restFilterInput), + })), + )( + `${FIELD_METADATA_TYPE} field type - should fail with filter : $stringifiedFilter`, + async ({ restFilterInput: filter, restErrorMessage: errorMessage }) => { + await testRestFailingScenario( + objectMetadataPluralName, + filter, + errorMessage, + ); + }, + ); + }); + + describe('Gql filter input - success', () => { + it.each( + successfulTestCases.map((testCase) => ({ + ...testCase, + stringifiedFilter: JSON.stringify(testCase.gqlFilterInput), + })), + )( + `${FIELD_METADATA_TYPE} field type - should succeed with filter : $stringifiedFilter`, + async ({ gqlFilterInput: filter, validateFilter }) => { + await testGqlSuccessfulScenario( + objectMetadataSingularName, + objectMetadataPluralName, + filter, + validateFilter, + ); + }, + ); + }); + + // TODO @guillim - fix this once REST API can handle morph relations + xdescribe('Rest filter input - success', () => { + it.each( + successfulTestCases.map((testCase) => ({ + ...testCase, + stringifiedFilter: JSON.stringify(testCase.restFilterInput), + })), + )( + `${FIELD_METADATA_TYPE} field type - should succeed with filter : $stringifiedFilter`, + async ({ restFilterInput, validateFilter }) => { + await testRestSuccessfulScenario( + objectMetadataPluralName, + restFilterInput, + validateFilter, + ); + }, + ); + }); +}); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/multi-select-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/multi-select-field-filter-input-validation.integration-spec.ts index d0a2e6950b..7844599e3e 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/multi-select-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/multi-select-field-filter-input-validation.integration-spec.ts @@ -18,7 +18,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -26,13 +27,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/number-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/number-field-filter-input-validation.integration-spec.ts index d8360efd1b..29fb05d107 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/number-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/number-field-filter-input-validation.integration-spec.ts @@ -15,7 +15,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -23,13 +24,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/phones-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/phones-field-filter-input-validation.integration-spec.ts index be28593038..c2e8517c00 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/phones-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/phones-field-filter-input-validation.integration-spec.ts @@ -13,7 +13,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -21,13 +22,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/rating-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/rating-field-filter-input-validation.integration-spec.ts index 502082b8ea..4740947ea6 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/rating-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/rating-field-filter-input-validation.integration-spec.ts @@ -18,7 +18,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -26,13 +27,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/raw-json-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/raw-json-field-filter-input-validation.integration-spec.ts index 1891f0d38f..f0fb2fb44e 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/raw-json-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/raw-json-field-filter-input-validation.integration-spec.ts @@ -15,7 +15,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -23,13 +24,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/relation-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/relation-field-filter-input-validation.integration-spec.ts index a4dfb6ddd0..62987f97ed 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/relation-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/relation-field-filter-input-validation.integration-spec.ts @@ -18,7 +18,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -26,13 +27,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/select-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/select-field-filter-input-validation.integration-spec.ts index 78570e8083..fbb383c988 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/select-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/select-field-filter-input-validation.integration-spec.ts @@ -17,7 +17,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -25,13 +26,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/text-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/text-field-filter-input-validation.integration-spec.ts index 8be9af6372..72ea697052 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/text-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/text-field-filter-input-validation.integration-spec.ts @@ -18,7 +18,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -26,13 +27,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/uuid-field-filter-input-validation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/uuid-field-filter-input-validation.integration-spec.ts index 510f33fdac..9d9c37885c 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/uuid-field-filter-input-validation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/filter-validation/uuid-field-filter-input-validation.integration-spec.ts @@ -18,7 +18,8 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { let objectMetadataId: string; let objectMetadataSingularName: string; let objectMetadataPluralName: string; - let targetObjectMetadataId: string; + let targetObjectMetadata1Id: string; + let targetObjectMetadata2Id: string; beforeAll(async () => { const setupTest = await setupTestObjectsWithAllFieldTypes(); @@ -26,13 +27,15 @@ describe(`Filter input validation - ${FIELD_METADATA_TYPE}`, () => { objectMetadataId = setupTest.objectMetadataId; objectMetadataSingularName = setupTest.objectMetadataSingularName; objectMetadataPluralName = setupTest.objectMetadataPluralName; - targetObjectMetadataId = setupTest.targetObjectMetadataId; + targetObjectMetadata1Id = setupTest.targetObjectMetadata1Id; + targetObjectMetadata2Id = setupTest.targetObjectMetadata2Id; }); afterAll(async () => { await destroyManyObjectsMetadata([ objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ]); }); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/types/field-metadata-type-to-test.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/types/field-metadata-type-to-test.ts index a9270aedd9..85707446df 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/types/field-metadata-type-to-test.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/types/field-metadata-type-to-test.ts @@ -5,7 +5,6 @@ type FieldMetadataTypesNotTestedForFilterInputValidation = | 'RICH_TEXT' | 'POSITION' | 'ACTOR' - | 'MORPH_RELATION' | 'NUMERIC' | 'RICH_TEXT_V2'; @@ -13,7 +12,6 @@ type FieldMetadataTypesNotTestedForCreateInputValidation = | 'TS_VECTOR' | 'ACTOR' | 'POSITION' - | 'MORPH_RELATION' | 'NUMERIC'; export type FieldMetadataTypesToTestForCreateInputValidation = Exclude< diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/get-field-metadata-creation-inputs.util.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/get-field-metadata-creation-inputs.util.ts index f927c32ac3..23e1891a16 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/get-field-metadata-creation-inputs.util.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/get-field-metadata-creation-inputs.util.ts @@ -17,11 +17,13 @@ type FieldMetadataCreationInput = { objectMetadataId: string; options?: FieldMetadataComplexOption[]; relationCreationPayload?: RelationCreationPayload; + morphRelationsCreationPayload?: RelationCreationPayload[]; }; export const getFieldMetadataCreationInputs = ( objectMetadataId: string, - targetObjectMetadataId: string, + targetObjectMetadata1Id: string, + targetObjectMetadata2Id: string, ) => { const fieldInputsMap: { [K in Exclude< @@ -170,7 +172,7 @@ export const getFieldMetadataCreationInputs = ( type: FieldMetadataType.RELATION, objectMetadataId, relationCreationPayload: { - targetObjectMetadataId: targetObjectMetadataId, + targetObjectMetadataId: targetObjectMetadata1Id, targetFieldLabel: 'oneToManyTargetRelationField', targetFieldIcon: 'IconListOpportunity', type: RelationType.MANY_TO_ONE, @@ -182,13 +184,47 @@ export const getFieldMetadataCreationInputs = ( type: FieldMetadataType.RELATION, objectMetadataId, relationCreationPayload: { - targetObjectMetadataId: targetObjectMetadataId, + targetObjectMetadataId: targetObjectMetadata1Id, targetFieldLabel: 'manyToOneTargetRelationField', targetFieldIcon: 'IconListOpportunity', type: RelationType.ONE_TO_MANY, }, }, ], + [FieldMetadataType.MORPH_RELATION]: [ + { + name: 'manyToOneMorphRelationField', + label: 'manyToOneMorphRelationField', + type: FieldMetadataType.MORPH_RELATION, + objectMetadataId, + morphRelationsCreationPayload: [ + { + targetObjectMetadataId: targetObjectMetadata1Id, + targetFieldLabel: 'oneToManyTarget1MorphRelationField', + targetFieldIcon: 'IconListOpportunity', + type: RelationType.MANY_TO_ONE, + }, + { + targetObjectMetadataId: targetObjectMetadata2Id, + targetFieldLabel: 'oneToManyTarget2MorphRelationField', + targetFieldIcon: 'IconListOpportunity', + type: RelationType.MANY_TO_ONE, + }, + ], + }, + // { + // name: 'oneToManyRelationField', + // label: 'oneToManyRelationField', + // type: FieldMetadataType.RELATION, + // objectMetadataId, + // relationCreationPayload: { + // targetObjectMetadataId: targetObjectMetadata1Id, + // targetFieldLabel: 'manyToOneTargetRelationField', + // targetFieldIcon: 'IconListOpportunity', + // type: RelationType.ONE_TO_MANY, + // }, + // }, + ], }; return Object.values(fieldInputsMap).flat(); diff --git a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util.ts b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util.ts index a85ffbdb74..4eb27ca5f5 100644 --- a/packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util.ts +++ b/packages/twenty-server/test/integration/graphql/suites/inputs-validation/utils/setup-test-objects-with-all-field-types.util.ts @@ -1,17 +1,22 @@ -import { randomUUID } from 'crypto'; - import { getFieldMetadataCreationInputs } from 'test/integration/graphql/suites/inputs-validation/utils/get-field-metadata-creation-inputs.util'; import { createManyOperationFactory } from 'test/integration/graphql/utils/create-many-operation-factory.util'; import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util'; import { createOneFieldMetadata } from 'test/integration/metadata/suites/field-metadata/utils/create-one-field-metadata.util'; import { createOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/create-one-object-metadata.util'; +import { RelationType } from 'twenty-shared/types'; +import { computeMorphRelationFieldName } from 'twenty-shared/utils'; +import { v4 } from 'uuid'; const TEST_OBJECT_METADATA_NAME_SINGULAR = 'apiInputValidationTestObject'; const TEST_OBJECT_METADATA_NAME_PLURAL = 'apiInputValidationTestObjects'; -const TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR = - 'apiInputValidationTargetTestObject'; -const TEST_TARGET_OBJECT_METADATA_NAME_PLURAL = - 'apiInputValidationTargetTestObjects'; +const TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR_1 = + 'apiInputValidationTargetTestObject1'; +const TEST_TARGET_OBJECT_METADATA_NAME_PLURAL_1 = + 'apiInputValidationTargetTestObjects1'; +const TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR_2 = + 'apiInputValidationTargetTestObject2'; +const TEST_TARGET_OBJECT_METADATA_NAME_PLURAL_2 = + 'apiInputValidationTargetTestObjects2'; export const TEST_TARGET_OBJECT_RECORD_ID = '20202020-a21e-4ec2-873b-de4264d89025'; @@ -21,6 +26,15 @@ export const TEST_UUID_FIELD_VALUE = '20202020-b21e-4ec2-873b-de4264d89025'; export const TEST_TARGET_OBJECT_RECORD_ID_FIELD_VALUE = '20202020-b21e-4ec2-873b-de4264d89021'; +export const joinColumnNameForManyToOneMorphRelationField1 = + computeMorphRelationFieldName({ + fieldName: 'manyToOneMorphRelationField', + relationType: RelationType.MANY_TO_ONE, + targetObjectMetadataNameSingular: + TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR_1, + targetObjectMetadataNamePlural: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL_1, + }) + 'Id'; + export const setupTestObjectsWithAllFieldTypes = async () => { const createdObjectMetadata = await createOneObjectMetadata({ input: { @@ -33,21 +47,33 @@ export const setupTestObjectsWithAllFieldTypes = async () => { const objectMetadataId = createdObjectMetadata.data.createOneObject.id; - const createdTargetObjectMetadata = await createOneObjectMetadata({ + const createdTargetObjectMetadata1 = await createOneObjectMetadata({ input: { - nameSingular: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR, - namePlural: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL, - labelSingular: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR, - labelPlural: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL, + nameSingular: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR_1, + namePlural: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL_1, + labelSingular: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR_1, + labelPlural: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL_1, }, }); - const targetObjectMetadataId = - createdTargetObjectMetadata.data.createOneObject.id; + const createdTargetObjectMetadata2 = await createOneObjectMetadata({ + input: { + nameSingular: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR_2, + namePlural: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL_2, + labelSingular: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR_2, + labelPlural: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL_2, + }, + }); + + const targetObjectMetadata1Id = + createdTargetObjectMetadata1.data.createOneObject.id; + const targetObjectMetadata2Id = + createdTargetObjectMetadata2.data.createOneObject.id; const fieldMetadataCreationInputs = getFieldMetadataCreationInputs( objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, ); for (const input of fieldMetadataCreationInputs) { @@ -58,8 +84,8 @@ export const setupTestObjectsWithAllFieldTypes = async () => { await makeGraphqlAPIRequest( createManyOperationFactory({ - objectMetadataSingularName: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR, - objectMetadataPluralName: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL, + objectMetadataSingularName: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR_1, + objectMetadataPluralName: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL_1, gqlFields: `id`, data: [ { @@ -73,11 +99,15 @@ export const setupTestObjectsWithAllFieldTypes = async () => { createManyOperationFactory({ objectMetadataSingularName: TEST_OBJECT_METADATA_NAME_SINGULAR, objectMetadataPluralName: TEST_OBJECT_METADATA_NAME_PLURAL, - gqlFields: `id`, + gqlFields: ` + id + ${joinColumnNameForManyToOneMorphRelationField1}`, data: [ { - id: randomUUID(), + id: v4(), manyToOneRelationFieldId: TEST_TARGET_OBJECT_RECORD_ID, + [joinColumnNameForManyToOneMorphRelationField1]: + TEST_TARGET_OBJECT_RECORD_ID, uuidField: TEST_UUID_FIELD_VALUE, textField: 'test', phonesField: { @@ -135,7 +165,7 @@ export const setupTestObjectsWithAllFieldTypes = async () => { arrayField: ['test'], }, { - id: randomUUID(), + id: v4(), }, ], }), @@ -143,8 +173,8 @@ export const setupTestObjectsWithAllFieldTypes = async () => { await makeGraphqlAPIRequest( createManyOperationFactory({ - objectMetadataSingularName: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR, - objectMetadataPluralName: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL, + objectMetadataSingularName: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR_1, + objectMetadataPluralName: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL_1, gqlFields: `id`, data: [ { @@ -156,7 +186,8 @@ export const setupTestObjectsWithAllFieldTypes = async () => { return { objectMetadataId, - targetObjectMetadataId, + targetObjectMetadata1Id, + targetObjectMetadata2Id, objectMetadataSingularName: TEST_OBJECT_METADATA_NAME_SINGULAR, objectMetadataPluralName: TEST_OBJECT_METADATA_NAME_PLURAL, }; diff --git a/packages/twenty-server/test/integration/graphql/utils/perform-create-many-operation.utils.ts b/packages/twenty-server/test/integration/graphql/utils/perform-create-many-operation.utils.ts index 7fd48ff51a..625ad03613 100644 --- a/packages/twenty-server/test/integration/graphql/utils/perform-create-many-operation.utils.ts +++ b/packages/twenty-server/test/integration/graphql/utils/perform-create-many-operation.utils.ts @@ -1,8 +1,7 @@ -import { randomUUID } from 'crypto'; - import { createManyOperationFactory } from 'test/integration/graphql/utils/create-many-operation-factory.util'; import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util'; import { capitalize } from 'twenty-shared/utils'; +import { v4 } from 'uuid'; export const performCreateManyOperation = async ( objectMetadataSingularName: string, @@ -16,7 +15,7 @@ export const performCreateManyOperation = async ( objectMetadataPluralName, gqlFields, data: data.map((item) => ({ - id: randomUUID(), + id: v4(), ...item, })), }),