1 | var oreo = require('..')
|
2 | var ok = require('assert').ok
|
3 | var fs = require('fs')
|
4 | var bluebird = require('bluebird')
|
5 | var async = require('../lib/async')
|
6 |
|
7 | var models = {
|
8 | books: require('./Book')
|
9 | }
|
10 |
|
11 | var db
|
12 | var platforms = [
|
13 | {
|
14 | driver: 'pg',
|
15 | user: 'postgres',
|
16 | pass: '',
|
17 | hosts: ['localhost:5432', 'localhost:5433', 'localhost:5430'],
|
18 | name: 'oreo_test',
|
19 | debug: false,
|
20 | silent: true,
|
21 | Promise: global.Promise || bluebird,
|
22 | models: models
|
23 | },
|
24 | {
|
25 | driver: 'pg',
|
26 | user: 'postgres',
|
27 | pass: '',
|
28 | hosts: ['localhost:5432', 'localhost:5433', 'localhost:5430'],
|
29 | name: 'oreo_test',
|
30 | debug: false,
|
31 | silent: true,
|
32 | memoize: 150,
|
33 | Promise: global.Promise || bluebird,
|
34 | models: models
|
35 | },
|
36 | {
|
37 | driver: 'mysql',
|
38 | user: 'root',
|
39 | pass: '',
|
40 | hosts: ['localhost'],
|
41 | name: 'oreo_test',
|
42 | debug: false,
|
43 | silent: true,
|
44 | Promise: global.Promise || bluebird,
|
45 | models: models
|
46 | }
|
47 | ]
|
48 |
|
49 | var showError = function (err) {
|
50 | console.log(err.stack)
|
51 | }
|
52 |
|
53 | var no = function (err) {
|
54 | ok(!err, err + '')
|
55 | }
|
56 |
|
57 | var mockRedis = function() {
|
58 | var cache = {}
|
59 | return {
|
60 | get: function(key, cb) {
|
61 | var val = cache[key]
|
62 | if (val) {
|
63 | val = JSON.parse(val)
|
64 | val.fromCache = true
|
65 | val = JSON.stringify(val)
|
66 | }
|
67 | cb(null, val)
|
68 | },
|
69 | set: function(key, val, cb) {
|
70 | cache[key] = val
|
71 | cb(null)
|
72 | }
|
73 | }
|
74 | }
|
75 |
|
76 | describe('oreo', function() {
|
77 |
|
78 | it('should fail with unknown driver', function(done) {
|
79 | db = oreo({
|
80 | driver: 'mssql'
|
81 | }, function(err) {
|
82 | ok(!!err, 'did not fail')
|
83 | done()
|
84 | })
|
85 | })
|
86 |
|
87 | platforms.forEach(function(config) {
|
88 |
|
89 | it('should connect and discover - cb', function(done) {
|
90 | console.log('\n', config.driver)
|
91 | db = oreo(config, function(err) {
|
92 | no(err)
|
93 | done()
|
94 | })
|
95 | })
|
96 |
|
97 | it('should create tables', function(done) {
|
98 | var sql = fs.readFileSync(__dirname + '/schema/' + config.driver + '.sql', 'utf8')
|
99 | db.executeWrite(sql, function(err, rs) {
|
100 | no(err)
|
101 | done()
|
102 | })
|
103 | })
|
104 |
|
105 | it('should rediscover and end - promise', function(done) {
|
106 | db.discover().then(function(db) {
|
107 | ok(!!db.authors, 'authors not discovered')
|
108 | config.schema = JSON.parse(JSON.stringify(db))
|
109 | db.authors.find().then(function () {
|
110 | var isDone = false
|
111 | db.end(function () {
|
112 | if (isDone) return
|
113 | isDone = true
|
114 | done()
|
115 | })
|
116 | })
|
117 | }).catch(showError)
|
118 | })
|
119 |
|
120 | it('should connect and discover - schema and onReady', function(done) {
|
121 | var count = 0
|
122 | var isDone = function () {
|
123 | count++
|
124 | if (count === 2) done()
|
125 | }
|
126 | db = oreo(config, function (err) {
|
127 | no(err)
|
128 | }).onReady(function() {
|
129 | isDone()
|
130 | })
|
131 | db.onReady(function () {
|
132 | ok(!!db.authors, 'authors not discovered')
|
133 | isDone()
|
134 | })
|
135 | })
|
136 |
|
137 | it('should rediscover - cb', function(done) {
|
138 | db.discover(function(err) {
|
139 | no(err)
|
140 | ok(!!db.authors, 'authors not discovered')
|
141 | done()
|
142 | })
|
143 | })
|
144 |
|
145 | it('should insert - cb', function(done) {
|
146 | db.authors.insert({
|
147 | name: 'Jack Kerouac',
|
148 | birthDate: '1922-03-12'
|
149 | }, function(err, author) {
|
150 | no(err)
|
151 | ok(author.id === 1, 'did not insert author - should insert')
|
152 | db.books.insert({
|
153 | title: 'On the Road',
|
154 | author_id: author.id
|
155 | }, function(err, book) {
|
156 | no(err)
|
157 | ok(book.id === 1, 'did not insert book')
|
158 | db.ratings.insert({
|
159 | author_id: author.id,
|
160 | book_id: book.id,
|
161 | stars: 10
|
162 | }, function(err, rating) {
|
163 | no(err)
|
164 | ok(rating.stars === 10, 'did not insert rating')
|
165 | done()
|
166 | })
|
167 | })
|
168 | })
|
169 | })
|
170 |
|
171 | it('should insert - promise', function(done) {
|
172 | db.authors.insert({
|
173 | name: 'Tom Wolfe',
|
174 | birthDate: '1931-03-02'
|
175 | }).then(function(author) {
|
176 | ok(author.id === 2, 'did not insert author - should insert')
|
177 | db.books.insert({
|
178 | title: 'The Electric Kool-Aid Acid Test',
|
179 | author_id: author.id
|
180 | }).then(function(book) {
|
181 | ok(book.id === 2, 'did not insert book')
|
182 | db.ratings.insert({
|
183 | author_id: author.id,
|
184 | book_id: book.id,
|
185 | stars: 9
|
186 | }).then(function(rating) {
|
187 | ok(rating.stars === 9, 'did not insert rating')
|
188 | done()
|
189 | })
|
190 | })
|
191 | }).catch(showError)
|
192 | })
|
193 |
|
194 | it('should save field with same name as 1-to-m fk - cb', function(done) {
|
195 | db.authors.save({
|
196 | id: 2,
|
197 | books: [2]
|
198 | }, function(err, author) {
|
199 | no(err)
|
200 | db.authors.get(2, function(err, author) {
|
201 | ok(author.books.toString() === '2', 'did not save books value')
|
202 | author.hydrate('books', function (err) {
|
203 | ok(!!err, 'books should not be hydratable')
|
204 | done()
|
205 | })
|
206 | })
|
207 | })
|
208 | })
|
209 |
|
210 | it('should not save 1-to-m row with same name as field - cb', function(done) {
|
211 | db.authors.save({
|
212 | id: 2,
|
213 | books: [
|
214 | {id: 2, author_id: 2, title: 'Working Title'}
|
215 | ]
|
216 | }, function(err, author) {
|
217 | ok(!!err, 'books should not save')
|
218 | done()
|
219 | })
|
220 | })
|
221 |
|
222 | it('should save field with same name as 1-to-1 fk - cb', function(done) {
|
223 | db.authors.save({
|
224 | id: 2,
|
225 | Country: {
|
226 | Code: 'US',
|
227 | name: 'United States'
|
228 | }
|
229 | }, function(err, author) {
|
230 | no(err)
|
231 | ok(author.Country === 'US', 'author.Country')
|
232 | db.authors.get(2, function(err, author) {
|
233 | no(err)
|
234 | ok(author.Country === 'US', 'did not save author.Country')
|
235 | author.hydrate('Country', function (err) {
|
236 | no(err)
|
237 | ok(author.Country.name === 'United States', 'author.Country.name')
|
238 | author.Country.update({
|
239 | name: 'USA'
|
240 | }, function (err, Country) {
|
241 | no(err)
|
242 | ok(Country.name === 'USA', 'Country.name not USA')
|
243 | author.update({
|
244 | Country: {
|
245 | Code: 'CA',
|
246 | name: 'Canada'
|
247 | }
|
248 | }, function (err, author) {
|
249 | no(err)
|
250 | ok(author.Country === 'CA', 'author.Country not CA')
|
251 | author.update({
|
252 | Country: 'MX'
|
253 | }, function (err, author) {
|
254 | ok(!!err, 'should violate fk constraint')
|
255 | db.authors.get(2, function (err, author) {
|
256 | no(err)
|
257 | ok(author.Country === 'CA', 'author.Country should still be CA')
|
258 | done()
|
259 | })
|
260 | })
|
261 | })
|
262 | })
|
263 | })
|
264 | })
|
265 | })
|
266 | })
|
267 |
|
268 | it('should static save - cb', function(done) {
|
269 | var data = {
|
270 | id: 1408,
|
271 | name: 'Stephen King'
|
272 | }
|
273 | db.authors.save(data, function(err, author) {
|
274 | no(err)
|
275 | ok(author.id === 1408, 'did not insert author')
|
276 | db.authors.save(data, function(err, author) {
|
277 | no(err)
|
278 | ok(author.id === 1408, 'did not update author')
|
279 | done()
|
280 | })
|
281 | })
|
282 | })
|
283 |
|
284 | it('should static save - promise', function(done) {
|
285 | var data = {
|
286 | id: 1984,
|
287 | name: 'George Orwell'
|
288 | }
|
289 | db.authors.save(data).then(function(author) {
|
290 | ok(author.id === 1984, 'did not insert author')
|
291 | db.authors.save(data).then(function(author) {
|
292 | ok(author.id === 1984, 'did not update author')
|
293 | done()
|
294 | })
|
295 | }).catch(showError)
|
296 | })
|
297 |
|
298 | it('should get - cb', function(done) {
|
299 | db.authors.get(1, function(err, author) {
|
300 | no(err)
|
301 | ok(author.birthDate === '1922-03-12', 'did not return correct date string')
|
302 | ok(author.id === 1, 'did not get author')
|
303 | done()
|
304 | })
|
305 | })
|
306 |
|
307 | it('should get - promise', function(done) {
|
308 | db.authors.get(1).then(function(author) {
|
309 | ok(author.id === 1, 'did not get author')
|
310 | done()
|
311 | }).catch(showError)
|
312 | })
|
313 |
|
314 | it('should parameterize array of numbers', function () {
|
315 | return db.execute(
|
316 | 'select * from authors where id in (:ids)',
|
317 | { ids: [1, 2] }
|
318 | ).then(function (authors) {
|
319 | ok(authors.length === 2)
|
320 | })
|
321 | })
|
322 |
|
323 | it('should parameterize array of strings', function () {
|
324 | return db.execute(
|
325 | 'select * from authors where name in (:names)',
|
326 | { names: ['Tom Wolfe', 'Jack Kerouac'] }
|
327 | ).then(function (authors) {
|
328 | ok(authors.length === 2)
|
329 | })
|
330 | })
|
331 |
|
332 | it('should get id=0 - promise', function (done) {
|
333 | if (config.driver === 'mysql') {
|
334 | return done()
|
335 | }
|
336 | db.authors.insert({
|
337 | id: 0,
|
338 | name: 'Nobody'
|
339 | })
|
340 | .then(function (author) {
|
341 | db.authors.get(0)
|
342 | .then(function (author) {
|
343 | ok(author.id === 0, 'did not get author')
|
344 | author.delete()
|
345 | .then(function () {
|
346 | done()
|
347 | })
|
348 | })
|
349 | })
|
350 | })
|
351 |
|
352 | it('should mget - cb', function(done) {
|
353 | db.authors.mget([1, 1984], function(err, authors) {
|
354 | no(err)
|
355 | ok(authors[0].id === 1, 'did not get authors')
|
356 | ok(authors[1].id === 1984, 'did not get second author')
|
357 | done()
|
358 | })
|
359 | })
|
360 |
|
361 | it('should mget with null value - promise', function(done) {
|
362 | db.authors.mget([1984, 999999, 1]).then(function(authors) {
|
363 | ok(authors[0].id === 1984, 'did not get first author')
|
364 | ok(authors[1] === null, 'second author is not null')
|
365 | ok(authors[2].id === 1, 'did not get third author')
|
366 | done()
|
367 | }).catch(showError)
|
368 | })
|
369 |
|
370 | it('should get (composite primary key object)', function(done) {
|
371 | db.ratings.get({
|
372 | author_id: 1,
|
373 | book_id: 1
|
374 | }, function(err, rating) {
|
375 | no(err)
|
376 | ok(rating.stars === 10, 'did not get rating')
|
377 | done()
|
378 | })
|
379 | })
|
380 |
|
381 | it('should get (composite primary key array)', function(done) {
|
382 | db.ratings.get([1, 1], function(err, rating) {
|
383 | no(err)
|
384 | ok(rating.stars === 10, 'did not get rating')
|
385 | done()
|
386 | })
|
387 | })
|
388 |
|
389 | it('should find all - cb', function(done) {
|
390 | db.authors.find(function(err, authors) {
|
391 | no(err)
|
392 | ok(authors.length === 4, 'authors.length')
|
393 | done()
|
394 | })
|
395 | })
|
396 |
|
397 | it('should find all - promise', function(done) {
|
398 | db.authors.find().then(function(authors) {
|
399 | ok(authors.length === 4, 'authors.length')
|
400 | done()
|
401 | }).catch(showError)
|
402 | })
|
403 |
|
404 | it('should count - promise', function(done) {
|
405 | db.authors.count().then(function(count) {
|
406 | ok(count === 4, 'count')
|
407 | done()
|
408 | }).catch(showError)
|
409 | })
|
410 |
|
411 | it('should find (where string)', function(done) {
|
412 | db.authors.find({
|
413 | where: "name = 'Jack Kerouac'"
|
414 | }, function(err, authors) {
|
415 | no(err)
|
416 | ok(authors[0].id === 1, 'did not find author')
|
417 | done()
|
418 | })
|
419 | })
|
420 |
|
421 | it('should find (case-sensitive)', function(done) {
|
422 | db.authors.find({
|
423 | where: {
|
424 | Country: 'CA'
|
425 | }
|
426 | }, function(err, authors) {
|
427 | no(err)
|
428 | ok(authors[0].id === 2, 'did not find author')
|
429 | done()
|
430 | })
|
431 | })
|
432 |
|
433 | it('should find (where array)', function(done) {
|
434 | db.authors.find({
|
435 | where: ["name = 'Jack Kerouac'"]
|
436 | }, function(err, authors) {
|
437 | no(err)
|
438 | ok(authors[0].id === 1, 'did not find author')
|
439 | done()
|
440 | })
|
441 | })
|
442 |
|
443 | it('should find (where parameterized array)', function(done) {
|
444 | var opts = {
|
445 | where: ['name = :name'],
|
446 | params: {
|
447 | name: 'Jack Kerouac'
|
448 | }
|
449 | }
|
450 | db.authors.find(opts, function(err, authors) {
|
451 | no(err)
|
452 | ok(authors[0].id === 1, 'did not find author')
|
453 | ok(authors[0].name === opts.params.name, 'did not find author name')
|
454 | done()
|
455 | })
|
456 | })
|
457 |
|
458 | it('should find (where object)', function(done) {
|
459 | db.authors.find({
|
460 | where: {
|
461 | name: 'Jack Kerouac'
|
462 | }
|
463 | }, function(err, authors) {
|
464 | no(err)
|
465 | ok(authors[0].id === 1, 'did not find author')
|
466 | done()
|
467 | })
|
468 | })
|
469 |
|
470 | it('should find (composite primary key)', function(done) {
|
471 | db.ratings.find({
|
472 | where: {
|
473 | stars: 10
|
474 | }
|
475 | }, function(err, ratings) {
|
476 | no(err)
|
477 | ok(ratings[0].author_id === 1, 'did not find rating')
|
478 | done()
|
479 | })
|
480 | })
|
481 |
|
482 | it('should order by', function(done) {
|
483 | db.authors.find({
|
484 | order: 'id desc'
|
485 | }).then(function(authors) {
|
486 | ok(authors[0].id === 1984, 'order first')
|
487 | ok(authors[1].id === 1408, 'order second')
|
488 | done()
|
489 | }).catch(showError)
|
490 | })
|
491 |
|
492 | it('should limit', function(done) {
|
493 | db.authors.find({
|
494 | limit: 2
|
495 | }).then(function(authors) {
|
496 | ok(authors.length === 2, 'limit')
|
497 | done()
|
498 | }).catch(showError)
|
499 | })
|
500 |
|
501 | it('should offset', function(done) {
|
502 | db.authors.find({
|
503 | order: 'id desc',
|
504 | limit: 1,
|
505 | offset: 1
|
506 | }).then(function(authors) {
|
507 | ok(authors[0].id === 1408, 'offset')
|
508 | done()
|
509 | }).catch(showError)
|
510 | })
|
511 |
|
512 | it('should findOne - cb', function(done) {
|
513 | db.authors.findOne({
|
514 | where: "name = 'Jack Kerouac'"
|
515 | }, function(err, author) {
|
516 | no(err)
|
517 | ok(author.id === 1, 'did not findOne author')
|
518 | done()
|
519 | })
|
520 | })
|
521 |
|
522 | it('should findOne - promise', function(done) {
|
523 | db.authors.findOne({
|
524 | where: "name = 'Jack Kerouac'"
|
525 | }).then(function(author) {
|
526 | ok(author.id === 1, 'did not findOne author')
|
527 | done()
|
528 | }).catch(showError)
|
529 | })
|
530 |
|
531 | it('should update - cb', function(done) {
|
532 | db.authors.get(1, function(err, author) {
|
533 | no(err)
|
534 | var new_name = 'Jim Kerouac'
|
535 | author.update({
|
536 | name: new_name
|
537 | }, function(err, author) {
|
538 | no(err)
|
539 | ok(author.id === 1, 'did not get correct author')
|
540 | ok(author.name === new_name, 'did not update author')
|
541 | done()
|
542 | })
|
543 | })
|
544 | })
|
545 |
|
546 | it('should update - promise', function(done) {
|
547 | db.authors.get(1).then(function(author) {
|
548 | var new_name = 'Jeff Kerouac'
|
549 | author.update({
|
550 | name: new_name
|
551 | }).then(function(author) {
|
552 | ok(author.id === 1, 'did not get correct author')
|
553 | ok(author.name === new_name, 'did not update author')
|
554 | done()
|
555 | })
|
556 | }).catch(showError)
|
557 | })
|
558 |
|
559 | it('should hydrate - cb', function(done) {
|
560 | db.books.get(1, function(err, book) {
|
561 | no(err)
|
562 | book.hydrate('author', function(err) {
|
563 | ok(book.author.id === book.author_id, 'did not hydrate author')
|
564 | ok(book.id === 1, 'weird')
|
565 | done()
|
566 | })
|
567 | })
|
568 | })
|
569 |
|
570 | it('should hydrate - promise', function(done) {
|
571 | db.books.get(1).then(function(book) {
|
572 | book.hydrate('author').then(function() {
|
573 | ok(book.author.id === book.author_id, 'did not hydrate author')
|
574 | ok(book.id === 1, 'weird')
|
575 | done()
|
576 | })
|
577 | }).catch(showError)
|
578 | })
|
579 |
|
580 | it('should hydrate composite foreign key', function(done) {
|
581 | db.samples.insert({
|
582 | author_id: 1,
|
583 | book_id: 1,
|
584 | description: 'this is an example'
|
585 | }, function(err, data) {
|
586 | no(err)
|
587 | db.samples.get(data.id, function(err, sample) {
|
588 | sample.hydrate('rating', function(err) {
|
589 | ok(sample.rating.stars === 10, 'did not hydrate rating')
|
590 | done()
|
591 | })
|
592 | })
|
593 | })
|
594 | })
|
595 |
|
596 | it('should hydrate 1-to-m - promise', function(done) {
|
597 | db.authors.get(1).then(function(author) {
|
598 | author.hydrate('author:books').then(function() {
|
599 | ok(author['author:books'].length === 1, 'did not hydrate author:books')
|
600 | ok(!!author['author:books'][0].title, 'author:books[0].title')
|
601 | done()
|
602 | })
|
603 | }).catch(showError)
|
604 | })
|
605 |
|
606 | it('should hydrate 1-to-m shorthand - promise', function(done) {
|
607 | db.books.get(1).then(function(book) {
|
608 | return book.hydrate('samples').then(function() {
|
609 | ok(!!book.samples[0].description, 'book.samples[0].description')
|
610 | done()
|
611 | })
|
612 | }).catch(showError)
|
613 | })
|
614 |
|
615 | it('should not hydrate ambiguous 1-to-m - promise', function(done) {
|
616 | db.battles.insert({
|
617 | author1_id: 1,
|
618 | author2_id: 2
|
619 | }).then(function (battle) {
|
620 | return battle.hydrate('a1').then(function () {
|
621 | var author = battle.a1
|
622 | return author.hydrate('battles')
|
623 | })
|
624 | }).catch(function (err) {
|
625 | ok(!!err, 'should have ambiguous hydration error')
|
626 | done()
|
627 | }).catch(showError)
|
628 | })
|
629 |
|
630 | it('should hydrate non-ambiguous 1-to-m - promise', function(done) {
|
631 | db.battles.insert({
|
632 | author1_id: 2,
|
633 | author2_id: 1
|
634 | }).then(function (battle) {
|
635 | db.authors.get(1).then(function (author) {
|
636 | author.hydrate(['a1:battles', 'a2:battles']).then(function () {
|
637 | ok(!!author['a1:battles'][0].id, 'a1.battles.id')
|
638 | ok(!!author['a2:battles'][0].id, 'a2.battles.id')
|
639 | done()
|
640 | })
|
641 | })
|
642 | }).catch(showError)
|
643 | })
|
644 |
|
645 | it('should not hydrate wrong 1-to-m - promise', function(done) {
|
646 | db.books.get(1).then(function(book) {
|
647 | return book.hydrate('author:books')
|
648 | }).catch(function (err) {
|
649 | ok(!!err, 'should have error')
|
650 | done()
|
651 | }).catch(showError)
|
652 | })
|
653 |
|
654 | it('should not hydrate shorthand 1-to-m conflicting column name - promise', function(done) {
|
655 | db.authors.get(1).then(function(author) {
|
656 | return author.hydrate('books')
|
657 | }).catch(function (err) {
|
658 | ok(!!err, 'should have error')
|
659 | done()
|
660 | }).catch(showError)
|
661 | })
|
662 |
|
663 | it('should hydrate in parallel - cb', function(done) {
|
664 | db.samples.get(1, function(err, sample) {
|
665 | ok(!err, err)
|
666 | async.each([
|
667 | function(next) {
|
668 | sample.hydrate('book', next)
|
669 | },
|
670 | function(next) {
|
671 | sample.hydrate('rating', next)
|
672 | }
|
673 | ], function (fn, end) {
|
674 | fn(end)
|
675 | }, function (err) {
|
676 | no(err)
|
677 | ok(sample.book.id === sample.book_id, 'did not hydrate book')
|
678 | ok(sample.rating.author_id === sample.author_id, 'did not hydrate rating')
|
679 | done()
|
680 | })
|
681 | })
|
682 | })
|
683 |
|
684 | it('should hydrate multiple in parallel - promise', function(done) {
|
685 | db.samples.get(1).then(function(sample) {
|
686 | sample.hydrate(['book', 'rating']).then(function () {
|
687 | ok(sample.book.id === sample.book_id, 'did not hydrate book')
|
688 | ok(sample.rating.author_id === sample.author_id, 'did not hydrate rating')
|
689 | done()
|
690 | })
|
691 | }).catch(showError)
|
692 | })
|
693 |
|
694 | it('should get and hydrate - promise', function(done) {
|
695 | db.samples.get([1, 1], {
|
696 | hydrate: ['book', 'rating']
|
697 | }).then(function(sample) {
|
698 | ok(!!sample.id, 'sample.id')
|
699 | ok(!!sample.book.id, 'sample.book.id')
|
700 | ok(!!sample.rating.stars, 'sample.rating')
|
701 | done()
|
702 | }).catch(showError)
|
703 | })
|
704 |
|
705 | it('should find and hydrate - promise', function(done) {
|
706 | db.books.find({
|
707 | hydrate: 'author'
|
708 | }).then(function(books) {
|
709 | ok(!!books[0].id, 'books[0].id')
|
710 | ok(!!books[0].author.id, 'books[0].author.id')
|
711 | ok(!!books[1].id, 'books[1].id')
|
712 | ok(!!books[1].author.id, 'books[1].author.id')
|
713 | done()
|
714 | }).catch(showError)
|
715 | })
|
716 |
|
717 | it('should findOne and hydrate - cb', function(done) {
|
718 | db.books.findOne({
|
719 | hydrate: ['author']
|
720 | }, function(err, book) {
|
721 | no(err)
|
722 | ok(!!book.id, 'book.id')
|
723 | ok(!!book.author.id, 'book.author.id')
|
724 | done()
|
725 | })
|
726 | })
|
727 |
|
728 | it('should set', function(done) {
|
729 | db.authors.get(1, function(err, author) {
|
730 | no(err)
|
731 | var old_name = author.name
|
732 | var new_name = 'Jack Kerouac'
|
733 | author.set({
|
734 | name: new_name
|
735 | })
|
736 | ok(author._data.name === old_name, 'did not set old name')
|
737 | ok(author.name === new_name, 'did not set new name')
|
738 | done()
|
739 | })
|
740 | })
|
741 |
|
742 | it('should save a row instance - cb', function(done) {
|
743 | db.authors.get(1, function(err, author) {
|
744 | no(err)
|
745 | var new_name = 'Jack2'
|
746 | author.set({
|
747 | name: new_name
|
748 | })
|
749 | author.save(function(err, author) {
|
750 | ok(!err, err)
|
751 | ok(author.id === 1, 'did not get correct author')
|
752 | ok(author.name === new_name, 'did not save author')
|
753 | db.authors.get(1, function(err, author) {
|
754 | ok(!err, err)
|
755 | ok(author.name === new_name, 'did not save new name')
|
756 | done()
|
757 | })
|
758 | })
|
759 | })
|
760 | })
|
761 |
|
762 | it('should save a row instance - promise', function(done) {
|
763 | db.authors.get(1).then(function(author) {
|
764 | var new_name = 'Jack3'
|
765 | author.set({
|
766 | name: new_name
|
767 | })
|
768 | author.save().then(function(author) {
|
769 | ok(author.id === 1, 'did not get correct author')
|
770 | ok(author.name === new_name, 'did not save author')
|
771 | db.authors.get(1).then(function(author) {
|
772 | ok(author.name === new_name, 'did not save new name')
|
773 | done()
|
774 | })
|
775 | })
|
776 | }).catch(showError)
|
777 | })
|
778 |
|
779 | xit('should error when calling save(data)', function(done) {
|
780 | db.authors.get(1, function(err, author) {
|
781 | no(err)
|
782 | author.save({ name: 'Jack2' }, function(err, author) {
|
783 | ok(!!err, err)
|
784 | done()
|
785 | })
|
786 | })
|
787 | })
|
788 |
|
789 | it('should instantiate model and use constructor - cb', function(done) {
|
790 | db.books.get(1, function(err, book) {
|
791 | no(err)
|
792 | ok(book instanceof db.books.Row, 'incorrect type')
|
793 | ok(book.getTitle() === book.title, 'did not get title')
|
794 | ok(book.getTitle2() === book.title, 'did not run model constructor')
|
795 | var desc = Object.getOwnPropertyDescriptor(book, 'something')
|
796 | ok(!desc.enumerable, 'did not modify data in constructor')
|
797 | done()
|
798 | })
|
799 | })
|
800 |
|
801 | it('should execute parameterized query - cb', function(done) {
|
802 | db.execute([
|
803 | 'select id',
|
804 | 'from authors',
|
805 | 'where name = :name'
|
806 | ], {
|
807 | name: 'Jack3',
|
808 | }, function(err, rs) {
|
809 | no(err)
|
810 | ok(rs[0].id === 1, 'wrong record')
|
811 | done()
|
812 | })
|
813 | })
|
814 |
|
815 | it('should execute parameterized query - promise', function(done) {
|
816 | db.execute([
|
817 | 'select id',
|
818 | 'from authors',
|
819 | 'where name = :name'
|
820 | ], {
|
821 | name: 'Jack3',
|
822 | }).then(function(rs) {
|
823 | ok(rs[0].id === 1, 'wrong record')
|
824 | done()
|
825 | }).catch(showError)
|
826 | })
|
827 |
|
828 | it('should prevent semicolon sqli', function(done) {
|
829 | db.books.find({
|
830 | where: {
|
831 | id: "1; update books set title = 'sqli' where id = '1"
|
832 | }
|
833 | }, function(err, books) {
|
834 | if (err) return done()
|
835 |
|
836 | db.books.get(1, function(err, book) {
|
837 | no(err)
|
838 | ok(book.title !== 'sqli', 'injected update ran')
|
839 | done()
|
840 | })
|
841 | })
|
842 | })
|
843 |
|
844 | it('should cache - cb', function(done) {
|
845 | db.books.db._opts.cache = mockRedis()
|
846 | db.books.get(1, function(err, book) {
|
847 | no(err)
|
848 | var new_title = 'New Title'
|
849 | book.update({
|
850 | title: new_title
|
851 | }, function(err) {
|
852 | no(err)
|
853 | db.books.get(1, function(err, book) {
|
854 | no(err)
|
855 | ok(book.title === new_title, 'did not save new title')
|
856 | ok(book.fromCache, 'did not get value from cache')
|
857 | done()
|
858 | })
|
859 | })
|
860 | })
|
861 | })
|
862 |
|
863 | it('should cache - promise', function(done) {
|
864 | db.books.get(1).then(function(book) {
|
865 | var new_title = 'New Title2'
|
866 | book.update({
|
867 | title: new_title
|
868 | }).then(function() {
|
869 | db.books.get(1).then(function(book) {
|
870 | ok(book.title === new_title, 'did not save new title')
|
871 | ok(book.fromCache, 'did not get value from cache')
|
872 | db.books.db._opts.cache = null
|
873 | done()
|
874 | })
|
875 | })
|
876 | }).catch(showError)
|
877 | })
|
878 |
|
879 | it('should cache mget using composite keys - promise', function(done) {
|
880 | db.authors.db._opts.cache = mockRedis()
|
881 | db.authors.get(1).then(function (author) {
|
882 | var list = [
|
883 | { id: 1984 },
|
884 | { id: 1 },
|
885 | { id: 1408 }
|
886 | ]
|
887 | db.authors.mget(list).then(function(authors) {
|
888 | ok(authors[0].id === list[0].id, 'did not get author 1')
|
889 | ok(authors[1].id === list[1].id, 'did not get author 2')
|
890 | ok(authors[2].id === list[2].id, 'did not get author 3')
|
891 | db.authors.get([1408]).then(function (author) {
|
892 | ok(author.id === 1408, 'did not get author')
|
893 | done()
|
894 | })
|
895 | })
|
896 | }).catch(showError)
|
897 | })
|
898 |
|
899 | it('should delete', function(done) {
|
900 | var newBook = {
|
901 | title: 'XYZ Book',
|
902 | author: {
|
903 | name: 'XYZ Author'
|
904 | }
|
905 | }
|
906 | db.books.insert(newBook, function(err, book) {
|
907 | no(err)
|
908 | var bookId = book.id
|
909 | var authorId = book.author_id
|
910 | ok(!!book.id, 'did not insert book')
|
911 | book.delete(function(err) {
|
912 | no(err)
|
913 | ok(!book.id, 'book should be deleted')
|
914 | db.books.get(bookId, function (err, book) {
|
915 | ok(!!err && !!err.notFound, 'should not find deleted book')
|
916 | db.authors.get(authorId, function (err, author) {
|
917 | no(err)
|
918 | ok(!!author.id, 'should not delete author')
|
919 | done()
|
920 | })
|
921 | })
|
922 | })
|
923 | })
|
924 | })
|
925 |
|
926 | it('should not delete without cascade', function(done) {
|
927 | var newBook = {
|
928 | title: 'XYZ Book',
|
929 | author: {
|
930 | name: 'XYZ Author'
|
931 | }
|
932 | }
|
933 | db.books.insert(newBook, function(err, book) {
|
934 | no(err)
|
935 | var bookId = book.id
|
936 | var authorId = book.author_id
|
937 | ok(!!book.id, 'did not insert book')
|
938 | book.hydrate('author', function (err) {
|
939 | no(err)
|
940 | book.author.delete(function(err) {
|
941 | ok(!!err, 'should not delete without cascade')
|
942 | done()
|
943 | })
|
944 | })
|
945 | })
|
946 | })
|
947 |
|
948 | it('should save 1-to-1 nested object (insert + insert)', function(done) {
|
949 | var newBook = {
|
950 | id: 11,
|
951 | title: 'Book #1',
|
952 | author: {
|
953 | name: 'Author #1'
|
954 | }
|
955 | }
|
956 | db.books.save(newBook, function(err, book) {
|
957 | no(err)
|
958 | ok(book.id === 11, 'did not insert book')
|
959 | book.hydrate('author', function(err) {
|
960 | no(err)
|
961 | ok(book.author_id === book.author.id, 'did not insert author')
|
962 | done()
|
963 | })
|
964 | })
|
965 | })
|
966 |
|
967 | it('should save 1-to-1 nested object (update + insert) - promise', function(done) {
|
968 | db.books.get(2).then(function(book) {
|
969 |
|
970 | book.author = {
|
971 | name: 'Author #2'
|
972 | }
|
973 | book.save().then(function(book) {
|
974 | ok(book.id === 2, 'did not get book')
|
975 | book.hydrate('author').then(function() {
|
976 | ok(book.author_id === book.author.id, 'did not insert author')
|
977 | done()
|
978 | })
|
979 | })
|
980 | }).catch(showError)
|
981 | })
|
982 |
|
983 | it('should save 1-to-1-to-1 nested objects (insert + insert + insert)', function(done) {
|
984 | var newBookData = {
|
985 | title: 'my title',
|
986 | author: {
|
987 | name: 'Author #3',
|
988 | Country: {
|
989 | Code: 'US',
|
990 | name: 'United States'
|
991 | }
|
992 | }
|
993 | }
|
994 | db.books.save(newBookData, function(err, book) {
|
995 | no(err)
|
996 | book.hydrate('author', function(err) {
|
997 | no(err)
|
998 | book.author.hydrate('Country', function(err) {
|
999 | no(err)
|
1000 | ok(book.author.Country.name === 'United States', 'did not save')
|
1001 | done()
|
1002 | })
|
1003 | })
|
1004 | })
|
1005 | })
|
1006 |
|
1007 | it('should not save shorthand 1-to-m w/ column name conflict', function(done) {
|
1008 | var newAuthor = {
|
1009 | name: 'Jimbo Jimson',
|
1010 | books: [
|
1011 | { title: 'My First Book' }
|
1012 | ]
|
1013 | }
|
1014 | db.authors.save(newAuthor).catch(function (err) {
|
1015 | ok(!!err, 'should have error')
|
1016 | done()
|
1017 | })
|
1018 | })
|
1019 |
|
1020 | it('should not save a 1-to-m field that is not an array', function(done) {
|
1021 | var newAuthor = {
|
1022 | name: 'Jimbo Jimson',
|
1023 | 'author:books': { title: 'My First Book' }
|
1024 | }
|
1025 | db.authors.save(newAuthor).catch(function (err) {
|
1026 | ok(!!err, 'should have error')
|
1027 | done()
|
1028 | })
|
1029 | })
|
1030 |
|
1031 | it('should save 1-to-m (insert + insert)', function(done) {
|
1032 | var newAuthor = {
|
1033 | name: 'Jimbo Jimson',
|
1034 | 'author:books': [
|
1035 | { title: 'My First Book' },
|
1036 | { title: 'My Second Book' }
|
1037 | ]
|
1038 | }
|
1039 | db.authors.save(newAuthor, function(err, author) {
|
1040 | no(err)
|
1041 | ok(!!author.id, 'did not insert author')
|
1042 | ok(author.name === newAuthor.name, 'wrong author.name')
|
1043 | var property = 'author:books'
|
1044 | author.hydrate([property], function(err) {
|
1045 | no(err)
|
1046 | ok(!!author[property], 'did not hydrate books')
|
1047 | ok(author[property].length === newAuthor[property].length, 'wrong number of books')
|
1048 | var book = author[property][0]
|
1049 | ok(book.author_id === author.id, 'did not insert book')
|
1050 | ok(book.title === newAuthor[property][0].title, 'wrong title')
|
1051 | done()
|
1052 | })
|
1053 | })
|
1054 | })
|
1055 |
|
1056 | it('should save shorthand 1-to-m (insert + insert)', function(done) {
|
1057 | var newBook = {
|
1058 | title: 'A Great Book',
|
1059 | samples: [
|
1060 | { description: 'Something!' },
|
1061 | { description: 'Something else!' }
|
1062 | ]
|
1063 | }
|
1064 | db.books.save(newBook, function(err, book) {
|
1065 | no(err)
|
1066 | ok(!!book.id, 'did not insert book')
|
1067 | ok(book.title === newBook.title, 'wrong book.title')
|
1068 | var property = 'samples'
|
1069 | book.hydrate(property, function(err) {
|
1070 | no(err)
|
1071 | ok(!!book[property], 'did not hydrate samples')
|
1072 | ok(book[property].length === newBook[property].length, 'wrong number of samples')
|
1073 | var sample = book[property][0]
|
1074 | ok(sample.book_id === book.id, 'did not insert sample')
|
1075 | ok(sample.description === newBook[property][0].description, 'wrong description')
|
1076 | done()
|
1077 | })
|
1078 | })
|
1079 | })
|
1080 |
|
1081 | it('should propagate errors', function() {
|
1082 | return db.books.find().then(function (books) {
|
1083 | console.log('ReferenceError', undefinedVariable)
|
1084 | }).catch(function (err) {
|
1085 | ok(!!err, 'should propogate error')
|
1086 | })
|
1087 | })
|
1088 |
|
1089 | xit('TODO should populate linking table keys', function(done) {
|
1090 | var newAuthor = {
|
1091 | name: 'Chuck Palahniuk',
|
1092 | ratings: [
|
1093 | {
|
1094 | stars: 5,
|
1095 | book: { title: 'Fight Club' }
|
1096 | },
|
1097 | {
|
1098 | stars: 4,
|
1099 | book: { title: 'Choke' }
|
1100 | }
|
1101 | ]
|
1102 | }
|
1103 | db.authors.save(newAuthor, function(err, author) {
|
1104 | no(err)
|
1105 | ok(!!author.id, 'did not insert author')
|
1106 | ok(author.name === newAuthor.name, 'wrong author.name')
|
1107 | var property = 'ratings'
|
1108 | author.hydrate([property], function(err) {
|
1109 | no(err)
|
1110 | ok(!!author[property], 'did not hydrate')
|
1111 | ok(author[property].length === newAuthor[property].length, 'wrong qty')
|
1112 | var rating = author[property][0]
|
1113 | console.log('rating:', rating)
|
1114 | rating.hydrate('book', function(err) {
|
1115 | var book = rating.book
|
1116 | console.log('book:', book)
|
1117 | ok(book.author_id === author.id, 'did not save book.author_id')
|
1118 | ok(book.title === newAuthor.ratings[0].book.title, 'wrong title')
|
1119 | done()
|
1120 | })
|
1121 | })
|
1122 | })
|
1123 | })
|
1124 |
|
1125 |
|
1126 |
|
1127 |
|
1128 |
|
1129 |
|
1130 |
|
1131 |
|
1132 |
|
1133 |
|
1134 |
|
1135 |
|
1136 |
|
1137 |
|
1138 |
|
1139 |
|
1140 |
|
1141 | it('should kill the connection pool', function (done) {
|
1142 | var isDone = false
|
1143 | db.end(function () {
|
1144 | if (isDone) return
|
1145 | isDone = true
|
1146 | done()
|
1147 | })
|
1148 | })
|
1149 |
|
1150 | })
|
1151 |
|
1152 | })
|