Skip to content

Commit

Permalink
Merge pull request #52 from kiva/49-current-link
Browse files Browse the repository at this point in the history
Use "current" to store collections
  • Loading branch information
Gabriel committed Apr 29, 2014
2 parents 088c12e + eb1f562 commit a7b92a6
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 39 deletions.
101 changes: 67 additions & 34 deletions src/backbone.siren.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,44 @@ function toCamelCase(name) {
}


/**
* Gets a link url by name from a raw siren enity
*
* @param {Object} rawEntity
* @param {String} name
* @returns {String|undefined}
*/
function getRawEntityUrl(rawEntity, name) {
var link, url;

link = _.filter(rawEntity.links, function (link) {
return !!(link.rel && _.filter(link.rel, function (relType) {
return relType == name;
}).length);
})[0];

if (link) {
url = link.href;
}

return url;
}


/**
* Gets the url from a raw Siren entity
*
* @static
* @param rawEntity
* @param {Object} rawEntity
* @returns {String|undefined}
*/
function getRawEntityUrl(rawEntity) {
var link, url;
function getRawEntitySelfUrl(rawEntity) {
var url;

if (rawEntity.href) {
url = rawEntity.href;
} else if (rawEntity.links) {
link = _.filter(rawEntity.links, function (link) {
return !!(link.rel && _.filter(link.rel, function (relType) {
return relType == 'self';
}).length);
})[0];

if (link) {
url = link.href;
}
url = getRawEntityUrl(rawEntity, 'self');
} else {
warn('Missing href or "self" link');
url = '';
Expand All @@ -63,7 +79,7 @@ function getRawEntityUrl(rawEntity) {
* Note: This is probably a temporary solution as Siren does not yet officially support names on entity's.
*
* @static
* @param rawEntity
* @param {Object} rawEntity
* @returns {String}
*/
function getRawEntityRelAsName(rawEntity) {
Expand Down Expand Up @@ -117,53 +133,57 @@ function hasClass(classname) {


/**
* Accesses to the entity's "class"
*
* @param rel
* @returns {Boolean}
* @returns {Array}
*/
function hasRel(rel) {
return _.indexOf(this.rel(), rel) > -1;
function classes() {
return this._data['class'] || [];
}


/**
* Access the entity's url.
* In some cases this would be the "self" link, in other cases it's the "href".
* Access to the entity's "title"
*
* @returns {String}
*/
function url() {
return getRawEntityUrl(this._data);
function title() {
return this._data.title;
}


/**
* Accesses to the entity's "class"
* Access to the entity's "rel"
*
* @returns {Array}
* @returns {Array|undefined}
*/
function classes() {
return this._data['class'] || [];
function rel() {
return this._data.rel || [];
}


/**
* Access to the entity's "title"
*
* @returns {String}
* @param rel
* @returns {Boolean}
*/
function title() {
return this._data.title;
function hasRel(rel) {
return _.indexOf(this.rel(), rel) > -1;
}


/**
* Access to the entity's "rel"
* Gets an entity's link by rel
*
* @returns {Array|undefined}
* @param {String} rel
* @returns {String|undefined}
*/
function rel() {
return this._data.rel || [];
function link(rel) {
if (rel == 'self') {
return getRawEntitySelfUrl(this._data);
}

return getRawEntityUrl(this._data, rel);
}


Expand All @@ -177,6 +197,17 @@ function links() {
}


/**
* Access the entity's url.
* In some cases this would be the "self" link, in other cases it's the "href".
*
* @returns {String}
*/
function url() {
return this.link('self');
}


/**
* Access to the entity's "actions"
*
Expand Down Expand Up @@ -639,6 +670,7 @@ _.extend(BbSiren, {
, classes: classes
, rel: rel
, actions: actions
, link: link
, links: links
, title: title
, hasClass: hasClass
Expand Down Expand Up @@ -684,7 +716,7 @@ _.extend(BbSiren, {
, deferred = new $.Deferred();

if ((rawEntity.href && options.autoFetch == 'linked') || options.autoFetch == 'all') {
BbSiren.resolveOne(getRawEntityUrl(rawEntity), options)
BbSiren.resolveOne(getRawEntitySelfUrl(rawEntity), options)
.done(function (bbSiren) {
deferred.resolve(self.setEntity(bbSiren, rawEntity.rel, getRawEntityName(rawEntity)));
});
Expand Down Expand Up @@ -844,6 +876,7 @@ _.extend(BbSiren, {
, classes: classes
, rel: rel
, actions: actions
, link: link
, links: links
, title: title
, hasClass: hasClass
Expand Down
7 changes: 5 additions & 2 deletions src/backbone.siren.store.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,18 @@ Store.prototype = {
* @return {Backbone.Siren.Model}
*/
add: function (bbSirenObj) {
var self = this;
var self = this
, index;

if (Backbone.Siren.isCollection(bbSirenObj)) {
bbSirenObj.each(function (sirenModel) {
self.add(sirenModel);
});

index = bbSirenObj.link('current');
}

this.data[bbSirenObj.url()] = bbSirenObj;
this.data[index || bbSirenObj.url()] = bbSirenObj;
return bbSirenObj;
}

Expand Down
19 changes: 19 additions & 0 deletions test/spec/backbone.siren.collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ describe('Siren Collection: ', function () {


describe('.url()', function () {
it('is a proxy to this.link(\'self\')', function () {
this.stub(sirenCollection, 'link');
sirenCollection.url();
expect(sirenCollection.link).toHaveBeenCalled();
});


it('returns a collection\'s url, getting it from the href', function () {
var mySirenCollection = new Backbone.Siren.Collection({href: 'http://api.x.io/blah'});
expect(mySirenCollection.url()).toEqual('http://api.x.io/blah');
Expand Down Expand Up @@ -78,6 +85,18 @@ describe('Siren Collection: ', function () {
});


describe('.link()', function () {
it('returns a collection\'s link, finding the first that matches the given rel', function () {
expect(sirenCollection.link('previous')).toBe('api.kiva.org/lenders/6282/loans?page=3');
});


it('returns undefined if there is no link with that rel', function () {
expect(sirenCollection.link('non-existent')).not.toBeDefined();
});
});


describe('.links()', function () {
it('returns an array of the collection\'s links', function () {
var expectedLinks = loansCollectionSiren.links;
Expand Down
25 changes: 22 additions & 3 deletions test/spec/backbone.siren.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ describe('Siren Model: ', function () {
, {"name": "update-customer","method": "POST", "href": "http://api.x.io/customers", fields: [{name: "customer"}]}
]
,"links":[
{"rel":["self"],"href":"http://api.x.io/orders/42"}
,{"rel":["previous"],"href":"http://api.x.io/orders/41"}
,{"rel":["next"],"href":"http://api.x.io/orders/43"}
{"rel":["self"],"href": "http://api.x.io/orders/42"}
, {"rel":["previous"],"href": "http://api.x.io/orders/41"}
, {"rel":["next"],"href": "http://api.x.io/orders/43"}
]
}
, sirenModel, store;
Expand All @@ -34,6 +34,13 @@ describe('Siren Model: ', function () {


describe('.url()', function () {
it('is a proxy to this.link(\'self\')', function () {
this.stub(sirenModel, 'link');
sirenModel.url();
expect(sirenModel.link).toHaveBeenCalled();
});


it('returns a model\'s url, getting it from the href', function () {
var mySirenModel = new Backbone.Siren.Model({href: 'http://api.x.io/blah'});
expect(mySirenModel.url()).toEqual('http://api.x.io/blah');
Expand Down Expand Up @@ -84,6 +91,18 @@ describe('Siren Model: ', function () {
});


describe('.link()', function () {
it('returns a model\'s link, finding the first that matches the given rel', function () {
expect(sirenModel.link('previous')).toBe('http://api.x.io/orders/41');
});


it('returns undefined if there is no link with that rel', function () {
expect(sirenModel.link('non-existent')).not.toBeDefined();
});
});


describe('.links()', function () {
it('returns an array of the model\'s links', function () {
var expectedLinks = settingsModelSiren.links;
Expand Down
26 changes: 26 additions & 0 deletions test/spec/backbone.siren.store.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,32 @@ describe('Backbone.Siren.Store: ', function () {
expect(store.data['http://two']).toBeDefined();
expect(store.data['http://three']).toBeDefined();
});


it('adds a collection to the store, indexing by "current" if available', function () {
var store = new Backbone.Siren.Store()
, bbSirenCollection = new Backbone.Siren.Collection({
'class': ['collection']
, entities: [
{properties: {}, links: [{rel: ['self'], href: 'http://one'}]}
, {properties: {}, links: [{rel: ['self'], href: 'http://two'}]}
, {properties: {}, links: [{rel: ['self'], href: 'http://three'}]}
]
, links: [
{
rel: ['self']
, href: 'http://collect'
}
, {
rel: ['current']
, href: 'http://collect?page=30'
}
]
});

store.add(bbSirenCollection);
expect(store.data['http://collect?page=30']).toBeDefined();
});
});


Expand Down

0 comments on commit a7b92a6

Please sign in to comment.