Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions lib/db/knexfile.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict'

// No momento só precisamos de um env configurado para o banco de dados
exports[process.env.NODE_ENV] = {
client: 'mysql2',
Expand Down
8 changes: 8 additions & 0 deletions lib/db/migrations/20161114224639_users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exports.up = knex => knex.schema.createTableIfNotExists('users', table => {
table.uuid('id').primary()
table.string('username', 20).unique().notNullable()
table.string('password', 60).notNullable()
table.timestamps()
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remover a linha em branco

exports.down = knex => knex.schema.dropTableIfExists('users')
4 changes: 4 additions & 0 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const express = require('express')
const glob = require('glob')
const path = require('path')
const helmet = require('helmet')
const morgan = require('morgan')

// Middlewares customizados
const errorHandler = require('./error-handler')
Expand All @@ -14,6 +15,9 @@ const app = express()
// Adiciona todos os middlewares necessários
app.use(helmet())

// Print request logs no console
app.use(morgan('combined'))

// Faz o require de todas as rotas dentro dos resources e injeta automaticamente
// na nossa app, assim não é necessário fazer o require um por um
const resourcePath = path.resolve(__dirname, '../resources')
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"helmet": "^3.1.0",
"joi": "^9.2.0",
"knex": "^0.12.6",
"morgan": "^1.7.0",
"mysql2": "^1.1.1"
},
"devDependencies": {
Expand Down
16 changes: 16 additions & 0 deletions resources/users/handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const db = require('../../lib/db')
const User = db.model('User')

exports.create = (req, res, next) => {
User.create(req.body)
.then(user => res.send({ success: true }))
.catch(err => {
if (err.code === 'ER_DUP_ENTRY') {
return res.status(400).send({
error: 'Este usuário já existe'
})
}

return next(err)
})
}
5 changes: 5 additions & 0 deletions resources/users/model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = bookshelf => bookshelf.model('User', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Se não usar o visibility também vamos responder as requests com a senha do usuário

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

k

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

esse eu já arrumei

tableName: 'users',
hidden: [ 'password' ],
bcrypt: { field: 'password' }
})
15 changes: 15 additions & 0 deletions resources/users/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const express = require('express')
const bodyParser = require('body-parser')

const validator = require('../../lib/validator')
const schemas = require('./schemas')
const handlers = require('./handlers')

const router = express.Router()

router.post('/usuarios',
bodyParser.json(),
validator({ body: schemas.create }),
handlers.create)

module.exports = router
13 changes: 13 additions & 0 deletions resources/users/schemas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const Joi = require('joi')

exports.model = Joi.object({
id: Joi.string().uuid(),
username: Joi.string(),
password: Joi.string()
})

exports.create = exports.model.concat(Joi.object({
id: Joi.forbidden(),
username: Joi.string().token().min(3).max(20).required(),
password: Joi.string().min(8).max(120).required()
}))
22 changes: 22 additions & 0 deletions test/fixtures/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const { knex } = require('../../lib/db')

/**
* Insere dois registros na tabela `users`
* @return {Promise} Uma promise que resolve quando os registros forem inseridos
*/
exports.insertMultiple = () => knex('users').insert([
{
id: '212dd279-129f-474a-beb2-a1cac605cf48',
username: 'alanhoff',
password: 'awesomePassword',
created_at: new Date(),
updated_at: new Date()
},
{
id: '6af458a8-df22-4da9-a726-89d14076e220',
username: 'thebergamo',
password: 'awesomePassword',
created_at: new Date(),
updated_at: new Date()
}
])
70 changes: 70 additions & 0 deletions test/resources/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
const lab = exports.lab = require('lab').script()
const expect = require('code').expect
const co = require('co')
const request = require('supertest')

const server = require('../../lib/server')
const db = require('../../lib/db')
const Model = db.model('User')

const ENDPOINT = '/usuarios'

lab.describe('users', () => {
lab.beforeEach(() => db.truncate())

lab.describe(`POST ${ENDPOINT}`, () => {
lab.test('não deve aceitar um payload que não esteja de acordo com o schema', co.wrap(function * () {
const req = yield request(server)
.post(ENDPOINT)
.send({ username: 'p' })

expect(req.statusCode).to.equal(422)
expect(req.res.body.error).to.equal('ValidationError')
}))

lab.test('deve criar uma nova linha no banco de dados', co.wrap(function * () {
const req = yield request(server)
.post(ENDPOINT)
.send({
username: 'mark',
password: 'awesomePass'
})

expect(req.statusCode).to.equal(200)
expect(req.res.body.success).to.equal(true)

const data = yield Model.findAll()
expect(data).to.have.length(1)
expect(data.at(0).toJSON()).to.contain({
username: 'mark'
})
}))

lab.test('retorna um erro quando o usuário já existir', co.wrap(function * () {
// first request
yield request(server)
.post(ENDPOINT)
.send({
username: 'foo',
password: 'foobarbaz'
})

const req = yield request(server)
.post(ENDPOINT)
.send({
username: 'foo',
password: 'foobarbaz'
})

expect(req.statusCode).to.equal(400)
expect(req.res.body.error).to.equal('Este usuário já existe')

const data = yield Model.findAll()
expect(data).to.have.length(1)
expect(data.at(0).toJSON()).to.contain({
username: 'foo'
})
}))
})
})