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:
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
`),
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user