Skip to content

Commit

Permalink
MemServer.Server route shortcuts tests done
Browse files Browse the repository at this point in the history
  • Loading branch information
izelnakri committed Oct 29, 2017
1 parent 40f52b2 commit ff10ccd
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 167 deletions.
10 changes: 9 additions & 1 deletion lib/mem-server/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,20 @@ export default function(options) {
return this.serialize(objectOrArray);
},
serialize(object) { // NOTE: add links object ?
const objectWithAllAttributes = this.attributes.reduce((result, attribute) => {
if (result[attribute] === undefined) {
result[attribute] = null;
}

return object;
}, object);

return Object.keys(this.embedReferences).reduce((result, embedKey) => {
const embedModel = this.embedReferences[embedKey];
const embeddedRecords = this.getRelationship(object, embedKey, embedModel);

return Object.assign(result, { [embedKey]: embedModel.serializer(embeddedRecords) });
}, object);
}, objectWithAllAttributes);
},
getRelationship(parentObject, relationshipName, relationshipModel) {
if (Array.isArray(parentObject)) {
Expand Down
41 changes: 19 additions & 22 deletions lib/mem-server/pretender-hacks.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,20 @@ window.Pretender.prototype.handleRequest = function(request) {
var pretender = this;
var verb = request.method.toUpperCase();
var path = request.url;
var handler = this._handlerFor(verb, path, request);
var handler = pretender._handlerFor(verb, path, request);

var _handleRequest = function(result) {
var statusCode, headers, body;

if (Array.isArray(result) && result.length === 3) {
statusCode = result[0],
headers = pretender.prepareHeaders(result[1]),
body = pretender.prepareBody(result[2], headers);
var statusCode = result[0];
var headers = pretender.prepareHeaders(result[1]);
var body = pretender.prepareBody(result[2], headers);

return pretender.handleResponse(request, async, function() {
request.respond(statusCode, headers, body);
pretender.handledRequest(verb, path, request);
})
} else if (!result) {
headers = pretender.prepareHeaders({ 'Content-Type': 'application/json' });
var headers = pretender.prepareHeaders({ 'Content-Type': 'application/json' });

if (verb === 'DELETE') {
return pretender.handleResponse(request, async, function() {
Expand All @@ -68,11 +66,10 @@ window.Pretender.prototype.handleRequest = function(request) {
});
}

var statusCode = getDefaultStatusCode(verb);
var headers = pretender.prepareHeaders({ 'Content-Type': 'application/json' });
var targetResult = typeof result === 'string' ? result : JSON.stringify(result);

statusCode = getDefaultStatusCode(verb);
headers = pretender.prepareHeaders({ 'Content-Type': 'application/json' });
body = pretender.prepareBody(targetResult, headers);
var body = pretender.prepareBody(targetResult, headers);

return pretender.handleResponse(request, async, function() {
request.respond(statusCode, headers, body);
Expand All @@ -81,8 +78,8 @@ window.Pretender.prototype.handleRequest = function(request) {
}

if (handler) {
handler.handler.numberOfCalls++;
var async = handler.handler.async;
handler.handler.numberOfCalls++;
this.handledRequests.push(request);

var result = handler.handler(request);
Expand All @@ -98,17 +95,17 @@ window.Pretender.prototype.handleRequest = function(request) {
this.unhandledRequest(verb, path, request);
}
}
}

function getDefaultStatusCode(verb) {
if (['GET', 'PUT', 'PATCH'].includes(verb)) {
return 200;
} else if (verb === 'POST') {
return 201;
} else if (verb === 'DELETE') {
return 204;
}

return 500;
function getDefaultStatusCode(verb) {
if (['GET', 'PUT', 'PATCH'].includes(verb)) {
return 200;
} else if (verb === 'POST') {
return 201;
} else if (verb === 'DELETE') {
return 204;
}

return 500;
}
// END: Pretender Response Defaults UX Hack
64 changes: 38 additions & 26 deletions lib/mem-server/server.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import chalk from 'chalk';
import { classify, underscore } from 'ember-cli-string-utils';

const { pluralize, singularize } = require('i')(); // NOTE: move to ES6 imports

const targetNamespace = typeof global === 'object' ? global : window;

export default function(options) {
const Server = require(`${process.cwd()}/memserver/server`).default; // NOTE: make this ES6 import
Expand All @@ -8,7 +13,7 @@ export default function(options) {
window.Pretender.prototype[verb] = function (path, handler, async) {
const { urlPrefix, namespace } = options; // NOTE: this doesnt allow for this.namespace declaration in the server.js
const fullPath = (urlPrefix || '') + (namespace ? ('/' + namespace) : '') + path;
const targetHandler = handler || getDefaultRouteHandler(verb, fullPath);
const targetHandler = handler || getDefaultRouteHandler(verb.toUpperCase(), fullPath);

return this.register(verb.toUpperCase(), fullPath, targetHandler, async || options.timing);
}
Expand Down Expand Up @@ -43,61 +48,68 @@ export default function(options) {
return pretender;
}

function colorStatusCode(statusCode) {
if (statusCode === 200 || statusCode === 201) {
return chalk.green(statusCode);
} else if (statusCode === 404 || statusCode === 204) {
return chalk.cyan(statusCode);
}

return chalk.red(statusCode);
}

function getDefaultRouteHandler(verb, path) {
const paths = path.split(/\//g);
const resourceReference = paths[paths.length - 1];
console.log('resourceReference');
console.log(resourceReference);
const lastPath = paths[paths.length - 1];

const ResourceModel = undefined; // TODO: change this
// TODO: if resourceModel not found throw error?
// TODO: if resourceModel not found throw error? with tests

if (verb === 'GET') {
if (resourceReference.includes(':')) {
if (lastPath.includes(':')) {
return (request) => {
const resourceKey = undefined; // TODO
const resourceKey = singularize(paths[paths.length - 2]);
const ResourceModel = targetNamespace.MemServer.Models[classify(resourceKey)];

return { [resourceKey]: ResourceModel.serialize(ResourceModel.find(request.params.id)) };
return { [resourceKey]: ResourceModel.serializer(ResourceModel.find(request.params.id)) };
}
}

return (request) => {
return { [resourceReference]: ResourceModel.serialize(ResourceModel.findAll()) };
const ResourceModel = targetNamespace.MemServer.Models[classify(singularize(lastPath))];

return { [lastPath]: ResourceModel.serializer(ResourceModel.findAll()) };
};
} else if (verb === 'POST') {
return (request) => {
return { [resourceReference]: ResourceModel.serialize(ResourceModel.insert(request.params)) };
const resourceKey = singularize(lastPath);
const ResourceModel = targetNamespace.MemServer.Models[classify(resourceKey)];
const resourceParams = request.params[resourceKey];

return { [resourceKey]: ResourceModel.serializer(ResourceModel.insert(resourceParams)) };
};
} else if (verb === 'PUT') {
return (request) => {
const resourceKey = undefined; // TODO
const resourceKey = singularize(paths[paths.length - 2]);
const ResourceModel = targetNamespace.MemServer.Models[classify(resourceKey)];
const resourceParams = request.params[resourceKey];

return { [resourceKey]: ResourceModel.serialize(ResourceModel.update(request.params)) };
return { [resourceKey]: ResourceModel.serializer(ResourceModel.update(resourceParams)) };
};
} else if (verb === 'DELETE') {
return (request) => { ResourceModel.delete(request.params) };
const resourceKey = singularize(paths[paths.length - 2]);
const ResourceModel = targetNamespace.MemServer.Models[classify(resourceKey)];

return (request) => { ResourceModel.delete({ id: request.params.id }) };
}
}

function colorStatusCode(statusCode) {
if (statusCode === 200 || statusCode === 201) {
return chalk.green(statusCode);
} else if (statusCode === 404 || statusCode === 204) {
return chalk.cyan(statusCode);
}

return chalk.red(statusCode);
}


// TODO:
// const defaultPassthroughs = [
// 'http://localhost:0/chromecheckurl', // mobile chrome
// 'http://localhost:30820/socket.io' // electron
// ];

// NOTE: maybe do { trackRequests: false }

// MOTE: Check/test that only routes defined after this.namespace are affected.
// This is useful if you have a few one-off routes that you don’t want under your namespace:

Expand Down
Loading

0 comments on commit ff10ccd

Please sign in to comment.