-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #84 from andela/feature/164798034-user-can-see-the…
…ir-reading-stats #164798034 User can see their reading stats
- Loading branch information
Showing
14 changed files
with
329 additions
and
0 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
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,119 @@ | ||
import moment from 'moment'; | ||
import models from '../models'; | ||
import serverError from '../helpers/server-error'; | ||
|
||
const { Statistic, Sequelize } = models; | ||
|
||
const { Op } = Sequelize; | ||
|
||
/** | ||
* @description Get daily statistics of readers | ||
* @param {*} req | ||
* @param {*} res | ||
* @returns {object} and objevt containing the message and the number of books read by the user | ||
*/ | ||
const getDailyStatistic = async (req, res) => { | ||
try { | ||
const statisticBox = await Statistic.findAndCountAll({ | ||
where: { | ||
user_id: req.params.userid, | ||
createdAt: { | ||
[Op.gte]: moment() | ||
.subtract(12, 'hours') | ||
.toDate(), | ||
}, | ||
}, | ||
attributes: ['article_id', 'createdAt'], | ||
}); | ||
if (statisticBox.count === 0) { | ||
return res.status(200).json({ | ||
message: 'You did not read any article today.', | ||
}); | ||
} | ||
|
||
return res.status(200).json({ | ||
message: 'Your Reading Statistic Today', | ||
statistic: `${statisticBox.count} article read today`, | ||
}); | ||
} catch (err) { | ||
return serverError; | ||
} | ||
}; | ||
|
||
/** | ||
* @description Get weekly statistics of readers | ||
* @param {*} req | ||
* @param {*} res | ||
* @returns {object} and objevt containing the message and the number of books read by the user | ||
*/ | ||
const getWeeklyStatistic = async (req, res) => { | ||
try { | ||
const statisticBox = await Statistic.findAndCountAll({ | ||
where: { | ||
user_id: req.params.userid, | ||
createdAt: { | ||
[Op.gte]: moment() | ||
.subtract(6, 'days') | ||
.toDate(), | ||
}, | ||
}, | ||
attributes: ['article_id', 'createdAt'], | ||
}); | ||
|
||
if (statisticBox.count === 0) { | ||
return res.status(200).json({ | ||
message: 'You did not read any article this week.', | ||
}); | ||
} | ||
|
||
return res.status(200).json({ | ||
message: 'Your Reading Statistic This week', | ||
statistic: `${statisticBox.count} article read this week`, | ||
}); | ||
} catch (err) { | ||
return serverError; | ||
} | ||
}; | ||
|
||
/** | ||
* @description Get monthly statistics of readers | ||
* @param {*} req | ||
* @param {*} res | ||
* @returns {object} and objevt containing the message and the number of books read by the user | ||
*/ | ||
const getMonthlyStatistic = async (req, res) => { | ||
try { | ||
const statisticBox = await Statistic.findAndCountAll({ | ||
where: { | ||
user_id: req.params.userid, | ||
createdAt: { | ||
[Op.gte]: moment() | ||
.subtract(30, 'days') | ||
.toDate(), | ||
}, | ||
}, | ||
attributes: ['article_id', 'createdAt'], | ||
}); | ||
|
||
if (statisticBox.count === 0) { | ||
return res.status(200).json({ | ||
message: 'You did not read any article this month.', | ||
}); | ||
} | ||
|
||
return res.status(200).json({ | ||
message: 'Your Reading Statistic This week', | ||
statistic: `${statisticBox.count} article read this month`, | ||
}); | ||
} catch (err) { | ||
return serverError; | ||
} | ||
}; | ||
|
||
const controller = { | ||
getDailyStatistic, | ||
getWeeklyStatistic, | ||
getMonthlyStatistic, | ||
}; | ||
|
||
export default controller; |
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,26 @@ | ||
import models from '../models'; | ||
import serverError from './server-error'; | ||
|
||
const { Statistic } = models; | ||
|
||
/** | ||
* | ||
* @param {*} userId | ||
* @param {*} articleId | ||
* @returns {*} userId, articleId in . | ||
*/ | ||
const saveUserStatistic = async (userId, articleId) => { | ||
try { | ||
const storedStatistic = await Statistic.create({ | ||
user_id: userId, | ||
article_id: articleId, | ||
}); | ||
return storedStatistic; | ||
} catch (err) { | ||
return serverError(); | ||
} | ||
}; | ||
|
||
const statistic = { saveUserStatistic }; | ||
|
||
export default statistic; |
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,12 @@ | ||
const checkIfUserIdIsCorrect = (req, res, next) => { | ||
if (req.params.userid !== req.user.userObj.id) { | ||
return res.status(401).json({ | ||
errors: { | ||
body: ["Sorry, you cannot access another user's reading statistic"], | ||
}, | ||
}); | ||
} | ||
return next(); | ||
}; | ||
|
||
export default { checkIfUserIdIsCorrect }; |
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,14 @@ | ||
import validations from '../helpers/validations'; | ||
|
||
const checkUUID = (req, res, next) => { | ||
if (!validations.verifyUUID(req.params.userid)) { | ||
return res.status(400).json({ | ||
errors: { | ||
body: ['userId is not valid'], | ||
}, | ||
}); | ||
} | ||
return next(); | ||
}; | ||
|
||
export default { checkUUID }; |
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
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,31 @@ | ||
import express from 'express'; | ||
import controllers from '../controllers/statistics.controller'; | ||
import middlewares from '../middlewares'; | ||
|
||
const { tokenValidator, uuidMiddleware, userIdMiddleware } = middlewares; | ||
|
||
const statisticRoute = express.Router(); | ||
|
||
statisticRoute.get( | ||
'/:userid/statistic/daily', | ||
tokenValidator.verifyToken, | ||
userIdMiddleware.checkIfUserIdIsCorrect, | ||
uuidMiddleware.checkUUID, | ||
controllers.getDailyStatistic | ||
); | ||
statisticRoute.get( | ||
'/:userid/statistic/week', | ||
tokenValidator.verifyToken, | ||
uuidMiddleware.checkUUID, | ||
userIdMiddleware.checkIfUserIdIsCorrect, | ||
controllers.getWeeklyStatistic | ||
); | ||
statisticRoute.get( | ||
'/:userid/statistic/month', | ||
tokenValidator.verifyToken, | ||
uuidMiddleware.checkUUID, | ||
userIdMiddleware.checkIfUserIdIsCorrect, | ||
controllers.getMonthlyStatistic | ||
); | ||
|
||
export default statisticRoute; |
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,15 @@ | ||
import chai, { expect } from 'chai'; | ||
import chaiHttp from 'chai-http'; | ||
import statistic from '../server/helpers/statistics-storer'; | ||
|
||
chai.use(chaiHttp); | ||
|
||
describe('Statistic storer function', () => { | ||
it('should accept a userId and aticleId and store it to the statistic table', async () => { | ||
const statisticStore = await statistic.saveUserStatistic( | ||
'2242e4ff-366d-46cc-9384-40eadb3b2644', | ||
'7139d3af-b8b4-44f6-a49f-9305791700f4' | ||
); | ||
expect(statisticStore).to.be.an('object'); | ||
}); | ||
}); |
Oops, something went wrong.