1 | var assert = require('assert');
|
2 | var express = require('express');
|
3 | var http = require('http');
|
4 | var request = require('request');
|
5 |
|
6 | // lets start testing!!
|
7 |
|
8 | // describe an enclosure for the entire test plan
|
9 | describe('REST API', function(){
|
10 | var app, mongoose, acre;
|
11 |
|
12 | // before each of our test suites run, we need to do some setup:
|
13 | beforeEach(function(){
|
14 | // first initialize acre and its dependencies (express, and mongoose)
|
15 | app = express();
|
16 | mongoose = require('mongoose');
|
17 | acre = require('acre');
|
18 |
|
19 | // setup express (web server)
|
20 | app.configure(function(){
|
21 | acre.bodyParser(app);
|
22 | app.use(express.bodyParser());
|
23 | app.use(express.cookieParser());
|
24 | app.use(express.methodOverride());
|
25 | app.use(app.router);
|
26 | });
|
27 |
|
28 | // setup mongoose schema (database component)
|
29 | var LibrarySchema = new mongoose.Schema({
|
30 | name: {
|
31 | type: String,
|
32 | required: true,
|
33 | index: true
|
34 | },
|
35 | books: [{
|
36 | title: {
|
37 | type: String,
|
38 | required: true,
|
39 | index: true
|
40 | },
|
41 | isdn: {
|
42 | type: Number,
|
43 | required: true
|
44 | },
|
45 | author: {
|
46 | first_name: {
|
47 | type: String,
|
48 | required: true,
|
49 | index: true
|
50 | },
|
51 | last_name: {
|
52 | type: String,
|
53 | required: true,
|
54 | index: true
|
55 | }
|
56 | }
|
57 | }]
|
58 | });
|
59 | mongoose.model('Library', LibrarySchema);
|
60 | });
|
61 |
|
62 | // after each of our test suites run, we want to de-init acre and its dependencies
|
63 | // this cleanup is important as it makes sure that each test suite is run on a CLEAN
|
64 | // config, and errors arent carried over between test suites
|
65 | afterEach(function(){
|
66 | // desroy acre
|
67 | delete acre;
|
68 | acre = null;
|
69 |
|
70 | // destroy express app
|
71 | delete app;
|
72 | app = null;
|
73 |
|
74 | // this is a bit of a hacky way to de-init mongoose
|
75 | if (mongoose != null){
|
76 | delete mongoose.models.Library;
|
77 | delete mongoose.models.AcreAdmin;
|
78 | delete mongoose.modelSchemas.Library;
|
79 | delete mongoose.modelSchemas.AcreAdmin;
|
80 | delete mongoose;
|
81 | mongoose = null;
|
82 | }
|
83 | });
|
84 |
|
85 |
|
86 |
|
87 | // describe an enclosure for our test suites for the acre.init method
|
88 | describe('init()', function(){
|
89 | // before each of our test suites run, we need to do some setup:
|
90 | beforeEach(function(){
|
91 | // first initialize acre and its dependencies (express, and mongoose)
|
92 | app = express();
|
93 | mongoose = require('mongoose');
|
94 | acre = require('acre');
|
95 |
|
96 | // setup express (web server)
|
97 | app.configure(function(){
|
98 | acre.bodyParser(app);
|
99 | app.use(express.bodyParser());
|
100 | app.use(express.cookieParser());
|
101 | app.use(express.methodOverride());
|
102 | app.use(app.router);
|
103 | });
|
104 | });
|
105 |
|
106 | // after each of our test suites run, we want to de-init acre and its dependencies
|
107 | // this cleanup is important as it makes sure that each test suite is run on a CLEAN
|
108 | // config, and errors arent carried over between test suites
|
109 | afterEach(function(){
|
110 | // destroy acre
|
111 | delete acre;
|
112 | acre = null;
|
113 |
|
114 | // destroy express app
|
115 | delete app;
|
116 | app = null;
|
117 |
|
118 | // this is a bit of a hacky way to de-init mongoose
|
119 | delete mongoose.models.Library;
|
120 | delete mongoose.models.AcreAdmin;
|
121 | delete mongoose.modelSchemas.Library;
|
122 | delete mongoose.modelSchemas.AcreAdmin;
|
123 | delete mongoose;
|
124 | mongoose = null;
|
125 |
|
126 | });
|
127 |
|
128 | // acre.init method rootpath option
|
129 | it('should initialize acre and create specified rootpath (good args, rootpath options)', function(done){
|
130 | acre
|
131 | .init(mongoose, app, {rootPath: ''})
|
132 | // .init(mongoose, app, {rootPath: 'new'}) // If root path is set , all directories begin with specified path
|
133 | .then(function(){
|
134 | done();
|
135 | }, function(error){
|
136 | done(error)
|
137 | });
|
138 | });
|
139 |
|
140 | // describe an enclosure for our test suites for the acre.init method
|
141 | it('should initialize acre (good args, default options)', function(done){
|
142 | acre
|
143 | .init(mongoose, app)
|
144 | .then(function(){
|
145 | done();
|
146 | }, function(error){
|
147 | done(error)
|
148 | });
|
149 | });
|
150 |
|
151 | // acre.init method putIsCreate option
|
152 | // putIsCreate is false so only post should create
|
153 | it('should initialize acre and create using POST(good args, rootpath options)', function(done){
|
154 | acre
|
155 | .init(mongoose, app, {putIsCreate: true})
|
156 | //if putIsCreate is false, only post will create
|
157 | //.init(mongoose, app, {putIsCreate: false})
|
158 | .then(function(){
|
159 | done();
|
160 | }, function(error){
|
161 | done(error)
|
162 | });
|
163 | });
|
164 |
|
165 | // acre.init method adminPortal option
|
166 | it('should initialize acre and create using admin rights (good args, adminPortal options)', function(done){
|
167 | acre
|
168 | // .init(mongoose, app, {adminPortal: true})
|
169 | //if adminPortal is false, user does not have admin rights
|
170 | .init(mongoose, app, {adminPortal: false})
|
171 | .then(function(){
|
172 | done();
|
173 | }, function(error){
|
174 | done(error)
|
175 | });
|
176 | });
|
177 | });
|
178 |
|
179 |
|
180 |
|
181 | // describe an enclosure for our test suites for the acre.pre method
|
182 | describe('acre.pre CREATE', function(){
|
183 | var server;
|
184 |
|
185 | // before each of our acre.pre test suites run, we want to...
|
186 | beforeEach(function(done){
|
187 | // give mongoose time to connect, mongohq sandbox db is sometimes slow
|
188 | // increased timeout from 3000 to 5000
|
189 | this.timeout(5000);
|
190 |
|
191 | // setup acre and an acre.pre method that we will test with
|
192 | // this acre.pre method should reject any library created with the name 'Maxwell McOdrum'
|
193 | acre = require('acre');
|
194 | acre.pre(acre.CREATE, '/libraries', function(request, response, next){
|
195 | console.log(request.body);
|
196 | if (request.body.name === 'Maxwell McOdrum')
|
197 | {
|
198 | response.send(400, 'Bad Request');
|
199 | }
|
200 | else
|
201 | {
|
202 | request.body.name = 'Simon Says: ' + request.body.name;
|
203 | next();
|
204 | }
|
205 | });
|
206 |
|
207 | // initialize acre
|
208 | acre
|
209 | .init(mongoose, app)
|
210 | .then(function(){
|
211 | // after acre init is done, here we can connect to the database
|
212 | mongoose.connect('mongodb://test:test@paulo.mongohq.com:10088/acre-tests');
|
213 | var db = mongoose.connection;
|
214 | db.on('error', console.error.bind(console, 'connection error:'));
|
215 | db.once('open', function() {
|
216 | // after database connects, now we can start the web server
|
217 | server = http.createServer(app).listen(3000, function(){
|
218 | console.log("web server listening on port 3000...");
|
219 | done();
|
220 | });
|
221 | });
|
222 | }, function(error){
|
223 | // if acre init fails, report any errors
|
224 | done(new Error(error));
|
225 | });
|
226 |
|
227 | });
|
228 |
|
229 | afterEach(function(done){
|
230 | // give more time for cleanup
|
231 | this.timeout(1000);
|
232 |
|
233 | function cleanupWebServer()
|
234 | {
|
235 | server.once('close', function(){
|
236 | // only done once http server is shutdown
|
237 | console.log('web server closed');
|
238 | done();
|
239 | });
|
240 |
|
241 | // shutdown the web server
|
242 | server.close();
|
243 | }
|
244 |
|
245 | function cleanupDB()
|
246 | {
|
247 | function finishedDBCleanup()
|
248 | {
|
249 | // shutdown the connection to the database
|
250 | mongoose.connection.close();
|
251 | cleanupWebServer();
|
252 | }
|
253 |
|
254 | // empty the database after each test runs
|
255 | mongoose.models.Library.count(function(error, count){
|
256 | if (error)
|
257 | {
|
258 | done(error);
|
259 | }
|
260 | else
|
261 | {
|
262 | // apparently you cant empty out an empty database, so need to check first
|
263 | if (count > 0)
|
264 | {
|
265 | mongoose.connection.collections['libraries'].drop(function(error){
|
266 | if (error)
|
267 | {
|
268 | done(error);
|
269 | }
|
270 | else
|
271 | {
|
272 | finishedDBCleanup();
|
273 | }
|
274 | });
|
275 | }
|
276 | else
|
277 | {
|
278 | finishedDBCleanup();
|
279 | }
|
280 | }
|
281 | });
|
282 | }
|
283 |
|
284 | // fire off db cleanup function
|
285 | cleanupDB();
|
286 | })
|
287 |
|
288 | it('should reject library named Maxwell McOdrum', function(done){
|
289 | var library = {
|
290 | name: 'Maxwell McOdrum',
|
291 | books: []
|
292 | };
|
293 |
|
294 | // try creating a library called 'Maxwell McOdrum'
|
295 | request.put('http://localhost:3000/libraries', {json: library}, function(error, response, body){
|
296 | if (error)
|
297 | {
|
298 | done(error);
|
299 | }
|
300 | else
|
301 | {
|
302 | // we should get an error code 400
|
303 | assert.equal(response.statusCode, 400);
|
304 | // body of the response must say 'Bad Request'
|
305 | assert.equal(body, 'Bad Request');
|
306 | done();
|
307 | }
|
308 | })
|
309 | });
|
310 |
|
311 | it('should permit library not named Maxwell McOdrum', function(done){
|
312 | var library = {
|
313 | name: 'City Library',
|
314 | books: []
|
315 | };
|
316 |
|
317 | // try creating a library with name 'City Library'
|
318 | request.put('http://localhost:3000/libraries', {json: library}, function(error, response, body){
|
319 | if (error)
|
320 | {
|
321 | done(error);
|
322 | }
|
323 | else
|
324 | {
|
325 | // should pass, status code should be 200 OK, means CREATE was successful
|
326 | assert.equal(response.statusCode, 200);
|
327 |
|
328 | // check the database to see if it was indeed added
|
329 | mongoose.models.Library.find(function(error, libraries){
|
330 | if (error)
|
331 | {
|
332 | done(error);
|
333 | }
|
334 | else
|
335 | {
|
336 | // check that there is only one library in the database: the one we just added
|
337 | assert.equal(libraries.length, 1);
|
338 | // check that library name is correct as modified by our acre.pre method
|
339 | assert.equal(libraries[0].name, 'Simon Says: City Library');
|
340 | // check that the library indeed has no books
|
341 | assert.equal(libraries[0].books.length, 0);
|
342 | done();
|
343 | }
|
344 | });
|
345 | }
|
346 | })
|
347 | });
|
348 |
|
349 | });
|
350 | });
|