Skip to content

Commit

Permalink
feat(article): user should get article read time
Browse files Browse the repository at this point in the history
  • Loading branch information
Elie Mugenzi authored and Elie Mugenzi committed Jun 17, 2019
1 parent 1e25f12 commit afeb64a
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 56 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,6 @@
"mocha": "^6.1.4",
"nodemon": "^1.19.1",
"nyc": "^14.1.1"
}
},
"repository": "https://github.com/andela/tesla-ah.git"
}
3 changes: 3 additions & 0 deletions src/api/controllers/articlesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/* eslint-disable no-console */
import articles from '../../helpers/articlesHelper';
import models from '../../sequelize/models';
import readTime from '../../helpers/ReadTime.helper';

const { article, User } = models;

Expand Down Expand Up @@ -54,6 +55,8 @@ class articlesController {

const oneArticle = await articles.getOneSlug(slug);
res.status(200).send({
status: 200,
readtime: readTime(oneArticle.body),
article: oneArticle
});
}
Expand Down
14 changes: 14 additions & 0 deletions src/helpers/ReadTime.helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const converter = (seconds) => {
if (seconds > 60) {
return `${Math.ceil(seconds / 60)} min`;
}
return 'Less than a minute';
};
const readTime = (body) => {
const numWords = w => w.split(' ').length;
const WPS = 4;
const words = numWords(body);
const sec = words / WPS;
return converter(sec);
};
export default readTime;
8 changes: 2 additions & 6 deletions src/middleware/droppedToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,13 @@ const dropToken = async (req, res, next) => {
}
});
if (user.length) {
const deleted = await Blacklist.destroy({
await Blacklist.destroy({
where: {
userId: id
}
});
if (deleted) {
next();
}
} else {
next();
}
next();
};

export default dropToken;
57 changes: 57 additions & 0 deletions src/sequelize/migrations/20190612225745-create-user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@


module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstName: {
type: Sequelize.STRING
},
lastName: {
type: Sequelize.STRING
},
username: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
bio: {
type: Sequelize.TEXT
},
image: {
type: Sequelize.TEXT
},
dateOfBirth: {
type: Sequelize.DATE
},
gender: {
type: Sequelize.STRING
},
provider: {
type: Sequelize.STRING
},
socialId: {
type: Sequelize.STRING
},
verified: {
type: Sequelize.BOOLEAN
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}),
down: queryInterface => queryInterface.dropTable('Users')
};
57 changes: 57 additions & 0 deletions src/sequelize/migrations/20190613144226-create-user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@


module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstName: {
type: Sequelize.STRING
},
lastName: {
type: Sequelize.STRING
},
username: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
bio: {
type: Sequelize.TEXT
},
image: {
type: Sequelize.TEXT
},
dateOfBirth: {
type: Sequelize.DATE
},
gender: {
type: Sequelize.STRING
},
provider: {
type: Sequelize.STRING
},
socialId: {
type: Sequelize.STRING
},
verified: {
type: Sequelize.BOOLEAN
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}),
down: queryInterface => queryInterface.dropTable('Users')
};
55 changes: 55 additions & 0 deletions src/sequelize/migrations/20190617175548-create-user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstName: {
type: Sequelize.STRING
},
lastName: {
type: Sequelize.STRING
},
username: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
bio: {
type: Sequelize.TEXT
},
image: {
type: Sequelize.TEXT
},
dateOfBirth: {
type: Sequelize.DATE
},
gender: {
type: Sequelize.STRING
},
provider: {
type: Sequelize.STRING
},
socialId: {
type: Sequelize.STRING
},
verified: {
type: Sequelize.BOOLEAN
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}),
down: queryInterface => queryInterface.dropTable('Users')
};
5 changes: 3 additions & 2 deletions src/sequelize/models/user.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* eslint-disable func-names */


module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
firstName: DataTypes.STRING,
Expand All @@ -7,14 +9,13 @@ module.exports = (sequelize, DataTypes) => {
email: DataTypes.STRING,
password: DataTypes.STRING,
bio: DataTypes.TEXT,
image: DataTypes.TEXT,
image: DataTypes.STRING,
dateOfBirth: DataTypes.DATE,
gender: DataTypes.STRING,
provider: DataTypes.STRING,
socialId: DataTypes.STRING,
verified: DataTypes.BOOLEAN
}, {});

User.associate = function (models) {
// associations can be defined here
User.hasMany(models.article, {
Expand Down
31 changes: 31 additions & 0 deletions test/readtime.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { expect } from 'chai';
import readTime from '../src/helpers/ReadTime.helper';


describe('Read time tests', () => {
it('should return a beautiful read time', () => {
const body = `Since joining Andela’s Bootcamp,
that was the first time to know how to test my codes,
because there are some situations where the software( like a website)
is being broken in production(means when the users are using that product and face the technical bugs).
The way this was a challenge to me is that I had to learn it fast and implement them immediately.
I found how important it is, the way you target every block of code as input and
expect each possible output in order to catch some errors and correct them before the product
is going to get deployed. The main thing I learned from this challenge is that
I have to make sure my codes are bug-free before getting deployed and make sure my tests are covering every
block of codes. How I adapted to this challenge is, I spent a lot of sleepless nights figuring out how
to write my tests, I didn’t know anything about Travis CI and I got several emails that my builds were failing.
The main key is working hard, ask around and do more research to get your work done.\nGit workflow was another challenge I faced.
I tried it before, but I never tried the feature-branch workflow.
I found that workflow was awesome because it helps you manage the project tasks and work them into branches.
The reason it was a challenge is that we had to work in several branches and merge our work into the main branch and sometimes you face some merge conflicts.
I didn’t know how to resolve conflicts, but I tried to make some research about it, ask my colleagues how to resolve them and luckily
I got my work really organized on Github.`;
expect(readTime(body)).to.equal('2 min');
});

it('should get a less than a minute read time', () => {
const body = 'This is an amazing project we are working on, Authors Haven';
expect(readTime(body)).to.equal('Less than a minute');
});
});
Loading

0 comments on commit afeb64a

Please sign in to comment.