From 8fa736517a7f56c997fc996c83822952f7509c3a Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Wed, 13 May 2015 18:34:11 +0200 Subject: [PATCH 1/3] Add test case to highlight fatal error when trying to include a scoped relationship through a polymorphic relationship --- test/relations.integration.js | 103 ++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/test/relations.integration.js b/test/relations.integration.js index 8c0766af..a0062c8f 100644 --- a/test/relations.integration.js +++ b/test/relations.integration.js @@ -27,6 +27,109 @@ describe('relations - integration', function() { this.app.models.widget.destroyAll(done); }); + describe.only('polymorphicHasMany', function() { + + before(function defineProductAndCategoryModels() { + var Group = app.model( + 'Group', + { properties: { name: 'string' }, + dataSource: 'db' + } + ); + var Reader = app.model( + 'Reader', + { properties: { name: 'string' }, + dataSource: 'db' + } + ); + var Picture = app.model( + 'Picture', + { properties: { name: 'string', imageableId: 'number', imageableType: 'string'}, + dataSource: 'db' + } + ); + + Reader.hasMany(Picture, { polymorphic: { // alternative syntax + as: 'imageable', // if not set, default to: reference + foreignKey: 'imageableId', // defaults to 'as + Id' + discriminator: 'imageableType' // defaults to 'as + Type' + } }); + + Picture.belongsTo('imageable', { polymorphic: { + foreignKey: 'imageableId', + discriminator: 'imageableType' + } }); + + Reader.belongsTo(Group); + }); + + before(function createEvent(done) { + var test = this; + app.models.Group.create({ name: 'Group 1' }, + function(err, group) { + if (err) return done(err); + test.group = group; + app.models.Reader.create({ name: 'Reader 1' }, + function(err, reader) { + if (err) return done(err); + test.reader = reader; + reader.pictures.create({ name: 'Picture 1' }); + reader.pictures.create({ name: 'Picture 2' }); + reader.group = test.group; + reader.save(done); + }); + } + ) + }); + + after(function(done) { + this.app.models.Reader.destroyAll(done); + }); + + it('includes the related child model', function(done) { + var url = '/api/readers/' + this.reader.id; + this.get(url) + .query({'filter': {'include' : 'pictures'}}) + .expect(200, function(err, res) { + // console.log(res.body); + expect(res.body.name).to.be.equal('Reader 1'); + expect(res.body.pictures).to.be.eql([ + { name: 'Picture 1', id: 1, imageableId: 1, imageableType: 'Reader'}, + { name: 'Picture 2', id: 2, imageableId: 1, imageableType: 'Reader'}, + ]); + done(); + }); + }); + + it('includes the related parent model', function(done) { + var url = '/api/pictures'; + this.get(url) + .query({'filter': {'include' : 'imageable'}}) + .expect(200, function(err, res) { + // console.log(res.body); + expect(res.body[0].name).to.be.equal('Picture 1'); + expect(res.body[1].name).to.be.equal('Picture 2'); + expect(res.body[0].imageable).to.be.eql({ name: 'Reader 1', id: 1}); + done(); + }); + }); + + it('includes related models scoped to the related parent model', function(done) { + var url = '/api/pictures'; + this.get(url) + .query({'filter': {'include' : {'relation': 'imageable', 'scope': { 'include' : 'group'}}}}) + .expect(200, function(err, res) { + console.log(res.body); + expect(res.body[0].name).to.be.equal('Picture 1'); + expect(res.body[1].name).to.be.equal('Picture 2'); + expect(res.body[0].imageable).to.be.eql({ name: 'Reader 1', id: 1}); + expect(res.body[0].imageable.group).to.be.eql({ name: 'Group 1', id: 1}); + done(); + }); + }); + + }); + describe('/store/superStores', function() { it('should invoke scoped methods remotely', function(done) { this.get('/api/stores/superStores') From d6c8d9725a987e8568025dbff7034e96fc499698 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Thu, 14 May 2015 22:09:51 +0200 Subject: [PATCH 2/3] Fix code standards issues --- test/relations.integration.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/relations.integration.js b/test/relations.integration.js index a0062c8f..6ffcd696 100644 --- a/test/relations.integration.js +++ b/test/relations.integration.js @@ -67,9 +67,9 @@ describe('relations - integration', function() { var test = this; app.models.Group.create({ name: 'Group 1' }, function(err, group) { - if (err) return done(err); - test.group = group; - app.models.Reader.create({ name: 'Reader 1' }, + if (err) return done(err); + test.group = group; + app.models.Reader.create({ name: 'Reader 1' }, function(err, reader) { if (err) return done(err); test.reader = reader; @@ -79,7 +79,7 @@ describe('relations - integration', function() { reader.save(done); }); } - ) + ); }); after(function(done) { From b5f702afd3cdf1b3d1b64829c010533093326b00 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Thu, 28 May 2015 16:15:02 -0700 Subject: [PATCH 3/3] Fix the test case --- test/relations.integration.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/test/relations.integration.js b/test/relations.integration.js index 6ffcd696..70f1ae12 100644 --- a/test/relations.integration.js +++ b/test/relations.integration.js @@ -27,11 +27,11 @@ describe('relations - integration', function() { this.app.models.widget.destroyAll(done); }); - describe.only('polymorphicHasMany', function() { + describe('polymorphicHasMany', function() { before(function defineProductAndCategoryModels() { - var Group = app.model( - 'Group', + var Team = app.model( + 'Team', { properties: { name: 'string' }, dataSource: 'db' } @@ -60,22 +60,22 @@ describe('relations - integration', function() { discriminator: 'imageableType' } }); - Reader.belongsTo(Group); + Reader.belongsTo(Team); }); before(function createEvent(done) { var test = this; - app.models.Group.create({ name: 'Group 1' }, - function(err, group) { + app.models.Team.create({ name: 'Team 1' }, + function(err, team) { if (err) return done(err); - test.group = group; + test.team = team; app.models.Reader.create({ name: 'Reader 1' }, function(err, reader) { if (err) return done(err); test.reader = reader; reader.pictures.create({ name: 'Picture 1' }); reader.pictures.create({ name: 'Picture 2' }); - reader.group = test.group; + reader.team(test.team); reader.save(done); }); } @@ -109,7 +109,7 @@ describe('relations - integration', function() { // console.log(res.body); expect(res.body[0].name).to.be.equal('Picture 1'); expect(res.body[1].name).to.be.equal('Picture 2'); - expect(res.body[0].imageable).to.be.eql({ name: 'Reader 1', id: 1}); + expect(res.body[0].imageable).to.be.eql({ name: 'Reader 1', id: 1, teamId: 1}); done(); }); }); @@ -117,13 +117,12 @@ describe('relations - integration', function() { it('includes related models scoped to the related parent model', function(done) { var url = '/api/pictures'; this.get(url) - .query({'filter': {'include' : {'relation': 'imageable', 'scope': { 'include' : 'group'}}}}) + .query({'filter': {'include' : {'relation': 'imageable', 'scope': { 'include' : 'team'}}}}) .expect(200, function(err, res) { - console.log(res.body); expect(res.body[0].name).to.be.equal('Picture 1'); expect(res.body[1].name).to.be.equal('Picture 2'); - expect(res.body[0].imageable).to.be.eql({ name: 'Reader 1', id: 1}); - expect(res.body[0].imageable.group).to.be.eql({ name: 'Group 1', id: 1}); + expect(res.body[0].imageable.name).to.be.eql('Reader 1'); + expect(res.body[0].imageable.team).to.be.eql({ name: 'Team 1', id: 1}); done(); }); });