Skip to content
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

feat: added controllere for TCR #2055

Merged
merged 3 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions constants/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,17 @@ export const ERROR_WHILE_UPDATING_REQUEST = "Error while updating request";

export const REQUEST_DOES_NOT_EXIST = "Request does not exist";
export const REQUEST_ALREADY_PENDING = "Request already exists please wait for approval or rejection";

export const TASK_REQUEST_MESSAGES = {
NOT_AUTHORIZED_TO_CREATE_REQUEST: "Not authorized to create the request",
USER_NOT_FOUND: "User not found",
TASK_NOT_EXIST: "Task does not exist",
INVALID_EXTERNAL_ISSUE_URL: "External issue url is not valid",
ISSUE_NOT_EXIST: "Issue does not exist",
TASK_REQUEST_EXISTS: "Task request already exists",
TASK_EXISTS_FOR_GIVEN_ISSUE: "Task exists for the given issue.",
TASK_ALREADY_REQUESTED: "Task was already requested",
TASK_REQUEST_CREATED_SUCCESS: "Task request created successfully",
ERROR_CREATING_TASK_REQUEST: "Error while creating task request",
TASK_REQUEST_UPDATED_SUCCESS: "Task request updated successfully",
};
6 changes: 5 additions & 1 deletion controllers/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import { CustomResponse } from "../typeDefinitions/global";
import { ExtensionRequestRequest, ExtensionRequestResponse } from "../types/extensionRequests";
import { createTaskExtensionRequest, updateTaskExtensionRequest } from "./extensionRequestsv2";
import { UpdateRequest } from "../types/requests";
import { TaskRequestRequest } from "../types/taskRequests";
import { createTaskRequestController } from "./taskRequestsv2";

export const createRequestController = async (
req: OooRequestCreateRequest | ExtensionRequestRequest,
req: OooRequestCreateRequest | ExtensionRequestRequest | TaskRequestRequest,
res: CustomResponse
) => {
const type = req.body.type;
Expand All @@ -22,6 +24,8 @@ export const createRequestController = async (
return await createOooRequestController(req as OooRequestCreateRequest, res as OooRequestResponse);
case REQUEST_TYPE.EXTENSION:
return await createTaskExtensionRequest(req as ExtensionRequestRequest, res as ExtensionRequestResponse);
case REQUEST_TYPE.TASK:
return await createTaskRequestController(req as TaskRequestRequest, res as CustomResponse);
default:
return res.boom.badRequest("Invalid request type");
}
Expand Down
174 changes: 174 additions & 0 deletions controllers/taskRequestsv2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { REQUEST_STATE, TASK_REQUEST_MESSAGES } from "../constants/requests";
import { TASK_REQUEST_TYPE } from "../constants/taskRequests";
import { addLog } from "../models/logs";
import { createRequest, getRequestByKeyValues } from "../models/requests";
import { fetchTask } from "../models/tasks";
import { fetchUser } from "../models/users";
import { fetchIssuesById } from "../services/githubService";
import { CustomResponse } from "../typeDefinitions/global";
import { userData } from "../types/global";
import { TaskRequestRequest } from "../types/taskRequests";

export const createTaskRequestController = async (req: TaskRequestRequest, res: CustomResponse) => {
const taskRequestData = req.body;
const requestedBy = req?.userData?.id;

if (!requestedBy) {
return res.boom.unauthorized();
}

if (req.userData.id !== taskRequestData.userId && !req.userData.roles?.super_user) {
return res.boom.forbidden(TASK_REQUEST_MESSAGES.NOT_AUTHORIZED_TO_CREATE_REQUEST);
}
Achintya-Chatterjee marked this conversation as resolved.
Show resolved Hide resolved

const userPromise: any = await fetchUser({ userId: taskRequestData.userId });
const userData: userData = userPromise.user;
if (!userData.id || !userData.username) {
return res.boom.notFound(TASK_REQUEST_MESSAGES.USER_NOT_FOUND);
}
try {
switch (taskRequestData.requestType) {
case TASK_REQUEST_TYPE.ASSIGNMENT: {
if (!req.userData.roles?.super_user) {
return res.boom.unauthorized(TASK_REQUEST_MESSAGES.NOT_AUTHORIZED_TO_CREATE_REQUEST);
}
const { taskData } = await fetchTask(taskRequestData.taskId);
if (!taskData) {
return res.boom.badRequest(TASK_REQUEST_MESSAGES.TASK_NOT_EXIST);
}
taskRequestData.taskTitle = taskData?.title;
break;
}
case TASK_REQUEST_TYPE.CREATION: {
let issueData: any;
try {
const url = new URL(taskRequestData.externalIssueUrl);
const issueUrlPaths = url.pathname.split("/");
const repositoryName = issueUrlPaths[3];
const issueNumber = issueUrlPaths[5];
issueData = await fetchIssuesById(repositoryName, issueNumber);
} catch (error) {
return res.boom.badRequest(TASK_REQUEST_MESSAGES.INVALID_EXTERNAL_ISSUE_URL);
}
if (!issueData) {
return res.boom.badRequest(TASK_REQUEST_MESSAGES.ISSUE_NOT_EXIST);
}
taskRequestData.taskTitle = issueData?.title;
break;
}
}
const existingRequest = await getRequestByKeyValues({
externalIssueUrl: taskRequestData.externalIssueUrl,
requestType: taskRequestData.requestType,
});

if (
existingRequest &&
existingRequest.state === REQUEST_STATE.PENDING &&
existingRequest.requestors.includes(requestedBy)
) {
return res.boom.badRequest(TASK_REQUEST_MESSAGES.TASK_REQUEST_EXISTS);
} else if (
existingRequest &&
existingRequest.state === REQUEST_STATE.PENDING &&
!existingRequest.requestors.includes(requestedBy)
) {
existingRequest.requestors.push(requestedBy);
existingRequest.users.push({
userId: userData.id,
username: userData.username,
proposedStartDate: taskRequestData.proposedStartDate,
proposedDeadline: taskRequestData.proposedDeadline,
description: taskRequestData.description,
markdownEnabled: taskRequestData.markdownEnabled,
firstName: userData.first_name,
lastName: userData.last_name,
state: REQUEST_STATE.PENDING,
requestedAt: Date.now(),
});
const updatedRequest = await createRequest(existingRequest);
const taskRequestLog = {
type: "taskRequests",
meta: {
taskRequestId: updatedRequest.id,
action: "update",
createdBy: req.userData.id,
createdAt: Date.now(),
lastModifiedBy: req.userData.id,
lastModifiedAt: Date.now(),
},
body: updatedRequest,
};
await addLog(taskRequestLog.type, taskRequestLog.meta, taskRequestLog.body);
const data = {
message: TASK_REQUEST_MESSAGES.TASK_REQUEST_UPDATED_SUCCESS,
data: {
id: updatedRequest.id,
...updatedRequest,
},
};
return res.status(200).json(data);
}

taskRequestData.requestedBy = requestedBy;
const createtaskRequestData = {
externalIssueUrl: taskRequestData.externalIssueUrl,
externalIssueHtmlUrl: taskRequestData.externalIssueHtmlUrl,
requestType: taskRequestData.requestType,
type: taskRequestData.type,
state: REQUEST_STATE.PENDING,
requestedBy: requestedBy,
taskTitle: taskRequestData.taskTitle,
users: [
{
userId: userData.id,
username: userData.username,
proposedStartDate: taskRequestData.proposedStartDate,
proposedDeadline: taskRequestData.proposedDeadline,
description: taskRequestData.description,
markdownEnabled: taskRequestData.markdownEnabled,
firstName: userData.first_name,
lastName: userData.last_name,
state: REQUEST_STATE.PENDING,
requestedAt: Date.now(),
},
],

requestors: [requestedBy],
};
const newTaskRequest = await createRequest(createtaskRequestData);

if (newTaskRequest.isCreationRequestApproved) {
return res.boom.badRequest(TASK_REQUEST_MESSAGES.TASK_EXISTS_FOR_GIVEN_ISSUE);
}
if (newTaskRequest.alreadyRequesting) {
return res.boom.badRequest(TASK_REQUEST_MESSAGES.TASK_ALREADY_REQUESTED);
}

const taskRequestLog = {
type: "taskRequests",
meta: {
taskRequestId: newTaskRequest.id,
action: "create",
createdBy: req.userData.id,
createdAt: Date.now(),
lastModifiedBy: req.userData.id,
lastModifiedAt: Date.now(),
},
body: newTaskRequest,
};
await addLog(taskRequestLog.type, taskRequestLog.meta, taskRequestLog.body);

const data = {
message: TASK_REQUEST_MESSAGES.TASK_REQUEST_CREATED_SUCCESS,
data: {
id: newTaskRequest.id,
...newTaskRequest,
},
};
return res.status(201).json(data);
} catch (err) {
logger.error(`${TASK_REQUEST_MESSAGES.ERROR_CREATING_TASK_REQUEST} : ${err}`);
return res.boom.serverUnavailable(TASK_REQUEST_MESSAGES.ERROR_CREATING_TASK_REQUEST);
}
};
62 changes: 62 additions & 0 deletions test/integration/requests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
REQUEST_ALREADY_REJECTED,
} from "../../constants/requests";
import { updateTask } from "../../models/tasks";
import { validTaskAssignmentRequest, validTaskCreqtionRequest } from "../fixtures/taskRequests/taskRequests";

const userData = userDataFixture();
chai.use(chaiHttp);
Expand Down Expand Up @@ -759,3 +760,64 @@ describe("/requests Extension", function () {
});

});


describe("/requests Task", function () {
let userId1: string;
let userJwtToken1: string;

beforeEach(async function () {
userId1 = await addUser(userData[16]);
userJwtToken1 = authService.generateAuthToken({ userId: userId1 });
});

afterEach(async function () {
await cleanDb();
});

describe("POST /requests", function () {
it("should return 401(Unauthorized) if user is not logged in", function (done) {
chai
.request(app)
.post("/requests?dev=true")
.send(validTaskCreqtionRequest)
.end(function (err, res) {
expect(res).to.have.status(401);
done();
});
});

it("should not create a new task request if issue does not exist", function (done) {
let taskRequestObj = validTaskCreqtionRequest
taskRequestObj.externalIssueUrl = "https://api.github.com/repos/Real-Dev-Squad/website-my/issues/1245";
taskRequestObj.userId = userId1;
chai
.request(app)
.post("/requests?dev=true")
.set("cookie", `${cookieName}=${userJwtToken1}`)
.send(taskRequestObj)
.end(function (err, res) {
expect(res).to.have.status(400);
expect(res.body).to.have.property("message");
expect(res.body.message).to.equal("Issue does not exist");
done();
});
});

it("should not create a new task request if task id is not present in the request body", function (done) {
let taskRequestObj = validTaskAssignmentRequest
delete taskRequestObj.taskId;
chai
.request(app)
.post("/requests?dev=true")
.set("cookie", `${cookieName}=${userJwtToken1}`)
.send(taskRequestObj)
.end(function (err, res) {
expect(res).to.have.status(400);
expect(res.body).to.have.property("message");
expect(res.body.message).to.equal('taskId is required when requestType is ASSIGNMENT');
done();
});
});
});
});
Loading