<NME> scopeInclude.test.js
<BEF> 'use strict'
var loopback = require('loopback');
var expect = require('chai').expect;
var JSONAPIComponent = require('../');
var ds;
var app;
var Post;
var Comment;

describe('include option', function () {
  beforeEach(function () {
describe('include option', function () {
  beforeEach(function () {
    app = loopback()
    app.set('legacyExplorer', false)
    ds = loopback.createDataSource('memory')
    Post = ds.createModel(
      'post',
      {
        id: { type: Number, id: true },
        title: String,
        content: String
      },
      {
        scope: {
    Comment = ds.createModel('comment', {
      id: {type: Number, id: true},
      postId: Number,
      title: String,
      comment: String
    });
    app.model(Comment);
    Post.hasMany(Comment, {as: 'comments', foreignKey: 'postId'});
    Comment.settings.plural = 'comments';

    app.use(loopback.rest());
    Post.hasMany(Comment, { as: 'comments', foreignKey: 'postId' })
    Post.belongsTo(Author, { as: 'author', foreignKey: 'authorId' })
    Post.belongsTo(Category, { as: 'category', foreignKey: 'categoryId' })
    Comment.settings.plural = 'comments'

    app.use(loopback.rest())
    JSONAPIComponent(app, { restApiRoot: '/' })
  })

  describe('include defined at model level', function () {
    beforeEach(function (done) {
      Post.create(
        {
          title: 'my post',
          post.comments.create({
            title: 'My second comment',
            comment: 'My second comment text'
          }, done);
        });
      });
    });

    describe('hasMany response', function () {

      it('should have key `included`', function (done) {
        request(app).get('/posts/1')
                    function () {
                      post.category.create(
                        {
                          name: 'Programming'
                        },
                        done
                      )
                    }
                  )
                }
              )
            }
          )
          });
      });

    });
  });

});
        })
      })

      it('with include paramter should have both models', function (done) {
        request(app)
          .get('/posts/1?filter[include]=author')
          .end(function (err, res) {
            expect(err).to.equal(null)
            expect(res.body.included.length).equal(3)
            expect(res.body.included[0].type).equal('authors')
            expect(res.body.included[1].type).equal('comments')
            done()
          })
      })
      it('should include comments', function (done) {
        request(app)
          .get('/posts/1?filter={"include":["comments"]}')
          .end(function (err, res) {
            expect(err).to.equal(null)
            expect(res.body.included.length).equal(2)
            expect(res.body.included[0].type).equal('comments')
            expect(res.body.included[1].type).equal('comments')
            done()
          })
      })
      it('should include categories with empty attributes object', function (
        done
      ) {
        request(app)
          .get(
            '/posts/1?filter={"include":[{"relation":"category", "scope": {"fields": ["id"]}}]}'
          )
          .end(function (err, res) {
            expect(err).to.equal(null)
            expect(res.body.included.length).equal(3)
            expect(res.body.included[0].type).equal('categories')
            expect(res.body.included[0].attributes).to.include({})
            done()
          })
      })
    })
  })
})

<MSG> implement scope include

<DFF> @@ -2,10 +2,7 @@ var request = require('supertest');
 var loopback = require('loopback');
 var expect = require('chai').expect;
 var JSONAPIComponent = require('../');
-var ds;
-var app;
-var Post;
-var Comment;
+var ds, app, Post, Author, Comment, Category;
 
 describe('include option', function () {
   beforeEach(function () {
@@ -26,11 +23,30 @@ describe('include option', function () {
     Comment = ds.createModel('comment', {
       id: {type: Number, id: true},
       postId: Number,
+      authorId: Number,
       title: String,
       comment: String
     });
+
     app.model(Comment);
+
+    Author = ds.createModel('author', {
+      id: {type: Number, id: true},
+      name: String
+    });
+
+    app.model(Author);
+
+    Category = ds.createModel('category', {
+      id: {type: Number, id: true},
+      name: String
+    });
+
+    app.model(Author);
+
     Post.hasMany(Comment, {as: 'comments', foreignKey: 'postId'});
+    Post.belongsTo(Author, {as: 'author', foreignKey: 'authorId'});
+    Post.belongsTo(Category, {as: 'category', foreignKey: 'categoryId'});
     Comment.settings.plural = 'comments';
 
     app.use(loopback.rest());
@@ -51,12 +67,20 @@ describe('include option', function () {
           post.comments.create({
             title: 'My second comment',
             comment: 'My second comment text'
-          }, done);
+          }, function () {
+            post.author.create({
+              name: 'Joe'
+            }, function () {
+              post.category.create({
+                name: 'Programming'
+              }, done);
+            });
+          });
         });
       });
     });
 
-    describe('hasMany response', function () {
+    describe('response', function () {
 
       it('should have key `included`', function (done) {
         request(app).get('/posts/1')
@@ -76,7 +100,18 @@ describe('include option', function () {
           });
       });
 
+      it('with include paramter should have both models', function (done) {
+        request(app).get('/posts/1?filter[include]=author')
+          .end(function (err, res) {
+            expect(err).to.equal(null);
+            expect(res.body.included.length).equal(3);
+            expect(res.body.included[0].type).equal('authors');
+            expect(res.body.included[1].type).equal('comments');
+            done();
+          });
+      });
     });
+
   });
 
 });

implement scope include