GraphQL { functions { call } } generic mutation (#5818)
* Generic call function mutation * Change function return type to any * First passing test * Testing errors * Testing different data types
This commit is contained in:
committed by
Douglas Muraoka
parent
6be15331a6
commit
0b86a86209
@@ -3372,6 +3372,149 @@ describe('ParseGraphQLServer', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Functions Mutations', () => {
|
||||||
|
it('can be called', async () => {
|
||||||
|
Parse.Cloud.define('hello', async () => {
|
||||||
|
return 'Hello world!';
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await apolloClient.mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation CallFunction {
|
||||||
|
functions {
|
||||||
|
call(functionName: "hello")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.data.functions.call).toEqual('Hello world!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can throw errors', async () => {
|
||||||
|
Parse.Cloud.define('hello', async () => {
|
||||||
|
throw new Error('Some error message.');
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await apolloClient.mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation CallFunction {
|
||||||
|
functions {
|
||||||
|
call(functionName: "hello")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
fail('Should throw an error');
|
||||||
|
} catch (e) {
|
||||||
|
const { graphQLErrors } = e;
|
||||||
|
expect(graphQLErrors.length).toBe(1);
|
||||||
|
expect(graphQLErrors[0].message).toBe('Some error message.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should accept different params', done => {
|
||||||
|
Parse.Cloud.define('hello', async req => {
|
||||||
|
expect(req.params.date instanceof Date).toBe(true);
|
||||||
|
expect(req.params.date.getTime()).toBe(1463907600000);
|
||||||
|
expect(req.params.dateList[0] instanceof Date).toBe(true);
|
||||||
|
expect(req.params.dateList[0].getTime()).toBe(1463907600000);
|
||||||
|
expect(req.params.complexStructure.date[0] instanceof Date).toBe(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(req.params.complexStructure.date[0].getTime()).toBe(
|
||||||
|
1463907600000
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
req.params.complexStructure.deepDate.date[0] instanceof Date
|
||||||
|
).toBe(true);
|
||||||
|
expect(req.params.complexStructure.deepDate.date[0].getTime()).toBe(
|
||||||
|
1463907600000
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
req.params.complexStructure.deepDate2[0].date instanceof Date
|
||||||
|
).toBe(true);
|
||||||
|
expect(
|
||||||
|
req.params.complexStructure.deepDate2[0].date.getTime()
|
||||||
|
).toBe(1463907600000);
|
||||||
|
// Regression for #2294
|
||||||
|
expect(req.params.file instanceof Parse.File).toBe(true);
|
||||||
|
expect(req.params.file.url()).toEqual('https://some.url');
|
||||||
|
// Regression for #2204
|
||||||
|
expect(req.params.array).toEqual(['a', 'b', 'c']);
|
||||||
|
expect(Array.isArray(req.params.array)).toBe(true);
|
||||||
|
expect(req.params.arrayOfArray).toEqual([
|
||||||
|
['a', 'b', 'c'],
|
||||||
|
['d', 'e', 'f'],
|
||||||
|
]);
|
||||||
|
expect(Array.isArray(req.params.arrayOfArray)).toBe(true);
|
||||||
|
expect(Array.isArray(req.params.arrayOfArray[0])).toBe(true);
|
||||||
|
expect(Array.isArray(req.params.arrayOfArray[1])).toBe(true);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
date: {
|
||||||
|
__type: 'Date',
|
||||||
|
iso: '2016-05-22T09:00:00.000Z',
|
||||||
|
},
|
||||||
|
dateList: [
|
||||||
|
{
|
||||||
|
__type: 'Date',
|
||||||
|
iso: '2016-05-22T09:00:00.000Z',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
lol: 'hello',
|
||||||
|
complexStructure: {
|
||||||
|
date: [
|
||||||
|
{
|
||||||
|
__type: 'Date',
|
||||||
|
iso: '2016-05-22T09:00:00.000Z',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
deepDate: {
|
||||||
|
date: [
|
||||||
|
{
|
||||||
|
__type: 'Date',
|
||||||
|
iso: '2016-05-22T09:00:00.000Z',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
deepDate2: [
|
||||||
|
{
|
||||||
|
date: {
|
||||||
|
__type: 'Date',
|
||||||
|
iso: '2016-05-22T09:00:00.000Z',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
file: Parse.File.fromJSON({
|
||||||
|
__type: 'File',
|
||||||
|
name: 'name',
|
||||||
|
url: 'https://some.url',
|
||||||
|
}),
|
||||||
|
array: ['a', 'b', 'c'],
|
||||||
|
arrayOfArray: [['a', 'b', 'c'], ['d', 'e', 'f']],
|
||||||
|
};
|
||||||
|
|
||||||
|
apolloClient.mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation CallFunction($params: Object) {
|
||||||
|
functions {
|
||||||
|
call(functionName: "hello", params: $params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: {
|
||||||
|
params,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Data Types', () => {
|
describe('Data Types', () => {
|
||||||
it('should support String', async () => {
|
it('should support String', async () => {
|
||||||
const someFieldValue = 'some string';
|
const someFieldValue = 'some string';
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import * as objectsMutations from './objectsMutations';
|
import * as objectsMutations from './objectsMutations';
|
||||||
import * as filesMutations from './filesMutations';
|
import * as filesMutations from './filesMutations';
|
||||||
import * as usersMutations from './usersMutations';
|
import * as usersMutations from './usersMutations';
|
||||||
|
import * as functionsMutations from './functionsMutations';
|
||||||
|
|
||||||
const load = parseGraphQLSchema => {
|
const load = parseGraphQLSchema => {
|
||||||
objectsMutations.load(parseGraphQLSchema);
|
objectsMutations.load(parseGraphQLSchema);
|
||||||
filesMutations.load(parseGraphQLSchema);
|
filesMutations.load(parseGraphQLSchema);
|
||||||
usersMutations.load(parseGraphQLSchema);
|
usersMutations.load(parseGraphQLSchema);
|
||||||
|
functionsMutations.load(parseGraphQLSchema);
|
||||||
};
|
};
|
||||||
|
|
||||||
export { load };
|
export { load };
|
||||||
|
|||||||
57
src/GraphQL/loaders/functionsMutations.js
Normal file
57
src/GraphQL/loaders/functionsMutations.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { GraphQLObjectType, GraphQLNonNull, GraphQLString } from 'graphql';
|
||||||
|
import { FunctionsRouter } from '../../Routers/FunctionsRouter';
|
||||||
|
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
||||||
|
|
||||||
|
const load = parseGraphQLSchema => {
|
||||||
|
const fields = {};
|
||||||
|
|
||||||
|
fields.call = {
|
||||||
|
description:
|
||||||
|
'The call mutation can be used to invoke a cloud code function.',
|
||||||
|
args: {
|
||||||
|
functionName: {
|
||||||
|
description: 'This is the name of the function to be called.',
|
||||||
|
type: new GraphQLNonNull(GraphQLString),
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
description: 'These are the params to be passed to the function.',
|
||||||
|
type: defaultGraphQLTypes.OBJECT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: defaultGraphQLTypes.ANY,
|
||||||
|
async resolve(_source, args, context) {
|
||||||
|
try {
|
||||||
|
const { functionName, params } = args;
|
||||||
|
const { config, auth, info } = context;
|
||||||
|
|
||||||
|
return (await FunctionsRouter.handleCloudFunction({
|
||||||
|
params: {
|
||||||
|
functionName,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
auth,
|
||||||
|
info,
|
||||||
|
body: params,
|
||||||
|
})).response.result;
|
||||||
|
} catch (e) {
|
||||||
|
parseGraphQLSchema.handleError(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const functionsMutation = new GraphQLObjectType({
|
||||||
|
name: 'FunctionsMutation',
|
||||||
|
description:
|
||||||
|
'FunctionsMutation is the top level type for functions mutations.',
|
||||||
|
fields,
|
||||||
|
});
|
||||||
|
parseGraphQLSchema.graphQLTypes.push(functionsMutation);
|
||||||
|
|
||||||
|
parseGraphQLSchema.graphQLMutations.functions = {
|
||||||
|
description: 'This is the top level for functions mutations.',
|
||||||
|
type: functionsMutation,
|
||||||
|
resolve: () => new Object(),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export { load };
|
||||||
Reference in New Issue
Block a user