feat: refactor schema builder and resolver builder (#2215)

* feat: wip refactor schema builder

* feat: wip store types and first queries generation

* feat: refactor schema-builder and resolver-builder

* fix: clean & small type fix

* fix: avoid breaking change

* fix: remove util from pg-graphql classes

* fix: required default fields

* Refactor frontend accordingly

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Jérémy M
2023-11-03 17:16:37 +01:00
committed by GitHub
parent aba3fd454b
commit 1ed4965a95
216 changed files with 3215 additions and 2028 deletions

View File

@ -0,0 +1,233 @@
import { GraphQLResolveInfo } from 'graphql';
import { FieldMetadataTargetColumnMap } from 'src/metadata/field-metadata/interfaces/field-metadata-target-column-map.interface';
import { FieldMetadata } from 'src/metadata/field-metadata/field-metadata.entity';
import {
PGGraphQLQueryBuilder,
PGGraphQLQueryBuilderOptions,
} from 'src/tenant/resolver-builder/pg-graphql/pg-graphql-query-builder';
const testUUID = '123e4567-e89b-12d3-a456-426614174001';
const normalizeWhitespace = (str) => str.replace(/\s+/g, '');
// Mocking dependencies
jest.mock('uuid', () => ({
v4: jest.fn(() => testUUID),
}));
jest.mock('graphql-fields', () =>
jest.fn(() => ({
name: true,
age: true,
complexField: {
subField1: true,
subField2: true,
},
})),
);
describe('PGGraphQLQueryBuilder', () => {
let queryBuilder;
let mockOptions: PGGraphQLQueryBuilderOptions;
beforeEach(() => {
const fieldMetadataCollection = [
{
name: 'name',
targetColumnMap: {
value: 'column_name',
} as FieldMetadataTargetColumnMap,
},
{
name: 'age',
targetColumnMap: {
value: 'column_age',
} as FieldMetadataTargetColumnMap,
},
{
name: 'complexField',
targetColumnMap: {
subField1: 'column_subField1',
subField2: 'column_subField2',
} as FieldMetadataTargetColumnMap,
},
] as FieldMetadata[];
mockOptions = {
targetTableName: 'TestTable',
info: {} as GraphQLResolveInfo,
fieldMetadataCollection,
};
queryBuilder = new PGGraphQLQueryBuilder(mockOptions);
});
test('findMany generates correct query with no arguments', () => {
const query = queryBuilder.findMany();
expect(normalizeWhitespace(query)).toBe(
normalizeWhitespace(`
query {
TestTableCollection {
name: column_name
age: column_age
___complexField_subField1: column_subField1
___complexField_subField2: column_subField2
}
}
`),
);
});
test('findMany generates correct query with filter parameters', () => {
const args = {
filter: {
name: { eq: 'Alice' },
age: { gt: 20 },
},
};
const query = queryBuilder.findMany(args);
expect(normalizeWhitespace(query)).toBe(
normalizeWhitespace(`
query {
TestTableCollection(filter: { column_name: { eq: "Alice" }, column_age: { gt: 20 } }) {
name: column_name
age: column_age
___complexField_subField1: column_subField1
___complexField_subField2: column_subField2
}
}
`),
);
});
test('findMany generates correct query with combined pagination parameters', () => {
const args = {
first: 5,
after: 'someCursor',
before: 'anotherCursor',
last: 3,
};
const query = queryBuilder.findMany(args);
expect(normalizeWhitespace(query)).toBe(
normalizeWhitespace(`
query {
TestTableCollection(
first: 5,
after: "someCursor",
before: "anotherCursor",
last: 3
) {
name: column_name
age: column_age
___complexField_subField1: column_subField1
___complexField_subField2: column_subField2
}
}
`),
);
});
test('findOne generates correct query with ID filter', () => {
const args = { filter: { id: { eq: testUUID } } };
const query = queryBuilder.findOne(args);
expect(normalizeWhitespace(query)).toBe(
normalizeWhitespace(`
query {
TestTableCollection(filter: { id: { eq: "${testUUID}" } }) {
edges {
node {
name: column_name
age: column_age
___complexField_subField1: column_subField1
___complexField_subField2: column_subField2
}
}
}
}
`),
);
});
test('createMany generates correct mutation with complex and nested fields', () => {
const args = {
data: [
{
name: 'Alice',
age: 30,
complexField: {
subField1: 'data1',
subField2: 'data2',
},
},
],
};
const query = queryBuilder.createMany(args);
expect(normalizeWhitespace(query)).toBe(
normalizeWhitespace(`
mutation {
insertIntoTestTableCollection(objects: [{
id: "${testUUID}",
column_name: "Alice",
column_age: 30,
column_subField1: "data1",
column_subField2: "data2"
}]) {
affectedCount
records {
name: column_name
age: column_age
___complexField_subField1: column_subField1
___complexField_subField2: column_subField2
}
}
}
`),
);
});
test('updateOne generates correct mutation with complex and nested fields', () => {
const args = {
id: '1',
data: {
name: 'Bob',
age: 40,
complexField: {
subField1: 'newData1',
subField2: 'newData2',
},
},
};
const query = queryBuilder.updateOne(args);
expect(normalizeWhitespace(query)).toBe(
normalizeWhitespace(`
mutation {
updateTestTableCollection(
set: {
column_name: "Bob",
column_age: 40,
column_subField1: "newData1",
column_subField2: "newData2"
},
filter: { id: { eq: "1" } }
) {
affectedCount
records {
name: column_name
age: column_age
___complexField_subField1: column_subField1
___complexField_subField2: column_subField2
}
}
}
`),
);
});
});