Rest/Gql - Filter input - Integration tests (#14836)
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.ADDRESS;
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.ARRAY;
|
||||
// const failingTestCases =
|
||||
// failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
// describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.BOOLEAN;
|
||||
// const failingTestCases =
|
||||
// failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
// describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+416
@@ -0,0 +1,416 @@
|
||||
import { type FieldMetadataTypeToTest } from 'test/integration/graphql/suites/args-validation/types/field-metadata-type-to-test';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { type CompositeFieldMetadataType } from 'src/engine/metadata-modules/workspace-migration/factories/composite-column-action.factory';
|
||||
|
||||
export const failingFilterInputByFieldMetadataType: {
|
||||
[K in Exclude<FieldMetadataTypeToTest, CompositeFieldMetadataType>]: {
|
||||
gqlFilterInput: any;
|
||||
restFilterInput: any;
|
||||
gqlErrorMessage: string;
|
||||
restErrorMessage: string;
|
||||
}[];
|
||||
} = {
|
||||
[FieldMetadataType.RELATION]: [
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationField: {
|
||||
eq: '6dd71a46-68fe-4420-82b3-0d5b00ad2642',
|
||||
},
|
||||
},
|
||||
gqlErrorMessage: 'is not defined by type',
|
||||
restFilterInput:
|
||||
'manyToOneRelationField[eq]:"6dd71a46-68fe-4420-82b3-0d5b00ad2642"',
|
||||
restErrorMessage: "'manyToOneRelationField' does not exist",
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: {
|
||||
eq: 'invalid-uuid',
|
||||
},
|
||||
},
|
||||
gqlErrorMessage: 'Invalid UUID',
|
||||
restFilterInput: 'manyToOneRelationFieldId[eq]:"invalid-uuid"',
|
||||
restErrorMessage: 'invalid input syntax for type uuid',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
oneToManyRelationField: {
|
||||
eq: '6dd71a46-68fe-4420-82b3-0d5b00ad2642',
|
||||
},
|
||||
},
|
||||
gqlErrorMessage: 'is not defined by type',
|
||||
restFilterInput:
|
||||
'oneToManyRelationFieldId[eq]:"6dd71a46-68fe-4420-82b3-0d5b00ad2642"',
|
||||
restErrorMessage: "'oneToManyRelationFieldId' does not exist",
|
||||
},
|
||||
// {
|
||||
// gqlFilterInput: {
|
||||
// oneToManyRelationFieldId: {
|
||||
// eq: 'invalid-uuid',
|
||||
// },
|
||||
// },
|
||||
// restFilterInput: 'oneToManyRelationFieldId[eq]:"invalid-uuid"',
|
||||
// gqlErrorMessage: 'is not defined by type',
|
||||
// restErrorMessage: "'oneToManyRelationFieldId' does not exist",
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.UUID]: [
|
||||
{
|
||||
gqlFilterInput: { uuidField: { eq: 'invalid-uuid' } },
|
||||
gqlErrorMessage: 'Invalid UUID',
|
||||
restFilterInput: 'uuidField[eq]:"invalid-uuid"',
|
||||
restErrorMessage: 'invalid input syntax for type uuid',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { uuidField: { eq: undefined } },
|
||||
gqlErrorMessage:
|
||||
'undefined is not iterable (cannot read property Symbol(Symbol.iterator))',
|
||||
restFilterInput: 'uuidField[eq]:"undefined"',
|
||||
restErrorMessage: 'invalid input syntax for type uuid',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { uuidField: { eq: 2 } },
|
||||
gqlErrorMessage: 'UUID must be a string',
|
||||
restFilterInput: 'uuidField[eq]:2',
|
||||
restErrorMessage: 'invalid input syntax for type uuid',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { uuidField: { eq: {} } },
|
||||
gqlErrorMessage: 'UUID must be a string',
|
||||
restFilterInput: 'uuidField[eq]:"{}"',
|
||||
restErrorMessage: 'invalid input syntax for type uuid',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { uuidField: { eq: [] } },
|
||||
gqlErrorMessage: 'UUID must be a string',
|
||||
restFilterInput: 'uuidField[eq]:"[]"',
|
||||
restErrorMessage: 'invalid input syntax for type uuid',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { uuidField: { eq: true } },
|
||||
gqlErrorMessage: 'UUID must be a string',
|
||||
restFilterInput: 'uuidField[eq]:"true"',
|
||||
restErrorMessage: 'invalid input syntax for type uuid',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { uuidField: { eq: '2025-01-01' } },
|
||||
gqlErrorMessage: 'Invalid UUID',
|
||||
restFilterInput: 'uuidField[eq]:"2025-01-01"',
|
||||
restErrorMessage: 'invalid input syntax for type uuid',
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.TEXT]: [
|
||||
{
|
||||
gqlFilterInput: {
|
||||
textField: { regex: 'test' },
|
||||
},
|
||||
gqlErrorMessage: 'Operator "regex" is not supported',
|
||||
restFilterInput: 'textField[regex]:test',
|
||||
restErrorMessage: 'comparator regex not in',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
textField: { iregex: 'test' },
|
||||
},
|
||||
gqlErrorMessage: 'Operator "iregex" is not supported',
|
||||
restFilterInput: 'textField[iregex]:test',
|
||||
restErrorMessage: 'comparator iregex not in',
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.DATE_TIME]: [
|
||||
{
|
||||
gqlFilterInput: { dateTimeField: { eq: 'not-a-date-time' } },
|
||||
gqlErrorMessage:
|
||||
'invalid input syntax for type timestamp with time zone: "0NaN-NaN-NaNTNaN:NaN:NaN.NaN+NaN:NaN"',
|
||||
restFilterInput: 'dateTimeField[eq]:"not-a-date-time"',
|
||||
restErrorMessage:
|
||||
'invalid input syntax for type timestamp with time zone',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateTimeField: { eq: {} } },
|
||||
gqlErrorMessage:
|
||||
'invalid input syntax for type timestamp with time zone: "0NaN-NaN-NaNTNaN:NaN:NaN.NaN+NaN:NaN"',
|
||||
restFilterInput: 'dateTimeField[eq]:"{}"',
|
||||
restErrorMessage:
|
||||
'invalid input syntax for type timestamp with time zone',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateTimeField: { eq: [] } },
|
||||
gqlErrorMessage:
|
||||
'invalid input syntax for type timestamp with time zone: "0NaN-NaN-NaNTNaN:NaN:NaN.NaN+NaN:NaN"',
|
||||
restFilterInput: 'dateTimeField[eq]:"[]"',
|
||||
restErrorMessage:
|
||||
'invalid input syntax for type timestamp with time zone',
|
||||
},
|
||||
// TODO - fix this, should throw an error
|
||||
// {
|
||||
// gqlFilterInput: { dateTimeField: { eq: true } },
|
||||
// gqlErrorMessage:
|
||||
// 'invalid input syntax for type timestamp with time zone: "0NaN-NaN-NaNTNaN:NaN:NaN.NaN+NaN:NaN"',
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.DATE]: [
|
||||
{
|
||||
gqlFilterInput: { dateField: { eq: 'not-a-date' } },
|
||||
gqlErrorMessage:
|
||||
'invalid input syntax for type date: "0NaN-NaN-NaNTNaN:NaN:NaN.NaN+NaN:NaN"',
|
||||
restFilterInput: 'dateField[eq]:"{}"',
|
||||
restErrorMessage: 'invalid input syntax for type date',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateField: { eq: {} } },
|
||||
gqlErrorMessage:
|
||||
'invalid input syntax for type date: "0NaN-NaN-NaNTNaN:NaN:NaN.NaN+NaN:NaN"',
|
||||
restFilterInput: 'dateField[eq]:"{}"',
|
||||
restErrorMessage: 'invalid input syntax for type date',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateField: { eq: [] } },
|
||||
gqlErrorMessage:
|
||||
'invalid input syntax for type date: "0NaN-NaN-NaNTNaN:NaN:NaN.NaN+NaN:NaN"',
|
||||
restFilterInput: 'dateField[eq]:"[]"',
|
||||
restErrorMessage: 'invalid input syntax for type date',
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.BOOLEAN]: [
|
||||
// {
|
||||
// gqlFilterInput: { booleanField: { eq: 'not-a-boolean' } },
|
||||
// gqlErrorMessage:
|
||||
// 'Boolean cannot represent a non boolean value: "not-a-boolean"',
|
||||
// // TODO - fix this, should throw an error
|
||||
// // restFilterInput: 'booleanField[eq]:"not-a-boolean"',
|
||||
// // restErrorMessage: 'invalid input syntax for type boolean',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { booleanField: { eq: [] } },
|
||||
// gqlErrorMessage: 'Boolean cannot represent a non boolean value: []',
|
||||
// // TODO - fix this, should throw an error
|
||||
// // restFilterInput: 'booleanField[eq]:"[]"',
|
||||
// // restErrorMessage: 'invalid input syntax for type boolean',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { booleanField: { eq: 2 } },
|
||||
// gqlErrorMessage: 'Boolean cannot represent a non boolean value: 2',
|
||||
// // TODO - fix this, should throw an error
|
||||
// // restFilterInput: 'booleanField[eq]:2',
|
||||
// // restErrorMessage: 'invalid input syntax for type boolean',
|
||||
// },
|
||||
// TODO - fix this, should throw an error
|
||||
// {
|
||||
// gqlFilterInput: { booleanField: { eq: null } },
|
||||
// gqlErrorMessage: 'Boolean cannot represent a non boolean value: null',
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.NUMBER]: [
|
||||
// {
|
||||
// gqlFilterInput: { numberField: { eq: 'not-a-number' } },
|
||||
// gqlErrorMessage:
|
||||
// 'Float cannot represent non numeric value: "not-a-number"',
|
||||
// // TODO - fix this, should throw an error
|
||||
// // restFilterInput: 'numberField[eq]:"not-a-number"',
|
||||
// // restErrorMessage: 'invalid input syntax for type float',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { numberField: { eq: {} } },
|
||||
// gqlErrorMessage: 'Float cannot represent non numeric value: {}',
|
||||
// // TODO - fix this, should throw an error
|
||||
// // restFilterInput: 'numberField[eq]:"{}"',
|
||||
// // restErrorMessage: 'invalid input syntax for type float',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { numberField: { eq: [] } },
|
||||
// gqlErrorMessage: 'Float cannot represent non numeric value: []',
|
||||
// // TODO - fix this, should throw an error
|
||||
// // restFilterInput: 'numberField[eq]:"[]"',
|
||||
// // restErrorMessage: 'invalid input syntax for type float',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { numberField: { eq: true } },
|
||||
// gqlErrorMessage: 'Float cannot represent non numeric value: true',
|
||||
// // TODO - fix this, should throw an error
|
||||
// // restFilterInput: 'numberField[eq]:"true"',
|
||||
// // restErrorMessage: 'invalid input syntax for type float',
|
||||
// },
|
||||
// TODO - ensure it should throw
|
||||
// {
|
||||
// gqlFilterInput: { numberField: { eq: null } },
|
||||
// gqlErrorMessage: 'Float cannot represent non numeric value: null',
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.RATING]: [
|
||||
{
|
||||
gqlFilterInput: { ratingField: { eq: 'not-a-rating' } },
|
||||
gqlErrorMessage: 'Value "not-a-rating" does not exist in ',
|
||||
restFilterInput: 'ratingField[eq]:"not-a-rating"',
|
||||
restErrorMessage: 'invalid input value for enum',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { ratingField: { eq: {} } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: {}.',
|
||||
restFilterInput: 'ratingField[eq]:"{}"',
|
||||
restErrorMessage: 'invalid input value for enum',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { ratingField: { eq: [] } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: [].',
|
||||
restFilterInput: 'ratingField[eq]:"[]"',
|
||||
restErrorMessage: 'invalid input value for enum',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { ratingField: { eq: true } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: true.',
|
||||
restFilterInput: 'ratingField[eq]:"true"',
|
||||
restErrorMessage: 'invalid input value for enum',
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { ratingField: { eq: 2 } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: 2.',
|
||||
restFilterInput: 'ratingField[eq]:2',
|
||||
restErrorMessage: 'invalid input value for enum',
|
||||
},
|
||||
// TODO - ensure it should throw
|
||||
// {
|
||||
// gqlFilterInput: { ratingField: { eq: null } },
|
||||
// gqlErrorMessage: 'cannot represent non-string value: null.',
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.SELECT]: [
|
||||
{
|
||||
gqlFilterInput: { selectField: { eq: 'not-a-select' } },
|
||||
gqlErrorMessage: 'Value "not-a-select" does not exist in',
|
||||
restFilterInput: 'selectField[eq]:"not-a-select"',
|
||||
restErrorMessage: "not available in 'selectField'",
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { selectField: { eq: {} } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: {}.',
|
||||
restFilterInput: 'selectField[eq]:"{}"',
|
||||
restErrorMessage: "not available in 'selectField'",
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { selectField: { eq: [] } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: [].',
|
||||
restFilterInput: 'selectField[eq]:"[]"',
|
||||
restErrorMessage: "not available in 'selectField'",
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { selectField: { eq: true } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: true.',
|
||||
restFilterInput: 'selectField[eq]:"true"',
|
||||
restErrorMessage: "not available in 'selectField'",
|
||||
},
|
||||
// TODO - ensure it should throw
|
||||
// {
|
||||
// gqlFilterInput: { selectField: { eq: null } },
|
||||
// gqlErrorMessage: 'cannot represent non-string value: null.',
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.MULTI_SELECT]: [
|
||||
{
|
||||
gqlFilterInput: { multiSelectField: { eq: 'not-a-multi-select' } },
|
||||
gqlErrorMessage: 'Value "not-a-multi-select" does not exist ',
|
||||
restFilterInput: 'multiSelectField[eq]:"not-a-multi-select"',
|
||||
restErrorMessage: "not available in 'multiSelectField'",
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { multiSelectField: { eq: {} } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: {}.',
|
||||
restFilterInput: 'multiSelectField[eq]:"{}"',
|
||||
restErrorMessage: "not available in 'multiSelectField'",
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { multiSelectField: { eq: [] } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: [].',
|
||||
restFilterInput: 'multiSelectField[eq]:"[]"',
|
||||
restErrorMessage: "not available in 'multiSelectField'",
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { multiSelectField: { eq: true } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: true.',
|
||||
restFilterInput: 'multiSelectField[eq]:"true"',
|
||||
restErrorMessage: "not available in 'multiSelectField'",
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { multiSelectField: { eq: 2 } },
|
||||
gqlErrorMessage: 'cannot represent non-string value: 2.',
|
||||
restFilterInput: 'multiSelectField[eq]:2',
|
||||
restErrorMessage: "enum value '2' not available in 'multiSelectField' ",
|
||||
},
|
||||
// TODO - ensure it should throw
|
||||
// {
|
||||
// gqlFilterInput: { multiSelectField: { eq: null } },
|
||||
// gqlErrorMessage: 'cannot represent non-string value: null.',
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.RAW_JSON]: [
|
||||
// {
|
||||
// gqlFilterInput: { rawJsonField: { like: {} } },
|
||||
// gqlErrorMessage: 'cannot represent a non string value',
|
||||
// // TODO - fix this ? for rest
|
||||
// // restFilterInput: 'rawJsonField[like]:"{}"',
|
||||
// // restErrorMessage: 'cannot represent a non string value',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { rawJsonField: { like: [] } },
|
||||
// gqlErrorMessage: 'cannot represent a non string value',
|
||||
// // TODO - fix this ? for rest
|
||||
// // restFilterInput: 'rawJsonField[like]:"[]"',
|
||||
// // restErrorMessage: 'cannot represent a non string value',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { rawJsonField: { like: true } },
|
||||
// gqlErrorMessage: 'cannot represent a non string value',
|
||||
// // TODO - fix this ? for rest
|
||||
// // restFilterInput: 'rawJsonField[like]:"true"',
|
||||
// // restErrorMessage: 'cannot represent a non string value',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { rawJsonField: { like: 2 } },
|
||||
// gqlErrorMessage: 'cannot represent a non string value',
|
||||
// // TODO - fix this ? for rest
|
||||
// // restFilterInput: 'rawJsonField[like]:2',
|
||||
// // restErrorMessage: 'cannot represent a non string value',
|
||||
// },
|
||||
// TODO - ensure it should throw
|
||||
// {
|
||||
// gqlFilterInput: { rawJsonField: { like: null } },
|
||||
// gqlErrorMessage: 'cannot represent non-string value: null.',
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.ARRAY]: [
|
||||
// {
|
||||
// gqlFilterInput: { arrayField: { containsIlike: {} } },
|
||||
// gqlErrorMessage: 'cannot represent a non string value',
|
||||
// // TODO - fix this ? containsIlike not existing for rest
|
||||
// // restFilterInput: 'arrayField[containsIlike]:"{}"',
|
||||
// // restErrorMessage: '',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { arrayField: { containsIlike: [] } },
|
||||
// gqlErrorMessage: 'cannot represent a non string value',
|
||||
// // TODO - fix this ? containsIlike not existing for rest
|
||||
// // restFilterInput: 'arrayField[containsIlike]:"[]"',
|
||||
// // restErrorMessage: '',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { arrayField: { containsIlike: true } },
|
||||
// gqlErrorMessage: 'cannot represent a non string value',
|
||||
// // TODO - fix this ? containsIlike not existing for rest
|
||||
// // restFilterInput: 'arrayField[containsIlike]:"true"',
|
||||
// // restErrorMessage: '',
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { arrayField: { containsIlike: 2 } },
|
||||
// gqlErrorMessage: 'cannot represent a non string value',
|
||||
// // TODO - fix this ? containsIlike not existing for rest
|
||||
// // restFilterInput: 'arrayField[containsIlike]:2',
|
||||
// // restErrorMessage: '',
|
||||
// },
|
||||
// TODO - ensure it should throw
|
||||
// {
|
||||
// gqlFilterInput: { arrayField: { containsIlike: null } },
|
||||
// gqlErrorMessage: 'cannot represent a non string value',
|
||||
// },
|
||||
],
|
||||
};
|
||||
+938
@@ -0,0 +1,938 @@
|
||||
import { isDefined } from 'class-validator';
|
||||
import { type FieldMetadataTypeToTest } from 'test/integration/graphql/suites/args-validation/types/field-metadata-type-to-test';
|
||||
import {
|
||||
TEST_TARGET_OBJECT_RECORD_ID,
|
||||
TEST_UUID_FIELD_VALUE,
|
||||
} from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
export const successfulFilterInputByFieldMetadataType: {
|
||||
[K in FieldMetadataTypeToTest]: {
|
||||
gqlFilterInput: any;
|
||||
restFilterInput: string;
|
||||
validateFilter: (record: Record<string, any>) => boolean;
|
||||
}[];
|
||||
} = {
|
||||
[FieldMetadataType.RELATION]: [
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: {
|
||||
neq: '00000000-0000-4000-8000-000000000000',
|
||||
},
|
||||
},
|
||||
restFilterInput: `manyToOneRelationFieldId[neq]:"00000000-0000-4000-8000-000000000000"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return (
|
||||
record.manyToOneRelationFieldId !==
|
||||
'00000000-0000-4000-8000-000000000000'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: {
|
||||
eq: TEST_TARGET_OBJECT_RECORD_ID,
|
||||
},
|
||||
},
|
||||
restFilterInput: `manyToOneRelationFieldId[eq]:"${TEST_TARGET_OBJECT_RECORD_ID}"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.manyToOneRelationFieldId === TEST_TARGET_OBJECT_RECORD_ID;
|
||||
},
|
||||
},
|
||||
// TODO - fix this, should be returning or not be allowed
|
||||
// {
|
||||
// gqlFilterInput: {
|
||||
// manyToOneRelationFieldId: {
|
||||
// eq: null,
|
||||
// },
|
||||
// },
|
||||
// restFilterInput: 'manyToOneRelationFieldId[eq]=null',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.manyToOneRelationField === null;
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: {
|
||||
gt: '00000000-0000-4000-8000-000000000000',
|
||||
},
|
||||
},
|
||||
restFilterInput:
|
||||
'manyToOneRelationFieldId[gt]:"00000000-0000-4000-8000-000000000000"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return (
|
||||
record.manyToOneRelationFieldId >
|
||||
'00000000-0000-4000-8000-000000000000'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: {
|
||||
gte: '00000000-0000-4000-8000-000000000000',
|
||||
},
|
||||
},
|
||||
restFilterInput: `manyToOneRelationFieldId[gte]:"00000000-0000-4000-8000-000000000000"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return (
|
||||
record.manyToOneRelationFieldId >=
|
||||
'00000000-0000-4000-8000-000000000000'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: {
|
||||
lt: 'ffffffff-ffff-4fff-bfff-ffffffffffff',
|
||||
},
|
||||
},
|
||||
restFilterInput: `manyToOneRelationFieldId[lt]:"ffffffff-ffff-4fff-bfff-ffffffffffff"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return (
|
||||
record.manyToOneRelationFieldId <
|
||||
'ffffffff-ffff-4fff-bfff-ffffffffffff'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: {
|
||||
lte: 'ffffffff-ffff-4fff-bfff-ffffffffffff',
|
||||
},
|
||||
},
|
||||
restFilterInput: `manyToOneRelationFieldId[lte]:"ffffffff-ffff-4fff-bfff-ffffffffffff"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return (
|
||||
record.manyToOneRelationFieldId <=
|
||||
'ffffffff-ffff-4fff-bfff-ffffffffffff'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: {
|
||||
in: [TEST_TARGET_OBJECT_RECORD_ID],
|
||||
},
|
||||
},
|
||||
restFilterInput: `manyToOneRelationFieldId[in]:["${TEST_TARGET_OBJECT_RECORD_ID}"]`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.manyToOneRelationFieldId === TEST_TARGET_OBJECT_RECORD_ID;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: { is: 'NULL' },
|
||||
},
|
||||
restFilterInput: 'manyToOneRelationFieldId[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.manyToOneRelationFieldId === null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
manyToOneRelationFieldId: { is: 'NOT_NULL' },
|
||||
},
|
||||
restFilterInput: 'manyToOneRelationFieldId[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.manyToOneRelationFieldId);
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.UUID]: [
|
||||
{
|
||||
gqlFilterInput: {
|
||||
uuidField: { neq: '00000000-0000-4000-8000-000000000000' },
|
||||
},
|
||||
restFilterInput: `uuidField[neq]:"00000000-0000-4000-8000-000000000000"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.uuidField !== '00000000-0000-4000-8000-000000000000';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
uuidField: { eq: TEST_UUID_FIELD_VALUE },
|
||||
},
|
||||
restFilterInput: `uuidField[eq]:"${TEST_UUID_FIELD_VALUE}"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.uuidField === TEST_UUID_FIELD_VALUE;
|
||||
},
|
||||
},
|
||||
// TODO - fix this, should be returning or not be allowed
|
||||
// {
|
||||
// gqlFilterInput: { uuidField: { eq: null } },
|
||||
// restFilterInput: 'uuidField[eq]=null',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.uuidField === null;
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: {
|
||||
uuidField: { gt: '00000000-0000-4000-8000-000000000000' },
|
||||
},
|
||||
restFilterInput: `uuidField[gt]:"00000000-0000-4000-8000-000000000000"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.uuidField > '00000000-0000-4000-8000-000000000000';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
uuidField: { gte: '00000000-0000-4000-8000-000000000000' },
|
||||
},
|
||||
restFilterInput: `uuidField[gte]:"00000000-0000-4000-8000-000000000000"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.uuidField >= '00000000-0000-4000-8000-000000000000';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
uuidField: { lt: 'ffffffff-ffff-4fff-bfff-ffffffffffff' },
|
||||
},
|
||||
restFilterInput: `uuidField[lt]:"ffffffff-ffff-4fff-bfff-ffffffffffff"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.uuidField < 'ffffffff-ffff-4fff-bfff-ffffffffffff';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
uuidField: { lte: 'ffffffff-ffff-4fff-bfff-ffffffffffff' },
|
||||
},
|
||||
restFilterInput: `uuidField[lte]:"ffffffff-ffff-4fff-bfff-ffffffffffff"`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.uuidField <= 'ffffffff-ffff-4fff-bfff-ffffffffffff';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
uuidField: { in: [TEST_UUID_FIELD_VALUE] },
|
||||
},
|
||||
restFilterInput: `uuidField[in]:["${TEST_UUID_FIELD_VALUE}"]`,
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.uuidField === TEST_UUID_FIELD_VALUE;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { uuidField: { is: 'NULL' } },
|
||||
restFilterInput: 'uuidField[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.uuidField === null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { uuidField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'uuidField[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.uuidField);
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.TEXT]: [
|
||||
{
|
||||
gqlFilterInput: { textField: { neq: 'neqtest' } },
|
||||
restFilterInput: 'textField[neq]:"neqtest"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.textField !== 'neqtest';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { textField: { eq: 'test' } },
|
||||
restFilterInput: 'textField[eq]:"test"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.textField === 'test';
|
||||
},
|
||||
},
|
||||
// TODO - fix this ? not working
|
||||
// {
|
||||
// gqlFilterInput: { textField: { eq: null } },
|
||||
// restFilterInput: 'textField[eq]:"null"',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.textField === '';
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: { textField: { gt: 'tess' } },
|
||||
restFilterInput: 'textField[gt]:"tess"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.textField > 'tess';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { textField: { gte: 'tess' } },
|
||||
restFilterInput: 'textField[gte]:"tess"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.textField >= 'tess';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { textField: { lt: 'tesu' } },
|
||||
restFilterInput: 'textField[lt]:"tesu"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.textField < 'tesu';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { textField: { lte: 'tesu' } },
|
||||
restFilterInput: 'textField[lte]:"tesu"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.textField <= 'tesu';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { textField: { in: ['test'] } },
|
||||
restFilterInput: 'textField[in]:["test"]',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.textField === 'test';
|
||||
},
|
||||
},
|
||||
// TODO - fix this ? not working
|
||||
// {
|
||||
// gqlFilterInput: { textField: { is: 'NULL' } },
|
||||
// restFilterInput: 'textField[is]:"NULL"',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.textField === '';
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: { textField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'textField[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.textField);
|
||||
},
|
||||
},
|
||||
// TODO - fix this ? not working
|
||||
// {
|
||||
// gqlFilterInput: { textField: { startsWith: 'tes' } },
|
||||
// restFilterInput: 'textField[startsWith]:"tes"',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.textField.startsWith('tes');
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: { textField: { like: '%es%' } },
|
||||
restFilterInput: 'textField[like]:"%es%"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.textField.includes('es');
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { textField: { ilike: '%ES%' } },
|
||||
restFilterInput: 'textField[ilike]:"%ES%"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.textField.toLowerCase().includes('es');
|
||||
},
|
||||
},
|
||||
//TODO - regex, iregex not working ? to remove from gql schema ?
|
||||
// {
|
||||
// gqlFilterInput: { textField: { regex: '^test$' } },
|
||||
// restFilterInput: 'textField[regex]:"^test$"',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.textField.includes('test');
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// gqlFilterInput: { textField: { iregex: '^test$' } },
|
||||
// restFilterInput: 'textField[iregex]:"^test$"',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.textField.toLowerCase().includes('test');
|
||||
// },
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.PHONES]: [
|
||||
{
|
||||
gqlFilterInput: {
|
||||
phonesField: { primaryPhoneNumber: { eq: '1234567890' } },
|
||||
},
|
||||
restFilterInput: 'phonesField.primaryPhoneNumber[eq]:"1234567890"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.phonesField.primaryPhoneNumber === '1234567890';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
phonesField: { primaryPhoneCallingCode: { is: 'NOT_NULL' } },
|
||||
},
|
||||
restFilterInput: 'phonesField.primaryPhoneCallingCode[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.phonesField.primaryPhoneCallingCode !== null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
phonesField: {
|
||||
additionalPhones: {
|
||||
is: 'NOT_NULL',
|
||||
},
|
||||
},
|
||||
},
|
||||
restFilterInput: 'phonesField.additionalPhones[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.phonesField.additionalPhones !== null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
phonesField: { primaryPhoneCountryCode: { like: 'FR' } },
|
||||
},
|
||||
restFilterInput: 'phonesField.primaryPhoneCountryCode[like]:"FR"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.phonesField.primaryPhoneCountryCode.includes('FR');
|
||||
},
|
||||
},
|
||||
// TODO - should be allowed ? two conditions simultaneously
|
||||
// {
|
||||
// gqlFilterInput: {
|
||||
// phonesField: {
|
||||
// primaryPhoneCountryCode: { is: 'NULL' },
|
||||
// primaryPhoneCallingCode: { is: 'NULL' },
|
||||
// },
|
||||
// },
|
||||
// restFilterInput:
|
||||
// 'phonesField[primaryPhoneCountryCode][is]=NULL&phonesField[primaryPhoneCallingCode][is]=NULL',
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.EMAILS]: [
|
||||
{
|
||||
gqlFilterInput: {
|
||||
emailsField: { primaryEmail: { eq: 'test@test.com' } },
|
||||
},
|
||||
restFilterInput: 'emailsField.primaryEmail[eq]:"test@test.com"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.emailsField.primaryEmail === 'test@test.com';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
emailsField: { additionalEmails: { is: 'NOT_NULL' } },
|
||||
},
|
||||
restFilterInput: 'emailsField.additionalEmails[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.emailsField.additionalEmails !== null;
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.DATE_TIME]: [
|
||||
// TODO - fix this ? not working
|
||||
// {
|
||||
// gqlFilterInput: { dateTimeField: { eq: '2025-01-01T00:00:00Z' } },
|
||||
// restFilterInput: 'dateTimeField[eq]=2025-01-01T00:00:00Z',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.dateTimeField === '2025-01-01T00:00:00Z';
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: { dateTimeField: { gt: '2005-01-01T00:00:00Z' } },
|
||||
restFilterInput: 'dateTimeField[gt]:"2005-01-01T00:00:00Z"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateTimeField > '2005-01-01T00:00:00Z';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateTimeField: { gte: '2005-01-01T00:00:00Z' } },
|
||||
restFilterInput: 'dateTimeField[gte]:"2005-01-01T00:00:00Z"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateTimeField >= '2005-01-01T00:00:00Z';
|
||||
},
|
||||
},
|
||||
// TODO - fix this ? not working
|
||||
// {
|
||||
// gqlFilterInput: { dateTimeField: { in: ['2025-01-01T00:00:00Z'] } },
|
||||
// restFilterInput: 'dateTimeField[in]=2025-01-01T00:00:00Z',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.dateTimeField === '2025-01-01T00:00:00Z';
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: { dateTimeField: { lt: '2125-01-01T00:00:00Z' } },
|
||||
restFilterInput: 'dateTimeField[lt]:"2125-01-01T00:00:00Z"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateTimeField < '2125-01-01T00:00:00Z';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateTimeField: { lte: '2125-01-01T00:00:00Z' } },
|
||||
restFilterInput: 'dateTimeField[lte]:"2125-01-01T00:00:00Z"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateTimeField <= '2125-01-01T00:00:00Z';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateTimeField: { neq: '2005-01-01T00:00:00Z' } },
|
||||
restFilterInput: 'dateTimeField[neq]:"2005-01-01T00:00:00Z"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateTimeField !== '2005-01-01T00:00:00Z';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateTimeField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'dateTimeField[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.dateTimeField);
|
||||
},
|
||||
},
|
||||
// {
|
||||
// gqlFilterInput: { dateTimeField: { is: 'NULL' } },
|
||||
// // TODO - fix this ? not working
|
||||
// // restFilterInput: 'dateTimeField[is]:"NULL"',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.dateTimeField === null;
|
||||
// },
|
||||
// },
|
||||
// TODO - fix this, should be returning or not be allowed
|
||||
// {
|
||||
// gqlFilterInput: { dateTimeField: { eq: null } },
|
||||
// restFilterInput: 'dateTimeField[eq]=null',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.dateTimeField === null;
|
||||
// },
|
||||
// },
|
||||
// TODO - why float are allowed ?
|
||||
// {
|
||||
// gqlFilterInput: { dateTimeField: { eq: 2 } },
|
||||
// restFilterInput: 'dateTimeField[eq]=2',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.dateTimeField === 2;
|
||||
// },
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.DATE]: [
|
||||
// TODO - fix this ? not working
|
||||
// {
|
||||
// gqlFilterInput: { dateField: { eq: '2025-01-01' } },
|
||||
// restFilterInput: 'dateField[eq]=2025-01-01',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.dateField === '2025-01-01';
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: { dateField: { neq: '2005-01-01' } },
|
||||
restFilterInput: 'dateField[neq]:"2005-01-01"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateField !== '2005-01-01';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateField: { gt: '2005-01-01' } },
|
||||
restFilterInput: 'dateField[gt]:"2005-01-01"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateField > '2005-01-01';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateField: { gte: '2005-01-01' } },
|
||||
restFilterInput: 'dateField[gte]:"2005-01-01"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateField >= '2005-01-01';
|
||||
},
|
||||
},
|
||||
// TODO - fix this ? not working
|
||||
// {
|
||||
// gqlFilterInput: { dateField: { in: ['2025-01-01'] } },
|
||||
// restFilterInput: 'dateField[in]=2025-01-01',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.dateField === '2025-01-01';
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: { dateField: { lt: '2125-01-01' } },
|
||||
restFilterInput: 'dateField[lt]:"2125-01-01"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateField < '2125-01-01';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateField: { lte: '2125-01-01' } },
|
||||
restFilterInput: 'dateField[lte]:"2125-01-01"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateField <= '2125-01-01';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'dateField[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.dateField);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { dateField: { is: 'NULL' } },
|
||||
restFilterInput: 'dateField[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.dateField === null;
|
||||
},
|
||||
},
|
||||
// TODO - fix this, should be returning or not be allowed
|
||||
// {
|
||||
// gqlFilterInput: { dateField: { eq: null } },
|
||||
// restFilterInput: 'dateField[eq]=null',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.dateField === null;
|
||||
// },
|
||||
// },
|
||||
// TODO - why float are allowed ?
|
||||
// {
|
||||
// gqlFilterInput: { dateField: { eq: 2 } },
|
||||
// restFilterInput: 'dateField[eq]=2',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.dateField === 2;
|
||||
// },
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.BOOLEAN]: [
|
||||
// {
|
||||
// gqlFilterInput: { booleanField: { eq: true } },
|
||||
// // TODO - fix this ? not working
|
||||
// // restFilterInput: 'booleanField[eq]:"true"',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.booleanField === true;
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: { booleanField: { is: 'NULL' } },
|
||||
restFilterInput: 'booleanField[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.booleanField === null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { booleanField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'booleanField[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.booleanField);
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.NUMBER]: [
|
||||
{
|
||||
gqlFilterInput: { numberField: { eq: 1 } },
|
||||
restFilterInput: 'numberField[eq]:1',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.numberField === 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { numberField: { gt: 0 } },
|
||||
restFilterInput: 'numberField[gt]:0',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.numberField > 0;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { numberField: { gte: 0 } },
|
||||
restFilterInput: 'numberField[gte]:0',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.numberField >= 0;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { numberField: { lt: 2 } },
|
||||
restFilterInput: 'numberField[lt]:2',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.numberField < 2;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { numberField: { lte: 1 } },
|
||||
restFilterInput: 'numberField[lte]:1',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.numberField <= 1;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { numberField: { neq: 2 } },
|
||||
restFilterInput: 'numberField[neq]:2',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.numberField !== 2;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { numberField: { is: 'NULL' } },
|
||||
restFilterInput: 'numberField[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.numberField === null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { numberField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'numberField[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.numberField);
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.LINKS]: [
|
||||
{
|
||||
gqlFilterInput: {
|
||||
linksField: { primaryLinkUrl: { eq: 'twenty.com' } },
|
||||
},
|
||||
restFilterInput: 'linksField.primaryLinkUrl[eq]:"twenty.com"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.linksField.primaryLinkUrl === 'twenty.com';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
linksField: {
|
||||
primaryLinkLabel: { eq: 'twenty - #1 Open source CRM' },
|
||||
},
|
||||
},
|
||||
restFilterInput:
|
||||
'linksField.primaryLinkLabel[eq]:"twenty - #1 Open source CRM"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return (
|
||||
record.linksField.primaryLinkLabel === 'twenty - #1 Open source CRM'
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { linksField: { secondaryLinks: { like: '%twenty%' } } },
|
||||
restFilterInput: 'linksField.secondaryLinks[like]:"%twenty%"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return JSON.stringify(record.linksField.secondaryLinks).includes(
|
||||
'twenty',
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.CURRENCY]: [
|
||||
{
|
||||
gqlFilterInput: {
|
||||
currencyField: { amountMicros: { eq: 1000000 } },
|
||||
},
|
||||
restFilterInput: 'currencyField.amountMicros[eq]:1000000',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return Number(record.currencyField.amountMicros) === 1000000;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { currencyField: { currencyCode: { eq: 'USD' } } },
|
||||
restFilterInput: 'currencyField.currencyCode[eq]:"USD"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.currencyField.currencyCode === 'USD';
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.FULL_NAME]: [
|
||||
{
|
||||
gqlFilterInput: { fullNameField: { firstName: { eq: 'John' } } },
|
||||
restFilterInput: 'fullNameField.firstName[eq]:"John"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.fullNameField.firstName === 'John';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { fullNameField: { lastName: { eq: 'Doe' } } },
|
||||
restFilterInput: 'fullNameField.lastName[eq]:"Doe"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.fullNameField.lastName === 'Doe';
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.RATING]: [
|
||||
{
|
||||
gqlFilterInput: { ratingField: { eq: 'RATING_5' } },
|
||||
restFilterInput: 'ratingField[eq]:"RATING_5"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.ratingField === 'RATING_5';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { ratingField: { neq: 'RATING_3' } },
|
||||
restFilterInput: 'ratingField[neq]:"RATING_3"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.ratingField !== 'RATING_3';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { ratingField: { is: 'NULL' } },
|
||||
restFilterInput: 'ratingField[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.ratingField === null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { ratingField: { in: ['RATING_5', 'RATING_4'] } },
|
||||
restFilterInput: 'ratingField[in]:["RATING_5","RATING_4"]',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return ['RATING_5', 'RATING_4'].includes(record.ratingField);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { ratingField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'ratingField[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.ratingField);
|
||||
},
|
||||
},
|
||||
// TODO - fix this, should be ok
|
||||
// {
|
||||
// gqlFilterInput: { ratingField: { isEmptyArray: true } },
|
||||
// restFilterInput: 'ratingField[isEmptyArray]=true',
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.SELECT]: [
|
||||
{
|
||||
gqlFilterInput: { selectField: { in: ['OPTION_1'] } },
|
||||
restFilterInput: 'selectField[in]:[OPTION_1]',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return ['OPTION_1'].includes(record.selectField);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { selectField: { is: 'NULL' } },
|
||||
restFilterInput: 'selectField[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.selectField === null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { selectField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'selectField[is]:NOT_NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.selectField);
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.MULTI_SELECT]: [
|
||||
{
|
||||
gqlFilterInput: { multiSelectField: { containsAny: ['OPTION_1'] } },
|
||||
restFilterInput: 'multiSelectField[containsAny]:[OPTION_1]',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.multiSelectField.includes('OPTION_1');
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { multiSelectField: { is: 'NULL' } },
|
||||
restFilterInput: 'multiSelectField[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.multiSelectField === null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { multiSelectField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'multiSelectField[is]:NOT_NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.multiSelectField);
|
||||
},
|
||||
},
|
||||
//TODO - null and empty array should be equivalent
|
||||
// {
|
||||
// gqlFilterInput: { multiSelectField: { isEmptyArray: true } },
|
||||
// restFilterInput: 'multiSelectField[isEmptyArray]=true',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.multiSelectField.length === 0;
|
||||
// },
|
||||
// },
|
||||
],
|
||||
[FieldMetadataType.ADDRESS]: [
|
||||
{
|
||||
gqlFilterInput: {
|
||||
addressField: { addressStreet1: { eq: 'address street 1' } },
|
||||
},
|
||||
restFilterInput: 'addressField.addressStreet1[eq]:"address street 1"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.addressField.addressStreet1 === 'address street 1';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
addressField: { addressStreet2: { eq: 'address street 2' } },
|
||||
},
|
||||
restFilterInput: 'addressField.addressStreet2[eq]:"address street 2"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.addressField.addressStreet2 === 'address street 2';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
addressField: { addressStreet2: { is: 'NOT_NULL' } },
|
||||
},
|
||||
restFilterInput: 'addressField.addressStreet2[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.addressField.addressStreet2);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
addressField: { addressCity: { eq: 'address city' } },
|
||||
},
|
||||
restFilterInput: 'addressField.addressCity[eq]:"address city"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.addressField.addressCity === 'address city';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
addressField: { addressState: { eq: 'address state' } },
|
||||
},
|
||||
restFilterInput: 'addressField.addressState[eq]:"address state"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.addressField.addressState === 'address state';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
addressField: { addressCountry: { eq: 'address country' } },
|
||||
},
|
||||
restFilterInput: 'addressField.addressCountry[eq]:"address country"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.addressField.addressCountry === 'address country';
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: {
|
||||
addressField: { addressPostcode: { eq: 'address postcode' } },
|
||||
},
|
||||
restFilterInput: 'addressField.addressPostcode[eq]:"address postcode"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.addressField.addressPostcode === 'address postcode';
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.RAW_JSON]: [
|
||||
{
|
||||
gqlFilterInput: { rawJsonField: { is: 'NULL' } },
|
||||
restFilterInput: 'rawJsonField[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.rawJsonField === null;
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { rawJsonField: { is: 'NOT_NULL' } },
|
||||
restFilterInput: 'rawJsonField[is]:"NOT_NULL"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return isDefined(record.rawJsonField);
|
||||
},
|
||||
},
|
||||
{
|
||||
gqlFilterInput: { rawJsonField: { like: '%test%' } },
|
||||
restFilterInput: 'rawJsonField[like]:"%test%"',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return JSON.stringify(record.rawJsonField).includes('test');
|
||||
},
|
||||
},
|
||||
],
|
||||
[FieldMetadataType.ARRAY]: [
|
||||
// {
|
||||
// gqlFilterInput: { arrayField: { containsIlike: 'test' } },
|
||||
// // TODO - fix this ? not existing for rest
|
||||
// // restFilterInput: 'arrayField[containsIlike]:"test"',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return JSON.stringify(record.arrayField).includes('test');
|
||||
// },
|
||||
// },
|
||||
{
|
||||
gqlFilterInput: { arrayField: { is: 'NULL' } },
|
||||
restFilterInput: 'arrayField[is]:NULL',
|
||||
validateFilter: (record: Record<string, any>) => {
|
||||
return record.arrayField === null;
|
||||
},
|
||||
},
|
||||
//TODO - null and empty array should be equivalent
|
||||
// {
|
||||
// gqlFilterInput: { arrayField: { isEmptyArray: true } },
|
||||
// restFilterInput: 'arrayField[isEmptyArray]=true',
|
||||
// validateFilter: (record: Record<string, any>) => {
|
||||
// return record.arrayField.length === 0;
|
||||
// },
|
||||
// },
|
||||
],
|
||||
};
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
export const TEST_OBJECT_GQL_FIELDS = `
|
||||
id
|
||||
manyToOneRelationFieldId
|
||||
manyToOneRelationField {
|
||||
id
|
||||
}
|
||||
uuidField
|
||||
textField
|
||||
phonesField {
|
||||
primaryPhoneNumber
|
||||
primaryPhoneCallingCode
|
||||
primaryPhoneCountryCode
|
||||
additionalPhones
|
||||
}
|
||||
emailsField {
|
||||
primaryEmail
|
||||
additionalEmails
|
||||
}
|
||||
dateTimeField
|
||||
dateField
|
||||
booleanField
|
||||
numberField
|
||||
linksField {
|
||||
primaryLinkUrl
|
||||
primaryLinkLabel
|
||||
secondaryLinks
|
||||
}
|
||||
currencyField {
|
||||
amountMicros
|
||||
currencyCode
|
||||
}
|
||||
fullNameField {
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
ratingField
|
||||
selectField
|
||||
multiSelectField
|
||||
addressField {
|
||||
addressStreet1
|
||||
addressStreet2
|
||||
addressCity
|
||||
addressState
|
||||
addressCountry
|
||||
addressPostcode
|
||||
}
|
||||
rawJsonField
|
||||
arrayField
|
||||
`;
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.CURRENCY;
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
import { failingFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant';
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-failing-scenario.util';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-failing-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.DATE;
|
||||
const failingTestCases =
|
||||
failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
import { failingFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant';
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-failing-scenario.util';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-failing-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.DATE_TIME;
|
||||
const failingTestCases =
|
||||
failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.EMAILS;
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.FULL_NAME;
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.LINKS;
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
import { failingFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant';
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-failing-scenario.util';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-failing-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.MULTI_SELECT;
|
||||
const failingTestCases =
|
||||
failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.NUMBER;
|
||||
// const failingTestCases =
|
||||
// failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
// describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.PHONES;
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
import { failingFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant';
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-failing-scenario.util';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-failing-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.RATING;
|
||||
const failingTestCases =
|
||||
failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.RAW_JSON;
|
||||
// const failingTestCases =
|
||||
// failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
// describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
import { failingFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant';
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-failing-scenario.util';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-failing-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.RELATION;
|
||||
const failingTestCases =
|
||||
failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
import { failingFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant';
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-failing-scenario.util';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.SELECT;
|
||||
const failingTestCases =
|
||||
failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
import { failingFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant';
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-failing-scenario.util';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-failing-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.TEXT;
|
||||
const failingTestCases =
|
||||
failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import { findManyOperationFactory } from 'test/integration/graphql/utils/find-many-operation-factory.util';
|
||||
import { makeGraphqlAPIRequestWithApiKey } from 'test/integration/graphql/utils/make-graphql-api-request-with-api-key.util';
|
||||
|
||||
export const testGqlFailingScenario = async (
|
||||
objectMetadataSingularName: string,
|
||||
objectMetadataPluralName: string,
|
||||
filter: any,
|
||||
errorMessage: string,
|
||||
) => {
|
||||
const graphqlOperation = findManyOperationFactory({
|
||||
objectMetadataSingularName: objectMetadataSingularName,
|
||||
objectMetadataPluralName: objectMetadataPluralName,
|
||||
gqlFields: 'id',
|
||||
filter,
|
||||
});
|
||||
|
||||
const response = await makeGraphqlAPIRequestWithApiKey(graphqlOperation);
|
||||
|
||||
expect(response.body.errors).toBeDefined();
|
||||
expect(response.body.errors[0].message).toContain(errorMessage);
|
||||
};
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import { TEST_OBJECT_GQL_FIELDS } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/test-object-gql-fields.constant';
|
||||
import { findManyOperationFactory } from 'test/integration/graphql/utils/find-many-operation-factory.util';
|
||||
import { makeGraphqlAPIRequestWithApiKey } from 'test/integration/graphql/utils/make-graphql-api-request-with-api-key.util';
|
||||
|
||||
export const testGqlSuccessfulScenario = async (
|
||||
objectMetadataSingularName: string,
|
||||
objectMetadataPluralName: string,
|
||||
filter: any,
|
||||
validateFilter: (record: Record<string, any>) => boolean,
|
||||
) => {
|
||||
const graphqlOperation = findManyOperationFactory({
|
||||
objectMetadataSingularName: objectMetadataSingularName,
|
||||
objectMetadataPluralName: objectMetadataPluralName,
|
||||
gqlFields: TEST_OBJECT_GQL_FIELDS,
|
||||
filter,
|
||||
});
|
||||
|
||||
const response = await makeGraphqlAPIRequestWithApiKey(graphqlOperation);
|
||||
|
||||
const records: Record<string, any>[] = response.body.data[
|
||||
objectMetadataPluralName
|
||||
].edges.map((edge: any) => edge.node);
|
||||
|
||||
expect(response.body.errors).toBeUndefined();
|
||||
|
||||
expect(records.length).toBeGreaterThan(0);
|
||||
expect(
|
||||
records.every((record: Record<string, any>) => validateFilter?.(record)),
|
||||
).toBe(true);
|
||||
};
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util';
|
||||
|
||||
export const testRestFailingScenario = async (
|
||||
objectMetadataPluralName: string,
|
||||
filter: any,
|
||||
errorMessage: string,
|
||||
) => {
|
||||
const encodedFilter = encodeURIComponent(filter);
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/${objectMetadataPluralName}?filter=${encodedFilter}`,
|
||||
});
|
||||
|
||||
expect(response.body.error).toBeDefined();
|
||||
expect(JSON.stringify(response.body.messages)).toContain(errorMessage);
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util';
|
||||
|
||||
export const testRestSuccessfulScenario = async (
|
||||
objectMetadataPluralName: string,
|
||||
filter: any,
|
||||
validateFilter: (record: Record<string, any>) => boolean,
|
||||
) => {
|
||||
const encodedFilter = encodeURIComponent(filter);
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/${objectMetadataPluralName}?filter=${encodedFilter}`,
|
||||
});
|
||||
|
||||
const records = response.body.data[objectMetadataPluralName];
|
||||
|
||||
expect(response.body.errors).toBeUndefined();
|
||||
|
||||
expect(records.length).toBeGreaterThan(0);
|
||||
|
||||
expect(
|
||||
records.every((record: Record<string, any>) => validateFilter?.(record)),
|
||||
).toBe(true);
|
||||
};
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
import { failingFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/failing-filter-input-by-field-metadata-type.constant';
|
||||
import { successfulFilterInputByFieldMetadataType } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/successful-filter-input-by-field-metadata-type.constant';
|
||||
import { testGqlFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-failing-scenario.util';
|
||||
import { testGqlSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-gql-successful-scenario.util';
|
||||
import { testRestFailingScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-failing-scenario.util';
|
||||
import { testRestSuccessfulScenario } from 'test/integration/graphql/suites/args-validation/filter-validation/utils/test-rest-successful-scenario.util';
|
||||
import { destroyManyObjectsMetadata } from 'test/integration/graphql/suites/args-validation/utils/destroy-many-objects-metadata';
|
||||
import { setupTestObjectsWithAllFieldTypes } from 'test/integration/graphql/suites/args-validation/utils/setup-test-objects-with-all-field-types.util';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
const FIELD_METADATA_TYPE = FieldMetadataType.UUID;
|
||||
const failingTestCases =
|
||||
failingFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
const successfulTestCases =
|
||||
successfulFilterInputByFieldMetadataType[FIELD_METADATA_TYPE];
|
||||
|
||||
describe(`Filter args validation - ${FIELD_METADATA_TYPE}`, () => {
|
||||
let objectMetadataId: string;
|
||||
let objectMetadataSingularName: string;
|
||||
let objectMetadataPluralName: string;
|
||||
let targetObjectMetadataId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
const setupTest = await setupTestObjectsWithAllFieldTypes();
|
||||
|
||||
objectMetadataId = setupTest.objectMetadataId;
|
||||
objectMetadataSingularName = setupTest.objectMetadataSingularName;
|
||||
objectMetadataPluralName = setupTest.objectMetadataPluralName;
|
||||
targetObjectMetadataId = setupTest.targetObjectMetadataId;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await destroyManyObjectsMetadata([
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('Gql filterInput - 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 filterInput - 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 filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('Rest filterInput - 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { type FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
type FieldMetadataTypesNotTested =
|
||||
| 'TS_VECTOR'
|
||||
| 'RICH_TEXT'
|
||||
| 'POSITION'
|
||||
| 'ACTOR'
|
||||
| 'MORPH_RELATION'
|
||||
| 'NUMERIC'
|
||||
| 'RICH_TEXT_V2';
|
||||
|
||||
export type FieldMetadataTypeToTest = Exclude<
|
||||
FieldMetadataType,
|
||||
FieldMetadataTypesNotTested
|
||||
>;
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { deleteOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/delete-one-object-metadata.util';
|
||||
import { updateOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/update-one-object-metadata.util';
|
||||
|
||||
export const destroyManyObjectsMetadata = async (
|
||||
objectMetadataIds: string[],
|
||||
) => {
|
||||
for (const objectMetadataId of objectMetadataIds) {
|
||||
await updateOneObjectMetadata({
|
||||
input: {
|
||||
idToUpdate: objectMetadataId,
|
||||
updatePayload: {
|
||||
isActive: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
await deleteOneObjectMetadata({
|
||||
input: {
|
||||
idToDelete: objectMetadataId,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
import { type FieldMetadataTypeToTest } from 'test/integration/graphql/suites/args-validation/types/field-metadata-type-to-test';
|
||||
import {
|
||||
FieldMetadataType,
|
||||
RelationType,
|
||||
type RelationCreationPayload,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { type FieldMetadataComplexOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input';
|
||||
|
||||
type FieldMetadataCreationInput = {
|
||||
name: string;
|
||||
label: string;
|
||||
type: FieldMetadataType;
|
||||
objectMetadataId: string;
|
||||
options?: FieldMetadataComplexOption[];
|
||||
relationCreationPayload?: RelationCreationPayload;
|
||||
};
|
||||
|
||||
export const getFieldMetadataCreationInputs = (
|
||||
objectMetadataId: string,
|
||||
targetObjectMetadataId: string,
|
||||
) => {
|
||||
const fieldInputsMap: {
|
||||
[K in FieldMetadataTypeToTest]:
|
||||
| FieldMetadataCreationInput
|
||||
| FieldMetadataCreationInput[];
|
||||
} = {
|
||||
[FieldMetadataType.TEXT]: {
|
||||
name: 'textField',
|
||||
label: 'textField',
|
||||
type: FieldMetadataType.TEXT,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.PHONES]: {
|
||||
name: 'phonesField',
|
||||
label: 'phonesField',
|
||||
type: FieldMetadataType.PHONES,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.EMAILS]: {
|
||||
name: 'emailsField',
|
||||
label: 'emailsField',
|
||||
type: FieldMetadataType.EMAILS,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.DATE_TIME]: {
|
||||
name: 'dateTimeField',
|
||||
label: 'dateTimeField',
|
||||
type: FieldMetadataType.DATE_TIME,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.DATE]: {
|
||||
name: 'dateField',
|
||||
label: 'dateField',
|
||||
type: FieldMetadataType.DATE,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.BOOLEAN]: {
|
||||
name: 'booleanField',
|
||||
label: 'booleanField',
|
||||
type: FieldMetadataType.BOOLEAN,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.NUMBER]: {
|
||||
name: 'numberField',
|
||||
label: 'numberField',
|
||||
type: FieldMetadataType.NUMBER,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.LINKS]: {
|
||||
name: 'linksField',
|
||||
label: 'linksField',
|
||||
type: FieldMetadataType.LINKS,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.CURRENCY]: {
|
||||
name: 'currencyField',
|
||||
label: 'currencyField',
|
||||
type: FieldMetadataType.CURRENCY,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.FULL_NAME]: {
|
||||
name: 'fullNameField',
|
||||
label: 'fullNameField',
|
||||
type: FieldMetadataType.FULL_NAME,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.RATING]: {
|
||||
name: 'ratingField',
|
||||
label: 'ratingField',
|
||||
type: FieldMetadataType.RATING,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.SELECT]: {
|
||||
name: 'selectField',
|
||||
label: 'selectField',
|
||||
type: FieldMetadataType.SELECT,
|
||||
options: [
|
||||
{
|
||||
label: 'Option 1',
|
||||
value: 'OPTION_1',
|
||||
color: 'green',
|
||||
position: 1,
|
||||
id: '26c602c3-cba9-4d83-92d4-4ba7dbae2f31',
|
||||
},
|
||||
],
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.MULTI_SELECT]: {
|
||||
name: 'multiSelectField',
|
||||
label: 'multiSelectField',
|
||||
type: FieldMetadataType.MULTI_SELECT,
|
||||
options: [
|
||||
{
|
||||
label: 'Option 1',
|
||||
value: 'OPTION_1',
|
||||
color: 'green',
|
||||
position: 1,
|
||||
id: '26c602c3-cba9-4d83-92d4-4ba7dbae2f31',
|
||||
},
|
||||
],
|
||||
objectMetadataId,
|
||||
},
|
||||
|
||||
[FieldMetadataType.ADDRESS]: {
|
||||
name: 'addressField',
|
||||
label: 'addressField',
|
||||
type: FieldMetadataType.ADDRESS,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.RAW_JSON]: {
|
||||
name: 'rawJsonField',
|
||||
label: 'rawJsonField',
|
||||
type: FieldMetadataType.RAW_JSON,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.ARRAY]: {
|
||||
name: 'arrayField',
|
||||
label: 'arrayField',
|
||||
type: FieldMetadataType.ARRAY,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.UUID]: {
|
||||
name: 'uuidField',
|
||||
label: 'uuidField',
|
||||
type: FieldMetadataType.UUID,
|
||||
objectMetadataId,
|
||||
},
|
||||
[FieldMetadataType.RELATION]: [
|
||||
{
|
||||
name: 'manyToOneRelationField',
|
||||
label: 'manyToOneRelationField',
|
||||
type: FieldMetadataType.RELATION,
|
||||
objectMetadataId,
|
||||
relationCreationPayload: {
|
||||
targetObjectMetadataId: targetObjectMetadataId,
|
||||
targetFieldLabel: 'oneToManyTargetRelationField',
|
||||
targetFieldIcon: 'IconListOpportunity',
|
||||
type: RelationType.MANY_TO_ONE,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'oneToManyRelationField',
|
||||
label: 'oneToManyRelationField',
|
||||
type: FieldMetadataType.RELATION,
|
||||
objectMetadataId,
|
||||
relationCreationPayload: {
|
||||
targetObjectMetadataId: targetObjectMetadataId,
|
||||
targetFieldLabel: 'manyToOneTargetRelationField',
|
||||
targetFieldIcon: 'IconListOpportunity',
|
||||
type: RelationType.ONE_TO_MANY,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return Object.values(fieldInputsMap).flat();
|
||||
};
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
import { randomUUID } from 'crypto';
|
||||
|
||||
import { TEST_OBJECT_GQL_FIELDS } from 'test/integration/graphql/suites/args-validation/filter-validation/constants/test-object-gql-fields.constant';
|
||||
import { getFieldMetadataCreationInputs } from 'test/integration/graphql/suites/args-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';
|
||||
|
||||
const TEST_OBJECT_METADATA_NAME_SINGULAR = 'apiFilterValidationTestObject';
|
||||
const TEST_OBJECT_METADATA_NAME_PLURAL = 'apiFilterValidationTestObjects';
|
||||
const TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR =
|
||||
'apiFilterValidationTargetTestObject';
|
||||
const TEST_TARGET_OBJECT_METADATA_NAME_PLURAL =
|
||||
'apiFilterValidationTargetTestObjects';
|
||||
|
||||
export const TEST_TARGET_OBJECT_RECORD_ID =
|
||||
'20202020-a21e-4ec2-873b-de4264d89025';
|
||||
|
||||
export const TEST_UUID_FIELD_VALUE = '20202020-b21e-4ec2-873b-de4264d89025';
|
||||
|
||||
export const setupTestObjectsWithAllFieldTypes = async () => {
|
||||
const createdObjectMetadata = await createOneObjectMetadata({
|
||||
input: {
|
||||
nameSingular: TEST_OBJECT_METADATA_NAME_SINGULAR,
|
||||
namePlural: TEST_OBJECT_METADATA_NAME_PLURAL,
|
||||
labelSingular: TEST_OBJECT_METADATA_NAME_SINGULAR,
|
||||
labelPlural: TEST_OBJECT_METADATA_NAME_PLURAL,
|
||||
},
|
||||
});
|
||||
|
||||
const objectMetadataId = createdObjectMetadata.data.createOneObject.id;
|
||||
|
||||
const createdTargetObjectMetadata = 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,
|
||||
},
|
||||
});
|
||||
|
||||
const targetObjectMetadataId =
|
||||
createdTargetObjectMetadata.data.createOneObject.id;
|
||||
|
||||
const fieldMetadataCreationInputs = getFieldMetadataCreationInputs(
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
);
|
||||
|
||||
for (const input of fieldMetadataCreationInputs) {
|
||||
await createOneFieldMetadata({
|
||||
input,
|
||||
});
|
||||
}
|
||||
|
||||
await makeGraphqlAPIRequest(
|
||||
createManyOperationFactory({
|
||||
objectMetadataSingularName: TEST_TARGET_OBJECT_METADATA_NAME_SINGULAR,
|
||||
objectMetadataPluralName: TEST_TARGET_OBJECT_METADATA_NAME_PLURAL,
|
||||
gqlFields: `id`,
|
||||
data: [
|
||||
{
|
||||
id: TEST_TARGET_OBJECT_RECORD_ID,
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
await makeGraphqlAPIRequest(
|
||||
createManyOperationFactory({
|
||||
objectMetadataSingularName: TEST_OBJECT_METADATA_NAME_SINGULAR,
|
||||
objectMetadataPluralName: TEST_OBJECT_METADATA_NAME_PLURAL,
|
||||
gqlFields: TEST_OBJECT_GQL_FIELDS,
|
||||
data: [
|
||||
{
|
||||
id: randomUUID(),
|
||||
manyToOneRelationFieldId: TEST_TARGET_OBJECT_RECORD_ID,
|
||||
uuidField: TEST_UUID_FIELD_VALUE,
|
||||
textField: 'test',
|
||||
phonesField: {
|
||||
primaryPhoneNumber: '01234567890',
|
||||
primaryPhoneCallingCode: '+33',
|
||||
primaryPhoneCountryCode: 'FR',
|
||||
additionalPhones: [
|
||||
{
|
||||
number: '01234567890',
|
||||
callingCode: '+33',
|
||||
countryCode: 'FR',
|
||||
},
|
||||
],
|
||||
},
|
||||
emailsField: {
|
||||
primaryEmail: 'test@test.com',
|
||||
additionalEmails: ['test@test.com'],
|
||||
},
|
||||
dateTimeField: '2025-01-01T00:00:00Z',
|
||||
dateField: '2025-01-01',
|
||||
booleanField: true,
|
||||
numberField: 1,
|
||||
linksField: {
|
||||
primaryLinkUrl: 'twenty.com',
|
||||
primaryLinkLabel: 'twenty - #1 Open source CRM',
|
||||
secondaryLinks: [
|
||||
{
|
||||
url: 'twenty.com',
|
||||
label: 'twenty - #1 Open source CRM',
|
||||
},
|
||||
],
|
||||
},
|
||||
currencyField: {
|
||||
amountMicros: 1000000,
|
||||
currencyCode: 'USD',
|
||||
},
|
||||
fullNameField: {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
},
|
||||
ratingField: 'RATING_5',
|
||||
selectField: 'OPTION_1',
|
||||
multiSelectField: ['OPTION_1'],
|
||||
addressField: {
|
||||
addressStreet1: 'address street 1',
|
||||
addressStreet2: 'address street 2',
|
||||
addressCity: 'address city',
|
||||
addressState: 'address state',
|
||||
addressCountry: 'address country',
|
||||
addressPostcode: 'address postcode',
|
||||
},
|
||||
rawJsonField: {
|
||||
test: 'test',
|
||||
},
|
||||
arrayField: ['test'],
|
||||
},
|
||||
{
|
||||
id: randomUUID(),
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
objectMetadataId,
|
||||
targetObjectMetadataId,
|
||||
objectMetadataSingularName: TEST_OBJECT_METADATA_NAME_SINGULAR,
|
||||
objectMetadataPluralName: TEST_OBJECT_METADATA_NAME_PLURAL,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user