Skip to content

Commit

Permalink
Koa: Testing get based on koa middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
Sefriol committed Jul 12, 2020
1 parent a86a9a1 commit fa37392
Show file tree
Hide file tree
Showing 5 changed files with 340 additions and 277 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "formio",
"parserOptions": {
"ecmaVersion": 2015
"ecmaVersion": 2020
},
"env": {
"browser": true,
Expand Down
2 changes: 1 addition & 1 deletion .mocharc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ module.exports = {
slow: 75,
timeout: 2000,
ui: 'bdd',
'watch-files': ['test/**/*.js']
'watch-files': ['test/**/testKoa.js']
};
162 changes: 111 additions & 51 deletions KoaResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ class Resource {
this.app.use(this.router.routes(), this.router.allowedMethods());
}

_generateMiddleware(options, position) {
let routeStack = [];

if (options && options[position]) {
const before = options[position].map((m) => m.bind(this));
routeStack = [...routeStack, ...before];
}
console.log(routeStack)
return compose(routeStack);
}

/**
* Sets the different responses and calls the next middleware for
* execution.
Expand Down Expand Up @@ -226,7 +237,7 @@ class Resource {
*/
static setResponse(res, resource, next) {
res.resource = resource;
next();
// next();
}

/**
Expand All @@ -248,7 +259,7 @@ class Resource {
// Uppercase the method.
method = method.charAt(0).toUpperCase() + method.slice(1).toLowerCase();
const methodOptions = { methodOptions: true };

console.log(options.before?.toString())
// Find all of the options that may have been passed to the rest method.
const beforeHandlers = options.before ?
(
Expand Down Expand Up @@ -629,61 +640,110 @@ class Resource {
get(options) {
options = Resource.getMethodOptions('get', options);
this.methods.push('get');
this._register('get', `${this.route}/:${this.name}Id`, (ctx, next) => {
// Store the internal method for response manipulation.
ctx.__rMethod = 'get';
if (ctx.skipResource) {
debug.get('Skipping Resource');
return next();
}
const middlewares = compose([
async(ctx, next) => {
console.log('test1')
return await next();
// Store the internal method for response manipulation.
ctx.__rMethod = 'get';
if (ctx.skipResource) {
debug.get('Skipping Resource');
return await next();
}
ctx.modelQuery = (ctx.modelQuery || ctx.model || this.model).findOne();
ctx.search = { '_id': ctx.params[`${this.name}Id`] };

const query = (ctx.modelQuery || ctx.model || this.model).findOne();
const search = { '_id': ctx.params[`${this.name}Id`] };
// Only call populate if they provide a populate query.
const populate = Resource.getParamQuery(ctx, 'populate');
if (populate) {
debug.get(`Populate: ${populate}`);
ctx.modelQuery.populate(populate);
}
return await next();
},
this._generateMiddleware.call(this, 'get', `${this.route}/:${this.name}Id`, options, 'before'),
async(ctx, next) => {
console.log('test2')
return await next();
ctx.item = await ctx.modelQuery.where(ctx.search).lean().exec();
if (!ctx.item) {
Resource.setResponse(ctx, { status: 404 }, next);
}
return await next();
},
this._generateMiddleware.call(this, 'get', `${this.route}/:${this.name}Id`, options, 'after'),
async(ctx, next) => {
console.log('test3')
return await next();
// Allow them to only return specified fields.
const select = Resource.getParamQuery(ctx, 'select');
if (select) {
const newItem = {};
// Always include the _id.
if (ctx.item._id) {
newItem._id = ctx.item._id;
}
select.split(' ').map(key => {
key = key.trim();
if (Object.prototype.hasOwnProperty.call(ctx.item,key)) {
newItem[key] = ctx.item[key];
}
});
ctx.item = newItem;
}
Resource.setResponse(ctx, { status: 200, item: ctx.item }, next);
return await next();
},
Resource.respond,
]);
console.log(middlewares.toString())
this.router.get(`${this.route}/:${this.name}Id`, middlewares);
this.app.use(this.router.routes(), this.router.allowedMethods());
/* this._register('get', `${this.route}/:${this.name}Id`, async(ctx, next) => {
try {
// Store the internal method for response manipulation.
ctx.__rMethod = 'get';
if (ctx.skipResource) {
debug.get('Skipping Resource');
return next();
}
// Only call populate if they provide a populate query.
const populate = Resource.getParamQuery(ctx, 'populate');
if (populate) {
debug.get(`Populate: ${populate}`);
query.populate(populate);
}
const query = (ctx.modelQuery || ctx.model || this.model).findOne();
ctx.search = { '_id': ctx.params[`${this.name}Id`] };
options.hooks.get.before.call(
this,
ctx,
search,
() => {
query.where(search).lean().exec((err, item) => {
if (err) return Resource.setResponse(ctx, { status: 400, error: err }, next);
if (!item) return Resource.setResponse(ctx, { status: 404 }, next);
// Only call populate if they provide a populate query.
const populate = Resource.getParamQuery(ctx, 'populate');
if (populate) {
debug.get(`Populate: ${populate}`);
query.populate(populate);
}
await next(); // options.hooks.get.before.call(this, ctx, search),
return options.hooks.get.after.call(
this,
ctx,
item,
() => {
// Allow them to only return specified fields.
const select = Resource.getParamQuery(ctx, 'select');
if (select) {
const newItem = {};
// Always include the _id.
if (item._id) {
newItem._id = item._id;
}
select.split(' ').map(key => {
key = key.trim();
if (Object.prototype.hasOwnProperty.call(item,key)) {
newItem[key] = item[key];
}
});
item = newItem;
}
Resource.setResponse(ctx, { status: 200, item: item }, next);
}
);
let item = await query.where(ctx.search).lean().exec();
if (!item) return Resource.setResponse(ctx, { status: 404 }, next);
await next(); // options.hooks.get.after.call(this, ctx, item);
// Allow them to only return specified fields.
const select = Resource.getParamQuery(ctx, 'select');
if (select) {
const newItem = {};
// Always include the _id.
if (item._id) {
newItem._id = item._id;
}
select.split(' ').map(key => {
key = key.trim();
if (Object.prototype.hasOwnProperty.call(item,key)) {
newItem[key] = item[key];
}
});
item = newItem;
}
);
}, Resource.respond, options);
Resource.setResponse(ctx, { status: 200, item: item }, next);
} catch (error) {
return Resource.setResponse(ctx, { status: 400, error }, next);
}
}, Resource.respond, options); */
return this;
}

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "A simple Express library to reflect Mongoose models to a REST interface.",
"main": "Resource.js",
"scripts": {
"test": "mocha --exit",
"test": "nyc mocha --exit",
"test:koa": "nyc mocha ./test/testKoa.js --exit",
"coverage": "nyc --reporter=lcov --report-dir=./coverage npm run test",
"lint": "eslint Resource.js"
},
Expand Down
Loading

0 comments on commit fa37392

Please sign in to comment.