diff --git a/package.json b/package.json index 512f9a3..f108cfc 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "koa-body": "^2.0.0", "koa-router": "^7.0.1", "mysql": "^2.13.0", + "nodemailer": "^3.1.8", "sequelize": "^3.30.2" }, "devDependencies": { @@ -28,6 +29,7 @@ "babel-preset-stage-0": "^6.22.0", "chai": "^3.5.0", "sequelize-fixtures": "^0.5.6", + "sinon-es6": "^0.0.3", "sqlite3": "^3.1.8", "supertest": "^3.0.0" } diff --git a/src/mail.js b/src/mail.js new file mode 100644 index 0000000..da23bfd --- /dev/null +++ b/src/mail.js @@ -0,0 +1,15 @@ +//@flow + +import nodemailer from 'nodemailer' + +const transporter = nodemailer.createTransport({ + host: "smtp.aliyun.com", + port: 25, + secureConnection: true, + auth: { + user: process.env.MAIL_ACCOUNT, + pass: process.env.MAIL_PASSWORD + } +}) + +export default transporter diff --git a/src/person/router.js b/src/person/router.js index 1efafd3..b4d3edb 100644 --- a/src/person/router.js +++ b/src/person/router.js @@ -4,6 +4,7 @@ import Router from 'koa-router' import Boom from 'boom' import Person from './model' import { auth } from '../middleware' +import mail from '../mail' const router = new Router({ prefix: '/people' @@ -35,4 +36,18 @@ router.post('/login', async ctx => { } }) +router.post('/create', async ctx => { + const { email, password, first_name, last_name } = ctx.request.body + if (!email || !password) { + throw Boom.expectationFailed('require email and password', { email, password }) + } + const person = await Person.create({ email, password, first_name, last_name }) + const token = person.generateToken() + mail.sendMail({ from: process.env.MAIL_ACCOUNT, to: email, subject: 'Welcome to iLabs Tech Talk', text: 'Nice to meet you' }) + ctx.body = { + token, + person: person.toSafeJSON() + } +}) + export default router diff --git a/test/person/person.spec.js b/test/person/person.spec.js index 93ccf58..4107b23 100644 --- a/test/person/person.spec.js +++ b/test/person/person.spec.js @@ -1,6 +1,8 @@ import Person from '../../src/person/model' +import sinon from 'sinon-es6' +import mail from '../../src/mail' -describe("router - people", () => { +describe("router - /people", () => { describe('/login', () => { it('should throw on missing infomation', async () => { @@ -59,4 +61,67 @@ describe("router - people", () => { expect(res.body.person.hash).to.not.exist }) }) + + describe('/create', () => { + it('should throw on empty body', async () => { + const res = await app.post('/people/create') + expect(res.status).to.equal(417) + expect(res.body.message).to.equal('require email and password') + }) + + it('should throw on password less than 6', async () => { + const res = await app.post('/people/create').send({ + email: 'shengning@gmail.com', + password: 'pass' + }) + expect(res.status).to.equal(417) + expect(res.body.message).to.equal('password should have at least 6 characters') + }) + + it('should throw on missing name', async () => { + const res = await app.post('/people/create').send({ + email: 'shengning@gmail.com', + password: 'password' + }) + expect(res.status).to.equal(422) + expect(res.body.message).to.equal('first_name cannot be null') + }) + + it('should throw on malformed email address', async () => { + const res = await app.post('/people/create').send({ + email: 'shengning@gmail', + first_name: 'rex', + last_name: 'sheng', + password: 'password' + }) + expect(res.status).to.equal(417) + expect(res.body.message).to.equal('Validation isEmail failed') + }) + + it('should create person', async () => { + const mock = sinon.mock(mail) + mock.expects('sendMail').withArgs().once() + + const res = await app.post('/people/create').send({ + email: 'rex@interactivelabs.co', + password: 'password', + first_name: 'rex', + last_name: 'sheng' + }) + expect(res.status).to.equal(200) + res.body.should.have.key('token', 'person') + mock.verify() + }) + + it('should throw error on existing email', async () => { + let res = await app.post('/people/create').send({ + email: 'shengning@gmail.com', + password: 'password', + first_name: 'rex', + last_name: 'sheng', + }) + expect(res.status).to.equal(409) + expect(res.body.message).to.equal('email must be unique') + }) + }) })