Issues (82)

app/tests/server.test.js (19 issues)

1
const expect        = require('expect');
2
const request       = require('supertest');
3
const {app}         = require('../');
4
const {ObjectID}    = require('mongodb');
5
const {Todo}        = require('./../models/todo');
6
const {User}        = require('./../models/user');
7
8
const {dummyTodos, populateTodos, dummyUsers, populateUsers} = require('./seed/seed');
9
10
11
// make the DB empty first
12
beforeEach(populateUsers);
13
beforeEach(populateTodos);
14
15
// write tests 
16
describe ('GET /todos', () => {
17
    it('should get all todos', (done) => {
18
19
        request(app)
20
        .get('/todos')
21
        .set('x-auth', dummyUsers[0].tokens[0].token)
22
        .expect(200)
23
        .expect((res) => {
24
            expect(res.body.data.length).toBe(2);
25
        })
26
        .end(done)
27
    });
28
});
29
30
describe ('POST /todos', () => {
31
32
    it('should create a new todo', (done) => {
33
        let text = 'make a test suit';
34
35
        request(app)
36
        .post('/todos')
37
        .set('x-auth', dummyUsers[0].tokens[0].token)
38
        .send({text})
39
        .expect(201)
40
        .expect((res) => {
41
            expect(res.body.text).toBe(text);
42
        }).end((err, res) => {
0 ignored issues
show
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
43
            if (err) {
44
                return done(err);
45
            }
46
            done();
0 ignored issues
show
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
47
        });
48
    });
49
50
    it ('should not create a todo for invalid data', (done) => {
51
52
        request(app)
53
        .post('/todos')
54
        .set('x-auth', dummyUsers[0].tokens[0].token)        
55
        .send({})
56
        .expect(500)
57
        .end((err, res) => {
0 ignored issues
show
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
58
            if(err) {
59
                return done(err);
60
            }
61
62
            Todo.find().then((todos) => {
63
                expect(todos.length).toBe(3);
64
                done();
65
            }).catch((err) => done(err));
0 ignored issues
show
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
66
        });
67
    });
68
69
});
70
71
72
describe ('GET /todos/:id', () => {
73
    it('should return a todo doc', (done) => {
74
        request(app)
75
        .get(`/todos/${dummyTodos[0]._id.toHexString()}`)
76
        .set('x-auth', dummyUsers[0].tokens[0].token)        
77
        .expect(200)
78
        .expect((res) => {
79
            expect(res.body.todo.text).toBe(dummyTodos[0].text);
80
        })
81
        .end(done);
82
    });
83
84
    it('should not return a todo doc created by othe user', (done) => {
85
        request(app)
86
        .get(`/todos/${dummyTodos[2]._id.toHexString()}`)
87
        .set('x-auth', dummyUsers[0].tokens[0].token)        
88
        .expect(404)
89
        .end(done);
90
    });
91
92
    it('should give a 404 if id not found', (done) => {
93
        //create a new id for testing 
94
        let hexID = new ObjectID();
95
        request(app)
96
        .get('/todos/' + hexID)
97
        .set('x-auth', dummyUsers[0].tokens[0].token)        
98
        .expect(404)
99
        .end(done);
100
    });
101
102
    it('should return a 422 if todo id is invalid', (done) => {
103
        request(app)
104
        .get(`/todos/${dummyTodos[0]._id.toHexString() + '21ab'}`)
105
        .set('x-auth', dummyUsers[0].tokens[0].token)        
106
        .expect(422)
107
        .end(done);
108
    });
109
});
110
111
describe('DELETE /todos/:id', () => {
112
113
    let hexID = new ObjectID();    
114
115
    it('should delete a todo for a valid id', (done) => {
116
        let todoHexID = dummyTodos[0]._id.toHexString();
117
118
        request(app)
119
        .delete(`/todos/${todoHexID}`)
120
        .set('x-auth', dummyUsers[0].tokens[0].token)
121
        .expect(200)
122
        .expect((res) => {
123
            expect(res.body.todo._id).toBe(todoHexID);
124
            expect(res.body.status).toBe(200);
125
        })
126
        .end((err, res) => {
0 ignored issues
show
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
127
            if(err) {
128
                return done(err);
129
            }
130
131
            Todo.findById(todoHexID).then((todo) => {
132
                expect(todo).toNotExist();
133
                done();
134
            }).catch((err) => done(err));
0 ignored issues
show
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
135
        });
136
    });
137
    
138
    it('should not delete a todo created by other user', (done) => {
139
        let todoHexID = dummyTodos[2]._id.toHexString();
140
141
        request(app)
142
        .delete(`/todos/${todoHexID}`)
143
        .set('x-auth', dummyUsers[0].tokens[0].token)
144
        .expect(404)
145
        .end((err, res) => {
0 ignored issues
show
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
146
            if(err) {
147
                return done(err);
148
            }
149
150
            Todo.findById(todoHexID).then((todo) => {
151
                expect(todo).toExist();
152
                done();
153
            }).catch((err) => done(err));
0 ignored issues
show
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
154
        });
155
    });
156
157
    it('should give 400 for invalid id', (done) => {
158
        request(app)
159
        .delete(`/todos/${hexID.toHexString() + '45'}`)
160
        .set('x-auth', dummyUsers[0].tokens[0].token)        
161
        .expect(400)
162
        .expect((res) => {
163
            expect(res.body.status).toBe(400);
164
        })
165
        .end(done);
166
    });
167
168
    it('should give 404 if todo not found', (done) => {
169
        request(app)
170
        .delete(`/todos/${hexID.toHexString()}`)
171
        .set('x-auth', dummyUsers[0].tokens[0].token)        
172
        .expect(404)
173
        .expect((res) => {
174
            expect(res.body.status).toBe(404);
175
        })
176
        .end(done);
177
    });
178
});
179
180
describe('PATCH /todos/:id', () => {
181
182
    it('should set completed of a todo as true', (done) => {
183
        let hexID = dummyTodos[0]._id.toHexString();
184
        let text = 'This should be the new text';
185
186
        request(app)
187
        .patch(`/todos/${hexID}`)
188
        .set('x-auth', dummyUsers[0].tokens[0].token)
189
        .send({
190
            text,
191
            completed : true
192
        })
193
        .expect(200)
194
        .expect((res) => {
195
            expect(res.body.todo.text).toBe(text);
196
            expect(res.body.todo.completed).toBe(true);
197
            expect(res.body.todo.completedAt).toBeA('number');
198
        })
199
        .end(done); 
200
    }); 
201
202
    it('should not set completed of a todo as true for other user', (done) => {
203
        let hexID = dummyTodos[2]._id.toHexString();
204
        let text = 'This should be the new text';
205
206
        request(app)
207
        .patch(`/todos/${hexID}`)
208
        .set('x-auth', dummyUsers[0].tokens[0].token)
209
        .send({
210
            text,
211
            completed : true
212
        })
213
        .expect(404)
214
        .end(done); 
215
    }); 
216
217
    it('should clear completed when todo edited/renamed', (done) => {
218
        let hexID = dummyTodos[1]._id.toHexString();
219
        text = 'Renamed to a new task';
0 ignored issues
show
The variable text seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.text.
Loading history...
220
221
        request(app)
222
        .patch(`/todos/${hexID}`)
223
        .set('x-auth', dummyUsers[0].tokens[0].token)
224
        .send({
225
            completed : false,
226
            completedAt : null,
227
            text
228
        })
229
        .expect(200)
230
        .expect((res) => {
231
            expect(res.body.todo.completed).toBe(false);
232
            expect(res.body.todo.text).toBe(text);
233
            expect(res.body.todo.completedAt).toNotExist();
234
            
235
        })
236
        .end(done);
237
238
    });
239
240
});
241
242
describe('GET /users/me', () => {
243
244
    it('should return a user for valid token', (done) => {
245
        request(app)
246
        .get('/users/me')
247
        .set('x-auth', dummyUsers[0].tokens[0].token)
248
        .expect(200)
249
        .expect((res) => {
250
            //console.log('**Response', res.body);
251
            expect(res.body.user._id).toBe(dummyUsers[0]._id.toHexString());
252
            expect(res.body.user.email).toBe(dummyUsers[0].email);
253
        }).end(done);
254
    });
255
256
    it('should give 401 for invalid token', (done) => {
257
        let value = undefined;
0 ignored issues
show
Unused Code Comprehensibility introduced by
The assignment of undefined is not necessary as value is implicitly marked as undefined by the declaration.
Loading history...
The variable value seems to be never used. Consider removing it.
Loading history...
258
        request(app)
259
        .get('/users/me')
260
        .expect(401)
261
        .expect((res) => {
262
            expect(res.body.status).toBe(401)
263
        }).end(done);        
264
    }); 
265
});
266
267
describe('POST /users', () => {
268
    it('should create a user with valid email and name', (done) => {
269
        let name = 'example';
270
        let email = '[email protected]';
271
        let password = 'example@pass';
272
273
        request(app)
274
        .post('/users')
275
        .send({name, email, password})
276
        .expect(200)
277
        .expect((res) => {
278
            expect(res.body.user.email).toBe(email);
279
            expect(res.body.user._id).toExist();
280
            expect(res.headers['x-auth']).toExist();
281
        }).end((err) => {
282
            if (err) {
283
                return done();
284
            }
285
            User.findOne({email}).then((user) => {
286
                expect(user).toExist();
287
                expect(user.email).toBe(email);
288
                expect(user.password).toNotBe(password);
289
                done();
290
            }).catch((err) => done(err));
0 ignored issues
show
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
291
        });
292
    });
293
294
    it('should give validation error for invalid data', (done) => {
295
        let email = 'error';
0 ignored issues
show
The variable email seems to be never used. Consider removing it.
Loading history...
296
        let password = 'abc';
0 ignored issues
show
The variable password seems to be never used. Consider removing it.
Loading history...
297
        
298
        request(app)
299
        .post('/users')
300
        .send({})
301
        .expect(400)
302
        .end(done);
303
    });
304
305
    it('should give a 400 for duplicate email', (done) => {
306
        request(app)
307
        .post('/users')
308
        .send(dummyUsers[0])
309
        .expect(400)
310
        .end(done);
311
    });
312
});
313
314
describe('POST /users/login', () => {
315
316
    it('should return a token and user for valid login', (done) => {
317
        
318
        request(app)
319
        .post('/users/login')
320
        .send({
321
            email : dummyUsers[1].email,
322
            password : dummyUsers[1].password
323
        })
324
        .expect(200)
325
        .expect((res) => {
326
            //console.log('**Res Body => ', res.body);
327
            expect(res.headers['x-auth']).toExist();
328
            expect(res.body.user.email).toBe(dummyUsers[1].email);
329
        }).end((err, res) => {
330
            if(err) {
331
                return done(err);
332
            }
333
334
            User.findById(dummyUsers[1]._id).then((user) => {
335
                expect(user.tokens[1]).toInclude({
336
                    access : 'auth',
337
                    token : res.headers['x-auth']
338
                });
339
                done();
340
            }).catch((err) => done(err));
0 ignored issues
show
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
341
        });
342
    });
343
344
    it('should return 500 for invalid email and password', (done) => {
345
        
346
        request(app)
347
        .post('/users/login')
348
        .send({
349
            email : dummyUsers[1].email,
350
            password : dummyUsers[1].password + 'abc'
351
        })
352
        .expect(500)
353
        .expect((res) => {
354
            expect(res.headers['x-auth']).toNotExist();
355
        }).end((err, res) => {
0 ignored issues
show
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
356
            if(err) {
357
                return done(err);
358
            }
359
360
            User.findById(dummyUsers[1]._id).then((user) => {
361
                expect(user.tokens.length).toBe(1);
362
                done();
363
            }).catch((err) => done(err));
0 ignored issues
show
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
364
        });
365
    });
366
});
367
368
describe('DELETE /users/logout', () => {
369
    it('should remove the valid token on logout', (done) => {
370
371
        request(app)
372
        .delete('/users/logout')
373
        .set('x-auth', dummyUsers[0].tokens[0].token)
374
        .expect(204)
375
        .end((err, res) => {
0 ignored issues
show
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
376
            if(err) {
377
                return done(err);
378
            }
379
380
            User.findById(dummyUsers[0]._id).then((user) => {
381
                expect(user.tokens.length).toBe(0);
382
                done();
383
            }).catch((err) => done(err));
0 ignored issues
show
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
384
        });
385
    });
386
});