44f97058ac
closes https://github.com/twentyhq/core-team-issues/issues/1605 TODO: ~~- add stories~~ ~~- add base graph on companies when creating a new graph widget~~
380 lines
12 KiB
TypeScript
380 lines
12 KiB
TypeScript
import { TEST_NOT_EXISTING_PAGE_LAYOUT_ID } from 'test/integration/constants/test-page-layout-ids.constants';
|
|
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 { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util';
|
|
import {
|
|
createTestPageLayoutWithRestApi,
|
|
deleteTestPageLayoutWithRestApi,
|
|
} from 'test/integration/rest/utils/page-layout-rest-api.util';
|
|
import {
|
|
assertRestApiErrorResponse,
|
|
assertRestApiSuccessfulResponse,
|
|
} from 'test/integration/rest/utils/rest-test-assertions.util';
|
|
import { generateRecordName } from 'test/integration/utils/generate-record-name';
|
|
import {
|
|
assertPageLayoutStructure,
|
|
cleanupPageLayoutRecords,
|
|
} from 'test/integration/utils/page-layout-test.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 REST API', () => {
|
|
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 },
|
|
});
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await cleanupPageLayoutRecords();
|
|
});
|
|
|
|
describe('GET /rest/metadata/pageLayouts', () => {
|
|
it('should return all page layouts for workspace', async () => {
|
|
const response = await makeRestAPIRequest({
|
|
method: 'get',
|
|
path: '/metadata/pageLayouts',
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiSuccessfulResponse(response);
|
|
expect(Array.isArray(response.body)).toBe(true);
|
|
});
|
|
|
|
it('should return page layouts filtered by objectMetadataId', async () => {
|
|
await createTestPageLayoutWithRestApi({
|
|
name: 'Test Page Layout for Filter',
|
|
objectMetadataId: testObjectMetadataId,
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
});
|
|
|
|
const response = await makeRestAPIRequest({
|
|
method: 'get',
|
|
path: `/metadata/pageLayouts?objectMetadataId=${testObjectMetadataId}`,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiSuccessfulResponse(response);
|
|
expect(Array.isArray(response.body)).toBe(true);
|
|
|
|
if (response.body.length > 0) {
|
|
assertPageLayoutStructure(response.body[0]);
|
|
expect(response.body[0].objectMetadataId).toBe(testObjectMetadataId);
|
|
}
|
|
});
|
|
|
|
it('should return empty array when no page layouts match objectMetadataId', async () => {
|
|
const response = await makeRestAPIRequest({
|
|
method: 'get',
|
|
path: `/metadata/pageLayouts?objectMetadataId=${TEST_NOT_EXISTING_PAGE_LAYOUT_ID}`,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiSuccessfulResponse(response);
|
|
expect(Array.isArray(response.body)).toBe(true);
|
|
expect(response.body).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe('POST /rest/metadata/pageLayouts', () => {
|
|
it('should create a new page layout with all properties', async () => {
|
|
const pageLayoutName = generateRecordName('Dashboard Page Layout');
|
|
const pageLayout = await createTestPageLayoutWithRestApi({
|
|
name: pageLayoutName,
|
|
type: PageLayoutType.DASHBOARD,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
assertPageLayoutStructure(pageLayout, {
|
|
name: pageLayoutName,
|
|
type: PageLayoutType.DASHBOARD,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
await deleteTestPageLayoutWithRestApi(pageLayout.id);
|
|
});
|
|
|
|
it('should create a page layout with minimum required fields', async () => {
|
|
const pageLayoutName = generateRecordName('Minimal Page Layout');
|
|
const pageLayout = await createTestPageLayoutWithRestApi({
|
|
name: pageLayoutName,
|
|
});
|
|
|
|
assertPageLayoutStructure(pageLayout, {
|
|
name: pageLayoutName,
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
objectMetadataId: null,
|
|
});
|
|
|
|
await deleteTestPageLayoutWithRestApi(pageLayout.id);
|
|
});
|
|
|
|
describe('GET /rest/metadata/pageLayouts/:id', () => {
|
|
it('should return a page layout by id', async () => {
|
|
const pageLayoutName = generateRecordName('Test Page Layout for Get');
|
|
const pageLayout = await createTestPageLayoutWithRestApi({
|
|
name: pageLayoutName,
|
|
type: PageLayoutType.DASHBOARD,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
const response = await makeRestAPIRequest({
|
|
method: 'get',
|
|
path: `/metadata/pageLayouts/${pageLayout.id}`,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiSuccessfulResponse(response);
|
|
assertPageLayoutStructure(response.body, {
|
|
id: pageLayout.id,
|
|
name: pageLayoutName,
|
|
type: PageLayoutType.DASHBOARD,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
await deleteTestPageLayoutWithRestApi(pageLayout.id);
|
|
});
|
|
|
|
it('should return {} for non-existent page layout', async () => {
|
|
const response = await makeRestAPIRequest({
|
|
method: 'get',
|
|
path: `/metadata/pageLayouts/${TEST_NOT_EXISTING_PAGE_LAYOUT_ID}`,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiErrorResponse(
|
|
response,
|
|
404,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('PATCH /rest/metadata/pageLayouts/:id', () => {
|
|
it('should update an existing page layout', async () => {
|
|
const pageLayoutName = generateRecordName(
|
|
'Test Page Layout for Update',
|
|
);
|
|
const pageLayout = await createTestPageLayoutWithRestApi({
|
|
name: pageLayoutName,
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
const updatedName = generateRecordName('Updated Page Layout');
|
|
const updateData = {
|
|
name: updatedName,
|
|
type: PageLayoutType.DASHBOARD,
|
|
};
|
|
|
|
const response = await makeRestAPIRequest({
|
|
method: 'patch',
|
|
path: `/metadata/pageLayouts/${pageLayout.id}`,
|
|
body: updateData,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiSuccessfulResponse(response);
|
|
assertPageLayoutStructure(response.body, {
|
|
id: pageLayout.id,
|
|
name: updatedName,
|
|
type: PageLayoutType.DASHBOARD,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
await deleteTestPageLayoutWithRestApi(pageLayout.id);
|
|
});
|
|
|
|
it('should update only provided fields', async () => {
|
|
const originalName = generateRecordName('Original Page Layout');
|
|
const pageLayout = await createTestPageLayoutWithRestApi({
|
|
name: originalName,
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
const updatedName = generateRecordName('Updated Name Only');
|
|
const updateData = {
|
|
name: updatedName,
|
|
};
|
|
|
|
const response = await makeRestAPIRequest({
|
|
method: 'patch',
|
|
path: `/metadata/pageLayouts/${pageLayout.id}`,
|
|
body: updateData,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiSuccessfulResponse(response);
|
|
assertPageLayoutStructure(response.body, {
|
|
id: pageLayout.id,
|
|
name: updatedName,
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
await deleteTestPageLayoutWithRestApi(pageLayout.id);
|
|
});
|
|
|
|
it('should return 404 error when updating non-existent page layout', async () => {
|
|
const updateData = {
|
|
name: 'Updated Page Layout',
|
|
type: PageLayoutType.DASHBOARD,
|
|
};
|
|
|
|
const response = await makeRestAPIRequest({
|
|
method: 'patch',
|
|
path: `/metadata/pageLayouts/${TEST_NOT_EXISTING_PAGE_LAYOUT_ID}`,
|
|
body: updateData,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiErrorResponse(
|
|
response,
|
|
404,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('DELETE /rest/metadata/pageLayouts/:id', () => {
|
|
it('should delete an existing page layout', async () => {
|
|
const pageLayoutName = generateRecordName(
|
|
'Test Page Layout for Delete',
|
|
);
|
|
const pageLayout = await createTestPageLayoutWithRestApi({
|
|
name: pageLayoutName,
|
|
type: PageLayoutType.RECORD_INDEX,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
const deleteResponse = await makeRestAPIRequest({
|
|
method: 'delete',
|
|
path: `/metadata/pageLayouts/${pageLayout.id}`,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiSuccessfulResponse(deleteResponse);
|
|
assertPageLayoutStructure(deleteResponse.body, pageLayout);
|
|
|
|
const getResponse = await makeRestAPIRequest({
|
|
method: 'get',
|
|
path: `/metadata/pageLayouts/${pageLayout.id}`,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiErrorResponse(
|
|
getResponse,
|
|
404,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
pageLayout.id,
|
|
),
|
|
);
|
|
});
|
|
|
|
it('should return 404 error when deleting non-existent page layout', async () => {
|
|
const response = await makeRestAPIRequest({
|
|
method: 'delete',
|
|
path: `/metadata/pageLayouts/${TEST_NOT_EXISTING_PAGE_LAYOUT_ID}`,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiErrorResponse(
|
|
response,
|
|
404,
|
|
generatePageLayoutExceptionMessage(
|
|
PageLayoutExceptionMessageKey.PAGE_LAYOUT_NOT_FOUND,
|
|
TEST_NOT_EXISTING_PAGE_LAYOUT_ID,
|
|
),
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('Edge Cases', () => {
|
|
it('should handle multiple page layouts for same object', async () => {
|
|
const pageLayout1 = await createTestPageLayoutWithRestApi({
|
|
name: generateRecordName('Page Layout 1'),
|
|
type: PageLayoutType.RECORD_PAGE,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
const pageLayout2 = await createTestPageLayoutWithRestApi({
|
|
name: generateRecordName('Page Layout 2'),
|
|
type: PageLayoutType.RECORD_INDEX,
|
|
objectMetadataId: testObjectMetadataId,
|
|
});
|
|
|
|
const response = await makeRestAPIRequest({
|
|
method: 'get',
|
|
path: `/metadata/pageLayouts?objectMetadataId=${testObjectMetadataId}`,
|
|
bearer: API_KEY_ACCESS_TOKEN,
|
|
});
|
|
|
|
assertRestApiSuccessfulResponse(response);
|
|
expect(response.body).toHaveLength(2);
|
|
|
|
await Promise.all([
|
|
deleteTestPageLayoutWithRestApi(pageLayout1.id),
|
|
deleteTestPageLayoutWithRestApi(pageLayout2.id),
|
|
]);
|
|
});
|
|
|
|
it('should handle page layouts with null objectMetadataId', async () => {
|
|
const pageLayout = await createTestPageLayoutWithRestApi({
|
|
name: generateRecordName('Global Page Layout'),
|
|
type: PageLayoutType.DASHBOARD,
|
|
objectMetadataId: null,
|
|
});
|
|
|
|
assertPageLayoutStructure(pageLayout, {
|
|
type: PageLayoutType.DASHBOARD,
|
|
objectMetadataId: null,
|
|
});
|
|
|
|
await deleteTestPageLayoutWithRestApi(pageLayout.id);
|
|
});
|
|
});
|
|
});
|
|
});
|