FieldMetadataServiceV2.deleteOneField (#13744)
# Introduction - Migrated the `deleteOneField` handler to new workspace migration v2 style - Refactored the build to expect `flatObjectMetadataMaps` that he instantly translate at the be beginning Commented `ObjectMetadataServiceV2` as it's still not implemented neither used
This commit is contained in:
+1126
-95
File diff suppressed because it is too large
Load Diff
+80
-196
@@ -3,19 +3,20 @@ import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
|
||||
import { COMPANY_FLAT_FIELDS_MOCK } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/company-flat-fields.mock';
|
||||
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
|
||||
import { OPPORTUNITY_FLAT_FIELDS_MOCK } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/opportunity-flat-fields.mock';
|
||||
import { PET_FLAT_FIELDS_MOCK } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/pet-flat-fields.mock';
|
||||
import { FLAT_OBJECT_METADATA_MAPS_MOCKS } from 'src/engine/metadata-modules/flat-object-metadata-maps/mocks/flat-object-metadata-maps.mock';
|
||||
import { addFlatFieldMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/add-flat-field-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
import { deleteFieldFromFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/delete-field-from-flat-object-metadata-maps-or-throw.util';
|
||||
import { replaceFlatFieldMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/replace-flat-field-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
import { COMPANY_FLAT_OBJECT_MOCK } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/company-flat-object.mock';
|
||||
import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock';
|
||||
import { PET_FLAT_OBJECT_MOCK } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/pet-flat-object.mock';
|
||||
import { ROCKET_FLAT_OBJECT_MOCK } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/rocket-flat-object.mock';
|
||||
import { type WorkspaceMigrationBuilderTestCase } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/__tests__/types/workspace-migration-builder-test-case.type';
|
||||
|
||||
const basicObjectMetadataId = faker.string.uuid();
|
||||
const basicFlatFieldMetadatas = Array.from({ length: 5 }, (_value, index) =>
|
||||
getFlatFieldMetadataMock({
|
||||
objectMetadataId: basicObjectMetadataId,
|
||||
uniqueIdentifier: `field_${index}`,
|
||||
type: FieldMetadataType.TEXT,
|
||||
}),
|
||||
);
|
||||
|
||||
// TODO prastoin test defaultValue and settings updates
|
||||
// TODO prastoin test standard abstraction in TDD style
|
||||
|
||||
@@ -24,16 +25,14 @@ const relationTestCases: WorkspaceMigrationBuilderTestCase[] = [
|
||||
title: 'It should build an create_field action for a RELATION field',
|
||||
context: {
|
||||
input: () => {
|
||||
const objectMetadataId = faker.string.uuid();
|
||||
const targetObjectMetadataId = faker.string.uuid();
|
||||
const createdFlatRelationFieldMetadata = getFlatFieldMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
objectMetadataId,
|
||||
objectMetadataId: PET_FLAT_OBJECT_MOCK.id,
|
||||
type: FieldMetadataType.RELATION,
|
||||
relationTargetFieldMetadataId: faker.string.uuid(),
|
||||
relationTargetObjectMetadataId: faker.string.uuid(),
|
||||
flatRelationTargetFieldMetadata: getFlatFieldMetadataMock({
|
||||
objectMetadataId: targetObjectMetadataId,
|
||||
objectMetadataId: COMPANY_FLAT_OBJECT_MOCK.id,
|
||||
type: FieldMetadataType.RELATION,
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-2',
|
||||
}),
|
||||
@@ -41,20 +40,14 @@ const relationTestCases: WorkspaceMigrationBuilderTestCase[] = [
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-2',
|
||||
}),
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
isLabelSyncedWithName: true,
|
||||
flatFieldMetadatas: [],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
flatFieldMetadatas: [createdFlatRelationFieldMetadata],
|
||||
},
|
||||
],
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps:
|
||||
addFlatFieldMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
flatFieldMetadata: createdFlatRelationFieldMetadata,
|
||||
}),
|
||||
};
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
@@ -65,42 +58,17 @@ const relationTestCases: WorkspaceMigrationBuilderTestCase[] = [
|
||||
{
|
||||
title: 'It should build an update_field action for a RELATION field',
|
||||
context: {
|
||||
input: () => {
|
||||
const objectMetadataId = faker.string.uuid();
|
||||
|
||||
const updatedFieldMetadata = getFlatFieldMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
objectMetadataId,
|
||||
type: FieldMetadataType.RELATION,
|
||||
relationTargetFieldMetadataId: faker.string.uuid(),
|
||||
relationTargetObjectMetadataId: faker.string.uuid(),
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
isLabelSyncedWithName: true,
|
||||
flatFieldMetadatas: [
|
||||
...basicFlatFieldMetadatas,
|
||||
updatedFieldMetadata,
|
||||
],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
flatFieldMetadatas: [
|
||||
...basicFlatFieldMetadatas,
|
||||
{
|
||||
...updatedFieldMetadata,
|
||||
isActive: false,
|
||||
description: 'new description',
|
||||
label: 'new label',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps:
|
||||
replaceFlatFieldMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatFieldMetadata: getFlatFieldMetadataMock({
|
||||
...PET_FLAT_FIELDS_MOCK.species,
|
||||
description: 'new description',
|
||||
label: 'new label',
|
||||
}),
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
}),
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
updateField: 1,
|
||||
@@ -111,47 +79,23 @@ const relationTestCases: WorkspaceMigrationBuilderTestCase[] = [
|
||||
title:
|
||||
'It should NOT build an update_field action for a field RELATION uncovered fields mutation',
|
||||
context: {
|
||||
input: () => {
|
||||
const objectMetadataId = faker.string.uuid();
|
||||
const updatedFieldMetadata = getFlatFieldMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
objectMetadataId,
|
||||
type: FieldMetadataType.RELATION,
|
||||
settings: {
|
||||
relationType: RelationType.MANY_TO_ONE,
|
||||
joinColumnName: 'column-name',
|
||||
onDelete: undefined,
|
||||
},
|
||||
relationTargetFieldMetadataId: faker.string.uuid(),
|
||||
relationTargetObjectMetadataId: faker.string.uuid(),
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
isLabelSyncedWithName: true,
|
||||
flatFieldMetadatas: [updatedFieldMetadata],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
flatFieldMetadatas: [
|
||||
{
|
||||
...updatedFieldMetadata,
|
||||
settings: {
|
||||
relationType: RelationType.ONE_TO_MANY,
|
||||
isForeignKey: false,
|
||||
joinColumnName: 'new-column-name',
|
||||
onDelete: undefined,
|
||||
},
|
||||
relationTargetFieldMetadataId: faker.string.uuid(),
|
||||
relationTargetObjectMetadataId: faker.string.uuid(),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps:
|
||||
replaceFlatFieldMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatFieldMetadata: getFlatFieldMetadataMock({
|
||||
...COMPANY_FLAT_FIELDS_MOCK.opportunities,
|
||||
settings: {
|
||||
relationType: RelationType.MANY_TO_ONE,
|
||||
joinColumnName: 'new-column-name',
|
||||
onDelete: undefined,
|
||||
},
|
||||
name: 'newName',
|
||||
relationTargetFieldMetadataId: faker.string.uuid(),
|
||||
relationTargetObjectMetadataId: faker.string.uuid(),
|
||||
}),
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -161,29 +105,17 @@ const basicCrudTestCases: WorkspaceMigrationBuilderTestCase[] = [
|
||||
{
|
||||
title: 'It should build an create_field action',
|
||||
context: {
|
||||
input: () => {
|
||||
const objectMetadataId = faker.string.uuid();
|
||||
|
||||
const flatFieldMetadata = getFlatFieldMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
type: FieldMetadataType.TEXT,
|
||||
objectMetadataId,
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
isLabelSyncedWithName: true,
|
||||
flatFieldMetadatas: [],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
flatFieldMetadatas: [flatFieldMetadata],
|
||||
},
|
||||
],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps:
|
||||
addFlatFieldMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatFieldMetadata: getFlatFieldMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
type: FieldMetadataType.TEXT,
|
||||
objectMetadataId: ROCKET_FLAT_OBJECT_MOCK.id,
|
||||
}),
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
}),
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
createField: 1,
|
||||
@@ -193,37 +125,19 @@ const basicCrudTestCases: WorkspaceMigrationBuilderTestCase[] = [
|
||||
{
|
||||
title: 'It should build an update_field action',
|
||||
context: {
|
||||
input: () => {
|
||||
const objectMetadataId = faker.string.uuid();
|
||||
|
||||
const flatFieldMetadata = getFlatFieldMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
type: FieldMetadataType.TEXT,
|
||||
objectMetadataId,
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
flatFieldMetadatas: [...basicFlatFieldMetadatas, flatFieldMetadata],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
flatFieldMetadatas: [
|
||||
...basicFlatFieldMetadatas,
|
||||
{
|
||||
...flatFieldMetadata,
|
||||
description: 'new description',
|
||||
name: 'new name',
|
||||
isActive: false,
|
||||
icon: 'new icon',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps:
|
||||
replaceFlatFieldMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
flatFieldMetadata: getFlatFieldMetadataMock({
|
||||
...OPPORTUNITY_FLAT_FIELDS_MOCK.stage,
|
||||
description: 'new description',
|
||||
name: 'new name',
|
||||
isActive: false,
|
||||
icon: 'new icon',
|
||||
}),
|
||||
}),
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
updateField: 1,
|
||||
@@ -233,28 +147,13 @@ const basicCrudTestCases: WorkspaceMigrationBuilderTestCase[] = [
|
||||
{
|
||||
title: 'It should build a delete_field action',
|
||||
context: {
|
||||
input: () => {
|
||||
const objectMetadataId = faker.string.uuid();
|
||||
|
||||
const flatFieldMetadata = getFlatFieldMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
type: FieldMetadataType.TEXT,
|
||||
objectMetadataId,
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
flatFieldMetadatas: [...basicFlatFieldMetadatas, flatFieldMetadata],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
flatFieldMetadatas: basicFlatFieldMetadatas,
|
||||
},
|
||||
],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps: deleteFieldFromFlatObjectMetadataMapsOrThrow({
|
||||
fieldMetadataId: PET_FLAT_FIELDS_MOCK.species.id,
|
||||
objectMetadataId: PET_FLAT_FIELDS_MOCK.species.objectMetadataId,
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
}),
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
deleteField: 1,
|
||||
@@ -271,24 +170,9 @@ export const WORKSPACE_MIGRATION_FIELD_BUILDER_TEST_CASES: WorkspaceMigrationBui
|
||||
title:
|
||||
'It should not infer any actions as from and to fields are identical',
|
||||
context: {
|
||||
input: () => {
|
||||
const objectMetadataId = faker.string.uuid();
|
||||
const flatFieldMetadata = getFlatFieldMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
type: FieldMetadataType.TEXT,
|
||||
objectMetadataId,
|
||||
});
|
||||
const from = [
|
||||
getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
flatFieldMetadatas: [flatFieldMetadata],
|
||||
}),
|
||||
];
|
||||
|
||||
return {
|
||||
from,
|
||||
to: from,
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
+57
-74
@@ -1,37 +1,30 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
|
||||
import { getFlatIndexMetadataMock } from 'src/engine/metadata-modules/flat-index-metadata/__mocks__/get-flat-index-metadata.mock';
|
||||
import { FLAT_OBJECT_METADATA_MAPS_MOCKS } from 'src/engine/metadata-modules/flat-object-metadata-maps/mocks/flat-object-metadata-maps.mock';
|
||||
import { replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/replace-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock';
|
||||
import { NOTE_FLAT_OBJECT_MOCK } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/note-flat-object.mock';
|
||||
import { type WorkspaceMigrationBuilderTestCase } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/__tests__/types/workspace-migration-builder-test-case.type';
|
||||
|
||||
// Should test more things such as flatFieldIndex diffing
|
||||
const objectMetadataId = faker.string.uuid();
|
||||
|
||||
export const WORKSPACE_MIGRATION_INDEX_BUILDER_TEST_CASES: WorkspaceMigrationBuilderTestCase[] =
|
||||
[
|
||||
{
|
||||
title: 'It should build an create_index action',
|
||||
context: {
|
||||
input: () => {
|
||||
const flatIndexMetadata = getFlatIndexMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
objectMetadataId,
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
isLabelSyncedWithName: true,
|
||||
flatIndexMetadatas: [],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
flatIndexMetadatas: [flatIndexMetadata],
|
||||
},
|
||||
],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps:
|
||||
replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
flatObjectMetadata: getFlatObjectMetadataMock({
|
||||
...NOTE_FLAT_OBJECT_MOCK,
|
||||
flatIndexMetadatas: [
|
||||
getFlatIndexMetadataMock({
|
||||
objectMetadataId: NOTE_FLAT_OBJECT_MOCK.id,
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
createIndex: 1,
|
||||
@@ -44,30 +37,37 @@ export const WORKSPACE_MIGRATION_INDEX_BUILDER_TEST_CASES: WorkspaceMigrationBui
|
||||
context: {
|
||||
input: () => {
|
||||
const flatIndexMetadata = getFlatIndexMetadataMock({
|
||||
objectMetadataId: NOTE_FLAT_OBJECT_MOCK.id,
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
objectMetadataId,
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
isLabelSyncedWithName: true,
|
||||
flatIndexMetadatas: [flatIndexMetadata],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
const fromFlatObjectMetadataMaps =
|
||||
replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
flatObjectMetadata: getFlatObjectMetadataMock({
|
||||
...NOTE_FLAT_OBJECT_MOCK,
|
||||
flatIndexMetadatas: [flatIndexMetadata],
|
||||
}),
|
||||
});
|
||||
const toFlatObjectMetadataMaps =
|
||||
replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
flatObjectMetadata: getFlatObjectMetadataMock({
|
||||
...NOTE_FLAT_OBJECT_MOCK,
|
||||
flatIndexMetadatas: [
|
||||
{
|
||||
...flatIndexMetadata,
|
||||
name: 'new index name',
|
||||
isUnique: false,
|
||||
indexWhereClause: 'new index where clause',
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
return {
|
||||
fromFlatObjectMetadataMaps,
|
||||
toFlatObjectMetadataMaps,
|
||||
};
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
@@ -79,26 +79,21 @@ export const WORKSPACE_MIGRATION_INDEX_BUILDER_TEST_CASES: WorkspaceMigrationBui
|
||||
{
|
||||
title: 'It should build a delete_index action',
|
||||
context: {
|
||||
input: () => {
|
||||
const flatIndexMetadata = getFlatIndexMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
objectMetadataId,
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
isLabelSyncedWithName: true,
|
||||
flatIndexMetadatas: [flatIndexMetadata],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
flatIndexMetadatas: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps:
|
||||
replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
flatObjectMetadata: getFlatObjectMetadataMock({
|
||||
...NOTE_FLAT_OBJECT_MOCK,
|
||||
flatIndexMetadatas: [
|
||||
getFlatIndexMetadataMock({
|
||||
objectMetadataId: NOTE_FLAT_OBJECT_MOCK.id,
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
toFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
deleteIndex: 1,
|
||||
@@ -109,21 +104,9 @@ export const WORKSPACE_MIGRATION_INDEX_BUILDER_TEST_CASES: WorkspaceMigrationBui
|
||||
title:
|
||||
'It should not infer any actions as from and to indexes are identical',
|
||||
context: {
|
||||
input: () => {
|
||||
const flatIndexMetadata = getFlatIndexMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
objectMetadataId,
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'object-metadata-unique-identifier-1',
|
||||
isLabelSyncedWithName: true,
|
||||
flatIndexMetadatas: [flatIndexMetadata],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [flatObjectMetadata],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
+53
-83
@@ -1,9 +1,13 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
|
||||
import { getFlatIndexMetadataMock } from 'src/engine/metadata-modules/flat-index-metadata/__mocks__/get-flat-index-metadata.mock';
|
||||
import { EMPTY_FLAT_OBJECT_METADATA_MAPS } from 'src/engine/metadata-modules/flat-object-metadata-maps/constant/empty-flat-object-metadata-maps.constant';
|
||||
import { FLAT_OBJECT_METADATA_MAPS_MOCKS } from 'src/engine/metadata-modules/flat-object-metadata-maps/mocks/flat-object-metadata-maps.mock';
|
||||
import { deleteObjectFromFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/delete-object-from-flat-object-metadata-maps-or-throw.util';
|
||||
import { replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow } from 'src/engine/metadata-modules/flat-object-metadata-maps/utils/replace-flat-object-metadata-in-flat-object-metadata-maps-or-throw.util';
|
||||
import { COMPANY_FLAT_OBJECT_MOCK } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/company-flat-object.mock';
|
||||
import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock';
|
||||
import { PET_FLAT_OBJECT_MOCK } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/pet-flat-object.mock';
|
||||
import { ROCKET_FLAT_OBJECT_MOCK } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/rocket-flat-object.mock';
|
||||
import { fromFlatObjectMetadatasToFlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadatas-to-flat-object-metadata-maps.util';
|
||||
import { type WorkspaceMigrationBuilderTestCase } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/__tests__/types/workspace-migration-builder-test-case.type';
|
||||
|
||||
export const WORKSPACE_MIGRATION_OBJECT_BUILDER_TEST_CASES: WorkspaceMigrationBuilderTestCase[] =
|
||||
@@ -12,25 +16,18 @@ export const WORKSPACE_MIGRATION_OBJECT_BUILDER_TEST_CASES: WorkspaceMigrationBu
|
||||
title:
|
||||
'It should build an update_object action with all object updated fields',
|
||||
context: {
|
||||
input: () => {
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'pomme',
|
||||
nameSingular: 'toto',
|
||||
namePlural: 'totos',
|
||||
isLabelSyncedWithName: true,
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [
|
||||
{
|
||||
...flatObjectMetadata,
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps:
|
||||
replaceFlatObjectMetadataInFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
flatObjectMetadata: getFlatObjectMetadataMock({
|
||||
...PET_FLAT_OBJECT_MOCK,
|
||||
nameSingular: 'prastouin',
|
||||
namePlural: 'prastoins',
|
||||
isLabelSyncedWithName: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
}),
|
||||
}),
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
updateObject: 1,
|
||||
@@ -40,18 +37,16 @@ export const WORKSPACE_MIGRATION_OBJECT_BUILDER_TEST_CASES: WorkspaceMigrationBu
|
||||
{
|
||||
title: 'It should build a create_object action',
|
||||
context: {
|
||||
input: () => {
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'pomme',
|
||||
nameSingular: 'toto',
|
||||
namePlural: 'totos',
|
||||
isLabelSyncedWithName: true,
|
||||
});
|
||||
|
||||
return {
|
||||
from: [],
|
||||
to: [flatObjectMetadata],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps:
|
||||
fromFlatObjectMetadatasToFlatObjectMetadataMaps([
|
||||
PET_FLAT_OBJECT_MOCK,
|
||||
]),
|
||||
toFlatObjectMetadataMaps:
|
||||
fromFlatObjectMetadatasToFlatObjectMetadataMaps([
|
||||
PET_FLAT_OBJECT_MOCK,
|
||||
ROCKET_FLAT_OBJECT_MOCK,
|
||||
]),
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
createObject: 1,
|
||||
@@ -60,37 +55,22 @@ export const WORKSPACE_MIGRATION_OBJECT_BUILDER_TEST_CASES: WorkspaceMigrationBu
|
||||
},
|
||||
{
|
||||
title:
|
||||
'It should build a create_object and create_field and create_index actions for each of this fieldMetadata',
|
||||
'It should build a create_object and create_index actions for each of this fieldMetadata',
|
||||
context: {
|
||||
input: () => {
|
||||
const objectMetadataId = faker.string.uuid();
|
||||
const flatFieldMetadatas = Array.from(
|
||||
{ length: 5 },
|
||||
(_value, index) =>
|
||||
getFlatFieldMetadataMock({
|
||||
type: FieldMetadataType.TEXT,
|
||||
objectMetadataId,
|
||||
uniqueIdentifier: `field_${index}`,
|
||||
}),
|
||||
);
|
||||
const flatIndexMetadata = getFlatIndexMetadataMock({
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
objectMetadataId,
|
||||
});
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'pomme',
|
||||
nameSingular: 'toto',
|
||||
namePlural: 'totos',
|
||||
isLabelSyncedWithName: true,
|
||||
id: objectMetadataId,
|
||||
flatFieldMetadatas,
|
||||
flatIndexMetadatas: [flatIndexMetadata],
|
||||
});
|
||||
|
||||
return {
|
||||
from: [],
|
||||
to: [flatObjectMetadata],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: EMPTY_FLAT_OBJECT_METADATA_MAPS,
|
||||
toFlatObjectMetadataMaps:
|
||||
fromFlatObjectMetadatasToFlatObjectMetadataMaps([
|
||||
{
|
||||
...ROCKET_FLAT_OBJECT_MOCK,
|
||||
flatIndexMetadatas: [
|
||||
getFlatIndexMetadataMock({
|
||||
objectMetadataId: ROCKET_FLAT_OBJECT_MOCK.id,
|
||||
uniqueIdentifier: 'field-metadata-unique-identifier-1',
|
||||
}),
|
||||
],
|
||||
},
|
||||
]),
|
||||
},
|
||||
|
||||
expectedActionsTypeCounter: {
|
||||
@@ -103,36 +83,26 @@ export const WORKSPACE_MIGRATION_OBJECT_BUILDER_TEST_CASES: WorkspaceMigrationBu
|
||||
{
|
||||
title: 'It should build a delete_object action',
|
||||
context: {
|
||||
input: () => {
|
||||
const flatObjectMetadata = getFlatObjectMetadataMock({
|
||||
uniqueIdentifier: 'pomme',
|
||||
nameSingular: 'toto',
|
||||
namePlural: 'totos',
|
||||
isLabelSyncedWithName: true,
|
||||
});
|
||||
|
||||
return {
|
||||
from: [flatObjectMetadata],
|
||||
to: [],
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps:
|
||||
deleteObjectFromFlatObjectMetadataMapsOrThrow({
|
||||
flatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
objectMetadataId: COMPANY_FLAT_OBJECT_MOCK.id,
|
||||
}),
|
||||
},
|
||||
expectedActionsTypeCounter: {
|
||||
deleteObject: 1,
|
||||
deleteField: COMPANY_FLAT_OBJECT_MOCK.flatFieldMetadatas.length,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'It should not infer any actions as from and to are identical',
|
||||
context: {
|
||||
input: () => {
|
||||
const from = [
|
||||
getFlatObjectMetadataMock({ uniqueIdentifier: 'pomme' }),
|
||||
];
|
||||
|
||||
return {
|
||||
from,
|
||||
to: from,
|
||||
};
|
||||
input: {
|
||||
fromFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
toFlatObjectMetadataMaps: FLAT_OBJECT_METADATA_MAPS_MOCKS,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
+4
-6
@@ -2,11 +2,7 @@ import { type EachTestingContext } from 'twenty-shared/testing';
|
||||
|
||||
import { type ConvertActionTypeToCamelCase } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/convert-action-type-to-camel-case.type';
|
||||
import { type WorkspaceMigrationActionTypeV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-action-common-v2';
|
||||
import { type WorkspaceMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-builder-v2.service';
|
||||
|
||||
type WorkspaceBuilderArgs = Parameters<
|
||||
typeof WorkspaceMigrationBuilderV2Service.prototype.build
|
||||
>[0]['objectMetadataFromToInputs'];
|
||||
import { type WorkspaceMigrationBuildArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-builder-v2.service';
|
||||
|
||||
export type CamelCasedWorkspaceMigrationActionsType =
|
||||
ConvertActionTypeToCamelCase<WorkspaceMigrationActionTypeV2>;
|
||||
@@ -16,6 +12,8 @@ export type ExpectedActionCounters = Partial<
|
||||
>;
|
||||
|
||||
export type WorkspaceMigrationBuilderTestCase = EachTestingContext<{
|
||||
input: WorkspaceBuilderArgs | (() => WorkspaceBuilderArgs);
|
||||
input:
|
||||
| Omit<WorkspaceMigrationBuildArgs, 'workspaceId'>
|
||||
| (() => Omit<WorkspaceMigrationBuildArgs, 'workspaceId'>);
|
||||
expectedActionsTypeCounter?: ExpectedActionCounters;
|
||||
}>;
|
||||
|
||||
+9
-5
@@ -31,6 +31,7 @@ const allWorkspaceBuilderTestCases: {
|
||||
},
|
||||
];
|
||||
|
||||
// TODO prastoin add coverage to infer deletion from missing entities
|
||||
const expectedActionsTypeCounterChecker = ({
|
||||
expectedActionsTypeCounter,
|
||||
workspaceMigration,
|
||||
@@ -81,12 +82,15 @@ describe.each(allWorkspaceBuilderTestCases)(
|
||||
it.each(eachTestingContextFilter(testCases))(
|
||||
'$title',
|
||||
({ context: { input, expectedActionsTypeCounter } }) => {
|
||||
const { from, to } = typeof input === 'function' ? input() : input;
|
||||
const {
|
||||
fromFlatObjectMetadataMaps,
|
||||
toFlatObjectMetadataMaps,
|
||||
inferDeletionFromMissingObjectFieldIndex,
|
||||
} = typeof input === 'function' ? input() : input;
|
||||
const workspaceMigration = service.build({
|
||||
objectMetadataFromToInputs: {
|
||||
from,
|
||||
to,
|
||||
},
|
||||
fromFlatObjectMetadataMaps,
|
||||
toFlatObjectMetadataMaps,
|
||||
inferDeletionFromMissingObjectFieldIndex,
|
||||
workspaceId: '20202020-52cc-4c64-ad63-76c26fc3a1e1',
|
||||
});
|
||||
|
||||
|
||||
+20
-8
@@ -2,7 +2,8 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { type FromTo } from 'twenty-shared/types';
|
||||
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { fromFlatObjectMetadataMapsToFlatObjectMetadatas } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-maps-to-flat-object-metadatas.util';
|
||||
import { deletedCreatedUpdatedMatrixDispatcher } from 'src/engine/workspace-manager/workspace-migration-v2/utils/deleted-created-updated-matrix-dispatcher.util';
|
||||
import { type WorkspaceMigrationV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-v2';
|
||||
import { computeUpdatedObjectMetadataDeletedCreatedUpdatedFieldMatrix } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/utils/compute-updated-object-metadata-deleted-created-updated-field-matrix.util';
|
||||
@@ -12,24 +13,35 @@ import { getWorkspaceMigrationV2CreateIndexAction } from 'src/engine/workspace-m
|
||||
import { buildWorkspaceMigrationV2FieldActions } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-v2-field-actions-builder';
|
||||
import { buildWorkspaceMigrationIndexActions } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-v2-index-actions-builder';
|
||||
import { buildWorkspaceMigrationV2ObjectActions } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-v2-object-actions-builder';
|
||||
export type WorkspaceMigrationBuildArgs = {
|
||||
workspaceId: string;
|
||||
inferDeletionFromMissingObjectFieldIndex?: boolean;
|
||||
} & FromTo<FlatObjectMetadataMaps, 'FlatObjectMetadataMaps'>;
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationBuilderV2Service {
|
||||
constructor() {}
|
||||
|
||||
build({
|
||||
objectMetadataFromToInputs,
|
||||
fromFlatObjectMetadataMaps,
|
||||
toFlatObjectMetadataMaps,
|
||||
workspaceId,
|
||||
inferDeletionFromMissingObjectFieldIndex = true,
|
||||
}: {
|
||||
objectMetadataFromToInputs: FromTo<FlatObjectMetadata[]>;
|
||||
workspaceId: string;
|
||||
inferDeletionFromMissingObjectFieldIndex?: boolean;
|
||||
}): WorkspaceMigrationV2 {
|
||||
}: WorkspaceMigrationBuildArgs): WorkspaceMigrationV2 {
|
||||
const fromFlatObjectMetadatas =
|
||||
fromFlatObjectMetadataMapsToFlatObjectMetadatas(
|
||||
fromFlatObjectMetadataMaps,
|
||||
);
|
||||
const toFlatObjectMetadatas =
|
||||
fromFlatObjectMetadataMapsToFlatObjectMetadatas(toFlatObjectMetadataMaps);
|
||||
|
||||
const {
|
||||
created: createdObjectMetadata,
|
||||
deleted: deletedObjectMetadata,
|
||||
updated: updatedObjectMetadata,
|
||||
} = deletedCreatedUpdatedMatrixDispatcher(objectMetadataFromToInputs);
|
||||
} = deletedCreatedUpdatedMatrixDispatcher({
|
||||
from: fromFlatObjectMetadatas,
|
||||
to: toFlatObjectMetadatas,
|
||||
});
|
||||
|
||||
const objectWorkspaceMigrationActions =
|
||||
buildWorkspaceMigrationV2ObjectActions({
|
||||
|
||||
+8
-3
@@ -3,6 +3,7 @@ import { InjectDataSource } from '@nestjs/typeorm';
|
||||
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
import { type FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
|
||||
import { WorkspaceMetadataCacheService } from 'src/engine/metadata-modules/workspace-metadata-cache/services/workspace-metadata-cache.service';
|
||||
import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service';
|
||||
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
|
||||
@@ -23,10 +24,12 @@ export class WorkspaceMigrationRunnerV2Service {
|
||||
private readonly coreDataSource: DataSource,
|
||||
) {}
|
||||
|
||||
run = async (workspaceMigration: WorkspaceMigrationV2) => {
|
||||
run = async (
|
||||
workspaceMigration: WorkspaceMigrationV2,
|
||||
): Promise<FlatObjectMetadataMaps> => {
|
||||
const queryRunner = this.coreDataSource.createQueryRunner();
|
||||
|
||||
const { flatObjectMetadataMaps } =
|
||||
const { flatObjectMetadataMaps: existingFlatObjectMetadataMaps } =
|
||||
await this.workspaceMetadataCacheService.getExistingOrRecomputeFlatObjectMetadataMaps(
|
||||
{
|
||||
workspaceId: workspaceMigration.workspaceId,
|
||||
@@ -36,7 +39,7 @@ export class WorkspaceMigrationRunnerV2Service {
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
let optimisticFlatObjectMetadataMaps = structuredClone(
|
||||
flatObjectMetadataMaps,
|
||||
existingFlatObjectMetadataMaps,
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -73,6 +76,8 @@ export class WorkspaceMigrationRunnerV2Service {
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
return optimisticFlatObjectMetadataMaps;
|
||||
} catch (error) {
|
||||
if (queryRunner.isTransactionActive) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
|
||||
Reference in New Issue
Block a user