diff --git a/lib/modules/apostrophe-global/index.js b/lib/modules/apostrophe-global/index.js index 8cbdb16ca8..4a6e5417aa 100644 --- a/lib/modules/apostrophe-global/index.js +++ b/lib/modules/apostrophe-global/index.js @@ -79,10 +79,42 @@ module.exports = { // with `(null, global)`. self.findGlobal = function(req, callback) { - return self.find(req, { slug: self.slug }) - .permission(false) - .sort(false) - .toObject(callback); + var global; + var cursor; + return async.series([ + find, after + ], function(err) { + if (err) { + return callback(err); + } + return callback(null, global); + }); + function find(callback) { + cursor = self.find(req, { slug: self.slug }) + .permission(false) + .sort(false) + .joins(false) + .areas(false); + return cursor.toObject(function(err, doc) { + global = doc; + // Make this available early, sans joins and area loaders, + // to avoid race conditions for modules like + // apostrophe-pieces-orderings-bundle if we wait + // for joins that might also need the global doc to find their + // default orderings, etc. + req.aposGlobalCore = global; + return callback(err); + }); + } + function after(callback) { + if (!global) { + return callback(null); + } + cursor = cursor.clone(); + cursor.joins(true); + cursor.areas(true); + return cursor.after([ global ], callback); + } }; self.modulesReady = function(callback) { diff --git a/test/global.js b/test/global.js index fafc05019c..24c955282c 100644 --- a/test/global.js +++ b/test/global.js @@ -24,6 +24,11 @@ describe('Global', function() { secret: 'xxx', port: 7900 }, + 'products': { + alias: 'products', + extend: 'apostrophe-pieces', + name: 'product' + }, 'apostrophe-global': { whileBusyDelay: 0.5, addFields: [ @@ -31,6 +36,11 @@ describe('Global', function() { name: 'testString', type: 'string', def: 'populated def' + }, + { + name: '_featuredProducts', + type: 'joinByArray', + withType: 'product' } ] } @@ -91,6 +101,38 @@ describe('Global', function() { }); }); + it('insert products via task', function() { + return apos.tasks.invoke('products:generate', [], {}); + }); + + var product; + + it('set a product join up in the global doc', function() { + var req = apos.tasks.getReq(); + return apos.products.find(req).sort({ sortTitle: 1}).limit(1).toObject().then(function(object) { + assert(object); + product = object; + }).then(function() { + return apos.docs.db.update({ + slug: 'global' + }, { + $set: { + featuredProductsIds: [ product._id ] + } + }); + }); + }); + + it('fetch the global doc, verify join', function() { + var req = apos.tasks.getAnonReq(); + return apos.global.addGlobalToData(req).then(function() { + assert(req.data.global); + assert(req.data.global._featuredProducts); + assert(req.data.global._featuredProducts.length === 1); + assert(req.data.global._featuredProducts[0].slug === product.slug); + }); + }); + it('give global doc a workflowLocale property to simulate use with workflow', function() { return apos.docs.db.update({ type: 'apostrophe-global'