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', () => {
|
||||
it('should support String', async () => {
|
||||
const someFieldValue = 'some string';
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import * as objectsMutations from './objectsMutations';
|
||||
import * as filesMutations from './filesMutations';
|
||||
import * as usersMutations from './usersMutations';
|
||||
import * as functionsMutations from './functionsMutations';
|
||||
|
||||
const load = parseGraphQLSchema => {
|
||||
objectsMutations.load(parseGraphQLSchema);
|
||||
filesMutations.load(parseGraphQLSchema);
|
||||
usersMutations.load(parseGraphQLSchema);
|
||||
functionsMutations.load(parseGraphQLSchema);
|
||||
};
|
||||
|
||||
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