From 97c9d54c43c52e3badcdc5d2ebe6d688d41ba799 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Fri, 15 May 2015 16:59:59 -0700 Subject: [PATCH] Add tests for propagating a transaction over relations --- lib/sql.js | 3 ++- test/connectors/test-sql-connector.js | 36 ++++++++++++++++----------- test/transaction.test.js | 36 ++++++++++++++++++++++----- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/lib/sql.js b/lib/sql.js index db4ddeb..301b0ba 100644 --- a/lib/sql.js +++ b/lib/sql.js @@ -1039,7 +1039,8 @@ SQLConnector.prototype.all = function find(model, filter, options, cb) { return self.fromRow(model, obj); }); if (filter && filter.include) { - self.getModelDefinition(model).model.include(objs, filter.include, cb); + self.getModelDefinition(model).model.include( + objs, filter.include, options, cb); } else { cb(null, objs); } diff --git a/test/connectors/test-sql-connector.js b/test/connectors/test-sql-connector.js index 390bb37..b7439df 100644 --- a/test/connectors/test-sql-connector.js +++ b/test/connectors/test-sql-connector.js @@ -10,20 +10,24 @@ var transactionId = 0; function MockTransaction(connector, name) { this.connector = connector; this.name = name; - this.data = []; + this.data = {}; } MockTransaction.prototype.commit = function(cb) { var self = this; - this.data.forEach(function(d) { - self.connector.collection.data.push(d); - }); - this.data = []; + // Merge data from this TX to the global data var + for (var m in this.data) { + self.connector.data[m] = self.connector.data[m] || []; + for (var i = 0, n = this.data[m].length; i < n; i++) { + self.connector.data[m].push(this.data[m]); + } + } + this.data = {}; cb(); }; MockTransaction.prototype.rollback = function(cb) { - this.data = []; + this.data = {}; cb(); }; @@ -41,9 +45,7 @@ exports.initialize = function initializeDataSource(dataSource, callback) { function TestConnector(settings) { SQLConnector.call(this, 'testdb', settings); this._tables = {}; - this.collection = { - data: [] - }; + this.data = {}; } util.inherits(TestConnector, SQLConnector); @@ -203,9 +205,12 @@ TestConnector.prototype.rollback = function(tx, cb) { TestConnector.prototype.executeSQL = function(sql, params, options, callback) { var transaction = options.transaction; + var model = options.model; if (transaction && transaction.connector === this && transaction.connection) { if (sql.indexOf('INSERT') === 0) { - transaction.connection.data.push({title: 't1', content: 'c1'}); + transaction.connection.data[model] = + transaction.connection.data[model] || []; + transaction.connection.data[model].push({sql: sql, params: params}); debug('INSERT', transaction.connection.data, sql, transaction.connection.name); callback(null, 1); @@ -213,16 +218,17 @@ TestConnector.prototype.executeSQL = function(sql, params, options, callback) { else { debug('SELECT', transaction.connection.data, sql, transaction.connection.name); - callback(null, transaction.connection.data); + callback(null, transaction.connection.data[model] || []); } } else { if (sql.indexOf('INSERT') === 0) { - this.collection.data.push({title: 't1', content: 'c1'}); - debug('INSERT', this.collection.data, sql); + this.data[model] = this.data[model] || []; + this.data[model].push({sql: sql, params: params}); + debug('INSERT', this.data, sql); callback(null, 1); } else { - debug('SELECT', this.collection.data, sql); - callback(null, this.collection.data); + debug('SELECT', this.data, sql); + callback(null, this.data[model] || []); } } }; diff --git a/test/transaction.test.js b/test/transaction.test.js index 6ca84de..4692217 100644 --- a/test/transaction.test.js +++ b/test/transaction.test.js @@ -6,6 +6,7 @@ var testConnector = require('./connectors/test-sql-connector'); var juggler = require('loopback-datasource-juggler'); var db, Post; +var Review; describe('transactions', function() { @@ -19,6 +20,11 @@ describe('transactions', function() { title: {type: String, length: 255, index: true}, content: {type: String} }); + Review = db.define('ReviewTX', { + author: String, + content: {type: String} + }); + Post.hasMany(Review, {as: 'reviews', foreignKey: 'postId'}); done(); }); }); @@ -54,12 +60,18 @@ describe('transactions', function() { next(); }); currentTx = tx; - Post.create(post, {transaction: tx}, + Post.create(post, {transaction: tx, model: 'Post'}, function(err, p) { if (err) { done(err); } else { - done(); + p.reviews.create({ + author: 'John', + content: 'Review for ' + p.title + }, {transaction: tx, model: 'Review'}, + function(err, c) { + done(err); + }); } }); }); @@ -70,7 +82,7 @@ describe('transactions', function() { // records to equal to the count function expectToFindPosts(where, count, inTx) { return function(done) { - var options = {}; + var options = {model: 'Post'}; if (inTx) { options.transaction = currentTx; } @@ -78,7 +90,19 @@ describe('transactions', function() { function(err, posts) { if (err) return done(err); expect(posts.length).to.be.eql(count); - done(); + if (count) { + // Find related reviews + options.model = 'Review'; + // Please note the empty {} is required, otherwise, the options + // will be treated as a filter + posts[0].reviews({}, options, function(err, reviews) { + if (err) return done(err); + expect(reviews.length).to.be.eql(count); + done(); + }); + } else { + done(); + } }); }; } @@ -114,7 +138,7 @@ describe('transactions', function() { before(function() { // Reset the collection - db.connector.collection.data = []; + db.connector.data = {}; }); var post = {title: 't2', content: 'c2'}; @@ -146,7 +170,7 @@ describe('transactions', function() { before(function() { // Reset the collection - db.connector.collection.data = []; + db.connector.data = {}; }); var post = {title: 't3', content: 'c3'};