Skip to content

Commit

Permalink
feat(tool): add tool service
Browse files Browse the repository at this point in the history
  • Loading branch information
mbarbeau committed Feb 24, 2017
1 parent 48cb954 commit 1602032
Show file tree
Hide file tree
Showing 6 changed files with 391 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/tools/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as Hapi from 'hapi';
import Routes from './routes';
import { IDatabase } from '../database';
import { IServerConfigurations } from '../configurations';

export function init(server: Hapi.Server,
configs: IServerConfigurations,
database: IDatabase) {
Routes(server, configs, database);
}
150 changes: 150 additions & 0 deletions src/tools/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import * as Hapi from 'hapi';
import * as Joi from 'joi';
import ToolController from './tool.controller';
import * as ToolValidator from './tool.validator';
// import { jwtValidator } from '../users/user-validator';
import { IDatabase } from '../database';
import { IServerConfigurations } from '../configurations';

export default function (server: Hapi.Server,
configs: IServerConfigurations,
database: IDatabase) {

const toolController = new ToolController(configs, database);
server.bind(toolController);

server.route({
method: 'GET',
path: '/tools/{id}',
config: {
handler: toolController.getToolById,
// auth: 'jwt',
auth: false,
tags: ['api', 'tools'],
description: 'Get tools by id.',
validate: {
params: {
id: Joi.string().required()
}
// headers: jwtValidator
},
plugins: {
'hapi-swagger': {
responses: {
'200': {
'description': 'Tool founded.'
},
'404': {
'description': 'Tool does not exists.'
}
}
}
}
}
});

server.route({
method: 'GET',
path: '/tools',
config: {
handler: toolController.getTools,
// auth: 'jwt',
auth: false,
tags: ['api', 'tools'],
description: 'Get all tools.',
validate: {
query: {
// top: Joi.number().default(5),
// skip: Joi.number().default(0)
}
// headers: jwtValidator
}
}
});

server.route({
method: 'DELETE',
path: '/tools/{id}',
config: {
handler: toolController.deleteTool,
// auth: 'jwt',
auth: false,
tags: ['api', 'tools'],
description: 'Delete tool by id.',
validate: {
params: {
id: Joi.string().required()
}
// headers: jwtValidator
},
plugins: {
'hapi-swagger': {
responses: {
'200': {
'description': 'Deleted Tool.',
},
'404': {
'description': 'Tool does not exists.'
}
}
}
}
}
});

server.route({
method: 'PUT',
path: '/tools/{id}',
config: {
handler: toolController.updateTool,
// auth: 'jwt',
auth: false,
tags: ['api', 'tools'],
description: 'Update tool by id.',
validate: {
params: {
id: Joi.string().required()
},
payload: ToolValidator.updateToolModel
// headers: jwtValidator
},
plugins: {
'hapi-swagger': {
responses: {
'200': {
'description': 'Deleted Tool.',
},
'404': {
'description': 'Tool does not exists.'
}
}
}
}
}
});

server.route({
method: 'POST',
path: '/tools',
config: {
handler: toolController.createTool,
// auth: 'jwt',
auth: false,
tags: ['api', 'tools'],
description: 'Create a tool.',
validate: {
payload: ToolValidator.createToolModel
// headers: jwtValidator
},
plugins: {
'hapi-swagger': {
responses: {
'201': {
'description': 'Created Tool.'
}
}
}
}
}
});
}
87 changes: 87 additions & 0 deletions src/tools/tool.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import * as Hapi from 'hapi';
import * as Boom from 'boom';
import { ITool, ToolInstance } from './tool.model';
import { IDatabase } from '../database';
import { IServerConfigurations } from '../configurations';

export default class ToolController {

private database: IDatabase;
private configs: IServerConfigurations;

constructor(configs: IServerConfigurations, database: IDatabase) {
this.configs = configs;
this.database = database;
}

public createTool(request: Hapi.Request, reply: Hapi.IReply) {
const newTool: ITool = request.payload;
this.database.tool.create(newTool).then((tool) => {
reply(tool).code(201);
}).catch((error) => {
reply(Boom.badImplementation(error));
});
}

public updateTool(request: Hapi.Request, reply: Hapi.IReply) {
const id = request.params['id'];
const tool: ITool = request.payload;

this.database.tool.update(tool, {
where: {
id: id
}
}).then((count: [number, ToolInstance[]]) => {
if (count[0]) {
reply({});
} else {
reply(Boom.notFound());
}
}).catch((error) => {
reply(Boom.badImplementation(error));
});
}

public deleteTool(request: Hapi.Request, reply: Hapi.IReply) {
const id = request.params['id'];
this.database.tool.destroy({
where: {
id: id
}
}).then((count: number) => {
if (count) {
reply({});
} else {
reply(Boom.notFound());
}
}).catch((error) => {
reply(Boom.badImplementation(error));
});
}

public getToolById(request: Hapi.Request, reply: Hapi.IReply) {
const id = request.params['id'];
this.database.tool.findOne({
where: {
id: id
}
}).then((tool: ToolInstance) => {
if (tool) {
reply(tool);
} else {
reply(Boom.notFound());
}
}).catch((error) => {
reply(Boom.badImplementation(error));
});
}

public getTools(request: Hapi.Request, reply: Hapi.IReply) {
this.database.tool.findAll()
.then((tools: Array<ToolInstance>) => {
reply(tools);
}).catch((error) => {
reply(Boom.badImplementation(error));
});
}
}
69 changes: 69 additions & 0 deletions src/tools/tool.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import * as Sequelize from 'sequelize';

interface PropertiesTool {
attribution: string;
minZoom: number;
maxZoom: number;
};

export interface ITool {
name: string;
url: string;
protected: boolean;
properties: PropertiesTool;
};

export interface ToolInstance extends Sequelize.Instance<ITool> {
id: string;
createdAt: Date;
updatedAt: Date;

name: string;
url: string;
protected: boolean;
properties: PropertiesTool;
}

export interface ToolModel
extends Sequelize.Model<ToolInstance, ITool> { }


export default function define(sequelize: Sequelize.Sequelize, DataTypes) {
const tool = sequelize.define<ToolModel, ITool>('tool', {
'id': {
'type': DataTypes.INTEGER,
'allowNull': false,
'primaryKey': true,
'autoIncrement': true
},
'name': {
'type': DataTypes.STRING(64)
},
'url': {
'type': DataTypes.STRING(255),
'validate': {
'isUrl': true
}
},
'protected': {
'type': DataTypes.BOOLEAN
},
'properties': {
'type': DataTypes.TEXT,
'get': function() {
return JSON.parse(this.getDataValue('properties'));
},
'set': function(val) {
this.setDataValue('properties', JSON.stringify({}));
}
}
},
{
'tableName': 'tool',
'timestamps': true
});

tool.sync();

return tool;
}
52 changes: 52 additions & 0 deletions src/tools/tool.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as test from 'tape';
// import ToolCont from './tool.controller';
import * as Server from '../server';
import * as Configs from '../configurations';

const serverConfigs = Configs.getServerConfigs();

Server.init(serverConfigs).then((server) => {

test('Basic HTTP Tests - GET /tools', function(t) {
const options = {
method: 'GET',
url: '/tools'
};
server.inject(options, function(response) {
t.equal(response.statusCode, 200);
t.equal(response.result.length, 0);
server.stop(t.end);
});
});


test('Basic HTTP Tests - GET /tools/{id}', function(t) {
const options = {
method: 'GET',
url: '/tools/2'
};
server.inject(options, function(response) {
t.equal(response.statusCode, 404);
server.stop(t.end);
});
});


test('Basic HTTP Tests - POST /tools', function(t) {
const options = {
method: 'POST',
url: '/tools',
payload: {
name: 'dummy',
protected: false,
properties: {}
}
};
server.inject(options, function(response) {
t.equal(response.statusCode, 201);
server.stop(t.end);
});
});


});
23 changes: 23 additions & 0 deletions src/tools/tool.validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as Joi from 'joi';

export const createToolModel = Joi.object().keys({
name: Joi.string().max(64),
url: Joi.string(),
protected: Joi.boolean(),
properties: Joi.object().required().keys({
attribution: Joi.string(),
minZoom: Joi.number(),
maxZoom: Joi.number()
})
});

export const updateToolModel = Joi.object().keys({
name: Joi.string().max(64),
url: Joi.string(),
protected: Joi.boolean(),
properties: Joi.object().required().keys({
attribution: Joi.string(),
minZoom: Joi.number(),
maxZoom: Joi.number()
})
});

0 comments on commit 1602032

Please sign in to comment.