Skip to content

Commit 8bfefc4

Browse files
antonioprestonodkz
authored andcommitted
feat: add beforeQueryHelper, improve beforeQuery logic (#189)
validate beforeQueryHelper returning query beforeQueryHelper: hide exec + pass mongoose model improve tests
1 parent 5b704a6 commit 8bfefc4

23 files changed

+357
-31
lines changed

src/resolvers/__tests__/connection-test.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* @flow */
22

33
import { Resolver, schemaComposer } from 'graphql-compose';
4+
import { Query } from 'mongoose';
45
import { UserModel } from '../../__mocks__/userModel';
56
import connection, { prepareCursorQuery } from '../connection';
67
import findMany from '../findMany';
@@ -217,6 +218,63 @@ describe('connection() resolver', () => {
217218
expect(result.edges[0].node).toBeInstanceOf(UserModel);
218219
expect(result.edges[1].node).toBeInstanceOf(UserModel);
219220
});
221+
222+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
223+
const mongooseActions = [];
224+
225+
UserModel.base.set('debug', function debugMongoose(...args) {
226+
mongooseActions.push(args);
227+
});
228+
229+
const resolver = connection(UserModel, UserTC);
230+
231+
if (!resolver) {
232+
throw new Error('resolver is undefined');
233+
}
234+
235+
const result = await resolver.resolve({
236+
args: {},
237+
beforeQuery: (query, rp) => {
238+
expect(query).toBeInstanceOf(Query);
239+
expect(rp.model).toBe(UserModel);
240+
// modify query before execution
241+
return query.where({ _id: user1.id }).limit(1989);
242+
},
243+
});
244+
245+
expect(mongooseActions).toEqual([
246+
[
247+
'users',
248+
'find',
249+
{ _id: user1._id },
250+
{
251+
limit: 1989,
252+
projection: {},
253+
},
254+
],
255+
]);
256+
257+
expect(result.edges).toHaveLength(1);
258+
});
259+
260+
it('should override result with `beforeQuery`', async () => {
261+
const resolver = connection(UserModel, UserTC);
262+
263+
if (!resolver) {
264+
throw new Error('resolver is undefined');
265+
}
266+
267+
const result = await resolver.resolve({
268+
args: {},
269+
beforeQuery: (query, rp) => {
270+
expect(query).toBeInstanceOf(Query);
271+
expect(rp.model).toBe(UserModel);
272+
return [{ overrides: true }];
273+
},
274+
});
275+
276+
expect(result).toHaveProperty('edges.0.node', { overrides: true });
277+
});
220278
});
221279
});
222280
});

src/resolvers/__tests__/count-test.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,50 @@ describe('count() ->', () => {
7070
});
7171
expect(result).toBe(1);
7272
});
73+
74+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
75+
const mongooseActions = [];
76+
77+
UserModel.base.set('debug', function debugMongoose(...args) {
78+
mongooseActions.push(args);
79+
});
80+
81+
const result = await count(UserModel, UserTC).resolve({
82+
args: {},
83+
beforeQuery: (query, rp) => {
84+
expect(query).toHaveProperty('exec');
85+
expect(rp.model).toBe(UserModel);
86+
87+
// modify query before execution
88+
return query.limit(1);
89+
},
90+
});
91+
92+
expect(mongooseActions).toEqual([
93+
[
94+
'users',
95+
'countDocuments',
96+
{},
97+
{
98+
limit: 1,
99+
},
100+
],
101+
]);
102+
103+
expect(result).toBe(1);
104+
});
105+
106+
it('should override result with `beforeQuery`', async () => {
107+
const result = await count(UserModel, UserTC).resolve({
108+
args: {},
109+
beforeQuery: (query, rp) => {
110+
expect(query).toHaveProperty('exec');
111+
expect(rp.model).toBe(UserModel);
112+
return 1989;
113+
},
114+
});
115+
expect(result).toBe(1989);
116+
});
73117
});
74118

75119
describe('Resolver.getType()', () => {

src/resolvers/__tests__/findById-test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,22 @@ describe('findById() ->', () => {
8787
});
8888
expect(result).toBeInstanceOf(PostModel);
8989
});
90+
91+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
92+
let beforeQueryCalled = false;
93+
94+
const result = await findById(PostModel, PostTypeComposer).resolve({
95+
args: { _id: 1 },
96+
beforeQuery: (query, rp) => {
97+
expect(query).toHaveProperty('exec');
98+
expect(rp.model).toBe(PostModel);
99+
beforeQueryCalled = true;
100+
return { overrides: true };
101+
},
102+
});
103+
104+
expect(beforeQueryCalled).toBe(true);
105+
expect(result).toEqual({ overrides: true });
106+
});
90107
});
91108
});

src/resolvers/__tests__/findByIds-test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,18 @@ describe('findByIds() ->', () => {
121121
expect(result[0]).toBeInstanceOf(UserModel);
122122
expect(result[1]).toBeInstanceOf(UserModel);
123123
});
124+
125+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
126+
const result = await findByIds(UserModel, UserTC).resolve({
127+
args: { _ids: [user1._id, user2._id] },
128+
beforeQuery(query, rp) {
129+
expect(rp.model).toBe(UserModel);
130+
expect(rp.query).toHaveProperty('exec');
131+
return query.where({ _id: user1._id });
132+
},
133+
});
134+
135+
expect(result).toHaveLength(1);
136+
});
124137
});
125138
});

src/resolvers/__tests__/findMany-test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,18 @@ describe('findMany() ->', () => {
110110
expect(result[0]).toBeInstanceOf(UserModel);
111111
expect(result[1]).toBeInstanceOf(UserModel);
112112
});
113+
114+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
115+
const result = await findMany(UserModel, UserTC).resolve({
116+
args: { limit: 2 },
117+
beforeQuery(query, rp) {
118+
expect(rp.model).toBe(UserModel);
119+
expect(rp.query).toHaveProperty('exec');
120+
return [{ overridden: true }];
121+
},
122+
});
123+
124+
expect(result).toEqual([{ overridden: true }]);
125+
});
113126
});
114127
});

src/resolvers/__tests__/findOne-test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,19 @@ describe('findOne() ->', () => {
118118
});
119119
expect(result).toBeInstanceOf(UserModel);
120120
});
121+
122+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
123+
const result = await findOne(UserModel, UserTC).resolve({
124+
args: { _id: user1._id },
125+
beforeQuery(query, rp) {
126+
expect(rp.model).toBe(UserModel);
127+
expect(rp.query).toHaveProperty('exec');
128+
return query.where({ _id: user2._id });
129+
},
130+
});
131+
132+
expect(result._id).toEqual(user2._id);
133+
});
121134
});
122135

123136
describe('Resolver.getType()', () => {

src/resolvers/__tests__/pagination-test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,5 +144,21 @@ describe('pagination() ->', () => {
144144
expect(result.items[0]).toBeInstanceOf(UserModel);
145145
expect(result.items[1]).toBeInstanceOf(UserModel);
146146
});
147+
148+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
149+
const resolver = pagination(UserModel, UserTC);
150+
if (!resolver) throw new Error('Pagination resolver is undefined');
151+
152+
const result = await resolver.resolve({
153+
args: { page: 1, perPage: 20 },
154+
beforeQuery(query, rp) {
155+
expect(rp.model).toBe(UserModel);
156+
expect(rp.query).toHaveProperty('exec');
157+
return [{ overrides: true }];
158+
},
159+
});
160+
161+
expect(result.items).toEqual([{ overrides: true }]);
162+
});
147163
});
148164
});

src/resolvers/__tests__/removeById-test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,32 @@ describe('removeById() ->', () => {
147147
const exist = await UserModel.collection.findOne({ _id: user._id });
148148
expect(exist.name).toBe(user.name);
149149
});
150+
151+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
152+
const mongooseActions = [];
153+
154+
UserModel.base.set('debug', function debugMongoose(...args) {
155+
mongooseActions.push(args);
156+
});
157+
158+
const resolveParams = {
159+
args: { _id: 'INVALID_ID' },
160+
context: { ip: '1.1.1.1' },
161+
beforeQuery(query, rp) {
162+
expect(rp.model).toBe(UserModel);
163+
expect(rp.query).toHaveProperty('exec');
164+
return query.where({ _id: user._id, canDelete: false });
165+
},
166+
};
167+
168+
const result = await removeById(UserModel, UserTC).resolve(resolveParams);
169+
170+
expect(mongooseActions).toEqual([
171+
['users', 'findOne', { _id: user._id, canDelete: false }, { projection: {} }],
172+
]);
173+
174+
expect(result).toBeNull();
175+
});
150176
});
151177

152178
describe('Resolver.getType()', () => {

src/resolvers/__tests__/removeMany-test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ describe('removeMany() ->', () => {
109109
args: {
110110
filter: { gender: 'female' },
111111
},
112-
beforeQuery: query => {
112+
beforeQuery: (query, rp) => {
113113
expect(query).toBeInstanceOf(Query);
114+
expect(rp.model).toBe(UserModel);
114115
beforeQueryCalled = true;
115116
return query;
116117
},

src/resolvers/__tests__/removeOne-test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,25 @@ describe('removeOne() ->', () => {
189189
const exist = await UserModel.collection.findOne({ _id: user1._id });
190190
expect(exist.name).toBe(user1.name);
191191
});
192+
193+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
194+
let beforeQueryCalled = false;
195+
196+
const result = await removeOne(UserModel, UserTC).resolve({
197+
args: { filter: { _id: 'INVALID_ID' } },
198+
beforeQuery: (query, rp) => {
199+
expect(query).toHaveProperty('exec');
200+
expect(rp.model).toBe(UserModel);
201+
202+
beforeQueryCalled = true;
203+
// modify query before execution
204+
return query.where({ _id: user1.id });
205+
},
206+
});
207+
208+
expect(result).toHaveProperty('record._id', user1._id);
209+
expect(beforeQueryCalled).toBe(true);
210+
});
192211
});
193212

194213
describe('Resolver.getType()', () => {

src/resolvers/__tests__/updateById-test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,25 @@ describe('updateById() ->', () => {
187187
const exist = await UserModel.collection.findOne({ _id: user1._id });
188188
expect(exist.name).toBe(user1.name);
189189
});
190+
191+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
192+
let beforeQueryCalled = false;
193+
194+
const result = await updateById(UserModel, UserTC).resolve({
195+
args: { record: { _id: user1.id, name: 'new name' } },
196+
beforeQuery: (query, rp) => {
197+
expect(query).toHaveProperty('exec');
198+
expect(rp.model).toBe(UserModel);
199+
200+
beforeQueryCalled = true;
201+
// modify query before execution
202+
return query.where({ _id: user2.id });
203+
},
204+
});
205+
206+
expect(result).toHaveProperty('record._id', user2._id);
207+
expect(beforeQueryCalled).toBe(true);
208+
});
190209
});
191210

192211
describe('Resolver.getType()', () => {

src/resolvers/__tests__/updateMany-test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,9 @@ describe('updateMany() ->', () => {
117117
args: {
118118
record: { gender: 'female' },
119119
},
120-
beforeQuery: query => {
120+
beforeQuery: (query, rp) => {
121121
expect(query).toBeInstanceOf(Query);
122+
expect(rp.model).toBe(UserModel);
122123
beforeQueryCalled = true;
123124
// modify query before execution
124125
return query.where({ _id: user1.id });

src/resolvers/__tests__/updateOne-test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,25 @@ describe('updateOne() ->', () => {
211211
const exist = await UserModel.collection.findOne({ _id: user1._id });
212212
expect(exist.name).toBe(user1.name);
213213
});
214+
215+
it('should call `beforeQuery` method with non-executed `query` as arg', async () => {
216+
let beforeQueryCalled = false;
217+
218+
const result = await updateOne(UserModel, UserTC).resolve({
219+
args: { filter: { _id: user1.id }, record: { name: 'new name' } },
220+
beforeQuery: (query, rp) => {
221+
expect(query).toHaveProperty('exec');
222+
expect(rp.model).toBe(UserModel);
223+
224+
beforeQueryCalled = true;
225+
// modify query before execution
226+
return query.where({ _id: user2.id });
227+
},
228+
});
229+
230+
expect(result).toHaveProperty('record._id', user2._id);
231+
expect(beforeQueryCalled).toBe(true);
232+
});
214233
});
215234

216235
describe('Resolver.getType()', () => {

src/resolvers/count.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { Resolver, ObjectTypeComposer } from 'graphql-compose';
55
import type { MongooseDocument } from 'mongoose';
66
import { filterHelper, filterHelperArgs } from './helpers';
77
import type { ExtendedResolveParams, GenResolverOpts } from './index';
8+
import { beforeQueryHelper } from './helpers/beforeQueryHelper';
89

910
export default function count<TSource: MongooseDocument, TContext>(
1011
model: Class<TSource>, // === MongooseModel
@@ -32,13 +33,16 @@ export default function count<TSource: MongooseDocument, TContext>(
3233
},
3334
resolve: (resolveParams: ExtendedResolveParams) => {
3435
resolveParams.query = model.find();
36+
resolveParams.model = model;
3537
filterHelper(resolveParams);
3638
if (resolveParams.query.countDocuments) {
3739
// mongoose 5.2.0 and above
38-
return resolveParams.query.countDocuments().exec();
40+
resolveParams.query.countDocuments();
41+
return beforeQueryHelper(resolveParams);
3942
} else {
4043
// mongoose 5 and below
41-
return resolveParams.query.count().exec();
44+
resolveParams.query.count();
45+
return beforeQueryHelper(resolveParams);
4246
}
4347
},
4448
});

0 commit comments

Comments
 (0)