From 3f15fc8f79aca82bba5add8f9a60fa21f9383744 Mon Sep 17 00:00:00 2001 From: scott Date: Thu, 10 Jul 2014 14:48:28 +0100 Subject: [PATCH 1/5] SelfLink suggested fixes - allow cross-site URLs to work with selfLinks and remove suffix fixes issue #493 to add the selfLink absolute URL to the start of the URLs for cross-site self links to work. Also if there is a request suffix it will remove it from the selfLink to allow for sub-resources to be referenced. --- src/restangular.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/restangular.js b/src/restangular.js index 493a1f47..4583d8b9 100644 --- a/src/restangular.js +++ b/src/restangular.js @@ -251,7 +251,8 @@ module.provider('Restangular', function() { }; config.getUrlFromElem = function(elem) { - return config.getFieldFromElem(config.restangularFields.selfLink, elem); + var selfLink = config.getFieldFromElem(config.restangularFields.selfLink, elem); + return (selfLink && config.suffix) ? selfLink.replace(config.suffix, '') : selfLink; }; config.useCannonicalId = _.isUndefined(config.useCannonicalId) ? false : config.useCannonicalId; @@ -636,7 +637,11 @@ module.provider('Restangular', function() { var elemSelfLink = __this.config.getUrlFromElem(elem); if (elemSelfLink) { if (__this.config.isAbsoluteUrl(elemSelfLink)) { - return elemSelfLink; + return + (__this.config.absoluteUrl) + ? __this.config.absoluteUrl //add the absolute URL to the start if set + + ( elemSelfLink.indexOf("/") === 0 ? elemSelfLink.substring(1) : elemSelfLink) //remove a leading forward slash if set + : elemSelfLink; } else { elemUrl = elemSelfLink; } From bfb03e58679b0750e1c4fd72cd37f5dfb4ae4d35 Mon Sep 17 00:00:00 2001 From: scott Date: Thu, 10 Jul 2014 15:39:23 +0100 Subject: [PATCH 2/5] SelfLink fixes --- src/restangular.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/restangular.js b/src/restangular.js index 4583d8b9..702d5fa5 100644 --- a/src/restangular.js +++ b/src/restangular.js @@ -637,8 +637,7 @@ module.provider('Restangular', function() { var elemSelfLink = __this.config.getUrlFromElem(elem); if (elemSelfLink) { if (__this.config.isAbsoluteUrl(elemSelfLink)) { - return - (__this.config.absoluteUrl) + return (__this.config.absoluteUrl && __this.config.absoluteUrl !== true) ? __this.config.absoluteUrl //add the absolute URL to the start if set + ( elemSelfLink.indexOf("/") === 0 ? elemSelfLink.substring(1) : elemSelfLink) //remove a leading forward slash if set : elemSelfLink; From 9e05ba25c4f750d183600be6cfdcd2cc3283e9bc Mon Sep 17 00:00:00 2001 From: scott Date: Thu, 10 Jul 2014 15:42:43 +0100 Subject: [PATCH 3/5] remove url check so that suffix will be added suffix will be added to self links --- src/restangular.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/restangular.js b/src/restangular.js index 702d5fa5..e49730f5 100644 --- a/src/restangular.js +++ b/src/restangular.js @@ -560,8 +560,7 @@ module.provider('Restangular', function() { } if (this.config.suffix && - url.indexOf(this.config.suffix, url.length - this.config.suffix.length) === -1 && - !this.config.getUrlFromElem(current)) { + url.indexOf(this.config.suffix, url.length - this.config.suffix.length) === -1) { url += this.config.suffix; } From ecdaefb6ddb43bcd7cfa16507f7cfe4b8541e168 Mon Sep 17 00:00:00 2001 From: scott Date: Fri, 11 Jul 2014 10:48:53 +0100 Subject: [PATCH 4/5] The suffix is now removed from selfLink urls The suffix is now removed from selfLink urls before concatenating the sub resources. --- src/restangular.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/restangular.js b/src/restangular.js index e49730f5..39c5c18d 100644 --- a/src/restangular.js +++ b/src/restangular.js @@ -251,10 +251,9 @@ module.provider('Restangular', function() { }; config.getUrlFromElem = function(elem) { - var selfLink = config.getFieldFromElem(config.restangularFields.selfLink, elem); - return (selfLink && config.suffix) ? selfLink.replace(config.suffix, '') : selfLink; + return config.getFieldFromElem(config.restangularFields.selfLink, elem); }; - + config.useCannonicalId = _.isUndefined(config.useCannonicalId) ? false : config.useCannonicalId; object.setUseCannonicalId = function(value) { config.useCannonicalId = value; @@ -558,9 +557,9 @@ module.provider('Restangular', function() { add += what; url += add; } - if (this.config.suffix && - url.indexOf(this.config.suffix, url.length - this.config.suffix.length) === -1) { + url.indexOf(this.config.suffix, url.length - this.config.suffix.length) === -1 && + !this.config.getUrlFromElem(current)) { url += this.config.suffix; } @@ -636,10 +635,9 @@ module.provider('Restangular', function() { var elemSelfLink = __this.config.getUrlFromElem(elem); if (elemSelfLink) { if (__this.config.isAbsoluteUrl(elemSelfLink)) { - return (__this.config.absoluteUrl && __this.config.absoluteUrl !== true) - ? __this.config.absoluteUrl //add the absolute URL to the start if set - + ( elemSelfLink.indexOf("/") === 0 ? elemSelfLink.substring(1) : elemSelfLink) //remove a leading forward slash if set - : elemSelfLink; + return (__this.config.absoluteUrl && __this.config.absoluteUrl !== true) + ? __this.config.absoluteUrl.replace(/\/$/, '') + "/" + elemSelfLink.replace(/^\//, '') //add the absolute URL to the start if set + : elemSelfLink; } else { elemUrl = elemSelfLink; } @@ -664,6 +662,8 @@ module.provider('Restangular', function() { } } } + //remove any trailing suffix from the url before concatinating new subresources + if (__this.config.suffix) acum = acum.replace(new RegExp(__this.config.suffix + '$'), ''); return acum.replace(/\/$/, '') + '/' + elemUrl; From 85dc1986e8ed4855f499512a58117157288fdc7c Mon Sep 17 00:00:00 2001 From: scott Date: Fri, 11 Jul 2014 10:49:35 +0100 Subject: [PATCH 5/5] Tests for issue #493 --- test/restangularSpec.js | 49 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/test/restangularSpec.js b/test/restangularSpec.js index 6dcad6ba..5a541766 100644 --- a/test/restangularSpec.js +++ b/test/restangularSpec.js @@ -24,10 +24,18 @@ describe("Restangular", function() { {from: "Anonymous", amount: 0.1416, id: 1, _links: {self: "/accountsHAL/paul/transactions/1"}} ], _links: {self: "/accountsHAL/paul"}} ]; + + accountsModelWithSuffix = [ + {id: 0, user: "Martin", amount: 42, transaction: [], href: "/accountsSuffix/martin.json"}, + {id: 1, user: "Paul", amount: 3.1416, transaction: [ + {from: "Martin", amount: 3, id: 0, href: "/accounts/paul/transactions/0.json"}, + {from: "Anonymous", amount: 0.1416, id: 1, href: "/accounts/paul/transactions/1.json"} + ], href: "/accounts/paul.json"} + ]; infoModel = { id: 0, text: "Some additional account information" - } + }; newAccount = {id: 44, user: "First User", amount: 45, transactions: []}; @@ -63,6 +71,14 @@ describe("Restangular", function() { accountsHalModel[0] = angular.fromJson(data); return [200, data, ""]; }); + + $httpBackend.whenGET("/accountsSuffix").respond(accountsModelWithSuffix); + $httpBackend.whenGET("/accountsSuffix.json").respond(accountsModelWithSuffix); + $httpBackend.whenGET("/accountsSuffix/martin.json").respond(accountsModelWithSuffix[0]); + $httpBackend.whenPUT("/accountsSuffix/martin/transactions.json").respond(function(method, url, data) { + accountsModelWithSuffix[0].transaction = angular.fromJson(data); + return [200, data, ""]; + }); // Full URL $httpBackend.whenGET('http://accounts.com/all').respond(accountsModel); @@ -745,6 +761,37 @@ describe("Restangular", function() { $httpBackend.flush(); }); }); + + describe("Self linking with suffix", function() { + it("Should allow for suffix in selfLinks", function() { + var linkRestangular = Restangular.withConfig(function(RestangularConfigurer) { + RestangularConfigurer.setRequestSuffix('.json'); + }); + + var arr = linkRestangular.all('accountsSuffix').getList().$object; + $httpBackend.flush(); + + var account = arr[0]; + var transactions = account.all('transactions'); + expect(transactions.getRestangularUrl()).toEqual("/accountsSuffix/martin/transactions"); + }); + }); + + describe("Cross-site selfLinks", function() { + it("Should add the absolute URL to the self link", function() { + var linkRestangular = Restangular.withConfig(function(RestangularConfigurer) { + RestangularConfigurer.setRequestSuffix('.json'); + RestangularConfigurer.setSelfLinkAbsoluteUrl('http://accounts.com/'); + }); + + var arr = linkRestangular.all('accountsSuffix').getList().$object; + $httpBackend.flush(); + + var account = arr[0]; + expect(account.getRestangularUrl()).toEqual("http://accounts.com/accountsSuffix/martin.json"); + expect(account.all('transactions').getRestangularUrl()).toEqual("http://accounts.com/accountsSuffix/martin/transactions"); + }); + }); describe("Singe one (endpoint not expecting an id)", function() { it('does not use the id for single resource GET', function() {