1 | import mongoose from 'mongoose' |
||
2 | import chai from 'chai' |
||
3 | import sinon from 'sinon' |
||
4 | import User from '../models/user' |
||
5 | import { allUsers } from '../app/user' |
||
6 | import factories from './factories' |
||
7 | |||
8 | const expect = chai.expect |
||
9 | |||
10 | describe('Mongoose Database test', () => { |
||
11 | // Before starting this test, we will create a sandboxed database connection |
||
12 | // Once connection is done, invoke done() |
||
13 | |||
14 | before((done) => { |
||
15 | mongoose.Promise = require('bluebird') |
||
16 | mongoose.connect('mongodb://localhost/testApp') |
||
17 | const db = mongoose.connection |
||
18 | db.on('error', () => console.error.bind(console, 'connection error!!')) |
||
19 | .once('open', () => { |
||
20 | console.log('We are connected to database.') |
||
21 | done() |
||
22 | }) |
||
23 | }) |
||
24 | |||
25 | // Test mongoose model ( required: true ) |
||
26 | describe('Mongoose model test', () => { |
||
27 | it('Should be invalid if name is empty', done => { |
||
28 | var user = new User() |
||
29 | user.validate(err => { |
||
30 | expect(err.errors.name).to.exist |
||
31 | done() |
||
32 | }) |
||
33 | }) |
||
34 | |||
35 | // if canPost = true, isAdmin = false then, canPost is required |
||
36 | it('Should have validation error for canPost if not isAdmin', (done) => { |
||
37 | const user = new User({ canPost: true }) |
||
38 | |||
39 | user.validate(err => { |
||
40 | expect(err.errors.canPost).to.exist |
||
41 | done() |
||
42 | }) |
||
43 | }) |
||
44 | |||
45 | // if canPost = true, isAdmin = true then, canPost is not required |
||
46 | it('should be valid canPost when isAdmin', done => { |
||
47 | const user = new User({ isAdmin: true, canPost: true}) |
||
48 | |||
49 | user.validate(err => { |
||
50 | expect(err.errors.canPost).to.not.exist |
||
51 | done() |
||
52 | }) |
||
53 | }) |
||
54 | }) |
||
55 | |||
56 | |||
57 | // Testing model instance methods |
||
58 | describe('Testing model instance methods', () => { |
||
59 | /* |
||
60 | * You’d typically have two kinds of instance methods on your models: |
||
61 | * 1) Instance methods which do not access the database |
||
62 | * 2) Instance methods which access the database |
||
63 | */ |
||
64 | |||
65 | beforeEach(function() { |
||
66 | sinon.stub(User, 'findOne') |
||
67 | }) |
||
68 | |||
69 | |||
70 | afterEach(function() { |
||
71 | User.findOne.restore() |
||
72 | }) |
||
73 | |||
74 | // Testing the checkForCanPost method |
||
75 | it('Should check for canpost with the same name', () => { |
||
76 | |||
77 | /* |
||
78 | * This is the function that would get called, |
||
79 | * so we stub it out so it doesn’t do any database access. |
||
80 | * Stubbing it also allows us to use Sinon to check whether it was called with the |
||
81 | * correct parameters. |
||
82 | */ |
||
83 | User.findOne |
||
84 | |||
85 | const expectedName = 'This name should be used in the check' |
||
86 | const user = new User({ name: expectedName }) |
||
87 | |||
88 | user.checkForCanPost(() => {}) |
||
89 | |||
90 | /* |
||
91 | * we use sinon.assert.calledWith to check the stubbed finder was called correctly. |
||
92 | */ |
||
93 | sinon.assert.calledWith(User.findOne, { |
||
94 | name: expectedName, |
||
95 | canPost: true |
||
96 | }) |
||
97 | }) |
||
98 | |||
99 | // another test for this to confirm the result from findOne is handled correctly |
||
100 | it('should call back with true when canPost exists', done => { |
||
101 | const canPostObject = { name: 'Madhav'} |
||
102 | |||
103 | /* |
||
104 | * The yields function on a stub makes it automatically call any callback function |
||
105 | * with a certain set of parameters – in this case, we’re passing null to signify |
||
106 | * no error, and the cannPostObject to act as a found Mongoose model. |
||
107 | */ |
||
108 | User.findOne.yields(null, canPostObject) |
||
109 | const user = new User({ name: 'Some name' }) |
||
110 | |||
111 | /* |
||
112 | * This time we use a callback in checkForCanPost to do the assertion, as we want to |
||
113 | * ensure it was called with the correct value. |
||
114 | */ |
||
115 | user.checkForCanPost(function(hasCanPost) { |
||
116 | expect(hasCanPost).to.be.true |
||
117 | done() |
||
118 | }) |
||
119 | }) |
||
120 | |||
121 | |||
122 | |||
123 | }) |
||
124 | |||
125 | describe('Mongoose database external functions test', () => { |
||
126 | beforeEach(function() { |
||
127 | sinon.stub(User, 'find') |
||
128 | }) |
||
129 | |||
130 | |||
131 | afterEach(function() { |
||
132 | User.find.restore() |
||
133 | }) |
||
134 | // Should send all users |
||
135 | it('Should send all users', () => { |
||
136 | const a = factories.validUser |
||
137 | const b = factories.validUser |
||
138 | const expectedModels = [a, b] |
||
139 | User.find.yields(null, expectedModels) |
||
140 | const req = { params: { } } |
||
141 | const res = { |
||
142 | send: sinon.stub() |
||
143 | } |
||
144 | |||
145 | allUsers(req, res) |
||
146 | sinon.assert.calledWith(res.send, expectedModels) |
||
147 | }) |
||
148 | |||
149 | /* |
||
150 | * In this one we’re setting up some expeced data – in this case, the expected list of models |
||
151 | * the find function should return. We also set up the stub to yield the result. |
||
152 | */ |
||
153 | it('Should query for cannot post if set as request parameter', () => { |
||
154 | User.find.yields(null, []) |
||
155 | const req = { |
||
156 | params: { |
||
157 | canPost: true |
||
158 | } |
||
159 | } |
||
160 | |||
161 | const res = { send: sinon.stub() } |
||
162 | |||
163 | allUsers(req, res) |
||
164 | sinon.assert.calledWith(User.find, { canPost: true }) |
||
165 | }) |
||
166 | }) |
||
167 | |||
168 | |||
169 | // Now we test the database |
||
170 | describe('Mongoose Database Test', () => { |
||
171 | |||
172 | // save object with 'name' value of 'John' |
||
173 | it('Should save new name to test database', (done) => { |
||
174 | const testUser = User({ |
||
175 | name: 'John' |
||
176 | }) |
||
177 | testUser.save(done) |
||
178 | }) |
||
179 | |||
180 | // Dont save incorrect object to database |
||
181 | it('Should not save wrong object data', (done) => { |
||
182 | const wrongUser = User({ |
||
183 | notName: 'Somebody else' |
||
184 | }) |
||
185 | |||
186 | wrongUser.save(err => { |
||
187 | if (err) return done() |
||
0 ignored issues
–
show
|
|||
188 | throw new Error('Should generate error..') |
||
189 | }) |
||
190 | }) |
||
191 | |||
192 | // Retrieve data from test database |
||
193 | it('Should retrieve data from test database', (done) => { |
||
194 | User.find({ name: 'John' }, (err, user) => { |
||
195 | if (err) throw err |
||
0 ignored issues
–
show
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later. Consider: if (a > 0)
b = 42;
If you or someone else later decides to put another statement in, only the first statement will be executed. if (a > 0)
console.log("a > 0");
b = 42;
In this case the statement if (a > 0) {
console.log("a > 0");
b = 42;
}
ensures that the proper code will be executed conditionally no matter how many statements are added or removed. ![]() |
|||
196 | if(user.length == 0) throw new Error('No data') |
||
0 ignored issues
–
show
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later. Consider: if (a > 0)
b = 42;
If you or someone else later decides to put another statement in, only the first statement will be executed. if (a > 0)
console.log("a > 0");
b = 42;
In this case the statement if (a > 0) {
console.log("a > 0");
b = 42;
}
ensures that the proper code will be executed conditionally no matter how many statements are added or removed. ![]() |
|||
197 | done() |
||
198 | }) |
||
199 | }) |
||
200 | |||
201 | // After all test is done drop database and close connection |
||
202 | after(done => { |
||
203 | mongoose.connection.db.dropDatabase(() => { |
||
204 | mongoose.connection.close(done) |
||
205 | }) |
||
206 | }) |
||
207 | }) |
||
208 | }) |
||
209 | |||
210 | |||
211 |
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.
Consider:
If you or someone else later decides to put another statement in, only the first statement will be executed.
In this case the statement
b = 42
will always be executed, while the logging statement will be executed conditionally.ensures that the proper code will be executed conditionally no matter how many statements are added or removed.