Skip to content

Commit

Permalink
Restricting Services/API to work with user
Browse files Browse the repository at this point in the history
  • Loading branch information
karudedios committed Jun 8, 2016
1 parent 07e0ce5 commit 42e55d6
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 74 deletions.
9 changes: 7 additions & 2 deletions features/todo/model/todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ const TodoSchema = new Schema({
type: String,
required: true
},

desc: {
type: String,
required: false,
default: ''
},

color: {
type: String,
required: false,
Expand All @@ -24,6 +24,11 @@ const TodoSchema = new Schema({
},
message: '{VALUE} is not a valid HEX color'
}
},

owner: {
ref: 'User',
type: Schema.Types.ObjectId,
}
});

Expand Down
27 changes: 14 additions & 13 deletions features/todo/router/todo.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const _ = require('lodash');
const TodoDto = require('../model/dto');
const Router = require('express').Router;
const FindTodo = require('../services/findTodo');
Expand All @@ -6,29 +7,29 @@ const UpdateTodo = require('../services/updateTodo');
const DeleteTodo = require('../services/deleteTodo');
const PromisedResponse = require('../../../utils/promisedResponse');

module.exports = (Todo) =>
module.exports = (Todo, strategy) =>
new Router()
.get('/', PromisedResponse(() =>
.get('/', strategy.authenticated, PromisedResponse((req) =>
new FindTodo(Todo)
.find({ })
.find({ owner: req.user._id })
.then(TodoDto.newList)))
.get('/:id', PromisedResponse(req =>

.get('/:id', strategy.authenticated, PromisedResponse(req =>
new FindTodo(Todo)
.findOne({ _id: req.params.id })
.findOne({ _id: req.params.id, owner: req.user._id })
.then(TodoDto.new)))
.put('/:id', PromisedResponse(req =>

.put('/:id', strategy.authenticated, PromisedResponse(req =>
new UpdateTodo(Todo)
.update(req.params.id, req.body)
.then(TodoDto.new)))
.post('/', PromisedResponse(req =>

.post('/', strategy.authenticated, PromisedResponse(req =>
new CreateTodo(Todo)
.create(req.body)
.create(_.assign({ owner: req.user._id }, req.body))
.then(TodoDto.new)))
.delete('/:id', PromisedResponse(req =>

.delete('/:id', strategy.authenticated, PromisedResponse(req =>
new DeleteTodo(Todo)
.delete(req.params.id)
.then(TodoDto.new)));
6 changes: 4 additions & 2 deletions features/todo/services/createTodo.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
const Q = require('q');
const Joi = require('joi');
const validateSchema = require('../../../utils/validateSchema');
const objectIdSchema = require('../../../utils/objectIdSchema');

const todoSchema = Joi.object().keys({
name: Joi.string().required().label('todo.name')
name: Joi.string().required().label('todo.name'),
owner: objectIdSchema.required().label('todo.owner')
}).label('todo');

module.exports = class CreateTodo {
constructor(Todo) {
Object.assign(this, { Todo });
}

create(todo) {
return Q.when(todo)
.then(validateSchema(todoSchema, todo))
Expand Down
5 changes: 3 additions & 2 deletions features/todo/services/findTodo.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,23 @@ const predicateSchema = Joi.object().keys({
_id: objectIdSchema.optional().label('todo._id'),
name: Joi.string().optional().label('todo.name'),
desc: Joi.string().optional().label('todo.desc'),
owner: objectIdSchema.optional().label('todo.owner'),
color: Joi.string().regex(/#[a-f0-9]{6}/i).optional().label('todo.color')
}).required().label('predicate');

module.exports = class FindTodo {
constructor(Todo) {
Object.assign(this, { Todo });
}

findOne(predicate) {
return Q.when()
.then(validateSchema(predicateSchema, predicate))
.then(() => {
return Q.ninvoke(this.Todo, 'findOne', predicate);
});
}

find(predicate) {
return Q.when()
.then(validateSchema(predicateSchema, predicate))
Expand Down
6 changes: 3 additions & 3 deletions features/user/router/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ const FindUser = require('../services/findUser');
const UpdateUser = require('../services/updateUser');
const PromisedResponse = require('../../../utils/promisedResponse');

module.exports = (User) =>
module.exports = (User, strategy) =>
new Router()
.get('/:id', PromisedResponse(req =>
.get('/:id', strategy.authenticated, PromisedResponse(req =>
new FindUser(User)
.findOne({ _id: req.params.id })
.then(UserDto.new)))

.put('/:id', PromisedResponse(req =>
.put('/:id', strategy.authenticated, PromisedResponse(req =>
new UpdateUser(User)
.update(req.params.id, req.body)
.then(UserDto.new)));
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"express-session": "^1.13.0",
"http": "0.0.0",
"joi": "^8.4.0",
"lodash": "^4.13.1",
"md5": "^2.1.0",
"mongoose": "^4.4.19",
"passport": "^0.3.2",
Expand Down
31 changes: 20 additions & 11 deletions specs/todo/createTodo-spec.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,58 @@
const chai = require('chai');
const DatabaseMock = require('../helpers/databaseMock');
const Todo = require('../../features/todo/model/todo');
//const User = require('../../features/user/model/user');
const CreateTodo = require('../../features/todo/services/createTodo');

describe('create todo', () => {
const db = new DatabaseMock();

before(() => {
chai.should();
db.connect();
});

after((done) => {
db.clearDb(function() {
db.disconnect();
done();
});
});

it('should ask for the dependencies it needs', () => {
CreateTodo.length.should.equal(1);
(() => new CreateTodo(Todo)).should.not.throw();
});
it('should gracefully fail if required fields are not provided', () => {

it('should gracefully fail if name is not provided', () => {
return new CreateTodo(Todo)
.create({ })
.create({ owner: new Array(24).fill('0').join('') })
.catch(err => {
err.message.should.contain('"todo.name" is required');
});
});


it('should gracefully fail if owner is not provided', () => {
return new CreateTodo(Todo)
.create({ name: 'Some name' })
.catch(err => {
err.message.should.contain('"todo.owner" is required');
});
});

it('should gracefully fail if required fields are invalid', () => {
return new CreateTodo(Todo)
.create({ name: 5 })
.create({ name: 5, owner: '' })
.catch(err => {
err.message.should.contain('"todo.name" must be a string');
});
});

it('should perform the creation when .create is called', () => {
const name = 'Write a book';

return new CreateTodo(Todo)
.create({ name })
.create({ name, owner: new Array(24).fill('0').join('') })
.then(todo => {
todo._id.should.not.equal(undefined);
todo.name.should.equal(name);
Expand Down
24 changes: 12 additions & 12 deletions specs/todo/deleteTodo-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,60 +6,60 @@ const CreateTodo = require('../../features/todo/services/createTodo');

describe('delete todo', () => {
let todo = {};

const db = new DatabaseMock();

before((done) => {
chai.should();
db.connect();

const createTodo =new CreateTodo(Todo);
createTodo.create({ name: "test" })

createTodo.create({ name: "test", owner: new Array(24).fill(0).join('') })
.then(newTodo => {
todo = newTodo;
done();
});
});

after((done) => {
db.clearDb(function() {
db.disconnect();
done();
});
});

it('should ask for the dependencies it needs', () => {
DeleteTodo.length.should.equal(1);
(() => new DeleteTodo(Todo)).should.not.throw();
});

it('should gracefully fail if invalid todo_id is provided', () => {
return new DeleteTodo(Todo)
.delete(15)
.catch(err => {
err.message.should.contain('"todo._id" must be a string');
});
});

it('should gracefully fail if non 24-byte todo_id is provided', () => {
const oId = new Array(23).fill("0").join('');

return new DeleteTodo(Todo)
.delete(oId)
.catch(err => {
err.message.should.contain('"todo._id" length must be 24 characters long');
});
});

it('should gracefully fail if todo_id is not provided', () => {
return new DeleteTodo(Todo)
.delete()
.catch(err => {
err.message.should.contain('"todo._id" is required');
});
});

it('should delete a todo if .delete is called', () => {
return new DeleteTodo(Todo)
.delete(todo._id)
Expand Down
Loading

0 comments on commit 42e55d6

Please sign in to comment.