UNPKG

graphql-compose-mongoose

Version:

Plugin for `graphql-compose` which derive a graphql types from a mongoose model.

223 lines (209 loc) 9.4 kB
"use strict"; var _mongoose = _interopRequireDefault(require("mongoose")); var _graphqlCompose = require("graphql-compose"); var _graphql = require("graphql-compose/lib/graphql"); var _userModel = require("../__mocks__/userModel"); var _composeWithMongoose = require("../composeWithMongoose"); var _mongoid = _interopRequireDefault(require("../types/mongoid")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* eslint-disable no-unused-expressions */ beforeAll(() => _userModel.UserModel.base.connect()); afterAll(() => _userModel.UserModel.base.disconnect()); describe('composeWithMongoose ->', () => { beforeEach(() => { _graphqlCompose.schemaComposer.clear(); }); describe('MongooseModelToTypeComposer()', () => { describe('basics', () => { it('should return ObjectTypeComposer', () => { expect((0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel)).toBeInstanceOf(_graphqlCompose.ObjectTypeComposer); expect((0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { name: 'Ok' })).toBeInstanceOf(_graphqlCompose.ObjectTypeComposer); }); it('should set type name from model or opts.name', () => { expect((0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel).getTypeName()).toBe(_userModel.UserModel.modelName); _graphqlCompose.schemaComposer.clear(); expect((0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { name: 'Ok' }).getTypeName()).toBe('Ok'); }); it('should set description from opts.description', () => { const description = 'This is model from mongoose'; expect((0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { description }).getDescription()).toBe(description); }); it('should get fields from mongoose model', () => { const tc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel); expect(tc.getFieldNames()).toEqual(expect.arrayContaining(['_id', 'name', 'gender', 'age'])); }); it('should have NonNull _id field', () => { const tc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel); expect(tc.getFieldType('_id')).toBeInstanceOf(_graphql.GraphQLNonNull); expect(tc.getFieldType('_id').ofType).toBe(_mongoid.default); }); it('composeWithMongoose should generate new ObjectTypeComposer (without cache)', () => { const tc1 = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel); _graphqlCompose.schemaComposer.clear(); const tc2 = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel); expect(tc1).not.toBe(tc2); }); }); describe('filterFields()', () => { it('should proceed opts.fields.remove', () => { const tc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { fields: { remove: ['name', 'gender'] } }); expect(tc.getFieldNames()).not.toEqual(expect.arrayContaining(['name', 'gender'])); expect(tc.getFieldNames()).toEqual(expect.arrayContaining(['_id', 'age'])); }); it('should proceed opts.fields.only', () => { const tc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { fields: { only: ['name', 'gender'] } }); expect(tc.getFieldNames()).toEqual(expect.arrayContaining(['name', 'gender'])); }); }); describe('createInputType()', () => { it('should be availiable InputTypeComposer', () => { const itc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel).getInputTypeComposer(); expect(itc).toBeInstanceOf(_graphqlCompose.InputTypeComposer); }); it('should set type name opts.inputType.name', () => { const itc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { inputType: { name: 'GreatUserInput' } }).getInputTypeComposer(); expect(itc.getTypeName()).toBe('GreatUserInput'); }); it('should set description from opts.inputType.name', () => { const itc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { inputType: { description: 'type for input data' } }).getInputTypeComposer(); expect(itc.getDescription()).toBe('type for input data'); }); it('should proceed opts.inputType.fields.remove', () => { const itc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { inputType: { fields: { remove: ['name', 'gender'] } } }).getInputTypeComposer(); expect(itc.getFieldNames()).not.toEqual(expect.arrayContaining(['name', 'gender'])); expect(itc.getFieldNames()).toEqual(expect.arrayContaining(['_id', 'age'])); }); it('should proceed opts.inputType.fields.only', () => { const itc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { inputType: { fields: { only: ['name', 'gender'] } } }).getInputTypeComposer(); expect(itc.getFieldNames()).toEqual(expect.arrayContaining(['name', 'gender'])); }); it('should proceed opts.inputType.fields.required', () => { const itc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { inputType: { fields: { required: ['name', 'gender'] } } }).getInputTypeComposer(); expect(itc.isFieldNonNull('name')).toBe(true); expect(itc.isFieldNonNull('gender')).toBe(true); expect(itc.isFieldNonNull('age')).toBe(false); }); }); describe('createResolvers()', () => { it('should not be called if opts.resolvers === false', () => { const tc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { resolvers: false }); expect(Array.from(tc.getResolvers().keys())).toHaveLength(0); }); it('should be called if opts.resolvers not exists or has value', () => { const tc = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel); expect(Array.from(tc.getResolvers().keys())).not.toHaveLength(0); const tc2 = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { resolvers: {} }); expect(Array.from(tc2.getResolvers().keys())).not.toHaveLength(0); }); it('should not provide resolver if opts.resolvers.[resolverName] === false', () => { const tc2 = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { resolvers: { removeById: false, findMany: {}, updateOne: { some: 123 } } }); const resolverKeys = Array.from(tc2.getResolvers().keys()); expect(resolverKeys).not.toContain('removeById'); expect(resolverKeys).toEqual(expect.arrayContaining(['findMany', 'updateOne', 'updateMany'])); }); }); }); describe('3rd party resolvers', () => { describe('graphql-compose-connection', () => { it('should add `connection` resolver by default', () => { const tc2 = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel); expect(tc2.getResolver('connection')).toBeDefined(); }); }); describe('graphql-compose-pagination', () => { it('should add `pagination` resolver by default', () => { const tc2 = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel); expect(tc2.getResolver('pagination')).toBeDefined(); }); it('should add `pagination` resolver with `perPage` option', () => { const tc2 = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { resolvers: { pagination: { perPage: 333 } } }); const resolver = tc2.getResolver('pagination'); expect(resolver).toBeDefined(); expect(resolver.getArgConfig('perPage').defaultValue).toBe(333); }); }); }); describe('complex situations', () => { it('required input fields, should be passed down to resolvers', () => { const typeComposer = (0, _composeWithMongoose.composeWithMongoose)(_userModel.UserModel, { inputType: { fields: { required: ['age'] } } }); const filterArgInFindOne = typeComposer.getResolver('findOne').getArgITC('filter'); expect(filterArgInFindOne.isFieldNonNull('age')).toBe(true); }); it('should use cached type to avoid maximum call stack size exceeded', () => { const PersonSchema = new _mongoose.default.Schema({ name: String }); PersonSchema.add({ spouse: PersonSchema, friends: [PersonSchema] }); const PersonModel = _mongoose.default.model('Person', PersonSchema); const tc = (0, _composeWithMongoose.composeWithMongoose)(PersonModel); expect(tc.getFieldNames()).toEqual(expect.arrayContaining(['_id', 'name', 'spouse', 'friends'])); }); }); });