Skip to content

Commit b69855c

Browse files
committed
Resolver removeById with tests.
1 parent 7bd8d89 commit b69855c

File tree

2 files changed

+202
-0
lines changed

2 files changed

+202
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/* @flow */
2+
3+
import { expect } from 'chai';
4+
import { UserModel } from '../../__mocks__/userModel.js';
5+
import removeById from '../removeById';
6+
import Resolver from '../../../../graphql-compose/src/resolver/resolver';
7+
import TypeComposer from '../../../../graphql-compose/src/typeComposer';
8+
import { convertModelToGraphQL } from '../../fieldsConverter';
9+
import { GraphQLNonNull } from 'graphql';
10+
import GraphQLMongoID from '../../types/mongoid';
11+
12+
const UserType = convertModelToGraphQL(UserModel, 'User');
13+
14+
describe('removeById() ->', () => {
15+
let user;
16+
17+
before('clear UserModel collection', (done) => {
18+
UserModel.collection.drop(done);
19+
});
20+
21+
beforeEach('add test user document to mongoDB', () => {
22+
user = new UserModel({
23+
name: 'userName1',
24+
skills: ['js', 'ruby', 'php', 'python'],
25+
gender: 'male',
26+
relocation: true,
27+
});
28+
29+
return Promise.all([
30+
user.save(),
31+
]);
32+
});
33+
34+
it('should return Resolver object', () => {
35+
const resolver = removeById(UserModel, UserType);
36+
expect(resolver).to.be.instanceof(Resolver);
37+
});
38+
39+
describe('Resolver.args', () => {
40+
it('should have non-null `_id` arg', () => {
41+
const resolver = removeById(UserModel, UserType);
42+
expect(resolver.hasArg('_id')).to.be.true;
43+
const argConfig = resolver.getArg('_id');
44+
expect(argConfig).property('type').that.instanceof(GraphQLNonNull);
45+
expect(argConfig).deep.property('type.ofType').that.equal(GraphQLMongoID);
46+
});
47+
});
48+
49+
describe('Resolver.resolve():Promise', () => {
50+
it('should be promise', () => {
51+
const result = removeById(UserModel, UserType).resolve({});
52+
expect(result).instanceof(Promise);
53+
result.catch(() => 'catch error if appear, hide it from mocha');
54+
});
55+
56+
it('should rejected with Error if args._id is empty', async () => {
57+
const result = removeById(UserModel, UserType).resolve({ args: { } });
58+
await expect(result).be.rejectedWith(Error, 'requires args._id');
59+
});
60+
61+
it('should return payload.recordId', async () => {
62+
const result = await removeById(UserModel, UserType).resolve({
63+
args: {
64+
_id: user.id,
65+
},
66+
});
67+
expect(result).have.property('recordId', user.id);
68+
});
69+
70+
it('should return payload.recordId even document not exists', async () => {
71+
const unexistedId = '500000000000000000000000';
72+
const result = await removeById(UserModel, UserType).resolve({
73+
args: {
74+
_id: unexistedId,
75+
},
76+
});
77+
expect(result).have.property('recordId', unexistedId);
78+
});
79+
80+
81+
it('should remove document in database', (done) => {
82+
removeById(UserModel, UserType).resolve({
83+
args: {
84+
_id: user.id,
85+
},
86+
}).then(() => {
87+
UserModel.collection.findOne({ _id: user._id }, (err, doc) => {
88+
expect(err).to.be.null;
89+
expect(doc).to.be.null;
90+
done();
91+
});
92+
});
93+
});
94+
95+
it('should return payload.record', async () => {
96+
const result = await removeById(UserModel, UserType).resolve({
97+
args: {
98+
_id: user.id,
99+
},
100+
});
101+
expect(result).have.deep.property('record.id', user.id);
102+
});
103+
});
104+
105+
describe('Resolver.getOutputType()', () => {
106+
it('should have correct output type name', () => {
107+
const outputType = removeById(UserModel, UserType).getOutputType();
108+
expect(outputType.name).to.equal(`RemoveById${UserType.name}Payload`);
109+
});
110+
111+
it('should have recordId field', () => {
112+
const outputType = removeById(UserModel, UserType).getOutputType();
113+
const typeComposer = new TypeComposer(outputType);
114+
expect(typeComposer.hasField('recordId')).to.be.true;
115+
expect(typeComposer.getField('recordId').type).to.equal(GraphQLMongoID);
116+
});
117+
118+
it('should have record field', () => {
119+
const outputType = removeById(UserModel, UserType).getOutputType();
120+
const typeComposer = new TypeComposer(outputType);
121+
expect(typeComposer.hasField('record')).to.be.true;
122+
expect(typeComposer.getField('record').type).to.equal(UserType);
123+
});
124+
});
125+
});

src/resolvers/removeById.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* @flow */
2+
/* eslint-disable no-param-reassign */
3+
4+
import { projectionHelper } from './helpers/projection';
5+
import findById from './findById';
6+
import {
7+
GraphQLObjectType,
8+
GraphQLNonNull,
9+
} from 'graphql';
10+
import GraphQLMongoID from '../types/mongoid';
11+
12+
import type {
13+
MongooseModelT,
14+
ExtendedResolveParams,
15+
} from '../definition';
16+
import Resolver from '../../../graphql-compose/src/resolver/resolver';
17+
18+
export default function removeById(
19+
model: MongooseModelT,
20+
gqType: GraphQLObjectType,
21+
): Resolver {
22+
const resolver = new Resolver({
23+
name: 'removeById',
24+
kind: 'mutation',
25+
description: 'Remove one document: '
26+
+ '1) Retrieve one document by findById. '
27+
+ '2) Remove mongoose document with hooks via findByIdAndRemove. '
28+
+ '3) Return removed document.',
29+
outputType: new GraphQLObjectType({
30+
name: `RemoveById${gqType.name}Payload`,
31+
fields: {
32+
recordId: {
33+
type: GraphQLMongoID,
34+
description: 'Removed document ID',
35+
},
36+
record: {
37+
type: gqType,
38+
description: 'Removed document',
39+
},
40+
},
41+
}),
42+
args: {
43+
_id: {
44+
name: '_id',
45+
type: new GraphQLNonNull(GraphQLMongoID),
46+
},
47+
},
48+
resolve: (resolveParams: ExtendedResolveParams) => {
49+
const args = resolveParams.args || {};
50+
51+
if (!args._id) {
52+
return Promise.reject(
53+
new Error(`${gqType.name}.removeById resolver requires args._id value`)
54+
);
55+
}
56+
57+
resolveParams.query = model.findByIdAndRemove(args._id);
58+
projectionHelper(resolveParams);
59+
60+
return resolveParams.query.exec()
61+
.then(res => {
62+
if (res) {
63+
return {
64+
record: res.toObject(),
65+
recordId: res.id,
66+
};
67+
}
68+
69+
return {
70+
recordId: args._id,
71+
};
72+
});
73+
},
74+
});
75+
76+
return resolver;
77+
}

0 commit comments

Comments
 (0)