Skip to content

Commit eae50ea

Browse files
committed
test: add integration test for dataLoaderXXX resolvers
1 parent 0a00527 commit eae50ea

File tree

4 files changed

+125
-8
lines changed

4 files changed

+125
-8
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/* eslint-disable no-param-reassign */
2+
3+
import { schemaComposer, graphql } from 'graphql-compose';
4+
import { composeWithMongoose } from '../../index';
5+
import { mongoose } from '../../__mocks__/mongooseCommon';
6+
7+
const UserSchema = new mongoose.Schema({
8+
name: { type: String, required: true },
9+
});
10+
const PostSchema = new mongoose.Schema({
11+
title: { type: String, required: true },
12+
authorId: { type: mongoose.Types.ObjectId },
13+
reviewerIds: { type: [mongoose.Types.ObjectId] },
14+
});
15+
16+
const UserModel = mongoose.model('User', UserSchema);
17+
const PostModel = mongoose.model('Post', PostSchema);
18+
19+
const UserTC = composeWithMongoose(UserModel);
20+
const PostTC = composeWithMongoose(PostModel);
21+
22+
PostTC.addRelation('author', {
23+
// resolver: UserTC.getResolver('dataLoader'), // <---- DataLoader for getting one mongoose doc by id (slower than `dataLoaderLean` but more functional)
24+
resolver: UserTC.getResolver('dataLoaderLean'), // <---- `Lean` loads record from DB without support of mongoose getters & virtuals
25+
prepareArgs: {
26+
_id: (s) => s.authorId,
27+
},
28+
projection: { authorId: true },
29+
});
30+
31+
PostTC.addRelation('reviewers', {
32+
// resolver: UserTC.getResolver('dataLoaderMany'), // <---- DataLoader for getting many mongoose docs by ids (slower than `dataLoaderManyLean` but more functional)
33+
resolver: UserTC.getResolver('dataLoaderManyLean'), // <---- `Lean` loads records from DB without support of mongoose getters & virtuals
34+
prepareArgs: {
35+
_ids: (s) => s.reviewerIds,
36+
},
37+
projection: { reviewerIds: true },
38+
});
39+
40+
schemaComposer.Query.addFields({
41+
posts: PostTC.getResolver('findMany'),
42+
});
43+
const schema = schemaComposer.buildSchema();
44+
45+
// console.log(schemaComposer.toSDL());
46+
47+
beforeAll(async () => {
48+
await UserModel.base.createConnection();
49+
const User1 = await UserModel.create({ name: 'User1' });
50+
const User2 = await UserModel.create({ name: 'User2' });
51+
const User3 = await UserModel.create({ name: 'User3' });
52+
53+
await PostModel.create({ title: 'Post1', authorId: User1._id });
54+
await PostModel.create({ title: 'Post2', authorId: User1._id, reviewerIds: [] });
55+
await PostModel.create({ title: 'Post3', authorId: User1._id, reviewerIds: [User2._id] });
56+
await PostModel.create({ title: 'Post4', authorId: User2._id, reviewerIds: [User1._id] });
57+
await PostModel.create({ title: 'Post5', authorId: User2._id, reviewerIds: [User1._id] });
58+
await PostModel.create({
59+
title: 'Post6',
60+
authorId: User3._id,
61+
reviewerIds: [User1._id, User2._id],
62+
});
63+
});
64+
afterAll(() => UserModel.base.disconnect());
65+
66+
describe('issue #260 - new resolvers which works via DataLoader', () => {
67+
it('check response', async () => {
68+
// 👀 uncomment next line if you want to see real mongoose queries
69+
// mongoose.set('debug', true);
70+
71+
expect(
72+
await graphql.graphql({
73+
schema,
74+
source: `query {
75+
posts {
76+
title
77+
author { name }
78+
reviewers { name }
79+
}
80+
}`,
81+
contextValue: {},
82+
})
83+
).toEqual({
84+
data: {
85+
posts: [
86+
{ title: 'Post1', author: { name: 'User1' }, reviewers: [] },
87+
{ title: 'Post2', author: { name: 'User1' }, reviewers: [] },
88+
{ title: 'Post3', author: { name: 'User1' }, reviewers: [{ name: 'User2' }] },
89+
{ title: 'Post4', author: { name: 'User2' }, reviewers: [{ name: 'User1' }] },
90+
{ title: 'Post5', author: { name: 'User2' }, reviewers: [{ name: 'User1' }] },
91+
{
92+
title: 'Post6',
93+
author: { name: 'User3' },
94+
reviewers: [{ name: 'User1' }, { name: 'User2' }],
95+
},
96+
],
97+
},
98+
});
99+
});
100+
});

src/__tests__/github_issues/282-test.ts renamed to src/__tests__/github_issues/gc282-test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ beforeAll(async () => {
6060
});
6161
afterAll(() => EventModel.base.disconnect());
6262

63-
describe('issue #282 - Filter nested array by string', () => {
63+
// Issue from graphql-compose repo
64+
// @see https://github.com/graphql-compose/graphql-compose/pull/282
65+
describe('graphql-compose/issue #282 - Filter nested array by string', () => {
6466
it('correct request', async () => {
6567
expect(
6668
await graphql.graphql(

src/resolvers/helpers/dataLoaderHelper.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,34 @@ export function getDataLoader(
1515
// get or create DataLoader in GraphQL context
1616
let dl: DataLoader<any, any> = _gqlDataLoaders.get(dlKey);
1717
if (!dl) {
18+
const dataLoaderOptions = {
19+
cacheKeyFn: (k) => {
20+
if (k?.equals) {
21+
// Convert ObjectId to string for combining different instances of same ObjectIds.
22+
// Eg. you have 10 articles with same authorId. So in memory `authorId` for every record
23+
// will have its own instance of ObjectID.
24+
//
25+
// mongoose will convert them back to ObjectId automatically when call `find` method
26+
return k.toString();
27+
}
28+
return k;
29+
},
30+
} as DataLoader.Options<any, any, any>;
31+
1832
dl = new DataLoader(async (ids) => {
1933
const result = await batchLoadFn(ids);
2034
// return docs in the same order as were provided their ids
2135
return ids.map((id) =>
22-
(result as any).find((d: any) => {
23-
if (d?._id?.equals) {
36+
(result as any).find((doc: any) => {
37+
if (doc?._id?.equals) {
2438
// compare correctly MongoIDs via ObjectID.equals() method
25-
return d._id.equals(id);
39+
return doc._id.equals(id);
2640
}
27-
return d._id === id;
41+
return doc._id === id;
2842
})
2943
);
30-
});
44+
}, dataLoaderOptions);
45+
3146
_gqlDataLoaders.set(dlKey, dl);
3247
}
3348
return dl;

src/resolvers/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import findOneLean from './findOneLean';
1818

1919
import dataLoader from './dataLoader';
2020
import dataLoaderLean from './dataLoaderLean';
21-
import dataLoaderMany from './dataLoader';
22-
import dataLoaderManyLean from './dataLoaderLean';
21+
import dataLoaderMany from './dataLoaderMany';
22+
import dataLoaderManyLean from './dataLoaderManyLean';
2323

2424
import type {
2525
FilterHelperArgsOpts,

0 commit comments

Comments
 (0)