From 26c1955b8a30f78cb7cab827735b1420fdc71899 Mon Sep 17 00:00:00 2001 From: Mick Hansen Date: Tue, 13 Oct 2015 11:58:57 +0200 Subject: [PATCH] support nested includes for nested connections --- src/generateIncludes.js | 27 ++++++++++++++++-------- test/relay.test.js | 46 ++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/generateIncludes.js b/src/generateIncludes.js index 9f08c796..886a30a7 100644 --- a/src/generateIncludes.js +++ b/src/generateIncludes.js @@ -14,13 +14,16 @@ export default function generateIncludes(simpleAST, type, root, options) { Object.keys(simpleAST.fields).forEach(function (key) { var association - , name = simpleAST.fields[key].key || key + , fieldAST = simpleAST.fields[key] + , name = fieldAST.key || key + , fieldType = type._fields[name] && type._fields[name].type , includeOptions - , args = simpleAST.fields[key].args + , args = fieldAST.args , includeResolver = type._fields[name].resolve , nestedResult , allowedAttributes - , include; + , include + , connectionFields = []; if (!includeResolver) return; @@ -30,10 +33,15 @@ export default function generateIncludes(simpleAST, type, root, options) { } } + if (isConnection(fieldType)) { + fieldAST = fieldAST.fields.edges.fields.node; + fieldType = fieldType._fields.edges.type.ofType._fields.node.type; + } + if (includeResolver.$passthrough) { var dummyResult = generateIncludes( - simpleAST.fields[key], - type._fields[key].type, + fieldAST, + fieldType, root, options ); @@ -53,7 +61,7 @@ export default function generateIncludes(simpleAST, type, root, options) { if (includeResolver.$before) { includeOptions = includeResolver.$before(includeOptions, args, root, { - ast: simpleAST.fields[key], + ast: fieldAST, type: type }); } @@ -80,14 +88,15 @@ export default function generateIncludes(simpleAST, type, root, options) { } includeOptions.attributes = (includeOptions.attributes || []) - .concat(Object.keys(simpleAST.fields[key].fields)) + .concat(Object.keys(fieldAST.fields)) + .concat(connectionFields) .filter(inList.bind(null, allowedAttributes)); includeOptions.attributes.push(association.target.primaryKeyAttribute); nestedResult = generateIncludes( - simpleAST.fields[key], - type._fields[key].type, + fieldAST, + fieldType, root, includeResolver.$options ); diff --git a/test/relay.test.js b/test/relay.test.js index 0fb359c9..301620e9 100644 --- a/test/relay.test.js +++ b/test/relay.test.js @@ -7,6 +7,7 @@ var chai = require('chai') , sequelize = helper.sequelize , Sequelize = require('sequelize') , Promise = helper.Promise + , sinon = require('sinon') , attributeFields = require('../src/attributeFields'); import { @@ -148,7 +149,7 @@ describe('relay', function () { } }), interfaces: [nodeInterface] -}); + }); nodeTypeMapper.mapTypes({ @@ -416,26 +417,24 @@ describe('relay', function () { } } } - `) - .then(function (result) { - return graphql(schema, ` - { - user(id: ${user.id}) { - name - tasks(last: 1, before: "${result.data.user.tasks.pageInfo.endCursor}") { - edges { - node { - name - } + `).then(function (result) { + return graphql(schema, ` + { + user(id: ${user.id}) { + name + tasks(last: 1, before: "${result.data.user.tasks.pageInfo.endCursor}") { + edges { + node { + name } } } } - `) - }) - .then(function (result) { - expect(result.data.user.tasks.edges[0].node.name).to.equal(user.tasks[1].name); - }); + } + `) + }).then(function (result) { + expect(result.data.user.tasks.edges[0].node.name).to.equal(user.tasks[1].name); + }); }); it('should resolve a plain result with a single connection', function () { @@ -507,7 +506,8 @@ describe('relay', function () { }); it('should resolve nested connections', function () { - var project = this.project; + var project = this.project + , sqlSpy = sinon.spy(); return graphql(schema, ` { @@ -528,17 +528,25 @@ describe('relay', function () { } } } - `).then(result => { + `, { + logging: sqlSpy + }).then(result => { if (result.errors) throw new Error(result.errors[0].stack); expect(result.data.project.users.edges).to.have.length(2); let [nodeA, nodeB] = result.data.project.users.edges; let userA = nodeA.node; let userB = nodeB.node; + expect(userA).to.have.property('tasks'); expect(userA.tasks.edges).to.have.length.above(0); + expect(userA.tasks.edges[0].node.name).to.be.ok; + expect(userB).to.have.property('tasks'); expect(userB.tasks.edges).to.have.length.above(0); + expect(userB.tasks.edges[0].node.name).to.be.ok; + + expect(sqlSpy).to.have.been.calledOnce; }); });