Skip to content

Commit

Permalink
feat(router): add namespace support for resource
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanfoster committed Mar 13, 2017
1 parent bdb312a commit 0548ed5
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 73 deletions.
33 changes: 28 additions & 5 deletions docs/classes/Router.html
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ <h3>Methods</h3>
<div class="meta">
<p>
Defined in
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L123">src/router.js:123</a>
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L127">src/router.js:127</a>
</p>


Expand Down Expand Up @@ -305,7 +305,7 @@ <h4>Returns:</h4>
<div class="meta">
<p>
Defined in
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L137">src/router.js:137</a>
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L141">src/router.js:141</a>
</p>


Expand Down Expand Up @@ -369,7 +369,7 @@ <h4>Returns:</h4>
<div class="meta">
<p>
Defined in
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L166">src/router.js:166</a>
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L170">src/router.js:170</a>
</p>


Expand Down Expand Up @@ -414,7 +414,7 @@ <h4>Returns:</h4>
<div class="meta">
<p>
Defined in
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L181">src/router.js:181</a>
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L185">src/router.js:185</a>
</p>


Expand Down Expand Up @@ -545,6 +545,9 @@ <h4>Parameters:</h4>
<li class="arg">
<code>name</code>
</li>
<li class="arg">
<code>options</code>
</li>
</ul><span class="paren">)</span>
</div>
</span>
Expand Down Expand Up @@ -586,6 +589,26 @@ <h4>Parameters:</h4>
</div>

</li>
<li class="param">
<code class="param-name">options</code>
<span class="type"><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="crosslink external" target="_blank">Object</a></span>


<div class="param-description"><p>resource mapping options</p>
</div>

<ul class="params-list">
<li class="param">
<code class="param-name">namespace</code>
<span class="type"><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String" class="crosslink external" target="_blank">String</a></span>

<div class="param-description"><p>mount the resource endpoint under a namespace</p>
<pre><code>this.resource("user", { namespace: "api" })</code></pre>
</div>

</li>
</ul>
</li>
</ul>
</div>

Expand Down Expand Up @@ -619,7 +642,7 @@ <h4>Parameters:</h4>
<div class="meta">
<p>
Defined in
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L95">src/router.js:95</a>
<a href="https://github.com/dylanfoster/parch/blob/0/src/router.js#L99">src/router.js:99</a>
</p>


Expand Down
26 changes: 19 additions & 7 deletions docs/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -707,14 +707,26 @@
"name": "name",
"description": "the resource name in singular form",
"type": "String"
},
{
"name": "options",
"description": "resource mapping options",
"type": "Object",
"props": [
{
"name": "namespace",
"description": "mount the resource endpoint under a namespace\n\n this.resource(\"user\", { namespace: \"api\" })",
"type": "String"
}
]
}
],
"class": "Router",
"module": "parch"
},
{
"file": "src/router.js",
"line": 95,
"line": 99,
"description": "Register a single route.\nUses {{#crossLink \"Router/_buildRoute:method\"}}_buildRoute{{/crossLink}} to\nnormalize the path\n\n Router.map(function () {\n this.route(\"/user/foo\", { using: \"users:foo\", method: \"get\" });\n });",
"itemtype": "method",
"name": "route",
Expand Down Expand Up @@ -747,7 +759,7 @@
},
{
"file": "src/router.js",
"line": 123,
"line": 127,
"description": "Consistently builds a route from a set of path segments using\n{{#crossLink \"Route\"}}Route{{/crossLink}}\n\n router._buildRoute(\"foo\", \"/bar\" \"baz/\");",
"itemtype": "method",
"name": "_buildRoute",
Expand All @@ -762,7 +774,7 @@
},
{
"file": "src/router.js",
"line": 137,
"line": 141,
"description": "generates main route handler plus pre and post hooks",
"access": "private",
"tagname": "",
Expand All @@ -789,7 +801,7 @@
},
{
"file": "src/router.js",
"line": 166,
"line": 170,
"description": "loads controllers from the loader",
"access": "private",
"tagname": "",
Expand All @@ -800,7 +812,7 @@
},
{
"file": "src/router.js",
"line": 181,
"line": 185,
"description": "maps a resource controller action and route",
"access": "private",
"tagname": "",
Expand Down Expand Up @@ -828,7 +840,7 @@
},
{
"file": "src/router.js",
"line": 205,
"line": 211,
"description": "configures router resources",
"static": 1,
"params": [
Expand Down Expand Up @@ -898,7 +910,7 @@
},
{
"message": "Missing item type\nconfigures router resources",
"line": " src/router.js:205"
"line": " src/router.js:211"
}
]
}
12 changes: 9 additions & 3 deletions docs/files/src_router.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,17 @@ <h1><i class="fa fa-file-code-o" aria-hidden="true"></i> File</h1>
*
* @method resource
* @param {String} name the resource name in singular form
* @param {Object} options resource mapping options
* @param {String} options.namespace mount the resource endpoint under a namespace
*
* this.resource(&quot;user&quot;, { namespace: &quot;api&quot; })
*/
resource(name) {
resource(name, options = {}) {
name = inflect.singularize(name);
const controller = this.controllers.get(name);

for (const [action] of restActionMapper) {
this._mapControllerAction(name, controller, action);
this._mapControllerAction(name, controller, action, options);
}
}

Expand Down Expand Up @@ -313,13 +317,15 @@ <h1><i class="fa fa-file-code-o" aria-hidden="true"></i> File</h1>
* @param {Object} controller the resource controller
* @param {String} action the controller method
*/
_mapControllerAction(resource, controller, action) {
_mapControllerAction(resource, controller, action, options) {
const method = restActionMapper.get(action);
const namespace = options.namespace || &quot;&quot;;
const singularResource = inflect.singularize(resource);
const pluralResource = inflect.pluralize(singularResource);
const pathSegment = restPathMapper.get(action);
const resourcePath = this._buildRoute(
this.namespacePrefix,
namespace,
pluralResource,
pathSegment
);
Expand Down
12 changes: 9 additions & 3 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,17 @@ class Router {
*
* @method resource
* @param {String} name the resource name in singular form
* @param {Object} options resource mapping options
* @param {String} options.namespace mount the resource endpoint under a namespace
*
* this.resource("user", { namespace: "api" })
*/
resource(name) {
resource(name, options = {}) {
name = inflect.singularize(name);
const controller = this.controllers.get(name);

for (const [action] of restActionMapper) {
this._mapControllerAction(name, controller, action);
this._mapControllerAction(name, controller, action, options);
}
}

Expand Down Expand Up @@ -187,13 +191,15 @@ class Router {
* @param {Object} controller the resource controller
* @param {String} action the controller method
*/
_mapControllerAction(resource, controller, action) {
_mapControllerAction(resource, controller, action, options) {
const method = restActionMapper.get(action);
const namespace = options.namespace || "";
const singularResource = inflect.singularize(resource);
const pluralResource = inflect.pluralize(singularResource);
const pathSegment = restPathMapper.get(action);
const resourcePath = this._buildRoute(
this.namespacePrefix,
namespace,
pluralResource,
pathSegment
);
Expand Down
120 changes: 65 additions & 55 deletions test/router_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,72 +130,82 @@ describe("Router", function () {
.end(done);
});

describe("hooks", function () {
let controller, create, destroy, hooks, index, show, update;
it("allows for namespacing", function (done) {
router.resource("foo", { namespace: "api" });

beforeEach(function () {
controller = router.controllers.get("foo");
});
client.get("/api/foos")
.expect(200)
.end(done);
});
});

it("binds a controller's index hooks", function (done) {
client.get("/foos")
.expect(200)
.end(function (err, res) {
if (err) { return done(err); }
describe("hooks", function () {
let controller, create, destroy, hooks, index, show, update;

expect(controller.hooks.index.before.called).to.be.true;
expect(controller.hooks.index.after.called).to.be.true;
done();
});
});
beforeEach(function () {
controller = router.controllers.get("foo");
router.resource("foo");
client = supertest(app);
});

it("binds a controller's show hooks", function (done) {
client.get("/foos/1")
.expect(200)
.end(function (err, res) {
if (err) { return done(err); }
it("binds a controller's index hooks", function (done) {
client.get("/foos")
.expect(200)
.end(function (err, res) {
if (err) { return done(err); }

expect(controller.hooks.show.before.called).to.be.true;
expect(controller.hooks.show.after.called).to.be.true;
done();
});
});
expect(controller.hooks.index.before.called).to.be.true;
expect(controller.hooks.index.after.called).to.be.true;
done();
});
});

it("binds a controller's create hooks", function (done) {
client.post("/foos")
.expect(201)
.end(function (err, res) {
if (err) { return done(err); }
it("binds a controller's show hooks", function (done) {
client.get("/foos/1")
.expect(200)
.end(function (err, res) {
if (err) { return done(err); }

expect(controller.hooks.create.before.called).to.be.true;
expect(controller.hooks.create.after.called).to.be.true;
done();
});
});
expect(controller.hooks.show.before.called).to.be.true;
expect(controller.hooks.show.after.called).to.be.true;
done();
});
});

it("binds a controller's update hooks", function (done) {
client.put("/foos/1")
.expect(200)
.end(function (err, res) {
if (err) { return done(err); }
it("binds a controller's create hooks", function (done) {
client.post("/foos")
.expect(201)
.end(function (err, res) {
if (err) { return done(err); }

expect(controller.hooks.update.before.called).to.be.true;
expect(controller.hooks.update.after.called).to.be.true;
done();
});
});
expect(controller.hooks.create.before.called).to.be.true;
expect(controller.hooks.create.after.called).to.be.true;
done();
});
});

it("binds a controller's destroy hooks", function (done) {
client.del("/foos/1")
.expect(204)
.end(function (err, res) {
if (err) { return done(err); }
it("binds a controller's update hooks", function (done) {
client.put("/foos/1")
.expect(200)
.end(function (err, res) {
if (err) { return done(err); }

expect(controller.hooks.destroy.before.called).to.be.true;
expect(controller.hooks.destroy.after.called).to.be.true;
done();
});
});
expect(controller.hooks.update.before.called).to.be.true;
expect(controller.hooks.update.after.called).to.be.true;
done();
});
});

it("binds a controller's destroy hooks", function (done) {
client.del("/foos/1")
.expect(204)
.end(function (err, res) {
if (err) { return done(err); }

expect(controller.hooks.destroy.before.called).to.be.true;
expect(controller.hooks.destroy.after.called).to.be.true;
done();
});
});
});

Expand Down

0 comments on commit 0548ed5

Please sign in to comment.