Fix deactivate objects impacts (#11185)

In this PR:
- Remove deactivated objects from ActivityTargetInlineCell record picker
- Prevent users to deactivate createdAt, updatedAt, deletedAt fields on
any objects

Still left:
- write unit tests on the assert utils
- write integration tests on field metadata service
- prevent users to deactivate createdAt, updatedAt, deletedAt on FE
This commit is contained in:
Charles Bochet
2025-03-26 20:45:46 +01:00
committed by GitHub
parent 90e884d33f
commit 5bd10d40cb
49 changed files with 861 additions and 531 deletions

View File

@ -1,30 +0,0 @@
import { createOneFieldMetadataFactory } from 'test/integration/metadata/suites/field-metadata/utils/create-one-field-metadata-factory.util';
import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util';
import { FieldMetadataType } from 'twenty-shared/types';
const FIELD_NAME = 'testName';
export const createCustomTextFieldMetadata = async (
objectMetadataItemId: string,
) => {
const createFieldInput = {
name: FIELD_NAME,
label: 'Test name',
type: FieldMetadataType.TEXT,
objectMetadataId: objectMetadataItemId,
isLabelSyncedWithName: true,
};
const graphqlOperation = createOneFieldMetadataFactory({
input: { field: createFieldInput },
gqlFields: `
id
name
label
isLabelSyncedWithName
`,
});
const response = await makeMetadataAPIRequest(graphqlOperation);
return { fieldMetadataId: response.body.data.createOneField.id };
};

View File

@ -1,24 +0,0 @@
import gql from 'graphql-tag';
import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
type CreateOneFieldFactoryParams = {
gqlFields: string;
input?: { field: Omit<CreateFieldInput, 'workspaceId' | 'dataSourceId'> };
};
export const createOneFieldMetadataFactory = ({
gqlFields,
input,
}: CreateOneFieldFactoryParams) => ({
query: gql`
mutation CreateOneFieldMetadataItem($input: CreateOneFieldMetadataInput!) {
createOneField(input: $input) {
${gqlFields}
}
}
`,
variables: {
input,
},
});

View File

@ -0,0 +1,25 @@
import gql from 'graphql-tag';
import { PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
export type CreateOneFieldFactoryInput = Omit<
CreateFieldInput,
'workspaceId' | 'dataSourceId'
>;
export const createOneFieldMetadataQueryFactory = ({
input,
gqlFields = 'id',
}: PerformMetadataQueryParams<CreateOneFieldFactoryInput>) => ({
query: gql`
mutation CreateOneFieldMetadataItem($input: CreateOneFieldMetadataInput!) {
createOneField(input: $input) {
${gqlFields}
}
}
`,
variables: {
input: { field: input },
},
});

View File

@ -0,0 +1,29 @@
import {
CreateOneFieldFactoryInput,
createOneFieldMetadataQueryFactory,
} from 'test/integration/metadata/suites/field-metadata/utils/create-one-field-metadata-query-factory.util';
import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util';
import { PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
export const createOneFieldMetadata = async ({
input,
gqlFields,
expectToFail = false,
}: PerformMetadataQueryParams<CreateOneFieldFactoryInput>) => {
const graphqlOperation = createOneFieldMetadataQueryFactory({
input,
gqlFields,
});
const response = await makeMetadataAPIRequest(graphqlOperation);
if (expectToFail) {
warnIfNoErrorButExpectedToFail({
response,
errorMessage: 'Field Metadata creation should have failed but did not',
});
}
return { data: response.body.data, errors: response.body.errors };
};

View File

@ -1,20 +0,0 @@
import gql from 'graphql-tag';
type DeleteOneFieldFactoryParams = {
idToDelete: string;
};
export const deleteOneFieldMetadataItemFactory = ({
idToDelete,
}: DeleteOneFieldFactoryParams) => ({
query: gql`
mutation DeleteOneFieldMetadataItem($idToDelete: UUID!) {
deleteOneField(input: { id: $idToDelete }) {
id
}
}
`,
variables: {
idToDelete,
},
});

View File

@ -0,0 +1,22 @@
import gql from 'graphql-tag';
import { PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
export type DeleteOneFieldFactoryInput = {
idToDelete: string;
};
export const deleteOneFieldMetadataQueryFactory = ({
input,
gqlFields = 'id',
}: PerformMetadataQueryParams<DeleteOneFieldFactoryInput>) => ({
query: gql`
mutation DeleteOneFieldMetadataItem($idToDelete: UUID!) {
deleteOneField(input: { id: $idToDelete }) {
${gqlFields}
}
}
`,
variables: {
idToDelete: input.idToDelete,
},
});

View File

@ -1,10 +1,29 @@
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
import { deleteOneFieldMetadataItemFactory } from 'test/integration/metadata/suites/field-metadata/utils/delete-one-field-metadata-factory.util';
import {
DeleteOneFieldFactoryInput,
deleteOneFieldMetadataQueryFactory,
} from 'test/integration/metadata/suites/field-metadata/utils/delete-one-field-metadata-query-factory.util';
import { PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
export const deleteFieldMetadata = async (fieldMetadataId: string) => {
const graphqlOperation = deleteOneFieldMetadataItemFactory({
idToDelete: fieldMetadataId,
export const deleteOneFieldMetadata = async ({
input,
gqlFields,
expectToFail = false,
}: PerformMetadataQueryParams<DeleteOneFieldFactoryInput>) => {
const graphqlOperation = deleteOneFieldMetadataQueryFactory({
input,
gqlFields,
});
await makeGraphqlAPIRequest(graphqlOperation);
const response = await makeGraphqlAPIRequest(graphqlOperation);
if (expectToFail) {
warnIfNoErrorButExpectedToFail({
response,
errorMessage: 'Field Metadata deletion should have failed but did not',
});
}
return { data: response.body.data, errors: response.body.errors };
};

View File

@ -0,0 +1,28 @@
import gql from 'graphql-tag';
import { PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
export type FindManyFieldsMetadataFactoryInput = {
filter: object;
paging: object;
};
export const findManyFieldsMetadataQueryFactory = ({
gqlFields = 'id',
input,
}: PerformMetadataQueryParams<FindManyFieldsMetadataFactoryInput>) => ({
query: gql`
query FieldsMetadata($filter: FieldFilter!, $paging: CursorPaging!) {
fields(filter: $filter, paging: $paging) {
edges {
node {
${gqlFields}
}
}
}
}
`,
variables: {
filter: input.filter,
paging: input.paging,
},
});

View File

@ -0,0 +1,29 @@
import {
FindManyFieldsMetadataFactoryInput,
findManyFieldsMetadataQueryFactory,
} from 'test/integration/metadata/suites/field-metadata/utils/find-many-fields-metadata-query-factory.util';
import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util';
import { PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
export const findManyFieldsMetadata = async ({
input,
gqlFields,
expectToFail = false,
}: PerformMetadataQueryParams<FindManyFieldsMetadataFactoryInput>) => {
const graphqlOperation = findManyFieldsMetadataQueryFactory({
input,
gqlFields,
});
const response = await makeMetadataAPIRequest(graphqlOperation);
if (expectToFail) {
warnIfNoErrorButExpectedToFail({
response,
errorMessage: 'Field Metadata retrieval should have failed but did not',
});
}
return response.body.data.fields.edges.map((edge) => edge.node);
};

View File

@ -1,25 +0,0 @@
import gql from 'graphql-tag';
import { UpdateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/update-field.input';
type UpdateOneFieldFactoryParams = {
gqlFields: string;
input: { id: string; update: Omit<UpdateFieldInput, 'workspaceId' | 'id'> };
};
export const updateOneFieldMetadataFactory = ({
gqlFields,
input,
}: UpdateOneFieldFactoryParams) => ({
query: gql`
mutation UpdateOneFieldMetadataItem($idToUpdate: UUID!, $updatePayload: UpdateFieldInput!) {
updateOneField(input: {id: $idToUpdate, update: $updatePayload}) {
${gqlFields}
}
}
`,
variables: {
idToUpdate: input.id,
updatePayload: input.update,
},
});

View File

@ -0,0 +1,26 @@
import gql from 'graphql-tag';
import { PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
import { UpdateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/update-field.input';
export type UpdateOneFieldFactoryInput = {
idToUpdate: string;
updatePayload: Omit<UpdateFieldInput, 'workspaceId' | 'id'>;
};
export const updateOneFieldMetadataQueryFactory = ({
gqlFields = 'id',
input,
}: PerformMetadataQueryParams<UpdateOneFieldFactoryInput>) => ({
query: gql`
mutation UpdateOneFieldMetadataItem($idToUpdate: UUID!, $updatePayload: UpdateFieldInput!) {
updateOneField(input: {id: $idToUpdate, update: $updatePayload}) {
${gqlFields}
}
}
`,
variables: {
idToUpdate: input.idToUpdate,
updatePayload: input.updatePayload,
},
});

View File

@ -0,0 +1,29 @@
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
import {
UpdateOneFieldFactoryInput,
updateOneFieldMetadataQueryFactory,
} from 'test/integration/metadata/suites/field-metadata/utils/update-one-field-metadata-query-factory.util';
import { PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
export const updateOneFieldMetadata = async ({
input,
gqlFields,
expectToFail = false,
}: PerformMetadataQueryParams<UpdateOneFieldFactoryInput>) => {
const graphqlOperation = updateOneFieldMetadataQueryFactory({
input,
gqlFields,
});
const response = await makeGraphqlAPIRequest(graphqlOperation);
if (expectToFail) {
warnIfNoErrorButExpectedToFail({
response,
errorMessage: 'Field Metadata update should have failed but did not',
});
}
return { data: response.body.data, errors: response.body.errors };
};