af0af0a237
# Introduction - Fixing app dependencyFlatEntityMaps load ( to load current app + dependent app ) - Fix empty flat entity maps and undefined optimistic override - Refactor the optimistic rendering to be mutation oriented at orchestrator level
266 lines
7.6 KiB
TypeScript
266 lines
7.6 KiB
TypeScript
import { buildDefaultObjectManifest } from 'test/integration/metadata/suites/application/utils/build-default-object-manifest.util';
|
|
import { setupApplicationForSync } from 'test/integration/metadata/suites/application/utils/setup-application-for-sync.util';
|
|
import { syncApplication } from 'test/integration/metadata/suites/application/utils/sync-application.util';
|
|
import { uninstallApplication } from 'test/integration/metadata/suites/application/utils/uninstall-application.util';
|
|
import { extractRecordIdsAndDatesAsExpectAny } from 'test/utils/extract-record-ids-and-dates-as-expect-any';
|
|
import { type Manifest } from 'twenty-shared/application';
|
|
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
|
|
import { FieldMetadataType } from 'twenty-shared/types';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
const TEST_APP_ID = uuidv4();
|
|
const TEST_ROLE_ID = uuidv4();
|
|
const TEST_SECOND_ROLE_ID = uuidv4();
|
|
const TEST_FIELD_ID = uuidv4();
|
|
const TEST_SKILL_ID = uuidv4();
|
|
|
|
const TEST_OBJECT = buildDefaultObjectManifest({
|
|
nameSingular: 'ticket',
|
|
namePlural: 'tickets',
|
|
labelSingular: 'Ticket',
|
|
labelPlural: 'Tickets',
|
|
description: 'A support ticket',
|
|
icon: 'IconTicket',
|
|
});
|
|
|
|
describe('syncApplication', () => {
|
|
let appCreated = false;
|
|
|
|
beforeAll(async () => {
|
|
await setupApplicationForSync({
|
|
applicationUniversalIdentifier: TEST_APP_ID,
|
|
name: 'Test Application',
|
|
description: 'A test application',
|
|
sourcePath: 'test-sync',
|
|
});
|
|
|
|
appCreated = true;
|
|
}, 60000);
|
|
|
|
afterEach(async () => {
|
|
if (!appCreated) {
|
|
return;
|
|
}
|
|
|
|
await uninstallApplication({
|
|
universalIdentifier: TEST_APP_ID,
|
|
expectToFail: false,
|
|
});
|
|
});
|
|
|
|
it('should return workspace migration actions on initial sync then on second sync with field rename and new role', async () => {
|
|
const initialManifest: Manifest = {
|
|
application: {
|
|
universalIdentifier: TEST_APP_ID,
|
|
defaultRoleUniversalIdentifier: TEST_ROLE_ID,
|
|
displayName: 'Test Application',
|
|
description: 'A test application for workspace migration',
|
|
icon: 'IconTestPipe',
|
|
applicationVariables: {},
|
|
packageJsonChecksum: null,
|
|
yarnLockChecksum: null,
|
|
apiClientChecksum: null,
|
|
},
|
|
roles: [
|
|
{
|
|
universalIdentifier: TEST_ROLE_ID,
|
|
label: 'Test Role',
|
|
description: 'A test role',
|
|
},
|
|
],
|
|
skills: [],
|
|
objects: [TEST_OBJECT],
|
|
fields: [
|
|
{
|
|
universalIdentifier: TEST_FIELD_ID,
|
|
type: FieldMetadataType.TEXT,
|
|
name: 'description',
|
|
label: 'Description',
|
|
description: 'Ticket description',
|
|
icon: 'IconFileDescription',
|
|
objectUniversalIdentifier: TEST_OBJECT.universalIdentifier,
|
|
},
|
|
],
|
|
logicFunctions: [],
|
|
frontComponents: [],
|
|
publicAssets: [],
|
|
views: [],
|
|
navigationMenuItems: [],
|
|
pageLayouts: [],
|
|
};
|
|
|
|
const { data: firstSyncData } = await syncApplication({
|
|
manifest: initialManifest,
|
|
expectToFail: false,
|
|
});
|
|
|
|
expect(firstSyncData).toMatchSnapshot(
|
|
extractRecordIdsAndDatesAsExpectAny(firstSyncData),
|
|
);
|
|
|
|
const updatedManifest: Manifest = {
|
|
...initialManifest,
|
|
roles: [
|
|
{
|
|
universalIdentifier: TEST_ROLE_ID,
|
|
label: 'Test Role',
|
|
description: 'A test role',
|
|
},
|
|
{
|
|
universalIdentifier: TEST_SECOND_ROLE_ID,
|
|
label: 'Viewer Role',
|
|
description: 'A read-only role',
|
|
},
|
|
],
|
|
fields: [
|
|
{
|
|
universalIdentifier: TEST_FIELD_ID,
|
|
type: FieldMetadataType.TEXT,
|
|
name: 'body',
|
|
label: 'Body',
|
|
description: 'Ticket description',
|
|
icon: 'IconFileDescription',
|
|
objectUniversalIdentifier: TEST_OBJECT.universalIdentifier,
|
|
},
|
|
],
|
|
};
|
|
|
|
const { data: secondSyncData } = await syncApplication({
|
|
manifest: updatedManifest,
|
|
expectToFail: false,
|
|
});
|
|
|
|
expect(secondSyncData).toMatchSnapshot(
|
|
extractRecordIdsAndDatesAsExpectAny(secondSyncData),
|
|
);
|
|
}, 60000);
|
|
|
|
it('should sync a skill then update it on second sync', async () => {
|
|
const initialManifest: Manifest = {
|
|
application: {
|
|
universalIdentifier: TEST_APP_ID,
|
|
defaultRoleUniversalIdentifier: TEST_ROLE_ID,
|
|
displayName: 'Test Application',
|
|
description: 'A test application for workspace migration',
|
|
icon: 'IconTestPipe',
|
|
applicationVariables: {},
|
|
packageJsonChecksum: null,
|
|
yarnLockChecksum: null,
|
|
apiClientChecksum: null,
|
|
},
|
|
roles: [
|
|
{
|
|
universalIdentifier: TEST_ROLE_ID,
|
|
label: 'Test Role',
|
|
description: 'A test role',
|
|
},
|
|
],
|
|
skills: [
|
|
{
|
|
universalIdentifier: TEST_SKILL_ID,
|
|
name: 'test-skill',
|
|
label: 'Test Skill',
|
|
description: 'A skill for testing',
|
|
icon: 'IconBrain',
|
|
content: '# Test Skill\n\nThis is a test skill.',
|
|
},
|
|
],
|
|
objects: [],
|
|
fields: [],
|
|
logicFunctions: [],
|
|
frontComponents: [],
|
|
publicAssets: [],
|
|
views: [],
|
|
navigationMenuItems: [],
|
|
pageLayouts: [],
|
|
};
|
|
|
|
const { data: firstSyncData } = await syncApplication({
|
|
manifest: initialManifest,
|
|
expectToFail: false,
|
|
});
|
|
|
|
expect(firstSyncData).toMatchSnapshot(
|
|
extractRecordIdsAndDatesAsExpectAny(firstSyncData),
|
|
);
|
|
|
|
const updatedManifest: Manifest = {
|
|
...initialManifest,
|
|
skills: [
|
|
{
|
|
universalIdentifier: TEST_SKILL_ID,
|
|
name: 'test-skill',
|
|
label: 'Test Skill Updated',
|
|
description: 'An updated skill for testing',
|
|
icon: 'IconBrain',
|
|
content:
|
|
'# Test Skill\n\nThis is an updated test skill with more content.',
|
|
},
|
|
],
|
|
};
|
|
|
|
const { data: secondSyncData } = await syncApplication({
|
|
manifest: updatedManifest,
|
|
expectToFail: false,
|
|
});
|
|
|
|
expect(secondSyncData).toMatchSnapshot(
|
|
extractRecordIdsAndDatesAsExpectAny(secondSyncData),
|
|
);
|
|
}, 60000);
|
|
|
|
it('should create a TEXT field on the standard Company object', async () => {
|
|
const companyFieldId = uuidv4();
|
|
|
|
const manifest: Manifest = {
|
|
application: {
|
|
universalIdentifier: TEST_APP_ID,
|
|
defaultRoleUniversalIdentifier: TEST_ROLE_ID,
|
|
displayName: 'Test Application',
|
|
description: 'A test application for workspace migration',
|
|
icon: 'IconTestPipe',
|
|
applicationVariables: {},
|
|
packageJsonChecksum: null,
|
|
yarnLockChecksum: null,
|
|
apiClientChecksum: null,
|
|
},
|
|
roles: [
|
|
{
|
|
universalIdentifier: TEST_ROLE_ID,
|
|
label: 'Test Role',
|
|
description: 'A test role',
|
|
},
|
|
],
|
|
skills: [],
|
|
objects: [],
|
|
fields: [
|
|
{
|
|
universalIdentifier: companyFieldId,
|
|
type: FieldMetadataType.TEXT,
|
|
name: 'industry',
|
|
label: 'Industry',
|
|
description: 'The industry of the company',
|
|
icon: 'IconBuildingFactory2',
|
|
objectUniversalIdentifier:
|
|
STANDARD_OBJECTS.company.universalIdentifier,
|
|
},
|
|
],
|
|
logicFunctions: [],
|
|
frontComponents: [],
|
|
publicAssets: [],
|
|
views: [],
|
|
navigationMenuItems: [],
|
|
pageLayouts: [],
|
|
};
|
|
|
|
const { data: syncData } = await syncApplication({
|
|
manifest,
|
|
expectToFail: false,
|
|
});
|
|
|
|
expect(syncData).toMatchSnapshot(
|
|
extractRecordIdsAndDatesAsExpectAny(syncData),
|
|
);
|
|
}, 60000);
|
|
});
|