Revert "Revert "[4/n]: migrate the RESTAPI GET /rest/* to use TwentyORM direc…" (#11349)
This commit is contained in:
@ -1,16 +0,0 @@
|
||||
import { PERSON_2_ID } from 'test/integration/constants/mock-person-ids.constants';
|
||||
|
||||
export const INITIAL_PERSON_DATA = {
|
||||
id: PERSON_2_ID,
|
||||
name: {
|
||||
firstName: 'Testing',
|
||||
lastName: 'User',
|
||||
},
|
||||
emails: {
|
||||
primaryEmail: 'test8@user.com',
|
||||
additionalEmails: ['user8@example.com'],
|
||||
},
|
||||
city: 'New York',
|
||||
jobTitle: 'Manager',
|
||||
companyId: '20202020-0713-40a5-8216-82802401d33e',
|
||||
};
|
||||
@ -1,4 +0,0 @@
|
||||
export const PERSON_1_ID = '777a8457-eb2d-40ac-a707-551b615b6987';
|
||||
export const PERSON_2_ID = '777a8457-eb2d-40ac-a707-551b615b6988';
|
||||
export const PERSON_3_ID = '777a8457-eb2d-40ac-a707-551b615b6989';
|
||||
export const NOT_EXISTING_PERSON_ID = '777a8457-eb2d-40ac-a707-551b615b6990';
|
||||
@ -0,0 +1 @@
|
||||
export const TEST_COMPANY_1_ID = '525c282e-030a-4a3e-90a0-d8aad0d33a93';
|
||||
@ -0,0 +1,6 @@
|
||||
export const TEST_PERSON_1_ID = '777a8457-eb2d-40ac-a707-551b615b6980';
|
||||
export const TEST_PERSON_2_ID = '777a8457-eb2d-40ac-a707-551b615b6981';
|
||||
export const TEST_PERSON_3_ID = '777a8457-eb2d-40ac-a707-551b615b6982';
|
||||
export const TEST_PERSON_4_ID = '777a8457-eb2d-40ac-a707-551b615b6983';
|
||||
export const NOT_EXISTING_TEST_PERSON_ID =
|
||||
'777a8457-eb2d-40ac-a707-551b615b6990';
|
||||
@ -0,0 +1 @@
|
||||
export const TEST_PRIMARY_LINK_URL = 'http://test/';
|
||||
@ -1,8 +1,8 @@
|
||||
import {
|
||||
PERSON_1_ID,
|
||||
PERSON_2_ID,
|
||||
PERSON_3_ID,
|
||||
} from 'test/integration/constants/mock-person-ids.constants';
|
||||
TEST_PERSON_1_ID,
|
||||
TEST_PERSON_2_ID,
|
||||
TEST_PERSON_3_ID,
|
||||
} from 'test/integration/constants/test-person-ids.constants';
|
||||
import { PERSON_GQL_FIELDS } from 'test/integration/constants/person-gql-fields.constants';
|
||||
import { createManyOperationFactory } from 'test/integration/graphql/utils/create-many-operation-factory.util';
|
||||
import { createOneOperationFactory } from 'test/integration/graphql/utils/create-one-operation-factory.util';
|
||||
@ -16,22 +16,27 @@ import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graph
|
||||
import { updateManyOperationFactory } from 'test/integration/graphql/utils/update-many-operation-factory.util';
|
||||
import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util';
|
||||
import { generateRecordName } from 'test/integration/utils/generate-record-name';
|
||||
import { deleteAllRecords } from 'test/integration/utils/delete-all-records';
|
||||
|
||||
describe('people resolvers (integration)', () => {
|
||||
beforeAll(async () => {
|
||||
await deleteAllRecords('person');
|
||||
});
|
||||
|
||||
it('1. should create and return people', async () => {
|
||||
const personCity1 = generateRecordName(PERSON_1_ID);
|
||||
const personCity2 = generateRecordName(PERSON_2_ID);
|
||||
const personCity1 = generateRecordName(TEST_PERSON_1_ID);
|
||||
const personCity2 = generateRecordName(TEST_PERSON_2_ID);
|
||||
const graphqlOperation = createManyOperationFactory({
|
||||
objectMetadataSingularName: 'person',
|
||||
objectMetadataPluralName: 'people',
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
data: [
|
||||
{
|
||||
id: PERSON_1_ID,
|
||||
id: TEST_PERSON_1_ID,
|
||||
city: personCity1,
|
||||
},
|
||||
{
|
||||
id: PERSON_2_ID,
|
||||
id: TEST_PERSON_2_ID,
|
||||
city: personCity2,
|
||||
},
|
||||
],
|
||||
@ -57,13 +62,13 @@ describe('people resolvers (integration)', () => {
|
||||
});
|
||||
|
||||
it('1b. should create and return one person', async () => {
|
||||
const personCity3 = generateRecordName(PERSON_3_ID);
|
||||
const personCity3 = generateRecordName(TEST_PERSON_3_ID);
|
||||
|
||||
const graphqlOperation = createOneOperationFactory({
|
||||
objectMetadataSingularName: 'person',
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
data: {
|
||||
id: PERSON_3_ID,
|
||||
id: TEST_PERSON_3_ID,
|
||||
city: personCity3,
|
||||
},
|
||||
});
|
||||
@ -121,7 +126,7 @@ describe('people resolvers (integration)', () => {
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
filter: {
|
||||
id: {
|
||||
eq: PERSON_3_ID,
|
||||
eq: TEST_PERSON_3_ID,
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -152,7 +157,7 @@ describe('people resolvers (integration)', () => {
|
||||
},
|
||||
filter: {
|
||||
id: {
|
||||
in: [PERSON_1_ID, PERSON_2_ID],
|
||||
in: [TEST_PERSON_1_ID, TEST_PERSON_2_ID],
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -175,7 +180,7 @@ describe('people resolvers (integration)', () => {
|
||||
data: {
|
||||
city: 'New City',
|
||||
},
|
||||
recordId: PERSON_3_ID,
|
||||
recordId: TEST_PERSON_3_ID,
|
||||
});
|
||||
|
||||
const response = await makeGraphqlAPIRequest(graphqlOperation);
|
||||
@ -225,7 +230,7 @@ describe('people resolvers (integration)', () => {
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
filter: {
|
||||
id: {
|
||||
in: [PERSON_1_ID, PERSON_2_ID],
|
||||
in: [TEST_PERSON_1_ID, TEST_PERSON_2_ID],
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -245,7 +250,7 @@ describe('people resolvers (integration)', () => {
|
||||
const graphqlOperation = deleteOneOperationFactory({
|
||||
objectMetadataSingularName: 'person',
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
recordId: PERSON_3_ID,
|
||||
recordId: TEST_PERSON_3_ID,
|
||||
});
|
||||
|
||||
const response = await makeGraphqlAPIRequest(graphqlOperation);
|
||||
@ -260,7 +265,7 @@ describe('people resolvers (integration)', () => {
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
filter: {
|
||||
id: {
|
||||
in: [PERSON_1_ID, PERSON_2_ID],
|
||||
in: [TEST_PERSON_1_ID, TEST_PERSON_2_ID],
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -276,7 +281,7 @@ describe('people resolvers (integration)', () => {
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
filter: {
|
||||
id: {
|
||||
eq: PERSON_3_ID,
|
||||
eq: TEST_PERSON_3_ID,
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -293,7 +298,7 @@ describe('people resolvers (integration)', () => {
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
filter: {
|
||||
id: {
|
||||
in: [PERSON_1_ID, PERSON_2_ID],
|
||||
in: [TEST_PERSON_1_ID, TEST_PERSON_2_ID],
|
||||
},
|
||||
not: {
|
||||
deletedAt: {
|
||||
@ -314,7 +319,7 @@ describe('people resolvers (integration)', () => {
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
filter: {
|
||||
id: {
|
||||
eq: PERSON_3_ID,
|
||||
eq: TEST_PERSON_3_ID,
|
||||
},
|
||||
not: {
|
||||
deletedAt: {
|
||||
@ -326,7 +331,7 @@ describe('people resolvers (integration)', () => {
|
||||
|
||||
const response = await makeGraphqlAPIRequest(graphqlOperation);
|
||||
|
||||
expect(response.body.data.person.id).toEqual(PERSON_3_ID);
|
||||
expect(response.body.data.person.id).toEqual(TEST_PERSON_3_ID);
|
||||
});
|
||||
|
||||
it('8. should destroy many people', async () => {
|
||||
@ -336,7 +341,7 @@ describe('people resolvers (integration)', () => {
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
filter: {
|
||||
id: {
|
||||
in: [PERSON_1_ID, PERSON_2_ID],
|
||||
in: [TEST_PERSON_1_ID, TEST_PERSON_2_ID],
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -350,7 +355,7 @@ describe('people resolvers (integration)', () => {
|
||||
const graphqlOperation = destroyOneOperationFactory({
|
||||
objectMetadataSingularName: 'person',
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
recordId: PERSON_3_ID,
|
||||
recordId: TEST_PERSON_3_ID,
|
||||
});
|
||||
|
||||
const destroyPeopleResponse = await makeGraphqlAPIRequest(graphqlOperation);
|
||||
@ -365,7 +370,7 @@ describe('people resolvers (integration)', () => {
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
filter: {
|
||||
id: {
|
||||
in: [PERSON_1_ID, PERSON_2_ID],
|
||||
in: [TEST_PERSON_1_ID, TEST_PERSON_2_ID],
|
||||
},
|
||||
not: {
|
||||
deletedAt: {
|
||||
@ -386,7 +391,7 @@ describe('people resolvers (integration)', () => {
|
||||
gqlFields: PERSON_GQL_FIELDS,
|
||||
filter: {
|
||||
id: {
|
||||
eq: PERSON_3_ID,
|
||||
eq: TEST_PERSON_3_ID,
|
||||
},
|
||||
not: {
|
||||
deletedAt: {
|
||||
|
||||
@ -8,7 +8,7 @@ const ORIGIN = new URL(SERVER_URL);
|
||||
|
||||
ORIGIN.hostname =
|
||||
process.env.IS_MULTIWORKSPACE_ENABLED === 'true'
|
||||
? `acme.${ORIGIN.hostname}`
|
||||
? `apple.${ORIGIN.hostname}`
|
||||
: ORIGIN.hostname;
|
||||
|
||||
const auth = {
|
||||
|
||||
@ -14,8 +14,6 @@ import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.
|
||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||
|
||||
describe('datamodel permissions', () => {
|
||||
beforeAll(async () => {});
|
||||
|
||||
describe('fieldMetadata', () => {
|
||||
let listingObjectId = '';
|
||||
let testFieldId = '';
|
||||
|
||||
@ -1,21 +1,31 @@
|
||||
import { PERSON_1_ID } from 'test/integration/constants/mock-person-ids.constants';
|
||||
import { TEST_PERSON_1_ID } from 'test/integration/constants/test-person-ids.constants';
|
||||
import { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util';
|
||||
import { deleteAllRecords } from 'test/integration/utils/delete-all-records';
|
||||
import { generateRecordName } from 'test/integration/utils/generate-record-name';
|
||||
import { TEST_COMPANY_1_ID } from 'test/integration/constants/test-company-ids.constants';
|
||||
import { TEST_PRIMARY_LINK_URL } from 'test/integration/constants/test-primary-link-url.constant';
|
||||
|
||||
describe('Core REST API Create One endpoint', () => {
|
||||
beforeAll(
|
||||
async () =>
|
||||
await makeRestAPIRequest({
|
||||
method: 'delete',
|
||||
path: `/people/${PERSON_1_ID}`,
|
||||
}),
|
||||
);
|
||||
beforeEach(async () => {
|
||||
await deleteAllRecords('person');
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: '/companies',
|
||||
body: {
|
||||
id: TEST_COMPANY_1_ID,
|
||||
domainName: {
|
||||
primaryLinkUrl: TEST_PRIMARY_LINK_URL,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a new person', async () => {
|
||||
const personCity = generateRecordName(PERSON_1_ID);
|
||||
const personCity = generateRecordName(TEST_PERSON_1_ID);
|
||||
const requestBody = {
|
||||
id: PERSON_1_ID,
|
||||
id: TEST_PERSON_1_ID,
|
||||
city: personCity,
|
||||
companyId: TEST_COMPANY_1_ID,
|
||||
};
|
||||
|
||||
await makeRestAPIRequest({
|
||||
@ -27,18 +37,97 @@ describe('Core REST API Create One endpoint', () => {
|
||||
.expect((res) => {
|
||||
const createdPerson = res.body.data.createPerson;
|
||||
|
||||
expect(createdPerson.id).toBe(PERSON_1_ID);
|
||||
expect(createdPerson.id).toBe(TEST_PERSON_1_ID);
|
||||
expect(createdPerson.city).toBe(personCity);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a BadRequestException when trying to create a person with an existing ID', async () => {
|
||||
const personCity = generateRecordName(PERSON_1_ID);
|
||||
it('should support depth 0 parameter', async () => {
|
||||
const personCity = generateRecordName(TEST_PERSON_1_ID);
|
||||
const requestBody = {
|
||||
id: PERSON_1_ID,
|
||||
id: TEST_PERSON_1_ID,
|
||||
city: personCity,
|
||||
companyId: TEST_COMPANY_1_ID,
|
||||
};
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: `/people?depth=0`,
|
||||
body: requestBody,
|
||||
})
|
||||
.expect(201)
|
||||
.expect((res) => {
|
||||
const createdPerson = res.body.data.createPerson;
|
||||
|
||||
expect(createdPerson.companyId).toBeDefined();
|
||||
expect(createdPerson.company).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should support depth 1 parameter', async () => {
|
||||
const personCity = generateRecordName(TEST_PERSON_1_ID);
|
||||
const requestBody = {
|
||||
id: TEST_PERSON_1_ID,
|
||||
city: personCity,
|
||||
companyId: TEST_COMPANY_1_ID,
|
||||
};
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: `/people?depth=1`,
|
||||
body: requestBody,
|
||||
})
|
||||
.expect(201)
|
||||
.expect((res) => {
|
||||
const createdPerson = res.body.data.createPerson;
|
||||
|
||||
expect(createdPerson.company).toBeDefined();
|
||||
expect(createdPerson.company.domainName.primaryLinkUrl).toBe(
|
||||
TEST_PRIMARY_LINK_URL,
|
||||
);
|
||||
expect(createdPerson.company.people).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should support depth 2 parameter', async () => {
|
||||
const personCity = generateRecordName(TEST_PERSON_1_ID);
|
||||
const requestBody = {
|
||||
id: TEST_PERSON_1_ID,
|
||||
city: personCity,
|
||||
companyId: TEST_COMPANY_1_ID,
|
||||
};
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: `/people?depth=2`,
|
||||
body: requestBody,
|
||||
})
|
||||
.expect(201)
|
||||
.expect((res) => {
|
||||
const createdPerson = res.body.data.createPerson;
|
||||
|
||||
expect(createdPerson.company.people).toBeDefined();
|
||||
const depth2Person = createdPerson.company.people.find(
|
||||
(p) => p.id === createdPerson.id,
|
||||
);
|
||||
|
||||
expect(depth2Person).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a BadRequestException when trying to create a person with an existing ID', async () => {
|
||||
const personCity = generateRecordName(TEST_PERSON_1_ID);
|
||||
const requestBody = {
|
||||
id: TEST_PERSON_1_ID,
|
||||
city: personCity,
|
||||
};
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: `/people`,
|
||||
body: requestBody,
|
||||
});
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: `/people`,
|
||||
|
||||
@ -1,34 +1,59 @@
|
||||
import {
|
||||
NOT_EXISTING_PERSON_ID,
|
||||
PERSON_1_ID,
|
||||
} from 'test/integration/constants/mock-person-ids.constants';
|
||||
NOT_EXISTING_TEST_PERSON_ID,
|
||||
TEST_PERSON_1_ID,
|
||||
} from 'test/integration/constants/test-person-ids.constants';
|
||||
import { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util';
|
||||
import { deleteAllRecords } from 'test/integration/utils/delete-all-records';
|
||||
|
||||
describe('Core REST API Delete One endpoint', () => {
|
||||
beforeAll(
|
||||
async () =>
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: `/people`,
|
||||
body: {
|
||||
id: PERSON_1_ID,
|
||||
},
|
||||
}),
|
||||
);
|
||||
beforeAll(async () => {
|
||||
await deleteAllRecords('person');
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: `/people`,
|
||||
body: {
|
||||
id: TEST_PERSON_1_ID,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should delete one person', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'delete',
|
||||
path: `/people/${PERSON_1_ID}`,
|
||||
path: `/people/${TEST_PERSON_1_ID}`,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) => expect(res.body.data.deletePerson.id).toBe(PERSON_1_ID));
|
||||
.expect((res) =>
|
||||
expect(res.body.data.deletePerson).toEqual({ id: TEST_PERSON_1_ID }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should delete one person with favorite', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: `/favorites`,
|
||||
body: {
|
||||
personId: TEST_PERSON_1_ID,
|
||||
},
|
||||
});
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'delete',
|
||||
path: `/people/${TEST_PERSON_1_ID}`,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) =>
|
||||
expect(res.body.data.deletePerson).toEqual({ id: TEST_PERSON_1_ID }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should return a EntityNotFoundError when trying to delete a non-existing person', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'delete',
|
||||
path: `/people/${NOT_EXISTING_PERSON_ID}`,
|
||||
path: `/people/${NOT_EXISTING_TEST_PERSON_ID}`,
|
||||
})
|
||||
.expect(400)
|
||||
.expect((res) => {
|
||||
|
||||
@ -0,0 +1,289 @@
|
||||
import {
|
||||
TEST_PERSON_1_ID,
|
||||
TEST_PERSON_2_ID,
|
||||
TEST_PERSON_3_ID,
|
||||
TEST_PERSON_4_ID,
|
||||
} from 'test/integration/constants/test-person-ids.constants';
|
||||
import { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util';
|
||||
import { generateRecordName } from 'test/integration/utils/generate-record-name';
|
||||
import { TEST_COMPANY_1_ID } from 'test/integration/constants/test-company-ids.constants';
|
||||
import { deleteAllRecords } from 'test/integration/utils/delete-all-records';
|
||||
import { TEST_PRIMARY_LINK_URL } from 'test/integration/constants/test-primary-link-url.constant';
|
||||
|
||||
describe('Core REST API Find Many endpoint', () => {
|
||||
const testPersonIds = [
|
||||
TEST_PERSON_1_ID,
|
||||
TEST_PERSON_2_ID,
|
||||
TEST_PERSON_3_ID,
|
||||
TEST_PERSON_4_ID,
|
||||
];
|
||||
const testPersonCities: Record<string, string> = {};
|
||||
|
||||
beforeAll(async () => {
|
||||
await deleteAllRecords('person');
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: '/companies',
|
||||
body: {
|
||||
id: TEST_COMPANY_1_ID,
|
||||
domainName: {
|
||||
primaryLinkUrl: TEST_PRIMARY_LINK_URL,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let index = 0;
|
||||
|
||||
for (const personId of testPersonIds) {
|
||||
const city = generateRecordName(personId);
|
||||
|
||||
testPersonCities[personId] = city;
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: '/people',
|
||||
body: {
|
||||
id: personId,
|
||||
city: city,
|
||||
position: index,
|
||||
companyId: TEST_COMPANY_1_ID,
|
||||
},
|
||||
});
|
||||
index++;
|
||||
}
|
||||
});
|
||||
|
||||
it('should retrieve all people with pagination metadata', async () => {
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people',
|
||||
}).expect(200);
|
||||
|
||||
const people = response.body.data.people;
|
||||
const pageInfo = response.body.pageInfo;
|
||||
const totalCount = response.body.totalCount;
|
||||
|
||||
expect(people).not.toBeNull();
|
||||
expect(Array.isArray(people)).toBe(true);
|
||||
expect(people.length).toBeGreaterThanOrEqual(testPersonIds.length);
|
||||
|
||||
// Check that our test people are included in the results
|
||||
for (const personId of testPersonIds) {
|
||||
const person = people.find((p) => p.id === personId);
|
||||
|
||||
expect(person).toBeDefined();
|
||||
expect(person.city).toBe(testPersonCities[personId]);
|
||||
}
|
||||
|
||||
// Check pagination metadata
|
||||
expect(pageInfo).toBeDefined();
|
||||
expect(pageInfo.startCursor).toBeDefined();
|
||||
expect(pageInfo.endCursor).toBeDefined();
|
||||
expect(typeof totalCount).toBe('number');
|
||||
expect(totalCount).toEqual(testPersonIds.length);
|
||||
expect(response.body.pageInfo.hasNextPage).toBe(false);
|
||||
});
|
||||
|
||||
it('should limit results based on the limit parameter', async () => {
|
||||
const limit = testPersonIds.length - 1;
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/people?limit=${limit}`,
|
||||
}).expect(200);
|
||||
|
||||
const people = response.body.data.people;
|
||||
|
||||
expect(people).not.toBeNull();
|
||||
expect(Array.isArray(people)).toBe(true);
|
||||
expect(people.length).toEqual(limit);
|
||||
expect(response.body.totalCount).toEqual(testPersonIds.length);
|
||||
expect(response.body.pageInfo.hasNextPage).toBe(true);
|
||||
});
|
||||
|
||||
it('should return filtered totalCount', async () => {
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/people?filter=position[lte]:1`,
|
||||
}).expect(200);
|
||||
|
||||
const people = response.body.data.people;
|
||||
|
||||
expect(people).not.toBeNull();
|
||||
expect(Array.isArray(people)).toBe(true);
|
||||
expect(people.length).toEqual(2);
|
||||
expect(response.body.totalCount).toEqual(2);
|
||||
expect(response.body.pageInfo.hasNextPage).toBe(false);
|
||||
});
|
||||
|
||||
it('should filter results based on filter parameters', async () => {
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?filter=position[lt]:2',
|
||||
}).expect(200);
|
||||
|
||||
const filteredPeople = response.body.data.people;
|
||||
|
||||
expect(filteredPeople).toBeDefined();
|
||||
expect(Array.isArray(filteredPeople)).toBe(true);
|
||||
expect(filteredPeople.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should support cursor-based pagination with starting_after', async () => {
|
||||
const initialResponse = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?limit=2',
|
||||
}).expect(200);
|
||||
|
||||
const people = initialResponse.body.data.people;
|
||||
const startCursor = initialResponse.body.pageInfo.startCursor;
|
||||
|
||||
expect(people).toBeDefined();
|
||||
expect(people.length).toBe(2);
|
||||
expect(startCursor).toBeDefined();
|
||||
|
||||
const nextPageResponse = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/people?starting_after=${startCursor}&limit=1`,
|
||||
}).expect(200);
|
||||
|
||||
const nextPagePeople = nextPageResponse.body.data.people;
|
||||
|
||||
expect(nextPagePeople).toBeDefined();
|
||||
expect(nextPagePeople.length).toBe(1);
|
||||
expect(nextPagePeople[0].id).toBe(people[1].id);
|
||||
});
|
||||
|
||||
it('should support cursor-based pagination with ending_before', async () => {
|
||||
const initialResponse = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?limit=4',
|
||||
}).expect(200);
|
||||
|
||||
const people = initialResponse.body.data.people;
|
||||
const endCursor = initialResponse.body.pageInfo.endCursor;
|
||||
|
||||
expect(people).toBeDefined();
|
||||
expect(people.length).toBe(4);
|
||||
expect(endCursor).toBeDefined();
|
||||
|
||||
const nextPageResponse = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/people?ending_before=${endCursor}&limit=2`,
|
||||
}).expect(200);
|
||||
|
||||
const nextPagePeople = nextPageResponse.body.data.people;
|
||||
|
||||
expect(nextPagePeople).toBeDefined();
|
||||
expect(nextPagePeople.length).toBe(2);
|
||||
expect(nextPagePeople[0].id).toBe(people[1].id);
|
||||
expect(nextPagePeople[1].id).toBe(people[2].id);
|
||||
});
|
||||
|
||||
it('should support ordering Asc of results', async () => {
|
||||
const ascResponse = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?order_by=position[AscNullsLast]',
|
||||
}).expect(200);
|
||||
|
||||
const ascPeople = ascResponse.body.data.people;
|
||||
|
||||
expect(ascPeople).toEqual(
|
||||
[...ascPeople].sort((a, b) => a.position - b.position),
|
||||
);
|
||||
});
|
||||
|
||||
it('should support ordering Desc of results', async () => {
|
||||
const descResponse = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?order_by=position[DescNullsLast]',
|
||||
}).expect(200);
|
||||
|
||||
const descPeople = descResponse.body.data.people;
|
||||
|
||||
expect(descPeople).toEqual(
|
||||
[...descPeople].sort((a, b) => -(a.position - b.position)),
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle invalid cursor gracefully', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?starting_after=invalid-cursor',
|
||||
})
|
||||
.expect(400)
|
||||
.expect((res) => {
|
||||
expect(res.body.error).toBe('BadRequestException');
|
||||
expect(res.body.messages[0]).toContain('Invalid cursor');
|
||||
});
|
||||
});
|
||||
|
||||
it('should combine filtering, ordering, and pagination', async () => {
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?filter=position[gt]:0&order_by=city[AscNullsFirst]&limit=2',
|
||||
}).expect(200);
|
||||
|
||||
const people = response.body.data.people;
|
||||
|
||||
const pageInfo = response.body.pageInfo;
|
||||
|
||||
expect(people).toBeDefined();
|
||||
expect(people.length).toBeLessThanOrEqual(2);
|
||||
expect(pageInfo).toBeDefined();
|
||||
|
||||
expect(people).toEqual([...people].sort((a, b) => a.city - b.city));
|
||||
});
|
||||
|
||||
it('should support depth 0 parameter', async () => {
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?depth=0',
|
||||
}).expect(200);
|
||||
|
||||
const people = response.body.data.people;
|
||||
|
||||
expect(people).toBeDefined();
|
||||
|
||||
const person = people[0];
|
||||
|
||||
expect(person).toBeDefined();
|
||||
expect(person.companyId).toBeDefined();
|
||||
expect(person.company).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should support depth 1 parameter', async () => {
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?depth=1',
|
||||
}).expect(200);
|
||||
|
||||
const people = response.body.data.people;
|
||||
|
||||
const person = people[0];
|
||||
|
||||
expect(person.company).toBeDefined();
|
||||
expect(person.company.domainName.primaryLinkUrl).toBe(
|
||||
TEST_PRIMARY_LINK_URL,
|
||||
);
|
||||
|
||||
expect(person.company.people).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should support depth 2 parameter', async () => {
|
||||
const response = await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: '/people?depth=2',
|
||||
}).expect(200);
|
||||
|
||||
const people = response.body.data.people;
|
||||
|
||||
const person = people[0];
|
||||
|
||||
expect(person.company.people).toBeDefined();
|
||||
|
||||
const depth2Person = person.company.people.find((p) => p.id === person.id);
|
||||
|
||||
expect(depth2Person).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,119 @@
|
||||
import {
|
||||
NOT_EXISTING_TEST_PERSON_ID,
|
||||
TEST_PERSON_1_ID,
|
||||
} from 'test/integration/constants/test-person-ids.constants';
|
||||
import { TEST_COMPANY_1_ID } from 'test/integration/constants/test-company-ids.constants';
|
||||
import { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util';
|
||||
import { generateRecordName } from 'test/integration/utils/generate-record-name';
|
||||
import { deleteAllRecords } from 'test/integration/utils/delete-all-records';
|
||||
import { TEST_PRIMARY_LINK_URL } from 'test/integration/constants/test-primary-link-url.constant';
|
||||
|
||||
describe('Core REST API Find One endpoint', () => {
|
||||
let personCity: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
await deleteAllRecords('person');
|
||||
await deleteAllRecords('company');
|
||||
|
||||
personCity = generateRecordName(TEST_PERSON_1_ID);
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: '/companies',
|
||||
body: {
|
||||
id: TEST_COMPANY_1_ID,
|
||||
domainName: {
|
||||
primaryLinkUrl: TEST_PRIMARY_LINK_URL,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: '/people',
|
||||
body: {
|
||||
id: TEST_PERSON_1_ID,
|
||||
city: personCity,
|
||||
companyId: TEST_COMPANY_1_ID,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should retrieve a person by ID', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/people/${TEST_PERSON_1_ID}`,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const person = res.body.data.person;
|
||||
|
||||
expect(person).not.toBeNull();
|
||||
expect(person.id).toBe(TEST_PERSON_1_ID);
|
||||
expect(person.city).toBe(personCity);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return 400 error when trying to retrieve a non-existing person', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/people/${NOT_EXISTING_TEST_PERSON_ID}`,
|
||||
})
|
||||
.expect(400)
|
||||
.expect((res) => {
|
||||
expect(res.body.messages[0]).toContain('Record not found');
|
||||
expect(res.body.error).toBe('BadRequestException');
|
||||
});
|
||||
});
|
||||
|
||||
it('should support depth 0 parameter', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/people/${TEST_PERSON_1_ID}?depth=0`,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const person = res.body.data.person;
|
||||
|
||||
expect(person).toBeDefined();
|
||||
expect(person.companyId).toBeDefined();
|
||||
expect(person.company).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should support depth 1 parameter', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/people/${TEST_PERSON_1_ID}?depth=1`,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const person = res.body.data.person;
|
||||
|
||||
expect(person.company).toBeDefined();
|
||||
expect(person.company.domainName.primaryLinkUrl).toBe(
|
||||
TEST_PRIMARY_LINK_URL,
|
||||
);
|
||||
expect(person.company.people).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should support depth 2 parameter', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'get',
|
||||
path: `/people/${TEST_PERSON_1_ID}?depth=2`,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const person = res.body.data.person;
|
||||
|
||||
expect(person.company.people).toBeDefined();
|
||||
|
||||
const depth2Person = person.company.people.find(
|
||||
(p) => p.id === person.id,
|
||||
);
|
||||
|
||||
expect(depth2Person).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,48 +1,59 @@
|
||||
import {
|
||||
NOT_EXISTING_PERSON_ID,
|
||||
PERSON_1_ID,
|
||||
} from 'test/integration/constants/mock-person-ids.constants';
|
||||
NOT_EXISTING_TEST_PERSON_ID,
|
||||
TEST_PERSON_1_ID,
|
||||
} from 'test/integration/constants/test-person-ids.constants';
|
||||
import { makeRestAPIRequest } from 'test/integration/rest/utils/make-rest-api-request.util';
|
||||
import { generateRecordName } from 'test/integration/utils/generate-record-name';
|
||||
import { deleteAllRecords } from 'test/integration/utils/delete-all-records';
|
||||
import { TEST_COMPANY_1_ID } from 'test/integration/constants/test-company-ids.constants';
|
||||
import { TEST_PRIMARY_LINK_URL } from 'test/integration/constants/test-primary-link-url.constant';
|
||||
|
||||
describe('Core REST API Update One endpoint', () => {
|
||||
const updatedData = {
|
||||
name: {
|
||||
firstName: 'Updated',
|
||||
lastName: 'Person',
|
||||
},
|
||||
emails: {
|
||||
primaryEmail: 'updated@example.com',
|
||||
additionalEmails: ['extra@example.com'],
|
||||
},
|
||||
city: generateRecordName(TEST_PERSON_1_ID),
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
await deleteAllRecords('person');
|
||||
await makeRestAPIRequest({
|
||||
method: 'delete',
|
||||
path: `/people/${PERSON_1_ID}`,
|
||||
method: 'post',
|
||||
path: '/companies',
|
||||
body: {
|
||||
id: TEST_COMPANY_1_ID,
|
||||
domainName: {
|
||||
primaryLinkUrl: TEST_PRIMARY_LINK_URL,
|
||||
},
|
||||
},
|
||||
});
|
||||
await makeRestAPIRequest({
|
||||
method: 'post',
|
||||
path: `/people`,
|
||||
body: {
|
||||
id: PERSON_1_ID,
|
||||
id: TEST_PERSON_1_ID,
|
||||
companyId: TEST_COMPANY_1_ID,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should update an existing person (name, emails, and city)', async () => {
|
||||
const updatedData = {
|
||||
name: {
|
||||
firstName: 'Updated',
|
||||
lastName: 'Person',
|
||||
},
|
||||
emails: {
|
||||
primaryEmail: 'updated@example.com',
|
||||
additionalEmails: ['extra@example.com'],
|
||||
},
|
||||
city: generateRecordName(PERSON_1_ID),
|
||||
};
|
||||
|
||||
await makeRestAPIRequest({
|
||||
method: 'patch',
|
||||
path: `/people/${PERSON_1_ID}`,
|
||||
path: `/people/${TEST_PERSON_1_ID}`,
|
||||
body: updatedData,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const updatedPerson = res.body.data.updatePerson;
|
||||
|
||||
expect(updatedPerson.id).toBe(PERSON_1_ID);
|
||||
expect(updatedPerson.id).toBe(TEST_PERSON_1_ID);
|
||||
expect(updatedPerson.name.firstName).toBe(updatedData.name.firstName);
|
||||
expect(updatedPerson.name.lastName).toBe(updatedData.name.lastName);
|
||||
expect(updatedPerson.emails.primaryEmail).toBe(
|
||||
@ -54,14 +65,67 @@ describe('Core REST API Update One endpoint', () => {
|
||||
expect(updatedPerson.city).toBe(updatedData.city);
|
||||
|
||||
expect(updatedPerson.jobTitle).toBe('');
|
||||
expect(updatedPerson.companyId).toBe(null);
|
||||
expect(updatedPerson.companyId).toBe(TEST_COMPANY_1_ID);
|
||||
});
|
||||
});
|
||||
|
||||
it('should support depth 0 parameter', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'patch',
|
||||
path: `/people/${TEST_PERSON_1_ID}?depth=0`,
|
||||
body: updatedData,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const updatedPerson = res.body.data.updatePerson;
|
||||
|
||||
expect(updatedPerson.companyId).toBeDefined();
|
||||
expect(updatedPerson.company).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should support depth 1 parameter', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'patch',
|
||||
path: `/people/${TEST_PERSON_1_ID}?depth=1`,
|
||||
body: updatedData,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const updatedPerson = res.body.data.updatePerson;
|
||||
|
||||
expect(updatedPerson.company).toBeDefined();
|
||||
expect(updatedPerson.company.domainName.primaryLinkUrl).toBe(
|
||||
TEST_PRIMARY_LINK_URL,
|
||||
);
|
||||
expect(updatedPerson.company.people).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should support depth 2 parameter', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'patch',
|
||||
path: `/people/${TEST_PERSON_1_ID}?depth=2`,
|
||||
body: updatedData,
|
||||
})
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const updatedPerson = res.body.data.updatePerson;
|
||||
|
||||
expect(updatedPerson.company.people).toBeDefined();
|
||||
|
||||
const depth2Person = updatedPerson.company.people.find(
|
||||
(p) => p.id === updatedPerson.id,
|
||||
);
|
||||
|
||||
expect(depth2Person).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a EntityNotFoundError when trying to update a non-existing person', async () => {
|
||||
await makeRestAPIRequest({
|
||||
method: 'patch',
|
||||
path: `/people/${NOT_EXISTING_PERSON_ID}`,
|
||||
path: `/people/${NOT_EXISTING_TEST_PERSON_ID}`,
|
||||
})
|
||||
.expect(400)
|
||||
.expect((res) => {
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
const TEST_SCHEMA_NAME = 'workspace_1wgvd1injqtife6y4rvfbu3h5';
|
||||
|
||||
export const deleteAllRecords = async (objectNameSingular: string) => {
|
||||
try {
|
||||
await global.testDataSource.query(
|
||||
`DELETE from "${TEST_SCHEMA_NAME}"."${objectNameSingular}"`,
|
||||
);
|
||||
} catch {
|
||||
/* empty */
|
||||
}
|
||||
};
|
||||
@ -1,6 +1,8 @@
|
||||
import { JestConfigWithTsJest } from 'ts-jest';
|
||||
import 'tsconfig-paths/register';
|
||||
|
||||
import { rawDataSource } from 'src/database/typeorm/raw/raw.datasource';
|
||||
|
||||
import { createApp } from './create-app';
|
||||
|
||||
export default async (_, projectConfig: JestConfigWithTsJest) => {
|
||||
@ -10,7 +12,10 @@ export default async (_, projectConfig: JestConfigWithTsJest) => {
|
||||
throw new Error('No globals found in project config');
|
||||
}
|
||||
|
||||
await rawDataSource.initialize();
|
||||
|
||||
await app.listen(projectConfig.globals.APP_PORT);
|
||||
|
||||
global.app = app;
|
||||
global.testDataSource = rawDataSource;
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'tsconfig-paths/register';
|
||||
|
||||
export default async () => {
|
||||
global.testDataSource.destroy();
|
||||
global.app.close();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user