Skip to content

Commit 17bd3cc

Browse files
author
Carl Evans
committed
fix(graphql): allow resolvers to be registered in provider wrappers
1 parent 6ba3511 commit 17bd3cc

File tree

7 files changed

+302
-1
lines changed

7 files changed

+302
-1
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Module } from '@nestjs/common';
2+
import { CatsResolver } from './cats.resolver';
3+
4+
@Module({})
5+
export class CatsModule {
6+
static register(resolverRegistrationMethod: 'useClass'|'useFactory'|'useValue') {
7+
switch (resolverRegistrationMethod) {
8+
case 'useClass':
9+
return {
10+
module: CatsModule,
11+
providers: [
12+
{
13+
provide: CatsResolver,
14+
useClass: CatsResolver
15+
},
16+
],
17+
};
18+
19+
case 'useValue':
20+
return {
21+
module: CatsModule,
22+
providers: [
23+
{
24+
provide: CatsResolver,
25+
useValue: new CatsResolver(),
26+
},
27+
],
28+
};
29+
30+
case 'useFactory':
31+
default:
32+
return {
33+
module: CatsModule,
34+
providers: [
35+
{
36+
provide: CatsResolver,
37+
useFactory() {
38+
return new CatsResolver();
39+
},
40+
},
41+
],
42+
};
43+
}
44+
}
45+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Query, Resolver } from '@nestjs/graphql';
2+
3+
@Resolver()
4+
export class CatsResolver {
5+
@Query(returns => String)
6+
getAnimalName(): string {
7+
return 'cat';
8+
}
9+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { INestApplication } from '@nestjs/common';
2+
import { Test } from '@nestjs/testing';
3+
import * as request from 'supertest';
4+
import { ApplicationModule } from '../code-first/app.module';
5+
import { CatsModule } from '../code-first/cats/cats.module';
6+
7+
describe('GraphQL - Resolver registration methods', () => {
8+
let app: INestApplication;
9+
10+
describe('useClass', () => {
11+
beforeEach(async () => {
12+
const module = await Test.createTestingModule({
13+
imports: [ApplicationModule, CatsModule.register('useClass')],
14+
}).compile();
15+
16+
app = module.createNestApplication();
17+
await app.init();
18+
});
19+
20+
it('should return the cats result', async () => {
21+
return request(app.getHttpServer())
22+
.post('/graphql')
23+
.send({
24+
operationName: null,
25+
variables: {},
26+
query: 'query {\n getAnimalName \n}\n',
27+
})
28+
.expect(200, {
29+
data: {
30+
getAnimalName: 'cat',
31+
}
32+
});
33+
});
34+
35+
afterEach(async () => {
36+
await app.close();
37+
});
38+
});
39+
40+
describe('useValue', () => {
41+
beforeEach(async () => {
42+
const module = await Test.createTestingModule({
43+
imports: [ApplicationModule, CatsModule.register('useValue')],
44+
}).compile();
45+
46+
app = module.createNestApplication();
47+
await app.init();
48+
});
49+
50+
it('should return the cats result', async () => {
51+
return request(app.getHttpServer())
52+
.post('/graphql')
53+
.send({
54+
operationName: null,
55+
variables: {},
56+
query: 'query {\n getAnimalName \n}\n',
57+
})
58+
.expect(200, {
59+
data: {
60+
getAnimalName: 'cat',
61+
}
62+
});
63+
});
64+
65+
afterEach(async () => {
66+
await app.close();
67+
});
68+
});
69+
70+
describe('useFactory', () => {
71+
beforeEach(async () => {
72+
const module = await Test.createTestingModule({
73+
imports: [ApplicationModule, CatsModule.register('useFactory')],
74+
}).compile();
75+
76+
app = module.createNestApplication();
77+
await app.init();
78+
});
79+
80+
it('should return the cats result', async () => {
81+
return request(app.getHttpServer())
82+
.post('/graphql')
83+
.send({
84+
operationName: null,
85+
variables: {},
86+
query: 'query {\n getAnimalName \n}\n',
87+
})
88+
.expect(200, {
89+
data: {
90+
getAnimalName: 'cat',
91+
}
92+
});
93+
});
94+
95+
afterEach(async () => {
96+
await app.close();
97+
});
98+
});
99+
});

packages/graphql/lib/services/resolvers-explorer.service.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,21 @@ export class ResolversExplorerService extends BaseExplorerService {
279279
};
280280
}
281281

282+
mapCtors(wrapper: InstanceWrapper): Function[] {
283+
const { instance } = wrapper;
284+
if (!instance) {
285+
return undefined;
286+
}
287+
288+
return instance.constructor;
289+
}
290+
282291
getAllCtors(): Function[] {
283292
const modules = this.getModules(
284293
this.modulesContainer,
285294
this.gqlOptions.include || [],
286295
);
287-
const resolvers = this.flatMap(modules, (instance) => instance.metatype);
296+
const resolvers = this.flatMap(modules, this.mapCtors).filter(Boolean);
288297
return resolvers;
289298
}
290299

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Module } from '@nestjs/common';
2+
import { CatsResolver } from './cats.resolver';
3+
4+
@Module({})
5+
export class CatsModule {
6+
static register(resolverRegistrationMethod: 'useClass'|'useFactory'|'useValue') {
7+
switch (resolverRegistrationMethod) {
8+
case 'useClass':
9+
return {
10+
module: CatsModule,
11+
providers: [
12+
{
13+
provide: CatsResolver,
14+
useClass: CatsResolver
15+
},
16+
],
17+
};
18+
19+
case 'useValue':
20+
return {
21+
module: CatsModule,
22+
providers: [
23+
{
24+
provide: CatsResolver,
25+
useValue: new CatsResolver(),
26+
},
27+
],
28+
};
29+
30+
case 'useFactory':
31+
default:
32+
return {
33+
module: CatsModule,
34+
providers: [
35+
{
36+
provide: CatsResolver,
37+
useFactory() {
38+
return new CatsResolver();
39+
},
40+
},
41+
],
42+
};
43+
}
44+
}
45+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Query, Resolver } from '@nestjs/graphql';
2+
3+
@Resolver()
4+
export class CatsResolver {
5+
@Query(returns => String)
6+
getAnimalName(): string {
7+
return 'cat';
8+
}
9+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { INestApplication } from '@nestjs/common';
2+
import { FastifyAdapter } from '@nestjs/platform-fastify';
3+
import { Test } from '@nestjs/testing';
4+
import mercurius from 'mercurius';
5+
import { ApplicationModule } from '../code-first/app.module';
6+
import { CatsModule } from '../code-first/cats/cats.module';
7+
8+
describe('GraphQL - Resolver registration methods', () => {
9+
let app: INestApplication;
10+
11+
describe('useClass', () => {
12+
beforeEach(async () => {
13+
const module = await Test.createTestingModule({
14+
imports: [ApplicationModule, CatsModule.register('useClass')],
15+
}).compile();
16+
17+
app = module.createNestApplication(new FastifyAdapter());
18+
await app.init();
19+
await app.getHttpAdapter().getInstance().ready();
20+
});
21+
22+
it('should return the cats result', async () => {
23+
const fastifyInstance = app.getHttpAdapter().getInstance();
24+
const response = await fastifyInstance.graphql(
25+
'query {\n getAnimalName \n}\n',
26+
);
27+
28+
expect(response.data).toEqual({ getAnimalName: 'cat' });
29+
});
30+
31+
afterEach(async () => {
32+
await app.close();
33+
});
34+
});
35+
36+
describe('useValue', () => {
37+
beforeEach(async () => {
38+
const module = await Test.createTestingModule({
39+
imports: [ApplicationModule, CatsModule.register('useValue')],
40+
}).compile();
41+
42+
app = module.createNestApplication(new FastifyAdapter());
43+
await app.init();
44+
await app.getHttpAdapter().getInstance().ready();
45+
});
46+
47+
it('should return the cats result', async () => {
48+
const fastifyInstance = app.getHttpAdapter().getInstance();
49+
const response = await fastifyInstance.graphql(
50+
'query {\n getAnimalName \n}\n',
51+
);
52+
53+
expect(response.data).toEqual({ getAnimalName: 'cat' });
54+
});
55+
56+
afterEach(async () => {
57+
await app.close();
58+
});
59+
});
60+
61+
describe('useFactory', () => {
62+
beforeEach(async () => {
63+
const module = await Test.createTestingModule({
64+
imports: [ApplicationModule, CatsModule.register('useFactory')],
65+
}).compile();
66+
67+
app = module.createNestApplication(new FastifyAdapter());
68+
await app.init();
69+
await app.getHttpAdapter().getInstance().ready();
70+
});
71+
72+
it('should return the cats result', async () => {
73+
const fastifyInstance = app.getHttpAdapter().getInstance();
74+
const response = await fastifyInstance.graphql(
75+
'query {\n getAnimalName \n}\n',
76+
);
77+
78+
expect(response.data).toEqual({ getAnimalName: 'cat' });
79+
});
80+
81+
afterEach(async () => {
82+
await app.close();
83+
});
84+
});
85+
});

0 commit comments

Comments
 (0)