From b79692bbf152123968d49ffe9603a2a29978a1a8 Mon Sep 17 00:00:00 2001 From: Divyateja Pasupuleti Date: Fri, 19 Apr 2024 22:21:38 +0530 Subject: [PATCH 1/5] feat: prisma db push --- backend/prisma/schema.prisma | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index e8693c00..77b1a9a8 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -26,8 +26,6 @@ model Post { authorId String @db.ObjectId // Request details requests Request[] - // Report details - reports Report[] } // User stores n number of posts and requests @@ -70,9 +68,8 @@ model Report { reason String status String @default("open") // Reporter details - reporter User @relation(fields: [reporterEmail], references: [email]) reporterEmail String - // Post details - post Post @relation(fields: [postId], references: [id]) - postId String @db.ObjectId + // User details + userReported User @relation(fields: [userReportedEmail], references: [email]) + userReportedEmail String } \ No newline at end of file From cc70fe7d7b5817005208c9285da91018e24d94c8 Mon Sep 17 00:00:00 2001 From: Just-a-Pirate Date: Tue, 23 Apr 2024 19:18:35 +0530 Subject: [PATCH 2/5] feat: add deltaKarma api --- backend/src/routes/admin.route.ts | 26 ++++++++++- backend/src/service/admin.service.ts | 68 ++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/backend/src/routes/admin.route.ts b/backend/src/routes/admin.route.ts index 81b40774..b4d60bab 100644 --- a/backend/src/routes/admin.route.ts +++ b/backend/src/routes/admin.route.ts @@ -1,7 +1,7 @@ import { Router } from "express"; import { HttpCodes } from "../types/HttpCodes"; import { CustomResponse } from "../types/CustomResponse"; -import { getAllUsers, promoteUser, demoteUser, banUser } from "../service/admin.service"; +import { getAllUsers, promoteUser, demoteUser, banUser, deltaKarma} from "../service/admin.service"; import prisma from '../db' import { getAllPosts } from "../service/posts.service"; export const adminRouter = Router(); @@ -158,6 +158,30 @@ adminRouter.put("/ban/:user", async (req, res) => { data: ban } + return res.status(HttpCodes.OK).json(response); + } +}) + +adminRouter.put("/deltaKarma/:user", async (req, res) => { + const userEmailId = req.params.user; + const amount= req.body.amount as number; + const sign= req.body.sign as boolean; + const fruit = await deltaKarma(userEmailId,amount,sign); + + if (fruit.error) { + const response: CustomResponse = { + error: true, + message: fruit.data as string, + data: null + } + return res.status(HttpCodes.INTERNAL_SERVER_ERROR).json(response); + } else { + const response: CustomResponse = { + error: false, + message: "Selected user's karma has been updated", + data: fruit + } + return res.status(HttpCodes.OK).json(response); } }) \ No newline at end of file diff --git a/backend/src/service/admin.service.ts b/backend/src/service/admin.service.ts index b4077455..6aa2f16f 100644 --- a/backend/src/service/admin.service.ts +++ b/backend/src/service/admin.service.ts @@ -121,4 +121,72 @@ export const banUser = async (userEmailId: string): Promise> data: "Some error occurred while banning user." } } +} + +export const deltaKarma =async (userEmailId: string, amount:number, sign:boolean): +Promise> => { + try { + let user = await prisma.user.findUnique({ + where: { + email: userEmailId + } + }); + + if (!user) return { + error: true, + data: "User does not exist." + } + + if (user.role == "admin") { + return { + error: true, + data: "An admin cannot be fruit :)." + } + } + + if (sign==false) { + if(user.karmaPoints Date: Wed, 24 Apr 2024 00:04:09 +0530 Subject: [PATCH 3/5] fix: tests with backend --- backend/src/routes/gauth.route.ts | 2 +- backend/src/service/posts.service.ts | 4 +-- backend/tests/admin.test.ts | 42 ++++++++++++++-------------- backend/tests/posts.test.ts | 27 +++++++++++++++++- backend/tests/user.test.ts | 6 ++-- 5 files changed, 53 insertions(+), 28 deletions(-) diff --git a/backend/src/routes/gauth.route.ts b/backend/src/routes/gauth.route.ts index 8bc2048c..9772b0c2 100644 --- a/backend/src/routes/gauth.route.ts +++ b/backend/src/routes/gauth.route.ts @@ -22,7 +22,7 @@ gauthRouter.get("/", async (req, res) => { if (appUser.data) { if (typeof appUser.data !== 'string' && appUser.data.role === "admin") { logger.info("Admin login"); - res.redirect(FRONTEND_URL + '/admin/home'); + res.redirect(FRONTEND_URL + '/admin/'); return; } } else { diff --git a/backend/src/service/posts.service.ts b/backend/src/service/posts.service.ts index 39bb3a5f..95ac268e 100644 --- a/backend/src/service/posts.service.ts +++ b/backend/src/service/posts.service.ts @@ -317,7 +317,7 @@ export const completePost = async (postId: string, authorEmail: string): Promise error: true, data: "Post has already been completed." }; - + else if (post.status == "open") return { error: true, data: "Post has not been closed yet." @@ -336,7 +336,7 @@ export const completePost = async (postId: string, authorEmail: string): Promise data: "Some error occurred while finding accepted requests." } - if (post.costInPoints>user.karmaPoints) return { + if (post.costInPoints > user.karmaPoints) return { error: true, data: "Not enough karma to complete this post." } diff --git a/backend/tests/admin.test.ts b/backend/tests/admin.test.ts index d311c8ab..78cc3a79 100644 --- a/backend/tests/admin.test.ts +++ b/backend/tests/admin.test.ts @@ -13,7 +13,7 @@ const user: User = { isPublic: true } -const a: User = { +const admin: User = { id: "2", name: "ben", email: "ben@hen.com", @@ -23,7 +23,7 @@ const a: User = { isPublic: true } -const na: User = { +const notadmin: User = { id: "2", name: "ben", email: "ben@hen.com", @@ -33,7 +33,7 @@ const na: User = { isPublic: true } -const bu: User= { +const bu: User = { id: "2", name: "ben", email: "ben@hen.com", @@ -65,20 +65,20 @@ describe("Get all users", () => { describe("promote user to admin", () => { it("should promote user to admin role", () => { - prismaMock.user.findUnique.mockResolvedValue(na); - prismaMock.user.update.mockResolvedValue(a); + prismaMock.user.findUnique.mockResolvedValue(notadmin); + prismaMock.user.update.mockResolvedValue(admin); - expect(promoteUser(na.email)).resolves.toEqual({ + expect(promoteUser(notadmin.email)).resolves.toEqual({ error: false, - data: a + data: admin }) }) it("should return error if any error occured", () => { - prismaMock.user.findUnique.mockResolvedValue(na); + prismaMock.user.findUnique.mockResolvedValue(notadmin); prismaMock.user.update.mockRejectedValue(new Error("Some error occurred")); - expect(promoteUser(na.email)).resolves.toEqual({ + expect(promoteUser(notadmin.email)).resolves.toEqual({ error: true, data: "Some error occurred while promoting user to admin role" }) @@ -87,20 +87,20 @@ describe("promote user to admin", () => { describe("demote admin to user", () => { it("should demote admin to user", () => { - prismaMock.user.findUnique.mockResolvedValue(a); - prismaMock.user.update.mockResolvedValue(na); + prismaMock.user.findUnique.mockResolvedValue(admin); + prismaMock.user.update.mockResolvedValue(notadmin); - expect(demoteUser(a.email)).resolves.toEqual({ + expect(demoteUser(user.email, admin.email)).resolves.toEqual({ error: false, - data: na + data: notadmin }) }) it("should return error if any error occured", () => { - prismaMock.user.findUnique.mockResolvedValue(a); + prismaMock.user.findUnique.mockResolvedValue(admin); prismaMock.user.update.mockRejectedValue(new Error("Some error occurred")); - expect(demoteUser(a.email)).resolves.toEqual({ + expect(demoteUser(user.email, admin.email)).resolves.toEqual({ error: true, data: "Some error occurred while demoting admin to user role" }) @@ -109,10 +109,10 @@ describe("demote admin to user", () => { describe("ban user", () => { it("should ban user", () => { - prismaMock.user.findUnique.mockResolvedValue(na); + prismaMock.user.findUnique.mockResolvedValue(notadmin); prismaMock.user.update.mockResolvedValue(bu); - expect(banUser(na.email)).resolves.toEqual({ + expect(banUser(notadmin.email)).resolves.toEqual({ error: false, data: bu }) @@ -127,20 +127,20 @@ describe("ban user", () => { }) it("should return error if user to be banned is an admin", () => { - prismaMock.user.findUnique.mockResolvedValue(a); + prismaMock.user.findUnique.mockResolvedValue(admin); prismaMock.user.update.mockResolvedValue(bu); - expect(banUser(a.email)).resolves.toEqual({ + expect(banUser(admin.email)).resolves.toEqual({ error: true, data: "An admin cannot be banned." }) }) it("should return error if any error occured", () => { - prismaMock.user.findUnique.mockResolvedValue(na); + prismaMock.user.findUnique.mockResolvedValue(notadmin); prismaMock.user.update.mockRejectedValue(new Error("Some error occurred")); - expect(banUser(na.email)).resolves.toEqual({ + expect(banUser(notadmin.email)).resolves.toEqual({ error: true, data: "Some error occurred while banning user." }) diff --git a/backend/tests/posts.test.ts b/backend/tests/posts.test.ts index c8b6882d..a911f60e 100644 --- a/backend/tests/posts.test.ts +++ b/backend/tests/posts.test.ts @@ -1,6 +1,6 @@ import { describe, expect } from "@jest/globals"; import { prismaMock } from "./_mockdb"; -import { createPost, getAllPosts, getMyPosts, getPostDetails, editPost, deletePost} from "../src/service/posts.service"; +import { createPost, getAllPosts, getMyPosts, getPostDetails, editPost, deletePost, completePost } from "../src/service/posts.service"; import { Post, User, Request } from ".prisma/client"; const userWith10KarmaPoints: User = { @@ -46,6 +46,19 @@ const post: Post & { status: "open", } +// const completedPost: Post & { +// authorEmail: string +// } = { +// id: "1", +// authorId: "1", +// authorEmail: "ben@ben.com", +// source: "source", +// destination: "destination", +// costInPoints: 10, +// service: "service", +// status: "completed", +// } + const request: Request = { id: "1", postId: "1", @@ -288,6 +301,18 @@ describe("Update post", () => { }); }) +describe("Complete post", () => { + it("should throw error if post already completed", () => { + prismaMock.user.findUnique.mockResolvedValue(userWith0KarmaPoints); + prismaMock.post.findUnique.mockRejectedValue(new Error("some error occurred")); + + expect(completePost(post.id, userWith0KarmaPoints.email)).resolves.toEqual({ + error: true, + data: "Some error occurred while completing the post" + }); + }); +}) + describe("Delete post", () => { it("should throw an error if user does not exist", () => { prismaMock.post.findUnique.mockResolvedValue(post); diff --git a/backend/tests/user.test.ts b/backend/tests/user.test.ts index 59cb065a..9bd3c798 100644 --- a/backend/tests/user.test.ts +++ b/backend/tests/user.test.ts @@ -250,7 +250,7 @@ describe("Fetch user data using id", () => { prismaMock.user.findUnique.mockResolvedValue(user); - expect(getUserById(user.id)).resolves.toEqual({ + expect(getUserById(user.id, user.email)).resolves.toEqual({ error: false, data: user }); @@ -269,7 +269,7 @@ describe("Fetch user data using id", () => { prismaMock.user.findUnique.mockResolvedValue(user); - expect(getUserById(user.id)).resolves.toEqual({ + expect(getUserById(user.id, user.email)).resolves.toEqual({ error: true, data: "User is not public." }); @@ -287,7 +287,7 @@ describe("Fetch user data using id", () => { prismaMock.user.findUnique.mockRejectedValue(new Error("Some error")); - expect(getUserById(user.id)).resolves.toEqual({ + expect(getUserById(user.id, user.email)).resolves.toEqual({ error: true, data: null }); From 709a4d2a4e440607aa3c33ea8f84286d0425aa72 Mon Sep 17 00:00:00 2001 From: Divyateja Pasupuleti Date: Wed, 24 Apr 2024 00:04:32 +0530 Subject: [PATCH 4/5] feat: change chip colors --- frontend/app/admin/{home => }/page.tsx | 4 ++-- frontend/app/tabs/MyPosts.tsx | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) rename frontend/app/admin/{home => }/page.tsx (99%) diff --git a/frontend/app/admin/home/page.tsx b/frontend/app/admin/page.tsx similarity index 99% rename from frontend/app/admin/home/page.tsx rename to frontend/app/admin/page.tsx index aa6aba9a..0f044c9d 100644 --- a/frontend/app/admin/home/page.tsx +++ b/frontend/app/admin/page.tsx @@ -87,7 +87,7 @@ const AdminHomepage = () => { await axios.put(siteConfig.server_url + `/admin/promote/${usermail}`); setMessage("User promoted to admin role") // Refresh users list after promoting - const response = await axios.get(siteConfig.server_url + '/admin/home'); + const response = await axios.get(siteConfig.server_url + '/admin/'); if (response.status == HttpCodes.UNAUTHORIZED) { window.location.href = "/"; return; @@ -98,7 +98,7 @@ const AdminHomepage = () => { await axios.put(siteConfig.server_url + `/admin/demote/${usermail}`); setMessage("User demoted to default role") // Refresh users list after promoting - const response = await axios.get(siteConfig.server_url + '/admin/home'); + const response = await axios.get(siteConfig.server_url + '/admin/'); if (response.status == HttpCodes.UNAUTHORIZED) { window.location.href = "/"; return; diff --git a/frontend/app/tabs/MyPosts.tsx b/frontend/app/tabs/MyPosts.tsx index 22f0d77f..a246b66c 100644 --- a/frontend/app/tabs/MyPosts.tsx +++ b/frontend/app/tabs/MyPosts.tsx @@ -69,7 +69,9 @@ export default function MyPosts() { {post.source} to {post.destination} {post.service} - {post.status.toUpperCase()} + {post.status.toUpperCase()} {post.costInPoints} From 9f859c45f921dd7cccd0eabc13558c4e10aafbd3 Mon Sep 17 00:00:00 2001 From: Just-a-Pirate Date: Wed, 24 Apr 2024 00:34:18 +0530 Subject: [PATCH 5/5] fix: tests --- backend/src/service/admin.service.ts | 6 +- backend/src/service/plot.service.ts | 0 backend/tests/admin.test.ts | 84 +++++++++++++++++++++++++++- backend/tests/user.test.ts | 8 ++- 4 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 backend/src/service/plot.service.ts diff --git a/backend/src/service/admin.service.ts b/backend/src/service/admin.service.ts index 6aa2f16f..6769b4c0 100644 --- a/backend/src/service/admin.service.ts +++ b/backend/src/service/admin.service.ts @@ -123,6 +123,8 @@ export const banUser = async (userEmailId: string): Promise> } } +//changes Karma of a user +//use sign=false to decrease sign=true to increase export const deltaKarma =async (userEmailId: string, amount:number, sign:boolean): Promise> => { try { @@ -140,7 +142,7 @@ Promise> => { if (user.role == "admin") { return { error: true, - data: "An admin cannot be fruit :)." + data: "Admin karma cannot be updated." } } @@ -148,7 +150,7 @@ Promise> => { if(user.karmaPoints { it("should get all users", () => { prismaMock.user.findMany.mockResolvedValue([user]); @@ -90,7 +110,7 @@ describe("demote admin to user", () => { prismaMock.user.findUnique.mockResolvedValue(a); prismaMock.user.update.mockResolvedValue(na); - expect(demoteUser(a.email)).resolves.toEqual({ + expect(demoteUser(a.email,na2.email)).resolves.toEqual({ error: false, data: na }) @@ -100,7 +120,7 @@ describe("demote admin to user", () => { prismaMock.user.findUnique.mockResolvedValue(a); prismaMock.user.update.mockRejectedValue(new Error("Some error occurred")); - expect(demoteUser(a.email)).resolves.toEqual({ + expect(demoteUser(a.email,na2.email)).resolves.toEqual({ error: true, data: "Some error occurred while demoting admin to user role" }) @@ -145,4 +165,62 @@ describe("ban user", () => { data: "Some error occurred while banning user." }) }) +}) + +describe("increase/decrease user karma", () => { + it("should increase karma", () => { + prismaMock.user.findUnique.mockResolvedValue(na); + prismaMock.user.update.mockResolvedValue(iku); + + expect(deltaKarma(na.email,12,true)).resolves.toEqual({ + error: false, + data: iku + }) + }) + + it("should decrease karma", () => { + prismaMock.user.findUnique.mockResolvedValue(iku); + prismaMock.user.update.mockResolvedValue(na); + + expect(deltaKarma(iku.email,12,false)).resolves.toEqual({ + error: false, + data: na + }) + }) + + it("should return error if target karma is negative", () => { + prismaMock.user.findUnique.mockResolvedValue(na); + + expect(deltaKarma(na.email,12,false)).resolves.toEqual({ + error: true, + data: "Stop, Stop! he is already dead." + }) + }) + + it("should return an error if user does not exist", () => { + + expect(banUser("random@random.com")).resolves.toEqual({ + error: true, + data: "User does not exist." + }) + }) + + it("should return error if user to be updated is an admin", () => { + prismaMock.user.findUnique.mockResolvedValue(a); + + expect(deltaKarma(a.email,12,true)).resolves.toEqual({ + error: true, + data: "Admin karma cannot be updated." + }) + }) + + it("should return error if any error occured", () => { + prismaMock.user.findUnique.mockResolvedValue(na); + prismaMock.user.update.mockRejectedValue(new Error("Some error occurred")); + + expect(deltaKarma(na.email,12,true)).resolves.toEqual({ + error: true, + data: "Some error occurred while changing karma." + }) + }) }) \ No newline at end of file diff --git a/backend/tests/user.test.ts b/backend/tests/user.test.ts index 59cb065a..6167674a 100644 --- a/backend/tests/user.test.ts +++ b/backend/tests/user.test.ts @@ -3,6 +3,8 @@ import { prismaMock } from "./_mockdb"; import { getUserByEmail, newUser, getUserById } from "../src/service/user.service"; import { updateUser } from "../src/service/user.service"; + + describe("Create a new user", () => { it("should create a new user", () => { const user = { @@ -250,7 +252,7 @@ describe("Fetch user data using id", () => { prismaMock.user.findUnique.mockResolvedValue(user); - expect(getUserById(user.id)).resolves.toEqual({ + expect(getUserById(user.id,user.id)).resolves.toEqual({ error: false, data: user }); @@ -269,7 +271,7 @@ describe("Fetch user data using id", () => { prismaMock.user.findUnique.mockResolvedValue(user); - expect(getUserById(user.id)).resolves.toEqual({ + expect(getUserById(user.id,user.id)).resolves.toEqual({ error: true, data: "User is not public." }); @@ -287,7 +289,7 @@ describe("Fetch user data using id", () => { prismaMock.user.findUnique.mockRejectedValue(new Error("Some error")); - expect(getUserById(user.id)).resolves.toEqual({ + expect(getUserById(user.id,user.id)).resolves.toEqual({ error: true, data: null });