-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Daniel t impliment crud for rating #57
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
const Rating = require("../models/rating"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the file should be a typescript file. plus you can simply import the module without setting up exporting file. |
||
const { crudControllers } = require("../utils/ratingCRUD"); | ||
|
||
module.exports = crudControllers(Rating); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
const mongoose = require("mongoose"); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add interface definition for the model that extends from mongoose.Doucment, to state the definition of the schema, state the schema definitions and model definition based on this interface |
||
const ratingSchema = mongoose.Schema({ | ||
stars: { | ||
type: Number, | ||
required: true, | ||
min: [1, "rating too low"], | ||
max: [5, "rating too high"], | ||
}, | ||
article: { | ||
type: mongoose.Types.ObjectId, | ||
ref: "Article", | ||
required: true | ||
}, | ||
user: { | ||
type: mongoose.Types.ObjectId, | ||
ref: "User", | ||
required: true | ||
}, | ||
}); | ||
|
||
const Rating = mongoose.model("Rating", ratingSchema); | ||
|
||
module.exports = Rating; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const express = require('express') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use import statements to adhere to es6 importing module pattern |
||
const router = express.Router() | ||
const ratingController = require('../controllers/rating.controller') | ||
|
||
|
||
router.route('/').get(ratingController.getMany) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use articles route to handle rating, since they are dependent. |
||
router.route('/').post(ratingController.createOne) | ||
|
||
router.route('/:id').get(ratingController.getOne) | ||
router.route('/:id').put(ratingController.updateOne) | ||
router.route('/:id').delete(ratingController.removeOne) | ||
|
||
module.exports = router |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import supertest from 'supertest'; | ||
import {MongoMemoryServer} from "mongodb-memory-server"; | ||
import app from "../../app" | ||
const mongoose = require('mongoose'); | ||
|
||
// payloads For all the tests | ||
const ratingPayload = { | ||
"stars" : 5, | ||
"article": "62d510eaf474e57abb69067e", | ||
"user": "62d502a8fea5ce18b53f1240" | ||
} | ||
|
||
const wrongRatingPayload = { | ||
"stars" : 5, | ||
"article": "62d510eaf474e57abb69067e", | ||
} | ||
|
||
describe.only('Rating', ()=> { | ||
beforeAll(async () => { | ||
const mongoServer = await MongoMemoryServer.create(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use setup.db to open and close in memory server |
||
|
||
await mongoose.connect(mongoServer.getUri()); | ||
}); | ||
|
||
afterAll(async () => { | ||
await mongoose.disconnect(); | ||
await mongoose.connection.close(); | ||
}); | ||
describe('get Rating routes', ()=>{ | ||
describe('given the rating does not exist', () => { | ||
it('should return a 404.', async () => { | ||
const ratingId = new mongoose.Types.ObjectId('62d9bb72804a5a74621f838a'); | ||
await supertest(app).get(`/api/v1/rating/${ratingId}`).expect(404); | ||
}); | ||
}); | ||
|
||
describe('given the rating does exist', () => { | ||
it('should return a 200 and the rating info.', async () => { | ||
//First lets create a rating | ||
const {statusCode, body } = await supertest(app).post(`/api/v1/rating`).send(ratingPayload); | ||
expect(statusCode).toBe(201); | ||
|
||
const ratingId = body.data._id; | ||
await supertest(app).get(`/api/v1/rating/${ratingId}`).expect(200); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('create Rating routes', ()=>{ | ||
describe('given the rating body is passed correctly', () => { | ||
it('should return a 200 and create the rating.', async () => { | ||
const {statusCode, body } = await supertest(app).post(`/api/v1/rating`).send(ratingPayload); | ||
expect(statusCode).toBe(201); | ||
const data = body.data; | ||
|
||
expect(Object.keys(data).length).toEqual(5); | ||
// expect(data).toEqual(expect.objectContaining({ | ||
// __v: expect.any(Number), | ||
// _id: expect.any(String), | ||
// article: expect.any(String), | ||
// starts: expect.any(Number), | ||
// user: expect.any(String) | ||
// })) | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add more testing to the files, simulate what happens when a user rates again, test update rating and other files too. |
||
}); | ||
describe('given the rating request body is passed incorrectly', () => { | ||
it('should return a 400.', async () => { | ||
await supertest(app).post(`/api/v1/rating`).send(wrongRatingPayload).expect(400); | ||
}); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
const getOne = (model) => async (req, res) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. file should be ts file, plus we don't need other folders, such as utils we can use controllers folder to handle business logics, clone master branch and work on that. plus we don't need crud for rating since its dependent on article you can add your function their. |
||
try { | ||
const doc = await model.findOne({ _id: req.params.id }).lean().exec(); | ||
|
||
if (!doc) { | ||
return res.status(404).end(); | ||
} | ||
|
||
res.status(200).json({ data: doc }); | ||
} catch (e) { | ||
console.error(e); | ||
res.status(400).end(); | ||
} | ||
}; | ||
|
||
const getMany = (model) => async (req, res) => { | ||
try { | ||
const docs = await model.find().lean().exec(); | ||
|
||
res.status(200).json({ data: docs }); | ||
} catch (e) { | ||
console.error(e); | ||
res.status(400).end(); | ||
} | ||
}; | ||
|
||
const createOne = (model) => async (req, res) => { | ||
try { | ||
const doc = await model.create({ ...req.body }); | ||
res.status(201).json({ data: doc }); | ||
} catch (e) { | ||
console.error(e); | ||
res.status(400).end(); | ||
} | ||
}; | ||
|
||
const updateOne = (model) => async (req, res) => { | ||
try { | ||
const updatedDoc = await model | ||
.findOneAndUpdate( | ||
{ | ||
_id: req.params.id, | ||
}, | ||
req.body, | ||
{ new: true } | ||
) | ||
.lean() | ||
.exec(); | ||
|
||
if (!updatedDoc) { | ||
return res.status(404).end(); | ||
} | ||
|
||
res.status(200).json({ data: updatedDoc }); | ||
} catch (e) { | ||
console.error(e); | ||
res.status(400).end(); | ||
} | ||
}; | ||
|
||
const removeOne = (model) => async (req, res) => { | ||
try { | ||
const removed = await model.findOneAndRemove({ | ||
_id: req.params.id, | ||
}); | ||
|
||
if (!removed) { | ||
return res.status(404).end(); | ||
} | ||
|
||
return res.status(200).json({ data: removed }); | ||
} catch (e) { | ||
console.error(e); | ||
res.status(400).end(); | ||
} | ||
}; | ||
|
||
const crudControllers = (model) => ({ | ||
removeOne: removeOne(model), | ||
updateOne: updateOne(model), | ||
getMany: getMany(model), | ||
getOne: getOne(model), | ||
createOne: createOne(model), | ||
}); | ||
|
||
module.exports = { crudControllers }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove unused routes