From a64399aa4948a0d265aa9f8aad86befa93b6a600 Mon Sep 17 00:00:00 2001 From: RiyadHassen Date: Mon, 11 Jul 2022 12:10:10 +0300 Subject: [PATCH] updated backend repo --- starter-project-backend/src/app.ts | 5 - .../src/controllers/article.ts | 142 ------------- .../src/controllers/ratings.ts | 120 ----------- starter-project-backend/src/models/article.ts | 52 ----- starter-project-backend/src/models/ratings.ts | 31 --- starter-project-backend/src/routes/article.ts | 16 -- starter-project-backend/src/routes/index.ts | 7 - starter-project-backend/src/routes/ratings.ts | 17 -- .../tests/__tests__/ArticleController.test.ts | 195 ------------------ .../src/tests/__tests__/ratings.test.ts | 101 --------- 10 files changed, 686 deletions(-) delete mode 100644 starter-project-backend/src/controllers/article.ts delete mode 100644 starter-project-backend/src/controllers/ratings.ts delete mode 100644 starter-project-backend/src/models/article.ts delete mode 100644 starter-project-backend/src/models/ratings.ts delete mode 100644 starter-project-backend/src/routes/article.ts delete mode 100644 starter-project-backend/src/routes/index.ts delete mode 100644 starter-project-backend/src/routes/ratings.ts delete mode 100644 starter-project-backend/src/tests/__tests__/ArticleController.test.ts delete mode 100644 starter-project-backend/src/tests/__tests__/ratings.test.ts diff --git a/starter-project-backend/src/app.ts b/starter-project-backend/src/app.ts index c6366272..d9414571 100644 --- a/starter-project-backend/src/app.ts +++ b/starter-project-backend/src/app.ts @@ -1,6 +1,5 @@ import express, {Application, Request, Response, NextFunction, json} from 'express'; import dotenv from 'dotenv'; -import routes from './routes' dotenv.config(); @@ -10,9 +9,5 @@ app.use(express.urlencoded({ extended: true })); app.use(express.json()); app.use("/", json({})) -app.use("/api/rate", routes.ratingsRouter) - - -app.use("/api/articles", routes.articleRouter) export default app diff --git a/starter-project-backend/src/controllers/article.ts b/starter-project-backend/src/controllers/article.ts deleted file mode 100644 index cc57610a..00000000 --- a/starter-project-backend/src/controllers/article.ts +++ /dev/null @@ -1,142 +0,0 @@ -import {Response, Request, NextFunction} from "express" -import Article from "../models/article" - -async function getAllArticle(req:Request, res:Response, next:NextFunction) -{ - try{ - let articles = await Article.find({}) - res.status(200).json({data: articles}) - }catch(e) - { - res.status(500).send("server error") - } - -} - -async function getArticleById( req:Request,res:Response, next:NextFunction) { - - - try{ - - const article = await Article.findById(req.params.id) - - if(!article){ - res.status(404).json("article not found") - return; - } - - res.status(200).json({data: article}) - - }catch(e) { - res.status(500).send("data error") - } - - -} - -async function addArticle(req:Request, res:Response, next:NextFunction) -{ - //TODO: what if the same object exists already - let {author, title, content} = req.body - - if(!author || !title || !content) - { - // bad request - res.status(400).send("bad request") - return; - } - - if(!author.firstName || !author.lastName) - { - //bad request - res.status(400).send("bad request author") - return; - } - - if(!author.bio){author.bio = ""} - - let newArticle = new Article({author, title, content}) - - - try{ - await newArticle.save() - res.status(200).send("saved successfully ") - }catch(e) - { - res.status(500).send("data Base error") - } - - -} - - - -async function updateArticleById( req:Request, res:Response, next:NextFunction) -{ - - try{ - let article = await Article.findById(req.params.id) - - if(!article) - { - // article not found - res.status(404).send("article not found"); - return - } - - - let {author, title, content} = req.body - - if(author && - author.firstName && - author.lastName && - author.bio) - { - article.author = author - } - - else if(title) {article.title = title} - else if(content){article.content = content;} - else { - res.status(400).send("bad request") - return; - } - - - - await article.save() - res.status(200).send("article updated") - - }catch(e) - { - res.status(500).send("database error") - } - -} -async function deleteArticleById( req:Request, res:Response, next:NextFunction) -{ - - try { - const article = await Article.findById(req.params.id) - if(!article) - { - res.status(400).send("bad request") - return - } - - await Article.findByIdAndDelete(req.params.id) - res.status(200).send("article deleted") - - }catch(e) { - res.status(500).send("databse error") - } - -} - -export default{ - getAllArticle, - getArticleById, - addArticle, - updateArticleById, - deleteArticleById -} diff --git a/starter-project-backend/src/controllers/ratings.ts b/starter-project-backend/src/controllers/ratings.ts deleted file mode 100644 index b937408a..00000000 --- a/starter-project-backend/src/controllers/ratings.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { NextFunction, Request, Response } from 'express' -import Rating, { IRating } from '../models/ratings' - -export const createRating = async ( - req: Request, - res: Response, - _next: NextFunction - ) => { - const {articleId} = req.params - const {userId, value} = req.body // we can also get user id from jwt - const date: Date = new Date(); - const rating = new Rating({ - articleId, - userId, - value, - date - }) - try { - if (value < 0 || value > 6) { - throw new Error() - } - const ratingExists = await Rating.findOne({articleId, userId}) - if (ratingExists) { - return res.status(409).json({ - message: `User has already rated this article` - }) - } - const newRating = await rating.save() - res.status(201).json({data: newRating}) - } catch (e) { - res.status(400).end() - } -} - -export const updateRating =async ( - req: Request, - res: Response, - _next: NextFunction - ) => { - const {articleId} = req.params - const {userId, value} = req.body - - try { - if (userId == undefined) { - return res.status(400).end() - } - const rating = await Rating.findOne({articleId, userId}) - if (!rating) { - return res.status(404).json({ - message: `User has not rated this article before` - }) - } - if (value) { - rating.value = value - } - - await rating.save() - return res.status(201).json({data: rating}) - } catch (e) { - return res.status(400).end() - } -} - -export const deleteRating = async ( - req: Request, - res: Response, - _next: NextFunction - ) => { - const {articleId} = req.params - const {userId} = req.body - try { - const rating = await Rating.findOneAndDelete({articleId, userId}) - if (!rating) { - - return res.status(404).json({ - message: `Rating doesn't exist` - }) - } - return res.status(201).json({message: 'Rating deleted successfully'}) - } catch (e) { - return res.status(400).end() - } -} - -export const getRating = async ( - req: Request, - res: Response, - _next: NextFunction - ) => { - const {articleId} = req.params - - try { - const avgRating = await Rating.aggregate( - [ - { - "$match": {"articleId": articleId} - }, - { - "$group" : { - "_id": articleId, - "averageRating": { - "$avg" : "$value" - } - } - } - ] - ) - - if (avgRating.length == 0) { - return res.status(200).json( - { - "_id": articleId, - "averageRating": 0 - }) - } - return res.status(200).json(avgRating[0]) - } catch (e) { - return res.status(400).end() - } -} diff --git a/starter-project-backend/src/models/article.ts b/starter-project-backend/src/models/article.ts deleted file mode 100644 index a89fcdf7..00000000 --- a/starter-project-backend/src/models/article.ts +++ /dev/null @@ -1,52 +0,0 @@ - -//mongoose.Schema is used as a type and as a function -// there is nested schema discreption with author -// I don't understand the <> thing -// why are we extening to .Document - -import mongoose from 'mongoose' - -export interface Article_Interface extends mongoose.Document{ - - author:{ - firstName:String, - lastName:String, - bio:String - },//author object - - title:String, - content:String, - -} - -const ArticleSchema:mongoose.Schema = new mongoose.Schema({ - - author:{ - firstName:{ - type:String, - required: true - }, - lastName:{ - type:String, - required: true - }, - bio:{ - type:String, - required: true - }, - },//author object - - title:{ - type:String, - required: true - }, - - content:{ - type:String, - required: true - }, -}) -let Article = mongoose.model("ArticleColl", ArticleSchema) -export default Article; - - diff --git a/starter-project-backend/src/models/ratings.ts b/starter-project-backend/src/models/ratings.ts deleted file mode 100644 index f61521c5..00000000 --- a/starter-project-backend/src/models/ratings.ts +++ /dev/null @@ -1,31 +0,0 @@ -import mongoose, { Schema, Document } from 'mongoose' - -export interface IRating extends Document { - userId: String, - articleId: String, - value: Number, - date: Date, -} - -const ratingSchema: Schema = new mongoose.Schema( - { - userId: { - type: String, - required: true, - }, - articleId: { - type: String, - required: true, - }, - value: { - type: Number, - required: true, - }, - timestamps: { - date: "date" - } - } -) - -const Rating = mongoose.model('Rating', ratingSchema) -export default Rating \ No newline at end of file diff --git a/starter-project-backend/src/routes/article.ts b/starter-project-backend/src/routes/article.ts deleted file mode 100644 index d6b0c255..00000000 --- a/starter-project-backend/src/routes/article.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {Router} from "express" -let router = Router() - -import controller from "../controllers/article"; - - -router.get("/",controller.getAllArticle)//not Id to get all posts - -router.get("/:id", controller.getArticleById) -router.delete("/:id", controller.deleteArticleById) -router.patch("/:id", controller.updateArticleById) - -router.post("/", controller.addArticle); - - -export default router; diff --git a/starter-project-backend/src/routes/index.ts b/starter-project-backend/src/routes/index.ts deleted file mode 100644 index a45b8199..00000000 --- a/starter-project-backend/src/routes/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import ratingsRouter from "./ratings" -import articleRouter from './article' - -export default { - articleRouter - ratingsRouter -} diff --git a/starter-project-backend/src/routes/ratings.ts b/starter-project-backend/src/routes/ratings.ts deleted file mode 100644 index d86078e2..00000000 --- a/starter-project-backend/src/routes/ratings.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {Router} from "express" -import { - createRating, - getRating, - updateRating, - deleteRating -} from "../controllers/ratings" - - -const router = Router({mergeParams: true}) - -router.get("/:articleId/ratings/", getRating) -router.patch("/:articleId/ratings/", updateRating) -router.delete("/:articleId/ratings/", deleteRating) -router.post("/:articleId/ratings/", createRating) - -export default router \ No newline at end of file diff --git a/starter-project-backend/src/tests/__tests__/ArticleController.test.ts b/starter-project-backend/src/tests/__tests__/ArticleController.test.ts deleted file mode 100644 index d9087010..00000000 --- a/starter-project-backend/src/tests/__tests__/ArticleController.test.ts +++ /dev/null @@ -1,195 +0,0 @@ -import app from "../../app" -import request from "supertest" -import * as dbHandler from "../setupdb"; - -const agent = request.agent(app) - -let sampleArticle = { - author:{ - firstName: "gzachew", - lastName: "demeke", - bio: "I'm blah blah" - }, - - title: "how I got to do jobs using mars", - content: "blah blah blah mars blah blah" -} - -let wrongArticle = { - author:{ - wrong_firstName: "gzachew", - wrong_lastName: "demeke", - wrong_bio: "I'm blah blah" - }, - - title: "how I got to do jobs using mars", - content: "blah blah blah mars blah blah" -} - -let wrongAuthor= { - author:{ - firstName: "gzachew", - lastName: "demeke", - bio: "I'm blah blah" - }, - - wrong_title: "how I got to do jobs using mars", - worng_content: "blah blah blah mars blah blah" -} - - - -beforeAll(async () => { - await dbHandler.connect() -}) - -afterEach(async () => { - await dbHandler.clear() -}) - -afterAll(async () => { - await dbHandler.disconnect() -}) - - -describe("POST Article ",()=>{ - - test("POST article",async()=>{ - const res = await agent.post("/api/articles").send(sampleArticle) - expect(res.status).toEqual(200) - }); - - test("POST article bad request wrong aticle shape",async()=>{ - const res = await agent.post("/api/articles").send(wrongArticle) - expect(res.status).toEqual(400) - }); - - test("POST article bad request wrong author shape",async()=>{ - const res = await agent.post("/api/articles").send(wrongArticle) - expect(res.status).toEqual(400) - }); - - -}); - -describe("GET all Article ",()=>{ - - test("GET all articles",async()=>{ - - await agent.post("/api/articles").send(sampleArticle) - const res = await agent.get("/api/articles") - expect(res.status).toEqual(200) - - }); - -}) - -describe("GET Article By ID",()=>{ - - test("should return 200 status",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - const sampleRes = await agent.get("/api/articles") - let sampleId = sampleRes.body.data[0]._id - const res = await agent.get("/api/articles/"+sampleId) - expect(res.status).toEqual(200) - - }); - - - test("should return 404 status",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - let wrongId = "825d207b5bc4207cc0d80844"; - - const res = await agent.get("/api/articles/"+wrongId) - expect(res.status).toEqual(404) - - }); - - test("should return 500 status for invalied id",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - let invaliedId= "kdjfkdj"; - - const res = await agent.get("/api/articles/" + invaliedId) - expect(res.status).toEqual(500) - - }); - -}); - -describe("PATCH Article API",()=>{ - - test("it should be 200",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - await agent.post("/api/articles").send(sampleArticle) - const sampleRes = await agent.get("/api/articles") - let sampleId = sampleRes.body.data[0]._id - const res = await agent.patch("/api/articles/"+sampleId).send({title:"another"}) - expect(res.status).toEqual(200) - }); - - test("it should be 404 for bad requested id",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - - let wrongId = "825d207b5bc4207cc0d80844"; - const res = await agent.patch("/api/articles/"+wrongId).send({title:"another"}) - expect(res.status).toEqual(404) - }); - - test("it should be 500 for invalied id",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - - let invaliedId = "jjkljdfsdfd"; - const res = await agent.patch("/api/articles/"+invaliedId).send({title:"another"}) - expect(res.status).toEqual(500) - }); - - test("it should be 400 if the body json is wrong",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - await agent.post("/api/articles").send(sampleArticle) - const sampleRes = await agent.get("/api/articles") - let sampleId = sampleRes.body.data[0]._id - const res = await agent.patch("/api/articles/"+sampleId).send({node:"another"}) - expect(res.status).toEqual(400) - }); - - -}); - -describe("DELET Article API",()=>{ - - test("it should be 200",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - await agent.post("/api/articles").send(sampleArticle) - const sampleRes = await agent.get("/api/articles") - let sampleId = sampleRes.body.data[0]._id - const res = await agent.delete("/api/articles/"+sampleId); - expect(res.status).toEqual(200) - }); - - test("it should be 400 for bad request",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - let wrongId = "825d207b5bc4207cc0d80844"; - const res = await agent.delete("/api/articles/"+wrongId); - expect(res.status).toEqual(400) - }); - - test("it should be 500 for invalied Id",async()=>{ - await agent.post("/api/articles").send(sampleArticle) - - let invaliedId = "lksjfklsd" - const res = await agent.delete("/api/articles/" + invaliedId); - expect(res.status).toEqual(500) - }); - -}); - - diff --git a/starter-project-backend/src/tests/__tests__/ratings.test.ts b/starter-project-backend/src/tests/__tests__/ratings.test.ts deleted file mode 100644 index 2905cead..00000000 --- a/starter-project-backend/src/tests/__tests__/ratings.test.ts +++ /dev/null @@ -1,101 +0,0 @@ -import * as dbHandler from '../setupdb' -import request from 'supertest' -import app from "../../app" - -beforeAll(async () => { - await dbHandler.connect() -}) - -afterEach(async () => { - await dbHandler.clear() -}) - -afterAll(async () => { - await dbHandler.disconnect() -}) - -describe('GET /api/rate/{id}/ratings', () => { - it('should return status code 200', async () => { - const res = await request(app) - .get("/api/rate/1/ratings") - .send() - expect(res.statusCode).toEqual(200) - }) -}) - -describe('POST /api/rate/{id}/ratings', () => { - it('should return status code 201',async () => { - const userId = "1" - const value = 3 - const res = await request(app) - .post("/api/rate/1/ratings") - .send({userId, value}) - expect(res.statusCode).toEqual(201) - }) - - it('should return status code 409 if user has already rated this article',async () => { - const userId = "1" - const value = 3 - const res = await request(app) - .post("/api/rate/1/ratings") - .send({userId, value}) - expect(res.statusCode).toEqual(201) - }) - - it('should return status code 400 if userId or value is missing', async () => { - const res = await request(app) - .post("/api/rate/2/ratings") - .send() - expect(res.statusCode).toEqual(400) - }) -}) - -describe('Update /api/rate/{id}/ratings', () => { - it('should return status code 201', async () => { - const userId = "1" - const value = 3 - await request(app) - .post("/api/rate/1/ratings") - .send({userId, "value": value + 1}) - const res = await request(app) - .patch("/api/rate/1/ratings") - .send({userId, value}) - - expect(res.statusCode).toEqual(201) - }) - - it('should return status code 400 if userId is missing', async () => { - const userId = "1" - const value = 3 - await request(app) - .post("/api/rate/1/ratings") - .send({userId, "value": value}) - const res = await request(app) - .patch("/api/rate/1/ratings") - .send() - expect(res.statusCode).toEqual(400) - }) - - it(`should return status code 404 if rating doesn't exist`,async () => { - const userId = "1" - const value = 3 - const res = await request(app) - .patch("/api/rate/1/ratings") - .send({userId, value}) - expect(res.statusCode).toEqual(404) - }) -}) - -describe('Delete /api/rate/{id}/ratings', () => { - it('should return status code 201', async () => { - const userId = "1" - const value = 3 - await request(app) - .post("/api/rate/1/ratings") - .send({userId, value}) - const res = await request(app) - .delete("/api/rate/1/ratings") - .send({userId}) - expect(res.statusCode).toEqual(201) - }) -}) \ No newline at end of file