-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
620 additions
and
360 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import models from '../models'; | ||
|
||
const { ReadingStats } = models; | ||
/** | ||
* @class { ReadingStatsController } | ||
* @description { Handles Reading stats GET Requests } | ||
*/ | ||
export default class ReadingStatsController { | ||
/** | ||
* Save reading stats | ||
* @param {object} req | ||
* @param {object} res | ||
* @returns {object} stats object | ||
*/ | ||
static async create(req, res) { | ||
try { | ||
const userId = req.user.id; | ||
const { articleId } = req.params; | ||
const [result, created] = await ReadingStats.findOrCreate({ where: | ||
{ userId, articleId }, }); | ||
if (!created) { | ||
await ReadingStats.update({ numberOfReading: | ||
result.numberOfReading + 1 }, | ||
{ where: { id: result.id }, returning: true }); | ||
} | ||
res.status(201).send({ message: 'Reading...', | ||
articleId: result.articleId, | ||
userId: result.userId }); | ||
} catch (error) { | ||
return res.status(500).json(error.message); | ||
} | ||
} | ||
|
||
/** | ||
* Get reading stats | ||
* @param {Object} req express request | ||
* @param {Object} res express response | ||
* @returns {Array} user reading statistics | ||
*/ | ||
static async getAll(req, res) { | ||
try { | ||
const totalReadingStats = await ReadingStats.count({ where: | ||
{ articleId: req.params.articleId } }); | ||
return totalReadingStats | ||
? res.status(200).json({ message: 'Reading Stats:', | ||
totalReadings: totalReadingStats }) | ||
: res.status(404).json({ message: ' stats not found' }); | ||
} catch (error) { | ||
return res.status(500).json(error.message); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
|
||
|
||
module.exports = { up: (queryInterface, Sequelize) => queryInterface.createTable('ReadingStats', { id: { allowNull: false, | ||
autoIncrement: true, | ||
primaryKey: true, | ||
type: Sequelize.INTEGER }, | ||
articleId: { type: Sequelize.INTEGER, | ||
onDelete: 'CASCADE', | ||
references: { model: 'Articles', | ||
key: 'id', }, | ||
allowNull: false }, | ||
userId: { type: Sequelize.INTEGER, | ||
allowNull: true, | ||
references: { model: 'User', | ||
key: 'id' }, | ||
onUpdate: 'CASCADE', | ||
onDelete: 'CASCADE' }, | ||
numberOfReading: { allowNull: true, | ||
type: Sequelize.INTEGER }, | ||
createdAt: { allowNull: false, | ||
type: Sequelize.DATE }, | ||
updatedAt: { allowNull: false, | ||
type: Sequelize.DATE } }), | ||
down: queryInterface => queryInterface.dropTable('ReadingStats') }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
module.exports = (sequelize, DataTypes) => { | ||
const ReadingStats = sequelize.define('ReadingStats', { articleId: { type: DataTypes.STRING, | ||
allowNull: false }, | ||
userId: { type: DataTypes.INTEGER, | ||
allowNull: false, | ||
references: { model: 'User', | ||
key: 'id' }, | ||
onUpdate: 'CASCADE', | ||
onDelete: 'CASCADE' }, | ||
numberOfReading: { type: DataTypes.INTEGER } }, {}); | ||
ReadingStats.associate = (models) => { | ||
// associations can be defined here | ||
ReadingStats.belongsTo(models.Articles, { foreignKey: 'articleId', | ||
targetKey: 'id', | ||
onDelete: 'CASCADE', | ||
onupdate: 'CASCADE' }); | ||
ReadingStats.belongsTo(models.User, { foreignKey: 'userId', | ||
// as: 'user', | ||
targetKey: 'id', | ||
onDelete: 'CASCADE', | ||
onupdate: 'CASCADE' }); | ||
}; | ||
return ReadingStats; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import express from 'express'; | ||
import Auth from '../middlewares/Auth'; | ||
import ReaderStatsController from '../controllers/ReadStatsController'; | ||
|
||
const { verifyToken } = Auth; | ||
const router = express.Router(); | ||
router.get('/readerstats/:articleId', verifyToken, ReaderStatsController.getAll); | ||
router.post('/:articleId/readerstats', verifyToken, ReaderStatsController.create); | ||
|
||
export default router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import chai from 'chai'; | ||
import chaiHttp from 'chai-http'; | ||
import app from '../index'; | ||
|
||
chai.use(chaiHttp); | ||
chai.should(); | ||
|
||
let tokenGen; | ||
describe('READING STATS TEST', () => { | ||
it('A new user who filled all required data should be registered', (done) => { | ||
const user = { username: 'Kagabof', | ||
email: 'kagabo1@gmail.com', | ||
password: 'Kagabo1@', }; | ||
chai.request(app) | ||
.post('/api/users') | ||
.send(user) | ||
.end((req, res) => { | ||
// eslint-disable-next-line prefer-destructuring | ||
res.should.have.status(201); | ||
res.body.should.have.property('message'); | ||
res.body.should.have.property('token'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('User should be able to sign in', (done) => { | ||
const user2 = { username: 'Kagabo1', | ||
email: 'kagabo1@gmail.com', | ||
password: 'Kagabo1@', }; | ||
chai.request(app) | ||
.post('/api/users/login') | ||
.send(user2) | ||
.end((req, res) => { | ||
res.should.have.status(200); | ||
res.body.data.should.be.an('object'); | ||
res.body.data.should.have.property('email'); | ||
res.body.data.should.have.property('token'); | ||
tokenGen = res.body.data.token; | ||
done(); | ||
}); | ||
}); | ||
it('Autenticated user should be able to create reading stats', (done) => { | ||
const articleId = 3; | ||
chai | ||
.request(app) | ||
.post(`/api/${articleId}/readerstats`) | ||
.set('token', tokenGen) | ||
.end((err, res) => { | ||
res.should.have.status(201); | ||
res.body.should.be.an('object'); | ||
done(); | ||
}); | ||
}); | ||
it('Autenticated user should be able get reading stats', (done) => { | ||
const articleId = 3; | ||
chai | ||
.request(app) | ||
.get(`/api/readerstats/${articleId}`) | ||
.set('token', tokenGen) | ||
.end((err, res) => { | ||
res.should.have.status(200); | ||
res.body.should.be.an('object'); | ||
done(); | ||
}); | ||
}); | ||
it('Fail to get reading stats when not found', (done) => { | ||
const articleId = 4; | ||
chai | ||
.request(app) | ||
.get(`/api/readerstats/${articleId}`) | ||
.set('token', tokenGen) | ||
.end((err, res) => { | ||
res.should.have.status(404); | ||
res.body.should.be.an('object'); | ||
done(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.