diff --git a/lib/query/lib/prepareForDelivery.js b/lib/query/lib/prepareForDelivery.js index e1a50a3..1b0071f 100755 --- a/lib/query/lib/prepareForDelivery.js +++ b/lib/query/lib/prepareForDelivery.js @@ -96,9 +96,18 @@ export function removeLinkStorages(node, sameLevelResults) { _.each(node.collectionNodes, collectionNode => { const removeStorageField = collectionNode.shouldCleanStorage; + _.each(sameLevelResults, result => { if (removeStorageField) { - delete result[collectionNode.linkStorageField]; + if (collectionNode.isVirtual) { + const childResults = getResultsArray(result[collectionNode.linkName]); + _.each(childResults, childResult => { + delete childResult[collectionNode.linkStorageField]; + }); + } + else { + delete result[collectionNode.linkStorageField]; + } } removeLinkStorages(collectionNode, result[collectionNode.linkName]); @@ -173,12 +182,13 @@ export function assembleMetadata(node, parentResults) { const childResult = parentResult[node.linkName]; if (node.isOneResult) { - const storage = childResult[node.linkStorageField]; - storeMetadata(childResult, parentResult, storage, true); + if (_.isObject(childResult)) { + const storage = childResult[node.linkStorageField]; + storeMetadata(childResult, parentResult, storage, true); + } } else { _.each(childResult, object => { const storage = object[node.linkStorageField]; - storeMetadata(object, parentResult, storage, true); }); } diff --git a/lib/query/testing/server.test.js b/lib/query/testing/server.test.js index ec647fa..8bd6e38 100755 --- a/lib/query/testing/server.test.js +++ b/lib/query/testing/server.test.js @@ -15,6 +15,35 @@ const ShoppingCart = new Mongo.Collection('__projection_operators_cart'); const Clients = new Mongo.Collection('__text_search_clients'); Clients._ensureIndex({name: 'text'}); +Clients.addLinks({ + shoppingCart: { + type: 'one', + collection: ShoppingCart, + metadata: true, + field: 'shoppingCartData', + unique: true + }, + + shoppingCarts: { + collection: ShoppingCart, + type: 'many', + metadata: true, + field: 'shoppingCartsData', + } +}); + +ShoppingCart.addLinks({ + user: { + collection: Clients, + inversedBy: 'shoppingCart' + }, + + users: { + collection: Clients, + inversedBy: 'shoppingCarts' + } +}); + describe('Hypernova', function() { it('Should support projection operators', () => { ShoppingCart.remove({}); @@ -311,6 +340,8 @@ describe('Hypernova', function() { }, }).fetch(); + // console.log(JSON.stringify(data, null, 2)); + _.each(data, post => { assert.isObject(post.author); assert.isArray(post.author.groups); @@ -720,4 +751,75 @@ describe('Hypernova', function() { }); }); }); + + it('Should handle empty inversedBy meta unique fields', () => { + ShoppingCart.remove({}); + ShoppingCart.insert({date: new Date(), items: [{title: 'Something'}]}); + + const data = ShoppingCart.createQuery({ + user: { + name: 1 + } + }).fetch(); + + assert.equal(data.length, 1); + const [cart] = data; + assert.isUndefined(cart.user); + }); + + it('Should remove link storage inversedBy meta unique fields', () => { + ShoppingCart.remove({}); + const cartId = ShoppingCart.insert({date: new Date(), items: [{title: 'Something'}]}); + + Clients.remove({}); + Clients.insert({ + name: 'John', + shoppingCartData: { + prime: 1, + _id: cartId + } + }) + + const data = ShoppingCart.createQuery({ + user: { + name: 1 + } + }).fetch(); + + assert.equal(data.length, 1); + const [cart] = data; + assert.isObject(cart.user); + assert.isString(cart.user.name); + // no link storage + assert.isUndefined(cart.user.shoppingCartData); + }); + + it('Should remove link storage inversedBy meta many fields', () => { + ShoppingCart.remove({}); + const cartId = ShoppingCart.insert({date: new Date(), items: [{title: 'Something'}]}); + + Clients.remove({}); + Clients.insert({ + name: 'John', + shoppingCartsData: [{ + prime: 1, + _id: cartId + }] + }) + + const data = ShoppingCart.createQuery({ + users: { + name: 1 + } + }).fetch(); + + assert.equal(data.length, 1); + const [cart] = data; + assert.isArray(cart.users); + assert.equal(cart.users.length, 1); + const [user] = cart.users; + assert.isString(user.name); + // no link storage + assert.isUndefined(user.shoppingCartsData); + }); });