Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: alphabetical GraphQL API, improved GraphQL Schema cache system and fix internal reassign #7344

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ ___
- ci: add node engine version check (Manuel Trezza) [#7574](https://github.com/parse-community/parse-server/pull/7574)

### Notable Changes
- 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)
- Added Parse Server Security Check to report weak security settings (Manuel Trezza, dblythy) [#7247](https://github.com/parse-community/parse-server/issues/7247)
- 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)
- 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)
Expand Down
8 changes: 4 additions & 4 deletions spec/ParseGraphQLSchema.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('ParseGraphQLSchema', () => {
it('should load a brand new GraphQL Schema if Parse Schema changes', async () => {
await parseGraphQLSchema.load();
const parseClasses = parseGraphQLSchema.parseClasses;
const parseClassesString = parseGraphQLSchema.parseClassesString;
const parseCachedClasses = parseGraphQLSchema.parseCachedClasses;
const parseClassTypes = parseGraphQLSchema.parseClassTypes;
const graphQLSchema = parseGraphQLSchema.graphQLSchema;
const graphQLTypes = parseGraphQLSchema.graphQLTypes;
Expand All @@ -70,7 +70,7 @@ describe('ParseGraphQLSchema', () => {
await new Promise(resolve => setTimeout(resolve, 200));
await parseGraphQLSchema.load();
expect(parseClasses).not.toBe(parseGraphQLSchema.parseClasses);
expect(parseClassesString).not.toBe(parseGraphQLSchema.parseClassesString);
expect(parseCachedClasses).not.toBe(parseGraphQLSchema.parseCachedClasses);
expect(parseClassTypes).not.toBe(parseGraphQLSchema.parseClassTypes);
expect(graphQLSchema).not.toBe(parseGraphQLSchema.graphQLSchema);
expect(graphQLTypes).not.toBe(parseGraphQLSchema.graphQLTypes);
Expand All @@ -94,7 +94,7 @@ describe('ParseGraphQLSchema', () => {
});
await parseGraphQLSchema.load();
const parseClasses = parseGraphQLSchema.parseClasses;
const parseClassesString = parseGraphQLSchema.parseClassesString;
const parseCachedClasses = parseGraphQLSchema.parseCachedClasses;
const parseClassTypes = parseGraphQLSchema.parseClassTypes;
const graphQLSchema = parseGraphQLSchema.graphQLSchema;
const graphQLTypes = parseGraphQLSchema.graphQLTypes;
Expand All @@ -109,7 +109,7 @@ describe('ParseGraphQLSchema', () => {
await new Promise(resolve => setTimeout(resolve, 200));
await parseGraphQLSchema.load();
expect(parseClasses).not.toBe(parseGraphQLSchema.parseClasses);
expect(parseClassesString).not.toBe(parseGraphQLSchema.parseClassesString);
expect(parseCachedClasses).not.toBe(parseGraphQLSchema.parseCachedClasses);
expect(parseClassTypes).not.toBe(parseGraphQLSchema.parseClassTypes);
expect(graphQLSchema).not.toBe(parseGraphQLSchema.graphQLSchema);
expect(graphQLTypes).not.toBe(parseGraphQLSchema.graphQLTypes);
Expand Down
94 changes: 94 additions & 0 deletions spec/ParseGraphQLServer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const {
GraphQLEnumType,
GraphQLInputObjectType,
GraphQLSchema,
GraphQLList,
} = require('graphql');
const { ParseServer } = require('../');
const { ParseGraphQLServer } = require('../lib/GraphQL/ParseGraphQLServer');
Expand Down Expand Up @@ -10341,6 +10342,18 @@ describe('ParseGraphQLServer', () => {
robot: { value: 'robot' },
},
});
const TypeEnumWhereInput = new GraphQLInputObjectType({
name: 'TypeEnumWhereInput',
fields: {
equalTo: { type: TypeEnum },
},
});
const SomeClass2WhereInput = new GraphQLInputObjectType({
name: 'SomeClass2WhereInput',
fields: {
type: { type: TypeEnumWhereInput },
},
});
const SomeClassType = new GraphQLObjectType({
name: 'SomeClass',
fields: {
Expand Down Expand Up @@ -10386,6 +10399,18 @@ describe('ParseGraphQLServer', () => {
return obj.toJSON();
},
},
customQueryWithAutoTypeReturnList: {
type: new GraphQLList(SomeClassType),
args: {
id: { type: new GraphQLNonNull(GraphQLString) },
},
resolve: async (p, { id }) => {
const obj = new Parse.Object('SomeClass');
obj.id = id;
await obj.fetch();
return [obj.toJSON(), obj.toJSON(), obj.toJSON()];
},
},
},
}),
types: [
Expand All @@ -10401,7 +10426,17 @@ describe('ParseGraphQLServer', () => {
type: { type: TypeEnum },
},
}),
// Enhanced where input with a extended enum
new GraphQLInputObjectType({
name: 'SomeClassWhereInput',
fields: {
type: {
type: TypeEnumWhereInput,
},
},
}),
SomeClassType,
SomeClass2WhereInput,
],
}),
});
Expand Down Expand Up @@ -10463,6 +10498,65 @@ describe('ParseGraphQLServer', () => {
expect(result.data.customQueryWithAutoTypeReturn.type).toEqual('robot');
});

it('can resolve a custom query with auto type list return', async () => {
const obj = new Parse.Object('SomeClass');
await obj.save({ name: 'aname', type: 'robot' });
await parseGraphQLServer.parseGraphQLSchema.schemaCache.clear();
const result = await apolloClient.query({
variables: { id: obj.id },
query: gql`
query CustomQuery($id: String!) {
customQueryWithAutoTypeReturnList(id: $id) {
id
objectId
nameUpperCase
name
type
}
}
`,
});
result.data.customQueryWithAutoTypeReturnList.forEach(rObj => {
expect(rObj.objectId).toBeDefined();
expect(rObj.objectId).toEqual(obj.id);
expect(rObj.name).toEqual('aname');
expect(rObj.nameUpperCase).toEqual('ANAME');
expect(rObj.type).toEqual('robot');
});
});

it('can resolve a stacked query with same where variables on overloaded where input', async () => {
const objPointer = new Parse.Object('SomeClass2');
await objPointer.save({ name: 'aname', type: 'robot' });
const obj = new Parse.Object('SomeClass');
await obj.save({ name: 'aname', type: 'robot', pointer: objPointer });
await parseGraphQLServer.parseGraphQLSchema.schemaCache.clear();
const result = await apolloClient.query({
variables: { where: { OR: [{ pointer: { have: { objectId: { exists: true } } } }] } },
query: gql`
query someQuery($where: SomeClassWhereInput!) {
q1: someClasses(where: $where) {
edges {
node {
id
}
}
}
q2: someClasses(where: $where) {
edges {
node {
id
}
}
}
}
`,
});
expect(result.data.q1.edges.length).toEqual(1);
expect(result.data.q2.edges.length).toEqual(1);
expect(result.data.q1.edges[0].node.id).toEqual(result.data.q2.edges[0].node.id);
});

it('can resolve a custom extend type', async () => {
const obj = new Parse.Object('SomeClass');
await obj.save({ name: 'aname', type: 'robot' });
Expand Down
Loading