diff --git a/spec/ParseGraphQLController.spec.js b/spec/ParseGraphQLController.spec.js index c7d7ccf9ff..2d214c2fb6 100644 --- a/spec/ParseGraphQLController.spec.js +++ b/spec/ParseGraphQLController.spec.js @@ -970,4 +970,102 @@ describe('ParseGraphQLController', () => { expect(cacheAfterValue).toBeNull(); }); }); + + describe('alias', () => { + it('should fail if query alias is not a string', async () => { + const parseGraphQLController = new ParseGraphQLController({ + databaseController, + }); + + const className = 'Bar'; + + expectAsync( + parseGraphQLController.updateGraphQLConfig({ + classConfigs: [ + { + className, + query: { + get: true, + getAlias: 1, + }, + }, + ], + }) + ).toBeRejected( + `Invalid graphQLConfig: classConfig:${className} is invalid because "query.getAlias" must be a string` + ); + + expectAsync( + parseGraphQLController.updateGraphQLConfig({ + classConfigs: [ + { + className, + query: { + find: true, + findAlias: { not: 'valid' }, + }, + }, + ], + }) + ).toBeRejected( + `Invalid graphQLConfig: classConfig:${className} is invalid because "query.findAlias" must be a string` + ); + }); + + it('should fail if mutation alias is not a string', async () => { + const parseGraphQLController = new ParseGraphQLController({ + databaseController, + }); + + const className = 'Bar'; + + expectAsync( + parseGraphQLController.updateGraphQLConfig({ + classConfigs: [ + { + className, + mutation: { + create: true, + createAlias: true, + }, + }, + ], + }) + ).toBeRejected( + `Invalid graphQLConfig: classConfig:${className} is invalid because "mutation.createAlias" must be a string` + ); + + expectAsync( + parseGraphQLController.updateGraphQLConfig({ + classConfigs: [ + { + className, + mutation: { + update: true, + updateAlias: 1, + }, + }, + ], + }) + ).toBeRejected( + `Invalid graphQLConfig: classConfig:${className} is invalid because "mutation.updateAlias" must be a string` + ); + + expectAsync( + parseGraphQLController.updateGraphQLConfig({ + classConfigs: [ + { + className, + mutation: { + destroy: true, + destroyAlias: { not: 'valid' }, + }, + }, + ], + }) + ).toBeRejected( + `Invalid graphQLConfig: classConfig:${className} is invalid because "mutation.destroyAlias" must be a string` + ); + }); + }); }); diff --git a/spec/ParseGraphQLSchema.spec.js b/spec/ParseGraphQLSchema.spec.js index 82391e06e5..3b368b57b4 100644 --- a/spec/ParseGraphQLSchema.spec.js +++ b/spec/ParseGraphQLSchema.spec.js @@ -564,9 +564,8 @@ describe('ParseGraphQLSchema', () => { ).toEqual(Object.keys(mutations2).sort()); }); }); - - describe('query alias', () => { - it('Should be able to define alias for find query', async () => { + describe('alias', () => { + it('Should be able to define alias for get and find query', async () => { const parseGraphQLSchema = new ParseGraphQLSchema({ databaseController, parseGraphQLController, @@ -601,7 +600,7 @@ describe('ParseGraphQLSchema', () => { expect(Object.keys(queries1)).toContain('precious_data'); }); - it('should fail if query alias is not a string', async () => { + it('Should be able to define alias for mutation', async () => { const parseGraphQLSchema = new ParseGraphQLSchema({ databaseController, parseGraphQLController, @@ -609,57 +608,34 @@ describe('ParseGraphQLSchema', () => { appId, }); - const classConfigsBoolFindAlias = { + await parseGraphQLSchema.parseGraphQLController.updateGraphQLConfig({ classConfigs: [ { - className: 'Data', - query: { - get: true, - getAlias: 'valid', - find: true, - findAlias: true, + className: 'Track', + mutation: { + create: true, + createAlias: 'addTrack', + update: true, + updateAlias: 'modifyTrack', + destroy: true, + destroyAlias: 'eraseTrack', }, }, ], - }; + }); - const classConfigsNumberGetAlias = { - classConfigs: [ - { - className: 'Pants', - query: { - get: true, - getAlias: 1, - find: true, - findAlias: 'valid', - }, - }, - ], - }; + const data = new Parse.Object('Track'); + + await data.save(); + + await parseGraphQLSchema.databaseController.schemaCache.clear(); + await parseGraphQLSchema.load(); + + const mutations = parseGraphQLSchema.graphQLMutations; - let className; - - className = classConfigsBoolFindAlias.classConfigs[0].className; - try { - await parseGraphQLSchema.parseGraphQLController.updateGraphQLConfig( - classConfigsBoolFindAlias - ); - } catch (e) { - expect(e).toMatch( - `Invalid graphQLConfig: classConfig:${className} is invalid because "query.findAlias" must be a string` - ); - } - - className = classConfigsNumberGetAlias.classConfigs[0].className; - try { - await parseGraphQLSchema.parseGraphQLController.updateGraphQLConfig( - classConfigsNumberGetAlias - ); - } catch (e) { - expect(e).toMatch( - `Invalid graphQLConfig: classConfig:${className} is invalid because "query.getAlias" must be a string` - ); - } + expect(Object.keys(mutations)).toContain('addTrack'); + expect(Object.keys(mutations)).toContain('modifyTrack'); + expect(Object.keys(mutations)).toContain('eraseTrack'); }); }); }); diff --git a/src/Controllers/ParseGraphQLController.js b/src/Controllers/ParseGraphQLController.js index a348dc9b37..35919d8dd9 100644 --- a/src/Controllers/ParseGraphQLController.js +++ b/src/Controllers/ParseGraphQLController.js @@ -296,6 +296,9 @@ class ParseGraphQLController { create = null, update = null, destroy = null, + createAlias = null, + updateAlias = null, + destroyAlias = null, ...invalidKeys } = mutation; if (Object.keys(invalidKeys).length) { @@ -312,6 +315,15 @@ class ParseGraphQLController { if (destroy !== null && typeof destroy !== 'boolean') { return `"mutation.destroy" must be a boolean`; } + if (createAlias !== null && typeof createAlias !== 'string') { + return `"mutation.createAlias" must be a string`; + } + if (updateAlias !== null && typeof updateAlias !== 'string') { + return `"mutation.updateAlias" must be a string`; + } + if (destroyAlias !== null && typeof destroyAlias !== 'string') { + return `"mutation.destroyAlias" must be a string`; + } } else { return `"mutation" must be a valid object`; } @@ -380,6 +392,9 @@ export interface ParseGraphQLClassConfig { update: ?boolean, // delete is a reserved key word in js destroy: ?boolean, + createAlias: ?String, + updateAlias: ?String, + destroyAlias: ?String, }; } diff --git a/src/GraphQL/loaders/parseClassMutations.js b/src/GraphQL/loaders/parseClassMutations.js index 13294b1175..3ca333a0db 100644 --- a/src/GraphQL/loaders/parseClassMutations.js +++ b/src/GraphQL/loaders/parseClassMutations.js @@ -51,6 +51,9 @@ const load = function( create: isCreateEnabled = true, update: isUpdateEnabled = true, destroy: isDestroyEnabled = true, + createAlias: createAlias = '', + updateAlias: updateAlias = '', + destroyAlias: destroyAlias = '', } = getParseClassMutationConfig(parseClassConfig); const { @@ -60,7 +63,8 @@ const load = function( } = parseGraphQLSchema.parseClassTypes[className]; if (isCreateEnabled) { - const createGraphQLMutationName = `create${graphQLClassName}`; + const createGraphQLMutationName = + createAlias || `create${graphQLClassName}`; const createGraphQLMutation = mutationWithClientMutationId({ name: `Create${graphQLClassName}`, description: `The ${createGraphQLMutationName} mutation can be used to create a new object of the ${graphQLClassName} class.`, @@ -150,7 +154,8 @@ const load = function( } if (isUpdateEnabled) { - const updateGraphQLMutationName = `update${graphQLClassName}`; + const updateGraphQLMutationName = + updateAlias || `update${graphQLClassName}`; const updateGraphQLMutation = mutationWithClientMutationId({ name: `Update${graphQLClassName}`, description: `The ${updateGraphQLMutationName} mutation can be used to update an object of the ${graphQLClassName} class.`, @@ -250,7 +255,8 @@ const load = function( } if (isDestroyEnabled) { - const deleteGraphQLMutationName = `delete${graphQLClassName}`; + const deleteGraphQLMutationName = + destroyAlias || `delete${graphQLClassName}`; const deleteGraphQLMutation = mutationWithClientMutationId({ name: `Delete${graphQLClassName}`, description: `The ${deleteGraphQLMutationName} mutation can be used to delete an object of the ${graphQLClassName} class.`,