Cleanup application and app registration test util (#19981)

## Introduction
Centralizing integ test app cleanup
Role will be deleted by the app uninstall if exists
This commit is contained in:
Paul Rastoin
2026-04-22 16:39:58 +02:00
committed by GitHub
parent b010599000
commit f0a625c3f8
14 changed files with 97 additions and 370 deletions
@@ -4,10 +4,10 @@ import { tmpdir } from 'os';
import { join } from 'path';
import * as tar from 'tar';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.util';
import { installApplication } from 'test/integration/metadata/suites/application/utils/install-application.util';
import { uploadAppTarball } from 'test/integration/metadata/suites/application/utils/upload-app-tarball.util';
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
import { type DataSource } from 'typeorm';
const createTestTarball = async (
files: Record<string, string>,
@@ -98,35 +98,17 @@ const buildManifestWithCrossEntityIdentifierConflict = (
});
describe('Install application should return structured validation errors', () => {
let ds: DataSource;
const createdRegistrationIds: string[] = [];
const createdApplicationUniversalIdentifiers: string[] = [];
beforeAll(() => {
jest.useRealTimers();
ds = globalThis.testDataSource;
});
afterAll(async () => {
for (const uid of createdApplicationUniversalIdentifiers) {
await ds.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[uid],
);
await ds.query(
`DELETE FROM core."application" WHERE "universalIdentifier" = $1`,
[uid],
);
}
for (const id of createdRegistrationIds) {
await ds.query(
`DELETE FROM core."applicationRegistration" WHERE id = $1`,
[id],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: uid,
});
}
jest.useFakeTimers();
@@ -160,7 +142,6 @@ describe('Install application should return structured validation errors', () =>
const registrationId = uploadResult.data!.uploadAppTarball.id;
createdRegistrationIds.push(registrationId);
createdApplicationUniversalIdentifiers.push(universalIdentifier);
const { errors } = await installApplication({
@@ -1,9 +1,9 @@
import { expectOneNotInternalServerErrorSnapshot } from 'test/integration/graphql/utils/expect-one-not-internal-server-error-snapshot.util';
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.util';
import { installApplication } from 'test/integration/metadata/suites/application/utils/install-application.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 { v4 as uuidv4 } from 'uuid';
const INVALID_UUID_APP_ID = uuidv4();
@@ -20,33 +20,9 @@ describe('Install application should fail when entity does not exist', () => {
}, 60000);
afterEach(async () => {
try {
await uninstallApplication({
universalIdentifier: INVALID_UUID_APP_ID,
expectToFail: false,
});
} catch {
// May fail if the test didn't install/sync
}
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[INVALID_UUID_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[INVALID_UUID_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[INVALID_UUID_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: INVALID_UUID_APP_ID,
});
});
it('should fail with execution error when installing non-existent app registration', async () => {
@@ -2,6 +2,7 @@ import { PermissionFlagType } from 'twenty-shared/constants';
import { expectOneNotInternalServerErrorSnapshot } from 'test/integration/graphql/utils/expect-one-not-internal-server-error-snapshot.util';
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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';
@@ -26,29 +27,9 @@ describe('Sync application should fail when creating permissions on a standard r
}, 60000);
afterAll(async () => {
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" = $1`,
[TEST_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it('should fail when adding a permission flag under the standard admin role', async () => {
@@ -1,6 +1,7 @@
import { expectOneNotInternalServerErrorSnapshot } from 'test/integration/graphql/utils/expect-one-not-internal-server-error-snapshot.util';
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { buildDefaultObjectManifest } from 'test/integration/metadata/suites/application/utils/build-default-object-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { type Manifest, type ObjectManifest } from 'twenty-shared/application';
@@ -102,7 +103,10 @@ const buildDefaultObjectWithModifiedSearchVector = ({
...defaultObject,
fields: defaultObject.fields.map((field) =>
field.name === 'searchVector'
? ({ ...field, ...searchVectorOverrides } as (typeof defaultObject.fields)[number])
? ({
...field,
...searchVectorOverrides,
} as (typeof defaultObject.fields)[number])
: field,
),
},
@@ -273,29 +277,9 @@ describe('Sync application should fail due to object system fields integrity', (
}, 60000);
afterAll(async () => {
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" = $1`,
[TEST_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it.each(
@@ -1,5 +1,6 @@
import { expectOneNotInternalServerErrorSnapshot } from 'test/integration/graphql/utils/expect-one-not-internal-server-error-snapshot.util';
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { STANDARD_OBJECTS } from 'twenty-shared/metadata';
@@ -8,8 +9,7 @@ import { STANDARD_ROLE } from 'src/engine/workspace-manager/twenty-standard-appl
const TEST_APP_ID = 'a1b2c3d4-0001-4000-a000-000000000001';
const TEST_ROLE_ID = 'a1b2c3d4-0002-4000-a000-000000000002';
const DUPLICATED_UNIVERSAL_IDENTIFIER =
'a1b2c3d4-0003-4000-a000-000000000003';
const DUPLICATED_UNIVERSAL_IDENTIFIER = 'a1b2c3d4-0003-4000-a000-000000000003';
describe('Sync application should fail on universalIdentifier conflicts', () => {
beforeAll(async () => {
@@ -22,29 +22,9 @@ describe('Sync application should fail on universalIdentifier conflicts', () =>
}, 60000);
afterAll(async () => {
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" = $1`,
[TEST_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it('should fail when two entities in the same manifest share the same universalIdentifier', async () => {
@@ -1,8 +1,8 @@
import { findAgents } from 'test/integration/metadata/suites/agent/utils/find-agents.util';
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { findAgents } from 'test/integration/metadata/suites/agent/utils/find-agents.util';
import { type Manifest } from 'twenty-shared/application';
import { v4 as uuidv4 } from 'uuid';
@@ -25,8 +25,7 @@ const findAppAgents = async () => {
});
return data.findManyAgents.filter(
(agent) =>
agent.name === 'sales-assistant' || agent.name === 'support-bot',
(agent) => agent.name === 'sales-assistant' || agent.name === 'support-bot',
);
};
@@ -41,38 +40,9 @@ describe('Manifest update - agents', () => {
}, 60000);
afterEach(async () => {
try {
await uninstallApplication({
universalIdentifier: TEST_APP_ID,
expectToFail: false,
});
} catch {
// May fail if the test didn't fully install/sync
}
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" = $1`,
[TEST_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it('should create a new agent when added to manifest on second sync', async () => {
@@ -201,9 +171,7 @@ describe('Manifest update - agents', () => {
expect(agentsAfterFirstSync).toHaveLength(2);
expect(
agentsAfterFirstSync.find(
(agent) => agent.name === 'sales-assistant',
),
agentsAfterFirstSync.find((agent) => agent.name === 'sales-assistant'),
).toBeDefined();
expect(
agentsAfterFirstSync.find((agent) => agent.name === 'support-bot'),
@@ -1,12 +1,12 @@
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { buildDefaultObjectManifest } from 'test/integration/metadata/suites/application/utils/build-default-object-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { findManyObjectMetadataWithIndexes } from 'test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata-with-indexes.util';
import { type Manifest } from 'twenty-shared/application';
import { FieldMetadataType } from 'twenty-shared/types';
import { v4 as uuidv4 } from 'uuid';
import { findManyObjectMetadataWithIndexes } from 'test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata-with-indexes.util';
const TEST_APP_ID = uuidv4();
const TEST_ROLE_ID = uuidv4();
@@ -52,38 +52,9 @@ describe('Manifest update - fields', () => {
}, 60000);
afterEach(async () => {
try {
await uninstallApplication({
universalIdentifier: TEST_APP_ID,
expectToFail: false,
});
} catch {
// May fail if the test didn't fully install/sync
}
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" = $1`,
[TEST_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it('should create a new field when added to manifest on second sync', async () => {
@@ -295,8 +266,7 @@ describe('Manifest update - fields', () => {
const object = objects.find(
(objectMetadata) =>
objectMetadata.universalIdentifier ===
TEST_OBJECT.universalIdentifier,
objectMetadata.universalIdentifier === TEST_OBJECT.universalIdentifier,
);
expect(object).toBeDefined();
@@ -311,8 +281,7 @@ describe('Manifest update - fields', () => {
(index) =>
index.isUnique &&
index.indexFieldMetadataList.some(
(indexField) =>
indexField.fieldMetadataId === externalIdField?.id,
(indexField) => indexField.fieldMetadataId === externalIdField?.id,
),
);
@@ -1,7 +1,7 @@
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { findNavigationMenuItems } from 'test/integration/metadata/suites/navigation-menu-item/utils/find-navigation-menu-items.util';
import { type Manifest } from 'twenty-shared/application';
import { NavigationMenuItemType } from 'twenty-shared/types';
@@ -64,38 +64,9 @@ describe('Manifest update - navigation menu items', () => {
}, 60000);
afterEach(async () => {
try {
await uninstallApplication({
universalIdentifier: TEST_APP_ID,
expectToFail: false,
});
} catch {
// May fail if the test didn't fully install/sync
}
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" = $1`,
[TEST_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it('should create a folder and a child item when child is listed BEFORE folder in manifest', async () => {
@@ -1,8 +1,8 @@
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { buildDefaultObjectManifest } from 'test/integration/metadata/suites/application/utils/build-default-object-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { findManyObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata.util';
import { type Manifest } from 'twenty-shared/application';
import { v4 as uuidv4 } from 'uuid';
@@ -41,38 +41,9 @@ describe('Manifest update - objects', () => {
}, 60000);
afterEach(async () => {
try {
await uninstallApplication({
universalIdentifier: TEST_APP_ID,
expectToFail: false,
});
} catch {
// May fail if the test didn't fully install/sync
}
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" = $1`,
[TEST_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it('should create a new object when added to manifest on second sync', async () => {
@@ -1,13 +1,12 @@
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { findRoles } from 'test/integration/metadata/suites/role/utils/find-roles.util';
import { type Manifest } from 'twenty-shared/application';
import { v4 as uuidv4 } from 'uuid';
const TEST_APP_ID = uuidv4();
const TEST_WORKSPACE_ID = '20202020-1c25-4d02-bf25-6aeccf7ea419';
const TEST_ROLE_ID = uuidv4();
const TEST_SECOND_ROLE_ID = uuidv4();
@@ -51,38 +50,9 @@ describe('Manifest update - roles', () => {
}, 60000);
afterEach(async () => {
try {
await uninstallApplication({
universalIdentifier: TEST_APP_ID,
expectToFail: false,
});
} catch {
// Application may not have been installed if the test failed early
}
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" IN ($1, $2)`,
[TEST_ROLE_ID, TEST_SECOND_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1 AND "workspaceId" = $2`,
[TEST_APP_ID, TEST_WORKSPACE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1 AND "workspaceId" = $2`,
[TEST_APP_ID, TEST_WORKSPACE_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it('should create a new role when added to manifest on second sync', async () => {
@@ -1,7 +1,7 @@
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { findSkills } from 'test/integration/metadata/suites/skill/utils/find-skills.util';
import { type Manifest } from 'twenty-shared/application';
import { v4 as uuidv4 } from 'uuid';
@@ -39,38 +39,9 @@ describe('Manifest update - skills', () => {
}, 60000);
afterEach(async () => {
try {
await uninstallApplication({
universalIdentifier: TEST_APP_ID,
expectToFail: false,
});
} catch {
// May fail if the test didn't fully install/sync
}
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" = $1`,
[TEST_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it('should create a new skill when added to manifest on second sync', async () => {
@@ -1,8 +1,8 @@
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { buildDefaultObjectManifest } from 'test/integration/metadata/suites/application/utils/build-default-object-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { type FieldManifest } from 'twenty-shared/application';
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
import { FieldMetadataType } from 'twenty-shared/types';
@@ -45,9 +45,8 @@ describe('Cross-entity universalIdentifier reuse across syncs', () => {
}, 60000);
afterAll(async () => {
await uninstallApplication({
universalIdentifier: TEST_APP_ID,
expectToFail: false,
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
@@ -1,8 +1,8 @@
import { buildBaseManifest } from 'test/integration/metadata/suites/application/utils/build-base-manifest.util';
import { buildDefaultObjectManifest } from 'test/integration/metadata/suites/application/utils/build-default-object-manifest.util';
import { cleanupApplicationAndAppRegistration } from 'test/integration/metadata/suites/application/utils/cleanup-application-and-app-registration.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 { findManyObjectMetadataWithIndexes } from 'test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata-with-indexes.util';
import { findManyObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/find-many-object-metadata.util';
import { findRoles } from 'test/integration/metadata/suites/role/utils/find-roles.util';
@@ -71,38 +71,9 @@ describe('syncApplication', () => {
}, 60000);
afterEach(async () => {
try {
await uninstallApplication({
universalIdentifier: TEST_APP_ID,
expectToFail: false,
});
} catch {
// May fail if the test didn't fully install/sync
}
await globalThis.testDataSource.query(
`DELETE FROM core."role" WHERE "universalIdentifier" = $1`,
[TEST_ROLE_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[TEST_APP_ID],
);
await cleanupApplicationAndAppRegistration({
applicationUniversalIdentifier: TEST_APP_ID,
});
});
it('should return workspace migration actions on initial sync then on second sync with field rename and new role', async () => {
@@ -0,0 +1,35 @@
import { uninstallApplication } from 'test/integration/metadata/suites/application/utils/uninstall-application.util';
export const cleanupApplicationAndAppRegistration = async ({
applicationUniversalIdentifier,
}: {
applicationUniversalIdentifier: string;
}) => {
try {
await uninstallApplication({
universalIdentifier: applicationUniversalIdentifier,
expectToFail: false,
});
} catch {
// May fail if the sync never succeeded
}
await globalThis.testDataSource.query(
`DELETE FROM core."file" WHERE "applicationId" IN (
SELECT id FROM core."application" WHERE "universalIdentifier" = $1
)`,
[applicationUniversalIdentifier],
);
await globalThis.testDataSource.query(
`DELETE FROM core."application"
WHERE "universalIdentifier" = $1`,
[applicationUniversalIdentifier],
);
await globalThis.testDataSource.query(
`DELETE FROM core."applicationRegistration"
WHERE "universalIdentifier" = $1`,
[applicationUniversalIdentifier],
);
};