Skip to content

Commit 18ad8e0

Browse files
committed
Add include feature to include serializing methods
1 parent 6df5f95 commit 18ad8e0

File tree

3 files changed

+159
-2
lines changed

3 files changed

+159
-2
lines changed

lib/serialize.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module.exports = function (app, defaults) {
3131
return regex.test(ctx.method.name);
3232
});
3333

34-
if (!matches.length) {
34+
if (!utils.shouldApplyJsonApi(ctx, defaults) && !matches.length) {
3535
return next();
3636
}
3737

lib/utils.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ module.exports = {
1515
pluralForModel: pluralForModel,
1616
urlFromContext: urlFromContext,
1717
primaryKeyForModel: primaryKeyForModel,
18-
shouldNotApplyJsonApi: shouldNotApplyJsonApi
18+
shouldNotApplyJsonApi: shouldNotApplyJsonApi,
19+
shouldApplyJsonApi: shouldApplyJsonApi
1920
};
2021

2122
function primaryKeyForModel (model) {
@@ -167,6 +168,24 @@ function buildModelUrl (protocol, host, apiRoot, modelName, id) {
167168
return result;
168169
}
169170

171+
function shouldApplyJsonApi (ctx, options) {
172+
if (!options.include) return false;
173+
174+
var modelName = ctx.method.sharedClass.name;
175+
var methodName = ctx.method.name;
176+
var model;
177+
var methods;
178+
for (var i = 0; i < options.include.length; i++) {
179+
model = options.include[i].model;
180+
methods = options.include[i].methods;
181+
if (model === modelName && !methods) return true;
182+
if (!model && methods === methodName) return true;
183+
if (model === modelName && methods === methodName) return true;
184+
if (model === modelName && _.contains(methods, methodName)) return true;
185+
}
186+
return false;
187+
}
188+
170189
function shouldNotApplyJsonApi (ctx, options) {
171190
//handle options.exclude
172191
if (!options.exclude) return false;

test/include.test.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
var request = require('supertest');
2+
var loopback = require('loopback');
3+
var expect = require('chai').expect;
4+
var JSONAPIComponent = require('../');
5+
var app;
6+
var Post;
7+
var Comment;
8+
9+
describe('include option', function () {
10+
beforeEach(function (done) {
11+
app = loopback();
12+
app.set('legacyExplorer', false);
13+
var ds = loopback.createDataSource('memory');
14+
15+
Post = ds.createModel('post', { title: String });
16+
app.model(Post);
17+
Post.customMethod = function (cb) {
18+
cb(null, {prop: 'value'});
19+
};
20+
Post.remoteMethod('customMethod', {
21+
http: {verb: 'get', path: '/custom'},
22+
returns: {root: true}
23+
});
24+
Post.customMethod2 = function (cb) {
25+
cb(null, {prop: 'value'});
26+
};
27+
Post.remoteMethod('customMethod2', {
28+
http: {verb: 'get', path: '/custom2'},
29+
returns: {root: true}
30+
});
31+
32+
Comment = ds.createModel('comment', { comment: String });
33+
app.model(Comment);
34+
Comment.customMethod = function (cb) {
35+
cb(null, {prop: 'value'});
36+
};
37+
Comment.remoteMethod('customMethod', {
38+
http: {verb: 'get', path: '/custom'},
39+
returns: {root: true}
40+
});
41+
42+
app.use(loopback.rest());
43+
44+
Post.create({title: 'my post'}, function () {
45+
Comment.create({comment: 'my comment'}, done);
46+
});
47+
});
48+
49+
describe('including a specific method', function () {
50+
beforeEach(function () {
51+
JSONAPIComponent(app, {
52+
include: [
53+
{methods: 'customMethod'}
54+
]
55+
});
56+
});
57+
58+
it('should apply jsonapi to post model output for customMethod method', function (done) {
59+
request(app).get('/posts/custom')
60+
.expect(200)
61+
.end(function (err, res) {
62+
expect(err).to.equal(null);
63+
expect(res.body.data).to.have.keys('type', 'attributes', 'links');
64+
done();
65+
});
66+
});
67+
68+
it('should apply jsonapi to comment model output for customMethod method', function (done) {
69+
request(app).get('/comments/custom')
70+
.expect(200)
71+
.end(function (err, res) {
72+
expect(err).to.equal(null);
73+
expect(res.body.data).to.have.keys('type', 'attributes', 'links');
74+
done();
75+
});
76+
});
77+
});
78+
79+
describe('including a specific method on a specific model', function () {
80+
beforeEach(function () {
81+
JSONAPIComponent(app, {
82+
include: [
83+
{model: 'post', methods: 'customMethod'}
84+
]
85+
});
86+
});
87+
88+
it('should apply jsonapi to post model output for customMethod method', function (done) {
89+
request(app).get('/posts/custom')
90+
.expect(200)
91+
.end(function (err, res) {
92+
expect(err).to.equal(null);
93+
expect(res.body.data).to.have.keys('type', 'attributes', 'links');
94+
done();
95+
});
96+
});
97+
98+
it('should not apply jsonapi to comment model output for customMethod method', function (done) {
99+
request(app).get('/comments/custom')
100+
.expect(200)
101+
.end(function (err, res) {
102+
expect(err).to.equal(null);
103+
expect(res.body).to.deep.equal({ prop: 'value'});
104+
done();
105+
});
106+
});
107+
});
108+
109+
describe('including a specific set of methods on a specific model', function () {
110+
beforeEach(function () {
111+
JSONAPIComponent(app, {
112+
include: [
113+
{model: 'post', methods: ['customMethod', 'customMethod2']}
114+
]
115+
});
116+
});
117+
118+
it('should apply jsonapi to post model output for customMethod method', function (done) {
119+
request(app).get('/posts/custom')
120+
.expect(200)
121+
.end(function (err, res) {
122+
expect(err).to.equal(null);
123+
expect(res.body.data).to.have.keys('type', 'attributes', 'links');
124+
done();
125+
});
126+
});
127+
128+
it('should apply jsonapi to post model output for customMethod method', function (done) {
129+
request(app).get('/posts/custom2')
130+
.expect(200)
131+
.end(function (err, res) {
132+
expect(err).to.equal(null);
133+
expect(res.body.data).to.have.keys('type', 'attributes', 'links');
134+
done();
135+
});
136+
});
137+
});
138+
});

0 commit comments

Comments
 (0)