Skip to content

Commit

Permalink
fix: middleware functions added in 'beforeAction' not executing
Browse files Browse the repository at this point in the history
  • Loading branch information
zacharygolba committed May 18, 2016
1 parent 81cdd21 commit 9bebefe
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 54 deletions.
5 changes: 3 additions & 2 deletions src/packages/application/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ class Application extends Base {
serializer.serializers = serializers;
});

const appController = controllers.get('application').create({
let appController = controllers.get('application');
appController = new appController({
store,
domain,
serializers,
Expand All @@ -88,7 +89,7 @@ class Application extends Base {
if (key !== 'application') {
const model = store.modelFor(singularize(key));

controller = controller.create({
controller = new controller({
store,
model,
domain,
Expand Down
176 changes: 125 additions & 51 deletions src/packages/controller/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import Promise from 'bluebird';

import Base from '../base';

import formatInclude from './utils/format-include';
import createPageLinks from './utils/create-page-links';

import action from './decorators/action';

class Controller extends Base {
const { isArray } = Array;
const { defineProperties } = Object;

class Controller {
store;
model;
domain;
Expand All @@ -16,73 +17,146 @@ class Controller extends Base {
attributes;
serializer;
serializers;
parentController;

sort = [];
filter = [];
params = [];
beforeAction = [];
defaultPerPage = 25;

constructor({ model, serializer, parentController, ...props }) {
_sort = [];
_filter = [];

constructor({
store,
model,
domain,
serializer,
serializers = new Map(),
parentController
}) {
let attributes = [];
let relationships = [];

if (model && serializer) {
const { primaryKey, attributeNames, relationshipNames } = model;
const { attributes: serializedAttributes } = serializer;
const serializedRelationships = [
...serializer.hasOne,
...serializer.hasMany
];

attributes = attributeNames.filter(attr => {
return attr === primaryKey || serializedAttributes.indexOf(attr) >= 0;
});

relationships = relationshipNames.filter(relationship => {
return serializedRelationships.indexOf(relationship) >= 0;
});
}

super();
defineProperties(this, {
model: {
value: model,
writable: false,
enumerable: true,
configurable: false
},

if (model) {
props = {
...props,
model,
modelName: model.modelName
};
serializer: {
value: serializer,
writable: false,
enumerable: true,
configurable: false
},

attributes = model.attributeNames;
store: {
value: store,
writable: false,
enumerable: false,
configurable: false
},

if (!this.sort.length) {
props.sort = attributes;
}
domain: {
value: domain,
writable: false,
enumerable: false,
configurable: false
},

modelName: {
value: model ? model.modelName : null,
writable: false,
enumerable: false,
configurable: false
},

attributes: {
value: attributes,
writable: false,
enumerable: false,
configurable: false
},

relationships: {
value: relationships,
writable: false,
enumerable: false,
configurable: false
},

serializers: {
value: serializers,
writable: false,
enumerable: false,
configurable: false
},

if (!this.filter.length) {
props.filter = attributes;
parentController: {
value: parentController,
writable: false,
enumerable: false,
configurable: false
}
});

return this;
}

get sort() {
const { attributes, _sort: sort } = this;

return sort.length ? sort : attributes;
}

set sort(value = []) {
if (isArray(value)) {
this._sort = value;
}
}

if (serializer) {
props = {
...props,
serializer,

attributes: ['id', ...serializer.attributes]
.filter(attr => {
return attributes.indexOf(attr) >= 0;
}),

relationships: [
...serializer.hasOne,
...serializer.hasMany
]
};
get filter() {
const { attributes, _filter: filter } = this;

return filter.length ? filter : attributes;
}

set filter(value = []) {
if (isArray(value)) {
this._filter = value;
}
}

get middleware() {
const { beforeAction, parentController } = this;

if (parentController) {
props = {
...props,
parentController,

middleware: [
...parentController.middleware,
...this.beforeAction
]
};
return [
...parentController.middleware,
...beforeAction
];
} else {
props = {
...props,
middleware: this.beforeAction
};
return beforeAction;
}

this.setProps(props);

return this;
}

@action
Expand Down
20 changes: 20 additions & 0 deletions test/integration/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -465,4 +465,24 @@ describe('Integration: class Controller', () => {
expect(subject.status).to.equal(204);
});
});

describe('Regression: #middleware (https://github.com/postlight/lux/issues/94)', () => {
let subject;

before(async () => {
subject = await fetch(`${host}/posts`);
});

it('includes middleware from it\'s parentController', () => {
expect(
subject.headers.get('X-Powered-By')
).to.equal('Lux');
});

it('executes middleware from it\'s parentController', () => {
expect(
subject.headers.get('X-Controller')
).to.equal('Posts');
});
});
});
6 changes: 5 additions & 1 deletion test/test-app/app/controllers/application.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { Controller } from '../../../../dist';

class ApplicationController extends Controller {

beforeAction = [
function (req, res) {
res.setHeader('X-Powered-By', 'Lux');
}
];
}

export default ApplicationController;
6 changes: 6 additions & 0 deletions test/test-app/app/controllers/authors.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ class AuthorsController extends Controller {
params = [
'name'
];

beforeAction = [
function (req, res) {
res.setHeader('X-Controller', 'Authors');
}
];
}

export default AuthorsController;
6 changes: 6 additions & 0 deletions test/test-app/app/controllers/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ class PostsController extends Controller {
'body',
'isPublic'
];

beforeAction = [
function (req, res) {
res.setHeader('X-Controller', 'Posts');
}
];
}

export default PostsController;

0 comments on commit 9bebefe

Please sign in to comment.