From 23acd1e3f9eb3535faf4ffd1ee8d7214f554c4b4 Mon Sep 17 00:00:00 2001 From: hennessyevan Date: Wed, 23 Oct 2019 10:53:55 -0400 Subject: [PATCH] fix: set path to fieldName for resolver(#19) --- jest/common/parent.model.ts | 6 +-- jest/common/simple.model.ts | 4 +- jest/tc-multiple.ts | 85 +++++++++++++++++++++++++++++++++++++ src/populate.spec.ts | 43 +++++++++++++++++++ src/registry.ts | 9 ++-- 5 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 jest/tc-multiple.ts diff --git a/jest/common/parent.model.ts b/jest/common/parent.model.ts index e086947..b559f0b 100644 --- a/jest/common/parent.model.ts +++ b/jest/common/parent.model.ts @@ -1,8 +1,8 @@ import { Connection, Document, Model, Schema } from 'mongoose'; -export function getParentModel(connection: Connection, child: Model) { +export function getParentModel(connection: Connection, child: Model, _name?: string) { - const name = 'ParentModel'; + const name = _name || 'ParentModel'; if (connection.modelNames().includes(name)) return connection.model(name); const ParentSchema = new Schema({ @@ -12,5 +12,5 @@ export function getParentModel(connection: Connection, child: Model) { } }); - return connection.model('ParentModel', ParentSchema); + return connection.model(name, ParentSchema); } diff --git a/jest/common/simple.model.ts b/jest/common/simple.model.ts index 5b961da..ae58745 100644 --- a/jest/common/simple.model.ts +++ b/jest/common/simple.model.ts @@ -1,8 +1,8 @@ import { Connection, Schema } from 'mongoose'; -export function getSimpleModel(connection: Connection) { +export function getSimpleModel(connection: Connection, _name?: string) { - const name = 'SimpleModel'; + const name = _name || 'SimpleModel'; if (connection.modelNames().includes(name)) return connection.model(name); const SimpleSchema = new Schema({ diff --git a/jest/tc-multiple.ts b/jest/tc-multiple.ts new file mode 100644 index 0000000..2c4c3c4 --- /dev/null +++ b/jest/tc-multiple.ts @@ -0,0 +1,85 @@ +import { GraphQLObjectType, GraphQLSchema } from 'graphql'; +import { Connection, Document, Model, models } from 'mongoose'; +import { getParentModel } from './common/parent.model'; +import { getSimpleModel } from './common/simple.model'; +import { simpleResponse } from './common/simple.response'; +import { SimpleType } from './common/simple.type'; +import { TestCase } from './tc'; + +interface MultipleTestCase extends Omit { + firstModel: Model + secondModel: Model + firstParentModelName:string + secondParentModelName:string + firstChildModelName:string + secondChildModelName:string +} + +/** + * A Ref Test Case. + * + * @param connection Mongoose Connection + * @returns Test Case + */ +export function multipleCase(connection: Connection): MultipleTestCase { + + const firstSimpleModel = getSimpleModel(connection, 'first'); + const firstChildModelName = firstSimpleModel.modelName; + const firstModel = getParentModel(connection, firstSimpleModel, 'FirstParent'); + const firstParentModelName = firstModel.modelName; + + const secondSimpleModel = getSimpleModel(connection, 'second'); + const secondChildModelName = secondSimpleModel.modelName; + const secondModel = getParentModel(connection, secondSimpleModel, 'SecondParent'); + const secondParentModelName = secondModel.modelName; + + const response = { + child: { ...simpleResponse } + }; + + const FirstType: GraphQLObjectType = new GraphQLObjectType({ + name: 'FirstType', + fields: () => ({ + child: { + type: SimpleType + } + }) + }); + + const SecondType: GraphQLObjectType = new GraphQLObjectType({ + name: 'SecondType', + fields: () => ({ + child: { + type: SimpleType + } + }) + }); + + const schema = new GraphQLSchema({ + query: new GraphQLObjectType({ + name: 'MultipleQueries', + fields: () => ({ + first: { + type: FirstType, + resolve: () => response + }, + second: { + type: SecondType, + resolve: () => response + } + }) + }) + }); + + + return { + firstModel, + secondModel, + response, + schema, + firstParentModelName, + secondParentModelName, + firstChildModelName, + secondChildModelName + }; +} diff --git a/src/populate.spec.ts b/src/populate.spec.ts index 7e52339..509d007 100644 --- a/src/populate.spec.ts +++ b/src/populate.spec.ts @@ -5,6 +5,7 @@ import { refCase } from '../jest/tc-ref'; import { refSelected } from '../jest/tc-ref-selected'; import { inlineFragmentRefCase } from '../jest/ts-inline-fragment-ref'; import { Registry } from './registry'; +import { multipleCase } from '../jest/tc-multiple'; describe('populate', () => { @@ -75,6 +76,48 @@ describe('populate', () => { expect(population).toEqual([{ path: 'child', populate: [], select: ['id', 'foo', 'bar'] }]); }); + it('should handle multiple GraphQL Fields', async () => { + + const tc = multipleCase(connection); + let firstpopulation: ModelPopulateOptions[]; + let secondpopulation: ModelPopulateOptions[]; + + const server = mockServer(tc.schema, { + FirstType: (...args) => { + const info = args[args.length - 1]; + firstpopulation = registry.populate(info, tc.firstModel.modelName); + return tc.response; + }, + SecondType: (...args) => { + const info = args[args.length - 1]; + secondpopulation = registry.populate(info, tc.secondModel.modelName); + return tc.response; + } + }); + + await server.query(` + query multiple { + first { + child { + foo + } + } + second { + child { + bar + } + } + } + `); + + expect(firstpopulation).toEqual([ + { path: 'child', populate: [], select: ['id', 'foo'] } + ]); + expect(secondpopulation).toEqual([ + { path: 'child', populate: [], select: ['id', 'bar'] } + ]); + }); + it('should handle complex GraphQL Fields', async () => { const tc = complexRefCase(connection); diff --git a/src/registry.ts b/src/registry.ts index 992ed21..dff9921 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -111,9 +111,12 @@ export class Registry { */ private _getSelections(info: GraphQLResolveInfo, root: string) { - const operationSelection: SelectionSetNode = - (info.operation.selectionSet.selections[0] as FieldNode) - .selectionSet as SelectionSetNode; + const operationSelection: SelectionSetNode = root + ? ((info.operation.selectionSet.selections[0] as FieldNode) + .selectionSet as SelectionSetNode) + : ((info.operation.selectionSet.selections.find( + selection => (selection as FieldNode).name.value === info.fieldName + ) as FieldNode).selectionSet as SelectionSetNode); return this._getSelectionsOffsetByPath( operationSelection,