Skip to content

Commit 85ef721

Browse files
authored
feat: alphabetical graphql api, fix internal reassign, enhanced Graphql schema cache system (#7344)
1 parent 90b18bc commit 85ef721

10 files changed

+220
-78
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ ___
108108
- ci: add node engine version check (Manuel Trezza) [#7574](https://github.com/parse-community/parse-server/pull/7574)
109109

110110
### Notable Changes
111+
- Alphabetical ordered GraphQL API, improved GraphQL Schema cache system and fix GraphQL input reassign issue (Moumouls) [#7344](https://github.com/parse-community/parse-server/issues/7344)
111112
- Added Parse Server Security Check to report weak security settings (Manuel Trezza, dblythy) [#7247](https://github.com/parse-community/parse-server/issues/7247)
112113
- EXPERIMENTAL: Added new page router with placeholder rendering and localization of custom and feature pages such as password reset and email verification (Manuel Trezza) [#7128](https://github.com/parse-community/parse-server/pull/7128)
113114
- EXPERIMENTAL: Added custom routes to easily customize flows for password reset, email verification or build entirely new flows (Manuel Trezza) [#7231](https://github.com/parse-community/parse-server/pull/7231)

spec/ParseGraphQLSchema.spec.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ describe('ParseGraphQLSchema', () => {
5757
it('should load a brand new GraphQL Schema if Parse Schema changes', async () => {
5858
await parseGraphQLSchema.load();
5959
const parseClasses = parseGraphQLSchema.parseClasses;
60-
const parseClassesString = parseGraphQLSchema.parseClassesString;
60+
const parseCachedClasses = parseGraphQLSchema.parseCachedClasses;
6161
const parseClassTypes = parseGraphQLSchema.parseClassTypes;
6262
const graphQLSchema = parseGraphQLSchema.graphQLSchema;
6363
const graphQLTypes = parseGraphQLSchema.graphQLTypes;
@@ -70,7 +70,7 @@ describe('ParseGraphQLSchema', () => {
7070
await new Promise(resolve => setTimeout(resolve, 200));
7171
await parseGraphQLSchema.load();
7272
expect(parseClasses).not.toBe(parseGraphQLSchema.parseClasses);
73-
expect(parseClassesString).not.toBe(parseGraphQLSchema.parseClassesString);
73+
expect(parseCachedClasses).not.toBe(parseGraphQLSchema.parseCachedClasses);
7474
expect(parseClassTypes).not.toBe(parseGraphQLSchema.parseClassTypes);
7575
expect(graphQLSchema).not.toBe(parseGraphQLSchema.graphQLSchema);
7676
expect(graphQLTypes).not.toBe(parseGraphQLSchema.graphQLTypes);
@@ -94,7 +94,7 @@ describe('ParseGraphQLSchema', () => {
9494
});
9595
await parseGraphQLSchema.load();
9696
const parseClasses = parseGraphQLSchema.parseClasses;
97-
const parseClassesString = parseGraphQLSchema.parseClassesString;
97+
const parseCachedClasses = parseGraphQLSchema.parseCachedClasses;
9898
const parseClassTypes = parseGraphQLSchema.parseClassTypes;
9999
const graphQLSchema = parseGraphQLSchema.graphQLSchema;
100100
const graphQLTypes = parseGraphQLSchema.graphQLTypes;
@@ -109,7 +109,7 @@ describe('ParseGraphQLSchema', () => {
109109
await new Promise(resolve => setTimeout(resolve, 200));
110110
await parseGraphQLSchema.load();
111111
expect(parseClasses).not.toBe(parseGraphQLSchema.parseClasses);
112-
expect(parseClassesString).not.toBe(parseGraphQLSchema.parseClassesString);
112+
expect(parseCachedClasses).not.toBe(parseGraphQLSchema.parseCachedClasses);
113113
expect(parseClassTypes).not.toBe(parseGraphQLSchema.parseClassTypes);
114114
expect(graphQLSchema).not.toBe(parseGraphQLSchema.graphQLSchema);
115115
expect(graphQLTypes).not.toBe(parseGraphQLSchema.graphQLTypes);

spec/ParseGraphQLServer.spec.js

+94
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const {
2525
GraphQLEnumType,
2626
GraphQLInputObjectType,
2727
GraphQLSchema,
28+
GraphQLList,
2829
} = require('graphql');
2930
const { ParseServer } = require('../');
3031
const { ParseGraphQLServer } = require('../lib/GraphQL/ParseGraphQLServer');
@@ -10341,6 +10342,18 @@ describe('ParseGraphQLServer', () => {
1034110342
robot: { value: 'robot' },
1034210343
},
1034310344
});
10345+
const TypeEnumWhereInput = new GraphQLInputObjectType({
10346+
name: 'TypeEnumWhereInput',
10347+
fields: {
10348+
equalTo: { type: TypeEnum },
10349+
},
10350+
});
10351+
const SomeClass2WhereInput = new GraphQLInputObjectType({
10352+
name: 'SomeClass2WhereInput',
10353+
fields: {
10354+
type: { type: TypeEnumWhereInput },
10355+
},
10356+
});
1034410357
const SomeClassType = new GraphQLObjectType({
1034510358
name: 'SomeClass',
1034610359
fields: {
@@ -10386,6 +10399,18 @@ describe('ParseGraphQLServer', () => {
1038610399
return obj.toJSON();
1038710400
},
1038810401
},
10402+
customQueryWithAutoTypeReturnList: {
10403+
type: new GraphQLList(SomeClassType),
10404+
args: {
10405+
id: { type: new GraphQLNonNull(GraphQLString) },
10406+
},
10407+
resolve: async (p, { id }) => {
10408+
const obj = new Parse.Object('SomeClass');
10409+
obj.id = id;
10410+
await obj.fetch();
10411+
return [obj.toJSON(), obj.toJSON(), obj.toJSON()];
10412+
},
10413+
},
1038910414
},
1039010415
}),
1039110416
types: [
@@ -10401,7 +10426,17 @@ describe('ParseGraphQLServer', () => {
1040110426
type: { type: TypeEnum },
1040210427
},
1040310428
}),
10429+
// Enhanced where input with a extended enum
10430+
new GraphQLInputObjectType({
10431+
name: 'SomeClassWhereInput',
10432+
fields: {
10433+
type: {
10434+
type: TypeEnumWhereInput,
10435+
},
10436+
},
10437+
}),
1040410438
SomeClassType,
10439+
SomeClass2WhereInput,
1040510440
],
1040610441
}),
1040710442
});
@@ -10463,6 +10498,65 @@ describe('ParseGraphQLServer', () => {
1046310498
expect(result.data.customQueryWithAutoTypeReturn.type).toEqual('robot');
1046410499
});
1046510500

10501+
it('can resolve a custom query with auto type list return', async () => {
10502+
const obj = new Parse.Object('SomeClass');
10503+
await obj.save({ name: 'aname', type: 'robot' });
10504+
await parseGraphQLServer.parseGraphQLSchema.schemaCache.clear();
10505+
const result = await apolloClient.query({
10506+
variables: { id: obj.id },
10507+
query: gql`
10508+
query CustomQuery($id: String!) {
10509+
customQueryWithAutoTypeReturnList(id: $id) {
10510+
id
10511+
objectId
10512+
nameUpperCase
10513+
name
10514+
type
10515+
}
10516+
}
10517+
`,
10518+
});
10519+
result.data.customQueryWithAutoTypeReturnList.forEach(rObj => {
10520+
expect(rObj.objectId).toBeDefined();
10521+
expect(rObj.objectId).toEqual(obj.id);
10522+
expect(rObj.name).toEqual('aname');
10523+
expect(rObj.nameUpperCase).toEqual('ANAME');
10524+
expect(rObj.type).toEqual('robot');
10525+
});
10526+
});
10527+
10528+
it('can resolve a stacked query with same where variables on overloaded where input', async () => {
10529+
const objPointer = new Parse.Object('SomeClass2');
10530+
await objPointer.save({ name: 'aname', type: 'robot' });
10531+
const obj = new Parse.Object('SomeClass');
10532+
await obj.save({ name: 'aname', type: 'robot', pointer: objPointer });
10533+
await parseGraphQLServer.parseGraphQLSchema.schemaCache.clear();
10534+
const result = await apolloClient.query({
10535+
variables: { where: { OR: [{ pointer: { have: { objectId: { exists: true } } } }] } },
10536+
query: gql`
10537+
query someQuery($where: SomeClassWhereInput!) {
10538+
q1: someClasses(where: $where) {
10539+
edges {
10540+
node {
10541+
id
10542+
}
10543+
}
10544+
}
10545+
q2: someClasses(where: $where) {
10546+
edges {
10547+
node {
10548+
id
10549+
}
10550+
}
10551+
}
10552+
}
10553+
`,
10554+
});
10555+
expect(result.data.q1.edges.length).toEqual(1);
10556+
expect(result.data.q2.edges.length).toEqual(1);
10557+
expect(result.data.q1.edges[0].node.id).toEqual(result.data.q2.edges[0].node.id);
10558+
});
10559+
1046610560
it('can resolve a custom extend type', async () => {
1046710561
const obj = new Parse.Object('SomeClass');
1046810562
await obj.save({ name: 'aname', type: 'robot' });

0 commit comments

Comments
 (0)