Skip to content

Commit

Permalink
feat: added controllere for TCR (#2055)
Browse files Browse the repository at this point in the history
  • Loading branch information
sahsisunny authored Jul 10, 2024
1 parent 2da9bff commit a33e9ea
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 1 deletion.
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);
}

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();
});
});
});
});

0 comments on commit a33e9ea

Please sign in to comment.