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.') |
||
0 ignored issues
–
show
Debugging Code
introduced
by
![]() |
|||
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() |
||
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 |
||
196 | if(user.length == 0) throw new Error('No data') |
||
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 |