From 0f5613899b40fb1707fa1342d0fa3d14ca8a67e3 Mon Sep 17 00:00:00 2001 From: Rick Dutour Geerling Date: Wed, 30 Oct 2019 08:34:33 +0100 Subject: [PATCH] test: add test for injecting custom buildservice into gateway --- .../gql-gateway-module-options.interface.ts | 2 +- .../e2e/graphql-gateway-buildservice.spec.ts | 87 +++++++++++++++++++ .../gateway/gateway-buildservice.module.ts | 34 ++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/graphql-gateway-buildservice.spec.ts create mode 100644 tests/graphql-federation/gateway/gateway-buildservice.module.ts diff --git a/lib/interfaces/gql-gateway-module-options.interface.ts b/lib/interfaces/gql-gateway-module-options.interface.ts index 03217ab4b2..5871873a60 100644 --- a/lib/interfaces/gql-gateway-module-options.interface.ts +++ b/lib/interfaces/gql-gateway-module-options.interface.ts @@ -22,7 +22,7 @@ export interface GatewayOptionsFactory { export interface GatewayModuleAsyncOptions extends Pick { useExisting?: Type; useClass?: Type; - useFactory?: (...args: any[]) => Promise | GqlModuleOptions; + useFactory?: (...args: any[]) => Promise | GatewayModuleOptions; inject?: any[]; } diff --git a/tests/e2e/graphql-gateway-buildservice.spec.ts b/tests/e2e/graphql-gateway-buildservice.spec.ts new file mode 100644 index 0000000000..e96021ced2 --- /dev/null +++ b/tests/e2e/graphql-gateway-buildservice.spec.ts @@ -0,0 +1,87 @@ +import { INestApplication } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import * as request from 'supertest'; +import { AppModule as PostsModule } from '../graphql-federation/posts-service/federation-posts.module'; +import { AppModule as UsersModule } from '../graphql-federation/users-service/federation-users.module'; +import { AppModule as GatewayModule } from '../graphql-federation/gateway/gateway-buildservice.module'; +import { RemoteGraphQLDataSource } from '@apollo/gateway'; +import { GRAPHQL_GATEWAY_BUILD_SERVICE } from '../../lib/graphql.constants'; + +describe('GraphQL Gateway buildservice', () => { + let postsApp: INestApplication; + let usersApp: INestApplication; + let gatewayApp: INestApplication; + let buildServiceHook: Function; + + beforeEach(async () => { + buildServiceHook = jest.fn(); + const usersModule = await Test.createTestingModule({ + imports: [UsersModule], + }).compile(); + + usersApp = usersModule.createNestApplication(); + await usersApp.listenAsync(3001); + + const postsModule = await Test.createTestingModule({ + imports: [PostsModule], + }).compile(); + + postsApp = postsModule.createNestApplication(); + await postsApp.listenAsync(3002); + + const gatewayModule = await Test.createTestingModule({ + imports: [GatewayModule], + }) + .overrideProvider(GRAPHQL_GATEWAY_BUILD_SERVICE) + .useValue(({ url }) => { + return new RemoteGraphQLDataSource({ url, willSendRequest: buildServiceHook as any }); + }) + .compile(); + + gatewayApp = gatewayModule.createNestApplication(); + await gatewayApp.init(); + }); + + it(`should run query through build service`, async () => { + await request(gatewayApp.getHttpServer()) + .post('/graphql') + .send({ + operationName: null, + variables: {}, + query: ` + { + getPosts { + id, + title, + body, + user { + id, + name, + } + } + }`, + }) + .expect(200, { + data: { + getPosts: [ + { + id: '1', + title: 'Hello world', + body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + user: { + id: '5', + name: 'GraphQL', + }, + }, + ], + }, + }); + expect(buildServiceHook).toHaveBeenCalled(); + }); + + afterEach(async () => { + await postsApp.close(); + await usersApp.close(); + await gatewayApp.close(); + }); +}); diff --git a/tests/graphql-federation/gateway/gateway-buildservice.module.ts b/tests/graphql-federation/gateway/gateway-buildservice.module.ts new file mode 100644 index 0000000000..8b4c262843 --- /dev/null +++ b/tests/graphql-federation/gateway/gateway-buildservice.module.ts @@ -0,0 +1,34 @@ +import { Module } from '@nestjs/common'; +import { GraphQLGatewayModule } from '../../../lib/graphql-gateway.module'; +import { GRAPHQL_GATEWAY_BUILD_SERVICE } from '../../../lib/graphql.constants'; +import { RemoteGraphQLDataSource } from '@apollo/gateway'; + +@Module({ + providers: [ + { + provide: GRAPHQL_GATEWAY_BUILD_SERVICE, + useValue: ({ name, url }) => { + console.log('BuildService: %s', name); + return new RemoteGraphQLDataSource({ url }); + }, + }, + ], + exports: [GRAPHQL_GATEWAY_BUILD_SERVICE], +}) +class BuildServiceModule {} + +@Module({ + imports: [ + GraphQLGatewayModule.forRootAsync({ + useFactory: async () => ({ + serviceList: [ + { name: 'users', url: 'http://localhost:3001/graphql' }, + { name: 'posts', url: 'http://localhost:3002/graphql' }, + ], + }), + imports: [BuildServiceModule], + inject: [GRAPHQL_GATEWAY_BUILD_SERVICE], + }), + ], +}) +export class AppModule {}