Skip to content
This repository has been archived by the owner on Apr 15, 2020. It is now read-only.

Commit

Permalink
[fix] allow renaming of subscription root fields
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacovCR committed Dec 31, 2019
1 parent 65ba644 commit 210e8aa
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -14,6 +14,10 @@
[@freiksenet](https://github.com/freiksenet) in [#1003](https://github.com/apollographql/graphql-tools/pull/1003)
* Allow user-provided `buildSchema` options. <br/>
[@trevor-scheer](https://github.com/trevor-scheer) in [#1154](https://github.com/apollographql/graphql-tools/pull/1154)
* Fix `delegateToSchema` to allow delegation to subscriptions with different root field names, allows
the use of the `RenameRootFields` transform with subscriptions,
pull request [#1104](https://github.com/apollographql/graphql-tools/pull/1104), fixes
[#997](https://github.com/apollographql/graphql-tools/issues/997). <br/>

### 4.0.4

Expand Down
7 changes: 3 additions & 4 deletions src/stitching/delegateToSchema.ts
Expand Up @@ -125,12 +125,11 @@ async function delegateToSchemaImplementation(
// "subscribe" to the subscription result and map the result through the transforms
return mapAsyncIterator<ExecutionResult, any>(executionResult, result => {
const transformedResult = applyResultTransforms(result, transforms);
const subscriptionKey = Object.keys(result.data)[0];

// for some reason the returned transformedResult needs to be nested inside the root subscription field
// does not work otherwise...
// wrap with fieldName to return for an additional round of resolutioon
// with payload as rootValue
return {
[subscriptionKey]: transformedResult,
[info.fieldName]: transformedResult,
};
});
}
Expand Down
64 changes: 62 additions & 2 deletions src/test/testAlternateMergeSchemas.ts
@@ -1,15 +1,28 @@
/* tslint:disable:no-unused-expression */

import { expect } from 'chai';
import { graphql, GraphQLSchema } from 'graphql';
import {
graphql,
GraphQLSchema,
ExecutionResult,
subscribe,
parse,
} from 'graphql';
import mergeSchemas from '../stitching/mergeSchemas';
import {
transformSchema,
FilterRootFields,
RenameTypes,
RenameRootFields,
} from '../transforms';
import { propertySchema, bookingSchema } from './testingSchemas';
import {
propertySchema,
bookingSchema,
subscriptionSchema,
subscriptionPubSub,
subscriptionPubSubTrigger,
} from './testingSchemas';
import { forAwaitEach } from 'iterall';

let linkSchema = `
"""
Expand Down Expand Up @@ -78,11 +91,23 @@ describe('merge schemas through transforms', () => {
(operation: string, name: string) => `Bookings_${name}`,
),
]);
const transformedSubscriptionSchema = transformSchema(subscriptionSchema, [
new FilterRootFields(
(operation: string, rootField: string) =>
// must include a Query type otherwise graphql will error
'Query.notifications' === `${operation}.${rootField}` ||
'Subscription.notifications' === `${operation}.${rootField}`,
),
new RenameTypes((name: string) => `Subscriptions_${name}`),
new RenameRootFields(
(operation: string, name: string) => `Subscriptions_${name}`),
]);

mergedSchema = mergeSchemas({
schemas: [
transformedPropertySchema,
transformedBookingSchema,
transformedSubscriptionSchema,
linkSchema,
],
resolvers: {
Expand Down Expand Up @@ -234,6 +259,41 @@ describe('merge schemas through transforms', () => {
},
});
});

it('local subscriptions should work even if root fields are renamed', done => {
const originalNotification = {
notifications: {
text: 'Hello world',
},
};

const transformedNotification = {
Subscriptions_notifications: originalNotification.notifications
};

const subscription = parse(`
subscription Subscription {
Subscriptions_notifications {
text
}
}
`);

let notificationCnt = 0;
subscribe(mergedSchema, subscription)
.then(results => {
forAwaitEach(
results as AsyncIterable<ExecutionResult>,
(result: ExecutionResult) => {
expect(result).to.have.property('data');
expect(result.data).to.deep.equal(transformedNotification);
!notificationCnt++ ? done() : null;
},
).catch(done);
}).then(() => {
subscriptionPubSub.publish(subscriptionPubSubTrigger, originalNotification);
}).catch(done);
});
});

describe('interface resolver inheritance', () => {
Expand Down

0 comments on commit 210e8aa

Please sign in to comment.