* add parse-graph-ql configuration for class schema customisation Not yet tested - essentially an RFC * refactor and add graphql router, controller and config cache * fix(GraphQLController): add missing check isEnabled * chore(GraphQLController): remove awaits from cache put * chore(GraphQLController): remove check for if its enabled * refactor(GraphQLController): only use cache if mounted * chore(GraphQLController): group all validation errors and throw at once * chore(GraphQLSchema): move transformations into controller validation * refactor(GraphQL): improve ctrl validation and fix schema usage of config * refactor(GraphQLSchema): remove code related to additional schema This code has been moved into a separate feature branch. * fix(GraphQLSchema): fix incorrect default return type for class configs * refactor(GraphQLSchema): update staleness check code to account for config * fix(GraphQLServer): fix regressed tests due to internal schema changes This will be followed up with a backwards compatability fix for the `ClassFields` issue to avoid breakages for our users * refactor: rename to ParseGraphQLController for consistency * fix(ParseGraphQLCtrl): numerous fixes for validity checking Also includes some minor code refactoring * chore(GraphQL): minor syntax cleanup * fix(SchemaController): add _GraphQLConfig to volatile classes * refactor(ParseGraphQLServer): return update config value in setGraphQLConfig * testing(ParseGraphQL): add test cases for new graphQLConfig * fix(GraphQLController): fix issue where config with multiple items was not being mapped to the db * fix(postgres): add _GraphQLConfig default schema on load fixes failing postgres tests * GraphQL @mock directive (#5836) * Add mock directive * Include tests for @mock directive * Fix existing tests due to the change from ClassFields to ClassCreateFields * fix(parseClassMutations): safer type transformation based on input type * fix(parseClassMutations): only define necessary input fields * fix(GraphQL): fix incorrect import paths
974 lines
27 KiB
JavaScript
974 lines
27 KiB
JavaScript
const {
|
|
default: ParseGraphQLController,
|
|
GraphQLConfigClassName,
|
|
GraphQLConfigId,
|
|
GraphQLConfigKey,
|
|
} = require('../lib/Controllers/ParseGraphQLController');
|
|
const { isEqual } = require('lodash');
|
|
|
|
describe('ParseGraphQLController', () => {
|
|
let parseServer;
|
|
let databaseController;
|
|
let cacheController;
|
|
let databaseUpdateArgs;
|
|
|
|
// Holds the graphQLConfig in memory instead of using the db
|
|
let graphQLConfigRecord;
|
|
|
|
const setConfigOnDb = graphQLConfigData => {
|
|
graphQLConfigRecord = {
|
|
objectId: GraphQLConfigId,
|
|
[GraphQLConfigKey]: graphQLConfigData,
|
|
};
|
|
};
|
|
const removeConfigFromDb = () => {
|
|
graphQLConfigRecord = null;
|
|
};
|
|
const getConfigFromDb = () => {
|
|
return graphQLConfigRecord;
|
|
};
|
|
|
|
beforeAll(async () => {
|
|
parseServer = await global.reconfigureServer({
|
|
schemaCacheTTL: 100,
|
|
});
|
|
databaseController = parseServer.config.databaseController;
|
|
cacheController = parseServer.config.cacheController;
|
|
|
|
const defaultFind = databaseController.find.bind(databaseController);
|
|
databaseController.find = async (className, query, ...args) => {
|
|
if (
|
|
className === GraphQLConfigClassName &&
|
|
isEqual(query, { objectId: GraphQLConfigId })
|
|
) {
|
|
const graphQLConfigRecord = getConfigFromDb();
|
|
return graphQLConfigRecord ? [graphQLConfigRecord] : [];
|
|
} else {
|
|
return defaultFind(className, query, ...args);
|
|
}
|
|
};
|
|
|
|
const defaultUpdate = databaseController.update.bind(databaseController);
|
|
databaseController.update = async (
|
|
className,
|
|
query,
|
|
update,
|
|
fullQueryOptions
|
|
) => {
|
|
databaseUpdateArgs = [className, query, update, fullQueryOptions];
|
|
if (
|
|
className === GraphQLConfigClassName &&
|
|
isEqual(query, { objectId: GraphQLConfigId }) &&
|
|
update &&
|
|
!!update[GraphQLConfigKey] &&
|
|
fullQueryOptions &&
|
|
isEqual(fullQueryOptions, { upsert: true })
|
|
) {
|
|
setConfigOnDb(update[GraphQLConfigKey]);
|
|
} else {
|
|
return defaultUpdate(...databaseUpdateArgs);
|
|
}
|
|
};
|
|
});
|
|
|
|
beforeEach(() => {
|
|
databaseUpdateArgs = null;
|
|
});
|
|
|
|
describe('constructor', () => {
|
|
it('should require a databaseController', () => {
|
|
expect(() => new ParseGraphQLController()).toThrow(
|
|
'ParseGraphQLController requires a "databaseController" to be instantiated.'
|
|
);
|
|
expect(() => new ParseGraphQLController({ cacheController })).toThrow(
|
|
'ParseGraphQLController requires a "databaseController" to be instantiated.'
|
|
);
|
|
expect(
|
|
() =>
|
|
new ParseGraphQLController({
|
|
cacheController,
|
|
mountGraphQL: false,
|
|
})
|
|
).toThrow(
|
|
'ParseGraphQLController requires a "databaseController" to be instantiated.'
|
|
);
|
|
});
|
|
it('should construct without a cacheController', () => {
|
|
expect(
|
|
() =>
|
|
new ParseGraphQLController({
|
|
databaseController,
|
|
})
|
|
).not.toThrow();
|
|
expect(
|
|
() =>
|
|
new ParseGraphQLController({
|
|
databaseController,
|
|
mountGraphQL: true,
|
|
})
|
|
).not.toThrow();
|
|
});
|
|
it('should set isMounted to true if config.mountGraphQL is true', () => {
|
|
const mountedController = new ParseGraphQLController({
|
|
databaseController,
|
|
mountGraphQL: true,
|
|
});
|
|
expect(mountedController.isMounted).toBe(true);
|
|
const unmountedController = new ParseGraphQLController({
|
|
databaseController,
|
|
mountGraphQL: false,
|
|
});
|
|
expect(unmountedController.isMounted).toBe(false);
|
|
const unmountedController2 = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expect(unmountedController2.isMounted).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('getGraphQLConfig', () => {
|
|
it('should return an empty graphQLConfig if collection has none', async () => {
|
|
removeConfigFromDb();
|
|
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
mountGraphQL: false,
|
|
});
|
|
|
|
const graphQLConfig = await parseGraphQLController.getGraphQLConfig();
|
|
expect(graphQLConfig).toEqual({});
|
|
});
|
|
it('should return an existing graphQLConfig', async () => {
|
|
setConfigOnDb({ enabledForClasses: ['_User'] });
|
|
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
mountGraphQL: false,
|
|
});
|
|
const graphQLConfig = await parseGraphQLController.getGraphQLConfig();
|
|
expect(graphQLConfig).toEqual({ enabledForClasses: ['_User'] });
|
|
});
|
|
it('should use the cache if mounted, and return the stored graphQLConfig', async () => {
|
|
removeConfigFromDb();
|
|
cacheController.graphQL.clear();
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
cacheController,
|
|
mountGraphQL: true,
|
|
});
|
|
cacheController.graphQL.put(parseGraphQLController.configCacheKey, {
|
|
enabledForClasses: ['SuperCar'],
|
|
});
|
|
|
|
const graphQLConfig = await parseGraphQLController.getGraphQLConfig();
|
|
expect(graphQLConfig).toEqual({ enabledForClasses: ['SuperCar'] });
|
|
});
|
|
it('should use the database when mounted and cache is empty', async () => {
|
|
setConfigOnDb({ disabledForClasses: ['SuperCar'] });
|
|
cacheController.graphQL.clear();
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
cacheController,
|
|
mountGraphQL: true,
|
|
});
|
|
const graphQLConfig = await parseGraphQLController.getGraphQLConfig();
|
|
expect(graphQLConfig).toEqual({ disabledForClasses: ['SuperCar'] });
|
|
});
|
|
it('should store the graphQLConfig in cache if mounted', async () => {
|
|
setConfigOnDb({ enabledForClasses: ['SuperCar'] });
|
|
cacheController.graphQL.clear();
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
cacheController,
|
|
mountGraphQL: true,
|
|
});
|
|
const cachedValueBefore = await cacheController.graphQL.get(
|
|
parseGraphQLController.configCacheKey
|
|
);
|
|
expect(cachedValueBefore).toBeNull();
|
|
await parseGraphQLController.getGraphQLConfig();
|
|
const cachedValueAfter = await cacheController.graphQL.get(
|
|
parseGraphQLController.configCacheKey
|
|
);
|
|
expect(cachedValueAfter).toEqual({ enabledForClasses: ['SuperCar'] });
|
|
});
|
|
});
|
|
|
|
describe('updateGraphQLConfig', () => {
|
|
const successfulUpdateResponse = { response: { result: true } };
|
|
|
|
it('should throw if graphQLConfig is not provided', async function() {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig()
|
|
).toBeRejectedWith('You must provide a graphQLConfig!');
|
|
});
|
|
|
|
it('should correct update the graphQLConfig object using the databaseController', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
const graphQLConfig = {
|
|
enabledForClasses: ['ClassA', 'ClassB'],
|
|
disabledForClasses: [],
|
|
classConfigs: [
|
|
{ className: 'ClassA', query: { get: false } },
|
|
{ className: 'ClassB', mutation: { destroy: false }, type: {} },
|
|
],
|
|
};
|
|
|
|
await parseGraphQLController.updateGraphQLConfig(graphQLConfig);
|
|
|
|
expect(databaseUpdateArgs).toBeTruthy();
|
|
const [className, query, update, op] = databaseUpdateArgs;
|
|
expect(className).toBe(GraphQLConfigClassName);
|
|
expect(query).toEqual({ objectId: GraphQLConfigId });
|
|
expect(update).toEqual({
|
|
[GraphQLConfigKey]: graphQLConfig,
|
|
});
|
|
expect(op).toEqual({ upsert: true });
|
|
});
|
|
|
|
it('should throw if graphQLConfig is not an object', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig([])
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig(function() {})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig(Promise.resolve({}))
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig('')
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if graphQLConfig has an invalid root key', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({ invalidKey: true })
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if graphQLConfig has invalid class filters', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({ enabledForClasses: {} })
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
enabledForClasses: [undefined],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
disabledForClasses: [null],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
enabledForClasses: ['_User', null],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({ disabledForClasses: [''] })
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
enabledForClasses: [],
|
|
disabledForClasses: ['_User'],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if classConfigs array is invalid', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({ classConfigs: {} })
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({ classConfigs: [null] })
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [undefined],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [{ className: 'ValidClass' }, null],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({ classConfigs: [] })
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if a classConfig has invalid type settings', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: [],
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
invalidKey: true,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if a classConfig has invalid type.inputFields settings', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: 'SuperCar',
|
|
type: {
|
|
inputFields: [],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: 'SuperCar',
|
|
type: {
|
|
inputFields: {
|
|
invalidKey: true,
|
|
},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: 'SuperCar',
|
|
type: {
|
|
inputFields: {
|
|
create: {},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: 'SuperCar',
|
|
type: {
|
|
inputFields: {
|
|
update: [null],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: 'SuperCar',
|
|
type: {
|
|
inputFields: {
|
|
create: [],
|
|
update: [],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: 'SuperCar',
|
|
type: {
|
|
inputFields: {
|
|
create: ['make', 'model'],
|
|
update: [],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if a classConfig has invalid type.outputFields settings', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
outputFields: {},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
outputFields: [null],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
outputFields: ['name', undefined],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
outputFields: [''],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
outputFields: [],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
outputFields: ['name'],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if a classConfig has invalid type.constraintFields settings', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
constraintFields: {},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
constraintFields: [null],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
constraintFields: ['name', undefined],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
constraintFields: [''],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
constraintFields: [],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
constraintFields: ['name'],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if a classConfig has invalid type.sortFields settings', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
sortFields: {},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
sortFields: [null],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
sortFields: [
|
|
{
|
|
field: undefined,
|
|
asc: true,
|
|
desc: true,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
sortFields: [
|
|
{
|
|
field: '',
|
|
asc: true,
|
|
desc: false,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
sortFields: [
|
|
{
|
|
field: 'name',
|
|
asc: true,
|
|
desc: 'false',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
sortFields: [
|
|
{
|
|
field: 'name',
|
|
asc: true,
|
|
desc: true,
|
|
},
|
|
null,
|
|
],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
sortFields: [],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
sortFields: [
|
|
{
|
|
field: 'name',
|
|
asc: true,
|
|
desc: true,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if a classConfig has invalid query params', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
query: [],
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
query: {
|
|
invalidKey: true,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
query: {
|
|
get: 1,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
query: {
|
|
find: 'true',
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
query: {
|
|
get: false,
|
|
find: true,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
query: {},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
it('should throw if a classConfig has invalid mutation params', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
mutation: [],
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
mutation: {
|
|
invalidKey: true,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
mutation: {
|
|
destroy: 1,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
mutation: {
|
|
update: 'true',
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
mutation: {},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
mutation: {
|
|
create: true,
|
|
update: true,
|
|
destroy: false,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolvedTo(successfulUpdateResponse);
|
|
});
|
|
|
|
it('should throw if _User create fields is missing username or password', async () => {
|
|
const parseGraphQLController = new ParseGraphQLController({
|
|
databaseController,
|
|
});
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
inputFields: {
|
|
create: ['username', 'no-password'],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeRejected();
|
|
expectAsync(
|
|
parseGraphQLController.updateGraphQLConfig({
|
|
classConfigs: [
|
|
{
|
|
className: '_User',
|
|
type: {
|
|
inputFields: {
|
|
create: ['username', 'password'],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
})
|
|
).toBeResolved(successfulUpdateResponse);
|
|
});
|
|
it('should update the cache if mounted', async () => {
|
|
removeConfigFromDb();
|
|
cacheController.graphQL.clear();
|
|
const mountedController = new ParseGraphQLController({
|
|
databaseController,
|
|
cacheController,
|
|
mountGraphQL: true,
|
|
});
|
|
const unmountedController = new ParseGraphQLController({
|
|
databaseController,
|
|
cacheController,
|
|
mountGraphQL: false,
|
|
});
|
|
|
|
let cacheBeforeValue;
|
|
let cacheAfterValue;
|
|
|
|
cacheBeforeValue = await cacheController.graphQL.get(
|
|
mountedController.configCacheKey
|
|
);
|
|
expect(cacheBeforeValue).toBeNull();
|
|
|
|
await mountedController.updateGraphQLConfig({
|
|
enabledForClasses: ['SuperCar'],
|
|
});
|
|
cacheAfterValue = await cacheController.graphQL.get(
|
|
mountedController.configCacheKey
|
|
);
|
|
expect(cacheAfterValue).toEqual({ enabledForClasses: ['SuperCar'] });
|
|
|
|
// reset
|
|
removeConfigFromDb();
|
|
cacheController.graphQL.clear();
|
|
|
|
cacheBeforeValue = await cacheController.graphQL.get(
|
|
unmountedController.configCacheKey
|
|
);
|
|
expect(cacheBeforeValue).toBeNull();
|
|
|
|
await unmountedController.updateGraphQLConfig({
|
|
enabledForClasses: ['SuperCar'],
|
|
});
|
|
cacheAfterValue = await cacheController.graphQL.get(
|
|
unmountedController.configCacheKey
|
|
);
|
|
expect(cacheAfterValue).toBeNull();
|
|
});
|
|
});
|
|
});
|