diff --git a/src/__tests__/composeWithMongooseDiscriminators-test.js b/src/__tests__/composeWithMongooseDiscriminators-test.js index 8d3e2363..55e3b171 100644 --- a/src/__tests__/composeWithMongooseDiscriminators-test.js +++ b/src/__tests__/composeWithMongooseDiscriminators-test.js @@ -56,5 +56,21 @@ describe('composeWithMongooseDiscriminators ->', () => { expect(itc.isRequired('name')).toBe(true); expect(itc.isRequired('friends')).toBe(true); }); + + it('should be passed down record opts to resolvers', () => { + const typeComposer = composeWithMongooseDiscriminators(CharacterModel, { + resolvers: { + createOne: { + record: { + removeFields: ['friends'], + requiredFields: ['name'], + }, + }, + }, + }); + const createOneRecordArgTC = typeComposer.getResolver('createOne').getArgTC('record'); + expect(createOneRecordArgTC.isRequired('name')).toBe(true); + expect(createOneRecordArgTC.hasField('friends')).toBe(false); + }); }); }); diff --git a/src/discriminators/__tests__/DiscriminatorTypeComposer-test.js b/src/discriminators/__tests__/DiscriminatorTypeComposer-test.js index 907d7b92..6b471fd1 100644 --- a/src/discriminators/__tests__/DiscriminatorTypeComposer-test.js +++ b/src/discriminators/__tests__/DiscriminatorTypeComposer-test.js @@ -1,6 +1,12 @@ /* @flow */ -import { schemaComposer, graphql, TypeComposer, InterfaceTypeComposer } from 'graphql-compose'; +import { + SchemaComposer, + schemaComposer, + graphql, + TypeComposer, + InterfaceTypeComposer, +} from 'graphql-compose'; import { getCharacterModels } from '../__mocks__/characterModels'; import { MovieModel } from '../__mocks__/movieModel'; import { composeWithMongoose } from '../../composeWithMongoose'; @@ -498,5 +504,31 @@ describe('DiscriminatorTypeComposer', () => { expect(tc.getFieldNames()).not.toEqual(expect.arrayContaining(['dob', 'starShips'])); }); + + it('should pass down baseTypeComposerResolverOptions', () => { + const personTC = composeWithMongooseDiscriminators(CharacterModel, { + schemaComposer: new SchemaComposer(), + resolvers: { + createOne: { + record: { + removeFields: ['friends'], + requiredFields: ['name'], + }, + }, + }, + }).discriminator(PersonModel, { + resolvers: { + createOne: { + record: { + requiredFields: ['dob'], + }, + }, + }, + }); + const createOneRecordArgTC = personTC.getResolver('createOne').getArgTC('record'); + expect(createOneRecordArgTC.isRequired('name')).toBe(true); + expect(createOneRecordArgTC.isRequired('dob')).toBe(true); + expect(createOneRecordArgTC.hasField('friends')).toBe(false); + }); }); }); diff --git a/src/discriminators/__tests__/prepareChildResolvers-test.js b/src/discriminators/__tests__/prepareChildResolvers-test.js new file mode 100644 index 00000000..147dc92e --- /dev/null +++ b/src/discriminators/__tests__/prepareChildResolvers-test.js @@ -0,0 +1,37 @@ +/* @flow */ + +import { schemaComposer } from 'graphql-compose'; +import { getCharacterModels } from '../__mocks__/characterModels'; +import { composeWithMongooseDiscriminators } from '../../composeWithMongooseDiscriminators'; + +const { CharacterModel, PersonModel } = getCharacterModels('type'); + +describe('prepareChildResolvers()', () => { + describe('copyResolverArgTypes()', () => { + afterAll(() => { + schemaComposer.clear(); + }); + // Note childResolver Arg fields are copied from baseResolver + const baseDTC = composeWithMongooseDiscriminators(CharacterModel, { + resolvers: { + createOne: { + requiredFields: ['kind'], + }, + }, + }); + const PersonTC = baseDTC.discriminator(PersonModel); + + it('should copy base common ResolverArgTypes to child', () => { + expect( + baseDTC + .getResolver('createOne') + .getArgTC('record') + .getFieldType('kind') + ).toEqual( + PersonTC.getResolver('createOne') + .getArgTC('record') + .getFieldType('kind') + ); + }); + }); +}); diff --git a/src/discriminators/prepareChildResolvers.js b/src/discriminators/prepareChildResolvers.js index 992db0e2..ac1e43a4 100644 --- a/src/discriminators/prepareChildResolvers.js +++ b/src/discriminators/prepareChildResolvers.js @@ -59,30 +59,32 @@ function hideDKey( } } -// makes sure that all input fields are same as that on Interface, -// that is all should be same as base typeComposer types -// only changes for common properties, executed only once, on discriminator creation -function setBaseInputTypesOnChildInputTypes( +// Set baseDTC resolver argTypes on childTC fields shared with DInterface +function copyResolverArgTypes( resolver: ResolverClass, baseDTC: DiscriminatorTypeComposer, - fromField: string[] | string + fromArg: string[] | string ) { - // set sharedField types on input types if (resolver && baseDTC.hasInputTypeComposer()) { - if (Array.isArray(fromField)) { - for (const field of fromField) { - setBaseInputTypesOnChildInputTypes(resolver, baseDTC, field); + if (Array.isArray(fromArg)) { + for (const field of fromArg) { + copyResolverArgTypes(resolver, baseDTC, field); } - } else if (fromField && resolver.hasArg(fromField)) { - const argTc = resolver.getArgTC(fromField); - - const baseITCFields = baseDTC.getInputTypeComposer().getFieldNames(); - - for (const baseField of baseITCFields) { - if (argTc.hasField(baseField) && baseField !== '_id') { - argTc.extendField(baseField, { - type: baseDTC.getInputTypeComposer().getFieldType(baseField), - }); + } else if (fromArg && resolver.hasArg(fromArg)) { + if ( + baseDTC.hasResolver(resolver.name) && + baseDTC.getResolver(resolver.name).hasArg(fromArg) + ) { + const childResolverArgTc = resolver.getArgTC(fromArg); + const baseResolverArgTC = baseDTC.getResolver(resolver.name).getArgTC(fromArg); + const baseResolverArgTCFields = baseResolverArgTC.getFieldNames(); + + for (const baseArgField of baseResolverArgTCFields) { + if (childResolverArgTc.hasField(baseArgField) && baseArgField !== '_id') { + childResolverArgTc.extendField(baseArgField, { + type: baseResolverArgTC.getFieldType(baseArgField), + }); + } } } } @@ -167,7 +169,7 @@ export function prepareChildResolvers( default: } - setBaseInputTypesOnChildInputTypes(resolver, baseDTC, ['filter', 'record']); + copyResolverArgTypes(resolver, baseDTC, ['filter', 'record']); reorderFieldsRecordFilter(resolver, baseDTC, opts.reorderFields, ['filter', 'record']); } } diff --git a/src/discriminators/utils/__tests__/mergeCustomizationOptions-test.js b/src/discriminators/utils/__tests__/mergeCustomizationOptions-test.js index a611829c..f886bded 100644 --- a/src/discriminators/utils/__tests__/mergeCustomizationOptions-test.js +++ b/src/discriminators/utils/__tests__/mergeCustomizationOptions-test.js @@ -147,6 +147,12 @@ describe('mergeCustomizationOptions()', () => { removeFields: ['parent', 'child'], }, }, + updateById: { + record: { + removeFields: ['one', 'two'], + requiredFields: ['eight'], + }, + }, findMany: { limit: { defaultValue: 20 }, // sort: false, @@ -191,9 +197,9 @@ describe('mergeCustomizationOptions()', () => { }, }, updateById: { - input: { - removeFields: ['one', 'two', 'five'], - requiredFields: ['eight', 'two', 'five'], + record: { + removeFields: ['five'], + requiredFields: ['two', 'five'], }, }, }, @@ -228,7 +234,7 @@ describe('mergeCustomizationOptions()', () => { }, findById: false, updateById: { - input: { + record: { removeFields: ['one', 'two', 'five'], requiredFields: ['eight', 'two', 'five'], }, @@ -236,6 +242,16 @@ describe('mergeCustomizationOptions()', () => { }, }; + it('should return most base options if no child', () => { + expect((mergeCustomizationOptions(baseCustomOptions): any).resolvers).toEqual( + baseCustomOptions.resolvers + ); + }); + + it('should return child if no base is found', () => { + expect(mergeCustomizationOptions({}, childCustomOptions)).toEqual(childCustomOptions); + }); + it('should merge customisation Options', () => { expect(mergeCustomizationOptions(baseCustomOptions, childCustomOptions)).toEqual(expected); });