From 4ad6a9c5b47af5531a48d18a8c3ad2ae1fd6effc Mon Sep 17 00:00:00 2001 From: Julien Pradet Date: Mon, 27 Apr 2020 15:51:31 +0200 Subject: [PATCH] Fix relationships when two types start with the same string --- lib/deserializer-utils.js | 9 ++++--- test/deserializer.js | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/lib/deserializer-utils.js b/lib/deserializer-utils.js index 1265fd4..b06796e 100644 --- a/lib/deserializer-utils.js +++ b/lib/deserializer-utils.js @@ -6,6 +6,9 @@ var _extend = require('lodash/extend'); var _transform = require('lodash/transform'); var Inflector = require('./inflector'); +const ancestrySeparator = ":"; +const idSeparator = ";"; + module.exports = function (jsonapi, data, opts) { var alreadyIncluded = []; @@ -36,7 +39,7 @@ module.exports = function (jsonapi, data, opts) { if (included) { // To prevent circular references, check if the record type // has already been processed in this thread - if (ancestry.indexOf(included.type) > -1) { + if (ancestry.indexOf(included.type + idSeparator) > -1) { return Promise .all([extractAttributes(included)]) .then(function (results) { @@ -47,7 +50,7 @@ module.exports = function (jsonapi, data, opts) { } return Promise - .all([extractAttributes(included), extractRelationships(included, ancestry + ':' + included.type + included.id)]) + .all([extractAttributes(included), extractRelationships(included, ancestry + ancestrySeparator + included.type + idSeparator + included.id)]) .then(function (results) { var attributes = results[0]; var relationships = results[1]; @@ -146,7 +149,7 @@ module.exports = function (jsonapi, data, opts) { this.perform = function () { return Promise - .all([extractAttributes(data), extractRelationships(data, data.type + data.id)]) + .all([extractAttributes(data), extractRelationships(data, data.type + ancestrySeparator + data.id)]) .then(function (results) { var attributes = results[0]; var relationships = results[1]; diff --git a/test/deserializer.js b/test/deserializer.js index bd5ae42..6d81d40 100644 --- a/test/deserializer.js +++ b/test/deserializer.js @@ -1394,6 +1394,56 @@ describe('JSON API Deserializer', function () { }); }); }); + + describe("With relationships using similar type names", function () { + it("should return all data without circular error", function (done) { + var dataSetSearch = { + data: { + type: "productsearch", + id: "47", + attributes: { + sku: "7TY55", + }, + relationships: { + product: { data: { type: "products", id: "122" } }, + }, + }, + included: [ + { + type: "images", + id: "49", + attributes: { + mimeType: "image/jpeg", + }, + relationships: { + product: { data: { type: "products", id: "122" } }, + }, + }, + { + type: "products", + id: "122", + attributes: { + sku: "7TY55" + }, + relationships: { + image: { data: { type: "images", id: "49" } }, + }, + }, + ], + }; + + // new JSONAPIDeserializer().deserialize(dataSetCart, function (err, json) { + new JSONAPIDeserializer().deserialize(dataSetSearch, function (err, json) { + expect(json).to.be.an('object').with.keys('id', 'sku', 'product'); + expect(json.product).to.exist; + expect(json.product).to.be.an('object').with.keys('id', 'sku', 'image'); + expect(json.product.image).to.exist; + expect(json.product.image).to.be.an('object').with.keys('id', 'mime-type', 'product'); + + done(null, json); + }); + }); + }); }); describe('without callback', function () {