4fbdfb6abc
## Introduction After enabling flag by default got following errors: ```ts Test Suites: 48 failed, 1 skipped, 97 passed, 145 of 146 total Tests: 499 failed, 1 skipped, 644 passed, 1144 total Snapshots: 61 failed, 133 passed, 194 total Time: 363.226 s Ran all test suites. ``` ## From <img width="2952" height="1510" alt="image" src="https://github.com/user-attachments/assets/7e3b20c6-2552-40a7-90bb-2d7b3002c895" /> ## To <img width="3134" height="1510" alt="image" src="https://github.com/user-attachments/assets/4fc9ada4-3c14-4333-a1db-11daf87db8d6" /> There's a huge test bundle in the latest shard that we could split up ## Notes - Set as failing morph relation field rename as for the moment we do not handle relation field mutation - fixed the object update and creation validation adding label identifier field metadata id checks - and more Some integrations tests are still on the v1 ( they have before and after all disabling and re-enabling the flat ) but mainly we now have more coverage on the v2 than the v1. Mainly related records, uniqueness have to be migrated the v2 and so tests too
543 lines
18 KiB
TypeScript
543 lines
18 KiB
TypeScript
import gql from 'graphql-tag';
|
|
import { TEST_NOT_EXISTING_PAGE_LAYOUT_ID } from 'test/integration/constants/test-page-layout-ids.constants';
|
|
import { createPageLayoutOperationFactory } from 'test/integration/graphql/utils/create-page-layout-operation-factory.util';
|
|
import { deletePageLayoutOperationFactory } from 'test/integration/graphql/utils/delete-page-layout-operation-factory.util';
|
|
import { destroyPageLayoutOperationFactory } from 'test/integration/graphql/utils/destroy-page-layout-operation-factory.util';
|
|
import { findPageLayoutOperationFactory } from 'test/integration/graphql/utils/find-page-layout-operation-factory.util';
|
|
import { findPageLayoutsOperationFactory } from 'test/integration/graphql/utils/find-page-layouts-operation-factory.util';
|
|
import {
|
|
assertGraphQLErrorResponse,
|
|
assertGraphQLSuccessfulResponse,
|
|
} from 'test/integration/graphql/utils/graphql-test-assertions.util';
|
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
|
import { createTestPageLayoutWithGraphQL } from 'test/integration/graphql/utils/page-layout-graphql.util';
|
|
import { restorePageLayoutOperationFactory } from 'test/integration/graphql/utils/restore-page-layout-operation-factory.util';
|
|
import { updatePageLayoutOperationFactory } from 'test/integration/graphql/utils/update-page-layout-operation-factory.util';
|
|
import { createOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/create-one-object-metadata.util';
|
|
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';
|
|
import {
|
|
assertPageLayoutStructure,
|
|
cleanupPageLayoutRecords,
|
|
} from 'test/integration/utils/page-layout-test.util';
|
|
|
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
|
import { PageLayoutType } from 'src/engine/core-modules/page-layout/enums/page-layout-type.enum';
|
|
import {
|
|
PageLayoutExceptionMessageKey,
|
|
generatePageLayoutExceptionMessage,
|
|
} from 'src/engine/core-modules/page-layout/exceptions/page-layout.exception';
|
|
|
|
describe('Page Layout Resolver', () => {
|
|
let testObjectMetadataId: string;
|
|
|
|
beforeAll(async () => {
|
|
const {
|
|
data: {
|
|
createOneObject: { id: objectMetadataId },
|
|
},
|
|
} = await createOneObjectMetadata({
|
|
input: {
|
|
nameSingular: 'myTestPageLayoutObject',
|
|
namePlural: 'myTestPageLayoutObjects',
|
|
labelSingular: 'My Test Page Layout Object',
|
|
labelPlural: 'My Test Page Layout Objects',
|
|
icon: 'IconLayout',
|
|
},
|
|
});
|
|
|
|
testObjectMetadataId = objectMetadataId;
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await updateOneObjectMetadata({
|
|
expectToFail: false,
|
|
input: {
|
|
idToUpdate: testObjectMetadataId,
|
|
updatePayload: {
|
|
isActive: false,
|
|
},
|
|
},
|
|
});
|
|
await deleteOneObjectMetadata({
|
|
input: { idToDelete: testObjectMetadataId },
|
|
});
|
|
await cleanupPageLayoutRecords();
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await cleanupPageLayoutRecords();
|
|
});
|
|
|
|
describe('getPageLayouts', () => {
|
|
it('should return all page layouts for workspace when no objectMetadataId provided', async () => {
|
|
const pageLayoutName = 'Test Page Layout for Workspace';
|
|
|
|
await createTestPageLayoutWithGraphQL({
|
|
name: pageLayoutName,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
const operation = findPageLayoutsOperationFactory();
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLSuccessfulResponse(response);
|
|
expect(response.body.data.getPageLayouts).toHaveLength(1);
|
|
assertPageLayoutStructure(response.body.data.getPageLayouts[0], {
|
|
name: pageLayoutName,
|
|
objectMetadataId: testObjectMetadataId,
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
});
|
|
});
|
|
|
|
it('should filter page layouts by objectMetadataId when provided', async () => {
|
|
const object1PageLayoutName = 'Page Layout for Object 1';
|
|
const object2PageLayoutName = 'Page Layout for Object 2';
|
|
|
|
const {
|
|
data: {
|
|
createOneObject: { id: objectMetadata2Id },
|
|
},
|
|
} = await createOneObjectMetadata({
|
|
input: {
|
|
nameSingular: 'myTestPageLayoutObject2',
|
|
namePlural: 'myTestPageLayoutObjects2',
|
|
labelSingular: 'My Test Page Layout Object 2',
|
|
labelPlural: 'My Test Page Layout Objects 2',
|
|
icon: 'IconLayout2',
|
|
isLabelSyncedWithName: false,
|
|
},
|
|
});
|
|
|
|
await Promise.all([
|
|
createTestPageLayoutWithGraphQL({
|
|
name: object1PageLayoutName,
|
|
objectMetadataId: testObjectMetadataId,
|
|
}),
|
|
createTestPageLayoutWithGraphQL({
|
|
name: object2PageLayoutName,
|
|
objectMetadataId: objectMetadata2Id,
|
|
}),
|
|
]);
|
|
|
|
const operation = findPageLayoutsOperationFactory({
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLSuccessfulResponse(response);
|
|
expect(response.body.data.getPageLayouts).toHaveLength(1);
|
|
assertPageLayoutStructure(response.body.data.getPageLayouts[0], {
|
|
name: object1PageLayoutName,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
await updateOneObjectMetadata({
|
|
expectToFail: false,
|
|
input: {
|
|
idToUpdate: objectMetadata2Id,
|
|
updatePayload: {
|
|
isActive: false,
|
|
},
|
|
},
|
|
});
|
|
await deleteOneObjectMetadata({
|
|
input: { idToDelete: objectMetadata2Id },
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('getPageLayout', () => {
|
|
it('should throw when page layout does not exist', async () => {
|
|
const operation = findPageLayoutOperationFactory({
|
|
pageLayoutId: TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLErrorResponse(
|
|
response,
|
|
ErrorCode.NOT_FOUND,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
),
|
|
);
|
|
});
|
|
|
|
it('should return page layout when it exists', async () => {
|
|
const pageLayoutName = 'Test Page Layout for Get';
|
|
|
|
const pageLayout = await createTestPageLayoutWithGraphQL({
|
|
name: pageLayoutName,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
const operation = findPageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLSuccessfulResponse(response);
|
|
assertPageLayoutStructure(response.body.data.getPageLayout, {
|
|
id: pageLayout.id,
|
|
name: pageLayoutName,
|
|
objectMetadataId: testObjectMetadataId,
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('createPageLayout', () => {
|
|
it('should create a new page layout with all properties', async () => {
|
|
const input = {
|
|
name: 'Dashboard Page Layout',
|
|
type: PageLayoutType.DASHBOARD,
|
|
objectMetadataId: testObjectMetadataId,
|
|
};
|
|
|
|
const operation = createPageLayoutOperationFactory({ data: input });
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLSuccessfulResponse(response);
|
|
|
|
const createdPageLayout = response.body.data.createPageLayout;
|
|
|
|
assertPageLayoutStructure(createdPageLayout, {
|
|
name: input.name,
|
|
type: input.type,
|
|
objectMetadataId: input.objectMetadataId,
|
|
deletedAt: null,
|
|
});
|
|
});
|
|
|
|
it('should create a page layout with minimum required fields', async () => {
|
|
const input = {
|
|
name: 'Minimal Page Layout',
|
|
};
|
|
|
|
const operation = createPageLayoutOperationFactory({ data: input });
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLSuccessfulResponse(response);
|
|
|
|
const createdPageLayout = response.body.data.createPageLayout;
|
|
|
|
assertPageLayoutStructure(createdPageLayout, {
|
|
name: input.name,
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
objectMetadataId: null,
|
|
deletedAt: null,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('updatePageLayout', () => {
|
|
it('should update an existing page layout', async () => {
|
|
const pageLayout = await createTestPageLayoutWithGraphQL({
|
|
name: 'Original Page Layout',
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
});
|
|
|
|
const updateInput = {
|
|
name: 'Updated Page Layout',
|
|
type: PageLayoutType.DASHBOARD,
|
|
};
|
|
|
|
const operation = updatePageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
data: updateInput,
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLSuccessfulResponse(response);
|
|
assertPageLayoutStructure(response.body.data.updatePageLayout, {
|
|
id: pageLayout.id,
|
|
name: updateInput.name,
|
|
type: updateInput.type,
|
|
deletedAt: null,
|
|
});
|
|
});
|
|
|
|
it('should update only provided fields', async () => {
|
|
const pageLayout = await createTestPageLayoutWithGraphQL({
|
|
name: 'Original Page Layout',
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
});
|
|
|
|
const updateInput = {
|
|
name: 'Updated Name Only',
|
|
};
|
|
|
|
const operation = updatePageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
data: updateInput,
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLSuccessfulResponse(response);
|
|
assertPageLayoutStructure(response.body.data.updatePageLayout, {
|
|
id: pageLayout.id,
|
|
name: updateInput.name,
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
deletedAt: null,
|
|
});
|
|
});
|
|
|
|
it('should throw error when updating non-existent page layout', async () => {
|
|
const operation = updatePageLayoutOperationFactory({
|
|
pageLayoutId: TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
data: { name: 'Non-existent Page Layout' },
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLErrorResponse(
|
|
response,
|
|
ErrorCode.NOT_FOUND,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('deletePageLayout', () => {
|
|
it('should delete an existing page layout (soft delete)', async () => {
|
|
const pageLayout = await createTestPageLayoutWithGraphQL({
|
|
name: 'Page Layout to Delete',
|
|
});
|
|
|
|
const deleteOperation = deletePageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
});
|
|
const deleteResponse = await makeGraphqlAPIRequest(deleteOperation);
|
|
|
|
assertGraphQLSuccessfulResponse(deleteResponse);
|
|
assertPageLayoutStructure(
|
|
deleteResponse.body.data.deletePageLayout,
|
|
pageLayout,
|
|
);
|
|
|
|
const getOperation = findPageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
});
|
|
const getResponse = await makeGraphqlAPIRequest(getOperation);
|
|
|
|
assertGraphQLErrorResponse(
|
|
getResponse,
|
|
ErrorCode.NOT_FOUND,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
pageLayout.id,
|
|
),
|
|
);
|
|
});
|
|
|
|
it('should throw an error when deleting non-existent page layout', async () => {
|
|
const operation = deletePageLayoutOperationFactory({
|
|
pageLayoutId: TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLErrorResponse(
|
|
response,
|
|
ErrorCode.NOT_FOUND,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('destroyPageLayout', () => {
|
|
it('should destroy an existing page layout (hard delete)', async () => {
|
|
const pageLayout = await createTestPageLayoutWithGraphQL({
|
|
name: 'Page Layout to Destroy',
|
|
});
|
|
|
|
const destroyOperation = destroyPageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
});
|
|
const destroyResponse = await makeGraphqlAPIRequest(destroyOperation);
|
|
|
|
assertGraphQLSuccessfulResponse(destroyResponse);
|
|
expect(destroyResponse.body.data.destroyPageLayout).toBe(true);
|
|
});
|
|
|
|
it('should throw an error when destroying non-existent page layout', async () => {
|
|
const operation = destroyPageLayoutOperationFactory({
|
|
pageLayoutId: TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLErrorResponse(
|
|
response,
|
|
ErrorCode.NOT_FOUND,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
),
|
|
);
|
|
});
|
|
|
|
it('should destroy all associated dashboards when page layout is of type dashboard', async () => {
|
|
const dashboardId = '20202020-304c-44f2-ba7b-070762ff0e8a';
|
|
|
|
const pageLayout = await createTestPageLayoutWithGraphQL({
|
|
name: 'Page Layout to Destroy',
|
|
type: PageLayoutType.DASHBOARD,
|
|
});
|
|
|
|
const findOneDashboardOperation = {
|
|
query: gql`
|
|
query Dashboard($filter: DashboardFilterInput!) {
|
|
dashboard(filter: $filter) {
|
|
id
|
|
}
|
|
}
|
|
`,
|
|
variables: {
|
|
filter: { id: { eq: dashboardId } },
|
|
},
|
|
};
|
|
|
|
await makeGraphqlAPIRequest({
|
|
query: gql`
|
|
mutation CreateDashboard($input: CreateDashboardInput!) {
|
|
createDashboard(input: $input) {
|
|
pageLayoutId
|
|
id
|
|
title
|
|
}
|
|
}
|
|
`,
|
|
variables: {
|
|
input: {
|
|
id: dashboardId,
|
|
name: 'Dashboard to Destroy',
|
|
pageLayoutId: pageLayout.id,
|
|
},
|
|
},
|
|
});
|
|
|
|
const findOneDashboardResponseBeforeDestroy = await makeGraphqlAPIRequest(
|
|
findOneDashboardOperation,
|
|
);
|
|
|
|
expect(
|
|
findOneDashboardResponseBeforeDestroy.body.data.dashboard,
|
|
).toBeDefined();
|
|
|
|
const destroyOperation = destroyPageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
});
|
|
const destroyResponse = await makeGraphqlAPIRequest(destroyOperation);
|
|
|
|
const findOneDashboardResponseAfterDestroy = await makeGraphqlAPIRequest(
|
|
findOneDashboardOperation,
|
|
);
|
|
|
|
assertGraphQLSuccessfulResponse(destroyResponse);
|
|
expect(destroyResponse.body.data.destroyPageLayout).toBe(true);
|
|
|
|
assertGraphQLErrorResponse(
|
|
findOneDashboardResponseAfterDestroy,
|
|
ErrorCode.NOT_FOUND,
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('restorePageLayout', () => {
|
|
it('should restore a soft deleted page layout', async () => {
|
|
const pageLayout = await createTestPageLayoutWithGraphQL({
|
|
name: 'Page Layout to Restore',
|
|
type: PageLayoutType.RECORD_INDEX,
|
|
});
|
|
|
|
const deleteOperation = deletePageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
});
|
|
const deleteResponse = await makeGraphqlAPIRequest(deleteOperation);
|
|
|
|
assertGraphQLSuccessfulResponse(deleteResponse);
|
|
|
|
const restoreOperation = restorePageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
});
|
|
const restoreResponse = await makeGraphqlAPIRequest(restoreOperation);
|
|
|
|
assertGraphQLSuccessfulResponse(restoreResponse);
|
|
assertPageLayoutStructure(restoreResponse.body.data.restorePageLayout, {
|
|
id: pageLayout.id,
|
|
name: 'Page Layout to Restore',
|
|
type: PageLayoutType.RECORD_INDEX,
|
|
deletedAt: null,
|
|
});
|
|
|
|
const getOperation = findPageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
});
|
|
const getResponse = await makeGraphqlAPIRequest(getOperation);
|
|
|
|
assertGraphQLSuccessfulResponse(getResponse);
|
|
assertPageLayoutStructure(getResponse.body.data.getPageLayout, {
|
|
id: pageLayout.id,
|
|
name: 'Page Layout to Restore',
|
|
type: PageLayoutType.RECORD_INDEX,
|
|
deletedAt: null,
|
|
});
|
|
});
|
|
|
|
it('should throw an error when restoring non-existent page layout', async () => {
|
|
const operation = restorePageLayoutOperationFactory({
|
|
pageLayoutId: TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLErrorResponse(
|
|
response,
|
|
ErrorCode.NOT_FOUND,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('tabs resolver field', () => {
|
|
it('should resolve tabs field for page layout', async () => {
|
|
const pageLayout = await createTestPageLayoutWithGraphQL({
|
|
name: 'Page Layout with Tabs',
|
|
});
|
|
|
|
const operation = findPageLayoutOperationFactory({
|
|
pageLayoutId: pageLayout.id,
|
|
gqlFields: `
|
|
id
|
|
name
|
|
type
|
|
createdAt
|
|
updatedAt
|
|
deletedAt
|
|
tabs {
|
|
id
|
|
title
|
|
position
|
|
pageLayoutId
|
|
}
|
|
`,
|
|
});
|
|
const response = await makeGraphqlAPIRequest(operation);
|
|
|
|
assertGraphQLSuccessfulResponse(response);
|
|
assertPageLayoutStructure(response.body.data.getPageLayout, {
|
|
id: pageLayout.id,
|
|
name: 'Page Layout with Tabs',
|
|
tabs: expect.any(Array),
|
|
});
|
|
});
|
|
});
|
|
});
|