Skip to content

Commit

Permalink
Merge pull request #24 from Divyateja04/reports
Browse files Browse the repository at this point in the history
report functionality
  • Loading branch information
thenicekat authored Apr 24, 2024
2 parents 25001d1 + 1ba7823 commit 32711e4
Show file tree
Hide file tree
Showing 12 changed files with 575 additions and 7 deletions.
3 changes: 2 additions & 1 deletion backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { userRouter } from './routes/user.route'
import { validateMiddleware } from './middleware/auth.middleware';
import { requestsRouter } from './routes/requests.route';
import { adminRouter } from './routes/admin.route';

import { reportsRouter } from './routes/report.route';
const app: Express = express()

// Add Config
Expand Down Expand Up @@ -78,6 +78,7 @@ app.use('/post', postsRouter)
app.use('/request', requestsRouter)
app.use('/user', userRouter)
app.use('/admin', adminRouter);
app.use('/report', reportsRouter)


// Start the server
Expand Down
2 changes: 2 additions & 0 deletions backend/src/routes/admin.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import prisma from '../db'
import { getAllPosts } from "../service/posts.service";
export const adminRouter = Router();



adminRouter.get("/allusers", async (req, res) => {
let currUserEmail = req.session.email;
let currUser;
Expand Down
76 changes: 76 additions & 0 deletions backend/src/routes/report.route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Router } from "express";
import { HttpCodes } from "../types/HttpCodes";
import { CustomResponse } from "../types/CustomResponse";
import { createReport, getAllReports, closeReport } from "../service/report.service";

export const reportsRouter = Router();

reportsRouter.get('/allreports', async(_, res) => {
const allReports = await getAllReports();
if (allReports.error) {
const response: CustomResponse = {
error: true,
message: "Error retrieving reports",
data: null
}
return res.status(HttpCodes.INTERNAL_SERVER_ERROR).json(response);
}

const response: CustomResponse = {
error: false,
message: "All reports retrieved successfully",
data: allReports.data
}
return res.status(HttpCodes.OK).json(response);
})

reportsRouter.post('/create', async(req, res) => {
const reason = req.body.reason as string;
const emailId = req.session.email as string;
const postId = req.body.postId as string;


const creRep = await createReport(
reason,
emailId,
postId
);

if (creRep.error) {
const response: CustomResponse = {
error: true,
message: creRep.data as string,
data: null
}
return res.status(HttpCodes.INTERNAL_SERVER_ERROR).json(response);
}

const response: CustomResponse = {
error: false,
message: "Report created successfully",
data: creRep.data
}
return res.status(HttpCodes.CREATED).json(response);

})

reportsRouter.post("/close", async (req, res) => {
const reportId = req.body.reportId as string;
const closeRep = await closeReport(reportId);
if (closeRep.error) {
const response: CustomResponse = {
error: true,
message: closeRep.data as string,
data: null
};
return res.status(HttpCodes.INTERNAL_SERVER_ERROR).json(response);
}

const response: CustomResponse = {
error: false,
message: "Report closed successfully",
data: closeRep.data
};
return res.status(HttpCodes.OK).json(response);
});

8 changes: 6 additions & 2 deletions backend/src/routes/requests.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ requestsRouter.put("/complete/:requestId", async (req, res) => {
const requestId = req.params.requestId as string;

const completeReq = await completeRequest(requestId);

console.log(completeReq.data);
if (completeReq.error) {
const response: CustomResponse = {
error: true,
Expand All @@ -92,4 +92,8 @@ requestsRouter.put("/complete/:requestId", async (req, res) => {
}
return res.status(HttpCodes.OK).json(response);
}
})
})

// requestsRouter.post('/create/report', async(req, res) => {

// })
115 changes: 115 additions & 0 deletions backend/src/service/report.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { Report, Post } from '@prisma/client'
import { CustomReturn } from '../types/CustomReturn'
import prisma from '../db'
import { logger } from '../utils/logger'

export const getAllReports = async (): Promise<CustomReturn<Report[]>> => {
try {
let allReports: Report[] = await prisma.report.findMany()
return {
error: false,
data: allReports
}
}
catch (error) {
return {
error: true,
data: "Some error occurred while fetching the reports."
}
}
}

export const createReport = async (reason: string, emailId: string, postId: string): Promise<CustomReturn<Report>> => {
if (!emailId) return {
error: true,
data: "Author email is required."
}

let checkPostExistence: Post | null = await prisma.post.findFirst({
where: {
id: postId,
}
})
if (!checkPostExistence) {
return {
error: true,
data: "Post does not exist."
}
}else {
if(checkPostExistence.status==="completed"){
return {
error: true,
data: "A Report cannot be made against a completed post."
}
}
}

if(!reason) return {
error: true,
data: "Reason is required."
}

let checkReportExistence: Report | null = await prisma.report.findFirst({
where: {
postId: postId
}
})

if(checkReportExistence) {
return {
error: true,
data: "A report already exists on this post."
}
}
try {
let createReport = await prisma.report.create({
data: {
reason: reason,
reporter: {
connect: {
email: emailId
}
},
post: {
connect: {
id: postId
}
},
},
})

return {
error: false,
data: createReport
};
} catch (err: any) {
logger.error(JSON.stringify({
location: "createReport",
message: err.toString()
}));
return {
error: true,
data: "Some error occurred while creating the report."
}
}
};

export const closeReport = async (reportId: string): Promise<CustomReturn<Report>> => {
try {

const updatedReport = await prisma.report.update({
where: { id: reportId },
data: { status: "closed" } // Assuming status field exists in the Report model
});

return {
error: false,
data: updatedReport
};
} catch (error) {
return {
error: true,
data: "Some error occurred while closing the report"
};
}
};
133 changes: 133 additions & 0 deletions backend/tests/report.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { describe, expect } from "@jest/globals";
import { prismaMock } from "./_mockdb";
import { getAllReports,createReport,closeReport } from "../src/service/report.service";
import {Post , Report} from ".prisma/client"

const validPost: Post = {
id: "1",
authorId: "1",
source: "source",
destination: "destination",
costInPoints: 10,
service: "service",
status: "open",
}

const completedPost: Post = {
id: "1",
authorId: "1",
source: "source",
destination: "destination",
costInPoints: 10,
service: "service",
status: "completed",
}

const report: Report = {
id: "1",
reason: "reason",
status: "open",
reporterEmail: "[email protected]",
postId: "1"
}


describe("Create a new report", () => {
it("should create a new report", () => {

prismaMock.post.findUnique.mockResolvedValue(validPost);
prismaMock.report.create.mockResolvedValue(report);

expect(createReport("random","[email protected]",validPost.id)).resolves.toEqual({
error: false,
data: report
});
});

it("should return an error if reason is not given", () => {
prismaMock.post.findUnique.mockResolvedValue(validPost);
prismaMock.report.create.mockResolvedValue(report);
expect(createReport("","[email protected]",validPost.id)).resolves.toEqual({
error: true,
data: "Reason is required."
});
})

it("should return an error if mail is not given", () => {

prismaMock.post.findUnique.mockResolvedValue(validPost);
prismaMock.report.create.mockResolvedValue(report);
expect(createReport("reason","",validPost.id)).resolves.toEqual({
error: true,
data: "Author email is required."
});
})


it("should return an error if post is completed", () => {
prismaMock.post.findFirst.mockResolvedValue(null);

expect(createReport("reason","[email protected]",completedPost.id)).resolves.toEqual({
error: true,
data: "A Report cannot be made against a completed post."
});
})

it("should catch any error occurred", () => {
prismaMock.post.findUnique.mockResolvedValue(validPost);
prismaMock.report.create.mockResolvedValue(report);

prismaMock.post.create.mockRejectedValue(new Error("Some error occurred"));

expect(createReport("reason", "[email protected]", validPost.id)).resolves.toEqual({
error: true,
data: "Some error occurred while creating the report."
});
})
})

describe("Get all reports", () => {
it("should get all reports", () => {
prismaMock.report.findMany.mockResolvedValue([report]);

expect(getAllReports()).resolves.toEqual({
error: false,
data: [report]
});
});

it("should catch any error occurred", () => {
prismaMock.report.findMany.mockRejectedValue(new Error("Some error occurred"));

expect(getAllReports()).resolves.toEqual({
error: true,
data: "Some error occurred while fetching the reports."
});
});
})

describe("Close a report", () => {
it("should close a report", () => {
prismaMock.report.findFirst.mockResolvedValue(report);

report.status = "closed";
prismaMock.report.update.mockResolvedValue(report);

expect(closeReport(report.id)).resolves.toEqual({
error: false,
data: report
});

it("should catch any error occurred", () => {
prismaMock.report.findFirst.mockResolvedValue(report);
prismaMock.report.findMany.mockRejectedValue(new Error("Some error occurred"));

expect(closeReport(report.id)).resolves.toEqual({
error: true,
data: "Some error occurred while closing the report"
});
});
})


})
Loading

0 comments on commit 32711e4

Please sign in to comment.