Skip to content

Commit

Permalink
refactor: cleanup unecessary controller props (#420)
Browse files Browse the repository at this point in the history
* refactor: cleanup unecessary controller props

* test: test against custom routes and model-less controllers
  • Loading branch information
zacharygolba authored Sep 27, 2016
1 parent a12bcad commit 0e6ec39
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 215 deletions.
74 changes: 7 additions & 67 deletions src/packages/controller/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
import { Model } from '../database';
import { getDomain } from '../server';
import { freezeProps, deepFreezeProps } from '../freezeable';
import { freezeProps } from '../freezeable';

import findOne from './utils/find-one';
import findMany from './utils/find-many';
Expand Down Expand Up @@ -170,30 +170,6 @@ class Controller {
*/
hasSerializer: boolean;

/**
* @property modelName
* @memberof Controller
* @instance
* @private
*/
modelName: string;

/**
* @property attributes
* @memberof Controller
* @instance
* @private
*/
attributes: Array<string>;

/**
* @property relationships
* @memberof Controller
* @instance
* @private
*/
relationships: Array<string>;

/**
* @property serializer
* @memberof Controller
Expand All @@ -211,37 +187,13 @@ class Controller {
controllers: Map<string, Controller>;

constructor({ model, namespace, serializer }: Controller$opts) {
const hasModel = Boolean(model);
const hasNamespace = Boolean(namespace);
const hasSerializer = Boolean(serializer);
let attributes = [];
let relationships = [];

if (hasModel && hasSerializer) {
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;
});

Object.freeze(attributes);
Object.freeze(relationships);
}

Object.assign(this, {
model,
namespace,
serializer
serializer,
hasModel: Boolean(model),
hasNamespace: Boolean(namespace),
hasSerializer: Boolean(serializer)
});

freezeProps(this, true,
Expand All @@ -250,22 +202,10 @@ class Controller {
'serializer'
);

Object.assign(this, {
hasModel,
hasNamespace,
hasSerializer,
attributes,
relationships,
modelName: hasModel ? model.modelName : '',
});

deepFreezeProps(this, false,
freezeProps(this, false,
'hasModel',
'hasNamespace',
'hasSerializer',
'attributes',
'relationships',
'modelName'
'hasSerializer'
);
}

Expand Down
109 changes: 41 additions & 68 deletions src/packages/router/route/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
import { ID_PATTERN } from './constants';

import { FreezeableSet } from '../../freezeable';
import { FreezeableSet, freezeProps, deepFreezeProps } from '../../freezeable';

import { createAction } from './action';
import { paramsFor, defaultParamsFor, validateResourceId } from './params';
Expand Down Expand Up @@ -33,6 +33,8 @@ class Route extends FreezeableSet<Action<any>> {

staticPath: string;

defaultParams: Object;

dynamicSegments: Array<string>;

constructor({
Expand All @@ -55,65 +57,44 @@ class Route extends FreezeableSet<Action<any>> {
dynamicSegments
});

const staticPath = getStaticPath(path, dynamicSegments);

const defaultParams = defaultParamsFor({
type,
controller
});

super(createAction(type, handler, controller));

Object.defineProperties(this, {
type: {
value: type,
writable: false,
enumerable: true,
configurable: false
},

path: {
value: path,
writable: false,
enumerable: true,
configurable: false
},

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

action: {
value: action,
writable: false,
enumerable: true,
configurable: false
},

method: {
value: method,
writable: false,
enumerable: true,
configurable: false
},

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

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

staticPath: {
value: getStaticPath(path, dynamicSegments),
writable: false,
enumerable: false,
configurable: false
}
Object.assign(this, {
type,
path,
params,
action,
method,
controller,
staticPath,
defaultParams,
dynamicSegments
});

freezeProps(this, true,
'type',
'path'
);

freezeProps(this, false,
'action',
'params',
'method',
'controller',
'staticPath'
);

deepFreezeProps(this, false,
'defaultParams',
'dynamicSegments'
);
} else {
const {
constructor: {
Expand Down Expand Up @@ -151,15 +132,6 @@ class Route extends FreezeableSet<Action<any>> {
}, {});
}

getDefaultParams() {
const { type, controller } = this;

return defaultParamsFor({
type,
controller
});
}

async execHandlers(req: Request, res: Response): Promise<any> {
for (const handler of this) {
const data = await handler(req, res);
Expand All @@ -171,9 +143,10 @@ class Route extends FreezeableSet<Action<any>> {
}

async visit(req: Request, res: Response): Promise<any> {
Object.assign(req, {
defaultParams: this.getDefaultParams(),
const { defaultParams } = this;

Object.assign(req, {
defaultParams,
params: this.params.validate({
...req.params,
...this.parseParams(req.url.pathname)
Expand Down
103 changes: 103 additions & 0 deletions src/packages/router/route/params/test/params.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// @flow
import { expect } from 'chai';
import { it, describe, before } from 'mocha';

import { defaultParamsFor } from '../index';

import setType from '../../../../../utils/set-type';
import { getTestApp } from '../../../../../../test/utils/get-test-app';

import type Controller from '../../../../controller';

describe('module "router/route/params"', () => {
describe('#defaultParamsFor()', () => {
let getController;

before(async () => {
const { controllers } = await getTestApp();

getController = (name: string): Controller => setType(() => {
return controllers.get(name);
});
});

describe('with collection route', () => {
let params;
let controller;

before(() => {
controller = getController('posts');
params = defaultParamsFor({
controller,
type: 'collection'
});
});

it('contains sort', () => {
expect(params).to.include.keys('sort');
});

it('contains page cursor', () => {
expect(params).to.include.keys('page');
expect(params.page).to.include.keys('size', 'number');
});

it('contains model fields', () => {
const { model, serializer: { attributes } } = controller;

expect(params.fields).to.include.keys(model.resourceName);
expect(params.fields[model.resourceName]).to.deep.equal(attributes);
});
});

describe('with member route', () => {
let params;
let controller;

before(() => {
controller = getController('posts');
params = defaultParamsFor({
controller,
type: 'member'
});
});

it('contains model fields', () => {
const { model, serializer: { attributes } } = controller;

expect(params.fields).to.include.keys(model.resourceName);
expect(params.fields[model.resourceName]).to.deep.equal(attributes);
});
});

describe('with custom route', () => {
let params;

before(() => {
params = defaultParamsFor({
type: 'custom',
controller: getController('posts')
});
});

it('is an empty object literal', () => {
expect(params).to.deep.equal({});
});
});

describe('with model-less controller', () => {
let params;

before(() => {
params = defaultParamsFor({
type: 'custom',
controller: getController('health')
});
});

it('is an empty object literal', () => {
expect(params).to.deep.equal({});
});
});
});
});
Loading

0 comments on commit 0e6ec39

Please sign in to comment.