Skip to content

Commit 81e000f

Browse files
yoadsnnodkz
authored andcommitted
fix(ConnectionResolver): Do not call findMany resolver, if requested only count field
Closes #5 * improve code style
1 parent 86ddc88 commit 81e000f

File tree

2 files changed

+138
-10
lines changed

2 files changed

+138
-10
lines changed

src/__tests__/connectionResolver-test.js

Lines changed: 128 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,25 +98,37 @@ describe('connectionResolver', () => {
9898
});
9999
});
100100

101-
describe('call of findMany resolver', () => {
101+
describe('call of resolvers', () => {
102102
let spyResolveParams;
103103
let mockedConnectionResolver;
104+
let findManyResolverCalled;
105+
let countResolverCalled;
104106

105107
beforeEach(() => {
108+
findManyResolverCalled = false;
109+
countResolverCalled = false;
106110
const mockedFindMany = userTypeComposer.getResolver('findMany')
107111
.wrapResolve((next) => (resolveParams) => {
112+
findManyResolverCalled = true;
113+
spyResolveParams = resolveParams;
114+
return next(resolveParams);
115+
});
116+
const mockedCount = userTypeComposer.getResolver('findMany')
117+
.wrapResolve((next) => (resolveParams) => {
118+
countResolverCalled = true;
108119
spyResolveParams = resolveParams;
109120
return next(resolveParams);
110121
});
111122
userTypeComposer.setResolver('mockedFindMany', mockedFindMany);
123+
userTypeComposer.setResolver('mockedCount', mockedCount);
112124
mockedConnectionResolver = prepareConnectionResolver(userTypeComposer, {
113-
countResolverName: 'count',
125+
countResolverName: 'mockedCount',
114126
findResolverName: 'mockedFindMany',
115127
sort: sortOptions,
116128
});
117129
});
118130

119-
it('should pass args.sort', async () => {
131+
it('should pass to findMany args.sort', async () => {
120132
const result = await mockedConnectionResolver.resolve({
121133
args: {
122134
sort: { name: 1 },
@@ -126,7 +138,7 @@ describe('connectionResolver', () => {
126138
expect(spyResolveParams).have.deep.property('args.sort.name', 1);
127139
});
128140

129-
it('should pass projection edges.node on top level', async () => {
141+
it('should pass to findMany projection edges.node on top level', async () => {
130142
const result = await mockedConnectionResolver.resolve({
131143
args: {},
132144
projection: {
@@ -142,7 +154,7 @@ describe('connectionResolver', () => {
142154
expect(spyResolveParams).have.deep.property('projection.age', true);
143155
});
144156

145-
it('should pass custom projections to top level', async () => {
157+
it('should pass to findMany custom projections to top level', async () => {
146158
const result = await mockedConnectionResolver.resolve({
147159
args: {},
148160
projection: {
@@ -153,6 +165,93 @@ describe('connectionResolver', () => {
153165
expect(spyResolveParams).have.deep.property('projection.score')
154166
.to.deep.equal({ $meta: 'textScore' });
155167
});
168+
169+
it('should call count but not findMany when only count is projected', async () => {
170+
const result = await mockedConnectionResolver.resolve({
171+
args: {},
172+
projection: {
173+
count : true
174+
},
175+
});
176+
expect(countResolverCalled, 'count resolver called').to.be.true;
177+
expect(findManyResolverCalled, 'findMany resolver called').to.be.false;
178+
});
179+
180+
it('should call count and findMany resolver when not only count is projected', async () => {
181+
const result = await mockedConnectionResolver.resolve({
182+
args: {},
183+
projection: {
184+
count : true,
185+
edges : {
186+
node : {
187+
name : true,
188+
age : true
189+
}
190+
}
191+
},
192+
});
193+
expect(countResolverCalled, 'count resolver called').to.be.true;
194+
expect(findManyResolverCalled, 'findMany resolver called').to.be.true;
195+
});
196+
197+
it('should call findMany and not count when arbitrary top level fields are projected without count', async () => {
198+
const result = await mockedConnectionResolver.resolve({
199+
args: {},
200+
projection: {
201+
name: true,
202+
age: true
203+
},
204+
});
205+
expect(countResolverCalled, 'count resolver called').to.be.false;
206+
expect(findManyResolverCalled, 'findMany resolver called').to.be.true;
207+
});
208+
209+
it('should call findMany and count when arbitrary top level fields are projected with count', async () => {
210+
const result = await mockedConnectionResolver.resolve({
211+
args: {},
212+
projection: {
213+
count: true,
214+
name: true,
215+
age: true
216+
},
217+
});
218+
expect(countResolverCalled, 'count resolver called').to.be.true;
219+
expect(findManyResolverCalled, 'findMany resolver called').to.be.true;
220+
});
221+
222+
it('should call count and findMany resolver when last arg is used but not first arg', async () => {
223+
const result = await mockedConnectionResolver.resolve({
224+
args: {
225+
last: 1
226+
},
227+
projection: {
228+
edges : {
229+
node : {
230+
name : true,
231+
age : true
232+
}
233+
}
234+
},
235+
});
236+
expect(countResolverCalled, 'count resolver called').to.be.true;
237+
expect(findManyResolverCalled, 'findMany resolver called').to.be.true;
238+
});
239+
240+
it('should call findMany but not count resolver when first arg is used', async () => {
241+
const result = await mockedConnectionResolver.resolve({
242+
args: { first: 1 },
243+
projection: {
244+
edges : {
245+
node : {
246+
name : true,
247+
age : true
248+
}
249+
}
250+
},
251+
});
252+
expect(countResolverCalled, 'count resolver called').to.be.false;
253+
expect(findManyResolverCalled, 'findMany resolver called').to.be.true;
254+
});
156255
});
157256

158257
describe('prepareRawQuery()', () => {
@@ -453,7 +552,14 @@ describe('connectionResolver', () => {
453552
first: 5,
454553
last: 3,
455554
},
456-
projection: { count: 1 },
555+
projection: {
556+
count: true,
557+
edges : {
558+
node : {
559+
name: true
560+
}
561+
}
562+
},
457563
});
458564
expect(result).deep.property('edges').to.have.length(3);
459565
expect(result).deep.property('edges.0.node.id').equals(8);
@@ -503,7 +609,14 @@ describe('connectionResolver', () => {
503609
sort: sortOptions.ID_ASC.value,
504610
first: 100,
505611
},
506-
projection: { count: 1 },
612+
projection: {
613+
count: true,
614+
edges : {
615+
node : {
616+
name: true
617+
}
618+
}
619+
},
507620
});
508621
expect(result).deep.property('edges').to.have.length(8);
509622
expect(result).deep.property('edges.0.node')
@@ -612,7 +725,14 @@ describe('connectionResolver', () => {
612725
first: 5,
613726
last: 3,
614727
},
615-
projection: { count: 1 },
728+
projection: {
729+
count: true,
730+
edges : {
731+
node : {
732+
id: true
733+
}
734+
}
735+
},
616736
});
617737
expect(result).deep.property('edges').to.have.length(3);
618738
expect(result).deep.property('edges.0.node.id').equals(8);

src/connectionResolver.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export function prepareConnectionResolver(
8686
},
8787
resolve: async (resolveParams: ConnectionResolveParams) => {
8888
let countPromise;
89+
let findManyPromise;
8990
const { projection = {}, args, rawQuery } = resolveParams;
9091
const findManyParams: ResolveParams = Object.assign(
9192
{},
@@ -117,7 +118,6 @@ export function prepareConnectionResolver(
117118
countPromise = Promise.resolve(0);
118119
}
119120

120-
121121
if (projection && projection.edges) {
122122
// combine top level projection (maybe somebody add additional fields via resolveParams.projection)
123123
// and edges.node (record needed fields)
@@ -173,7 +173,15 @@ export function prepareConnectionResolver(
173173
resolveParams.findManyResolveParams = findManyParams;
174174
resolveParams.countResolveParams = countParams;
175175

176-
return Promise.all([findManyResolve(findManyParams), countPromise])
176+
// This allows to optimize and not actually call the findMany resolver
177+
// if only the count is projected
178+
if (projection.count && Object.keys(projection).length == 1) {
179+
findManyPromise = Promise.resolve([]);
180+
} else {
181+
findManyPromise = findManyResolve(findManyParams);
182+
}
183+
184+
return Promise.all([findManyPromise, countPromise])
177185
.then(([recordList, count]) => {
178186
const edges = [];
179187
// transform record to object { cursor, node }

0 commit comments

Comments
 (0)