Skip to content

Commit adcc1d2

Browse files
authored
add taskTitle field to /task/update API (#227)
* add taskTitle field to /task/update API * feat:add test case for sendTaskUpdate util * feat: add test cases to taskUpdateHandler * refactor: add message in constant responses * remove: extra line
1 parent bdbb0c6 commit adcc1d2

File tree

6 files changed

+124
-22
lines changed

6 files changed

+124
-22
lines changed

src/constants/responses.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,5 @@ export const INVALID_TOKEN_FORMAT =
7777
"Invalid Authentication header format. Expected 'Bearer <token>'";
7878

7979
export const AUTHENTICATION_ERROR = "Invalid Authentication token";
80+
export const TASK_UPDATE_SENT_MESSAGE =
81+
"Task update sent on Discord's tracking-updates channel.";

src/controllers/taskUpdatesHandler.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,18 @@ export const sendTaskUpdatesHandler = async (request: IRequest, env: env) => {
1414
try {
1515
await verifyNodejsBackendAuthToken(authHeader, env);
1616
const updates: TaskUpdates = await request.json();
17-
const { completed, planned, blockers, userName, taskId } = updates.content;
18-
await sendTaskUpdate(completed, planned, blockers, userName, taskId, env);
19-
return new JSONResponse(
20-
"Task update sent on Discord's tracking-updates channel."
17+
const { completed, planned, blockers, userName, taskId, taskTitle } =
18+
updates.content;
19+
await sendTaskUpdate(
20+
completed,
21+
planned,
22+
blockers,
23+
userName,
24+
taskId,
25+
taskTitle,
26+
env
2127
);
28+
return new JSONResponse(response.TASK_UPDATE_SENT_MESSAGE);
2229
} catch (error: any) {
2330
return new JSONResponse({
2431
res: response.INTERNAL_SERVER_ERROR,

src/typeDefinitions/taskUpdate.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ export interface TaskUpdates {
55
blockers: string;
66
userName: string;
77
taskId: string;
8+
taskTitle: string;
89
};
910
}

src/utils/sendTaskUpdates.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ export async function sendTaskUpdate(
77
blockers: string,
88
userName: string,
99
taskId: string,
10+
taskTitle: string,
1011
env: env
1112
): Promise<void> {
1213
const taskUrl = config(env).RDS_STATUS_SITE_URL + `/tasks/${taskId}`;
1314
const formattedString =
14-
`${userName} added an update to their task: <${taskUrl}>\n` +
15+
`**${userName}** added an update to their task: [${taskTitle}](<${taskUrl}>)\n` +
1516
`\n**Completed**\n${completed}\n\n` +
1617
`**Planned**\n${planned}\n\n` +
1718
`**Blockers**\n${blockers}`;

tests/unit/handlers/taskUpdateHandler.test.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { sendTaskUpdatesHandler } from "../../../src/controllers/taskUpdatesHand
22
import JSONResponse from "../../../src/utils/JsonResponse";
33
import * as response from "../../../src/constants/responses";
44
import { sendTaskUpdate } from "../../../src/utils/sendTaskUpdates";
5-
65
import { generateDummyRequestObject } from "../../fixtures/fixture";
76

87
jest.mock("../../../src/utils/verifyAuthToken", () => ({
@@ -11,7 +10,6 @@ jest.mock("../../../src/utils/verifyAuthToken", () => ({
1110
jest.mock("../../../src/utils/sendTaskUpdates", () => ({
1211
sendTaskUpdate: jest.fn().mockResolvedValue(undefined),
1312
}));
14-
1513
describe("sendTaskUpdatesHandler", () => {
1614
const mockEnv = { DISCORD_TOKEN: "mockToken" };
1715
const mockData = {
@@ -21,20 +19,22 @@ describe("sendTaskUpdatesHandler", () => {
2119
blockers: "NA",
2220
userName: "12345678910",
2321
taskId: "79wMEIek990",
22+
taskTitle: "Hyperlink as task Title",
2423
},
2524
};
2625
afterEach(() => {
2726
jest.clearAllMocks();
2827
});
29-
3028
it("sendTaskUpdate function should return undefined after successfully sending the message", async () => {
31-
const { completed, planned, blockers, userName, taskId } = mockData.content;
29+
const { completed, planned, blockers, userName, taskId, taskTitle } =
30+
mockData.content;
3231
const response = await sendTaskUpdate(
3332
completed,
3433
planned,
3534
blockers,
3635
userName,
3736
taskId,
37+
taskTitle,
3838
mockEnv
3939
);
4040
expect(response).toBe(undefined);
@@ -50,4 +50,22 @@ describe("sendTaskUpdatesHandler", () => {
5050
expect(result.status).toBe(401);
5151
expect(jsonResponse).toEqual(response.UNAUTHORIZED);
5252
});
53+
it("should return success response if task update is sent successfully", async () => {
54+
const mockRequest = generateDummyRequestObject({
55+
url: "/task/update",
56+
method: "POST",
57+
headers: {
58+
"Content-Type": "application/json",
59+
Authorization: "Bearer dummyToken",
60+
},
61+
});
62+
mockRequest.json = jest.fn().mockResolvedValue(mockData);
63+
const result: JSONResponse = await sendTaskUpdatesHandler(
64+
mockRequest,
65+
mockEnv
66+
);
67+
expect(result.status).toBe(200);
68+
const res: JSONResponse = await result.json();
69+
expect(res).toBe(response.TASK_UPDATE_SENT_MESSAGE);
70+
});
5371
});

tests/unit/utils/sendTasksUpdates.test.ts

Lines changed: 86 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ describe("sendTaskUpdate function", () => {
99
const blockers = "No blockers";
1010
const userName = "Tejas";
1111
const taskId = "69nduIn210";
12+
const taskTitle = "Hyperlink as task title";
1213
const taskUrl = config(mockEnv).RDS_STATUS_SITE_URL + `/tasks/${taskId}`;
1314
const assertFetchCall = (url: string, bodyObj: any, mockEnv: any) => {
1415
expect(global.fetch).toHaveBeenCalledWith(url, {
@@ -24,11 +25,42 @@ describe("sendTaskUpdate function", () => {
2425
afterEach(() => {
2526
jest.clearAllMocks();
2627
});
28+
test("should throw an error if response status is not OK", async () => {
29+
const url = config(mockEnv).TRACKING_CHANNEL_URL;
30+
const formattedString =
31+
`**${userName}** added an update to their task: [${taskTitle}](<${taskUrl}>)\n` +
32+
`\n**Completed**\n${completed}\n\n` +
33+
`**Planned**\n${planned}\n\n` +
34+
`**Blockers**\n${blockers}`;
35+
const bodyObj = {
36+
content: formattedString,
37+
};
38+
39+
jest
40+
.spyOn(global, "fetch")
41+
.mockResolvedValueOnce(
42+
new JSONResponse("", { status: 400, statusText: "Bad Request" })
43+
);
44+
45+
await expect(
46+
sendTaskUpdate(
47+
completed,
48+
planned,
49+
blockers,
50+
userName,
51+
taskId,
52+
taskTitle,
53+
mockEnv
54+
)
55+
).rejects.toThrowError("Failed to send task update: 400 - Bad Request");
56+
57+
assertFetchCall(url, bodyObj, mockEnv);
58+
});
2759

2860
test("should send the task update to discord tracking channel when all fields are present", async () => {
2961
const url = config(mockEnv).TRACKING_CHANNEL_URL;
3062
const formattedString =
31-
`${userName} added an update to their task: <${taskUrl}>\n` +
63+
`**${userName}** added an update to their task: [${taskTitle}](<${taskUrl}>)\n` +
3264
`\n**Completed**\n${completed}\n\n` +
3365
`**Planned**\n${planned}\n\n` +
3466
`**Blockers**\n${blockers}`;
@@ -46,6 +78,7 @@ describe("sendTaskUpdate function", () => {
4678
blockers,
4779
userName,
4880
taskId,
81+
taskTitle,
4982
mockEnv
5083
);
5184

@@ -55,7 +88,7 @@ describe("sendTaskUpdate function", () => {
5588
test("should send the task update to discord tracking channel when only completed is present", async () => {
5689
const url = config(mockEnv).TRACKING_CHANNEL_URL;
5790
const formattedString =
58-
`${userName} added an update to their task: <${taskUrl}>\n` +
91+
`**${userName}** added an update to their task: [${taskTitle}](<${taskUrl}>)\n` +
5992
`\n**Completed**\n${completed}\n\n` +
6093
`**Planned**\n\n\n` +
6194
`**Blockers**\n`;
@@ -67,15 +100,23 @@ describe("sendTaskUpdate function", () => {
67100
.spyOn(global, "fetch")
68101
.mockImplementation(() => Promise.resolve(new JSONResponse("")));
69102

70-
await sendTaskUpdate(completed, "", "", userName, taskId, mockEnv);
103+
await sendTaskUpdate(
104+
completed,
105+
"",
106+
"",
107+
userName,
108+
taskId,
109+
taskTitle,
110+
mockEnv
111+
);
71112

72113
assertFetchCall(url, bodyObj, mockEnv);
73114
});
74115

75116
test("should send the task update to discord tracking channel when only planned is present", async () => {
76117
const url = config(mockEnv).TRACKING_CHANNEL_URL;
77118
const formattedString =
78-
`${userName} added an update to their task: <${taskUrl}>\n` +
119+
`**${userName}** added an update to their task: [${taskTitle}](<${taskUrl}>)\n` +
79120
`\n**Completed**\n\n\n` +
80121
`**Planned**\n${planned}\n\n` +
81122
`**Blockers**\n`;
@@ -87,15 +128,15 @@ describe("sendTaskUpdate function", () => {
87128
.spyOn(global, "fetch")
88129
.mockImplementation(() => Promise.resolve(new JSONResponse("")));
89130

90-
await sendTaskUpdate("", planned, "", userName, taskId, mockEnv);
131+
await sendTaskUpdate("", planned, "", userName, taskId, taskTitle, mockEnv);
91132

92133
assertFetchCall(url, bodyObj, mockEnv);
93134
});
94135

95136
test("should send the task update to discord tracking channel when only blockers is present", async () => {
96137
const url = config(mockEnv).TRACKING_CHANNEL_URL;
97138
const formattedString =
98-
`${userName} added an update to their task: <${taskUrl}>\n` +
139+
`**${userName}** added an update to their task: [${taskTitle}](<${taskUrl}>)\n` +
99140
`\n**Completed**\n\n\n` +
100141
`**Planned**\n\n\n` +
101142
`**Blockers**\n${blockers}`;
@@ -107,15 +148,23 @@ describe("sendTaskUpdate function", () => {
107148
.spyOn(global, "fetch")
108149
.mockImplementation(() => Promise.resolve(new JSONResponse("")));
109150

110-
await sendTaskUpdate("", "", blockers, userName, taskId, mockEnv);
151+
await sendTaskUpdate(
152+
"",
153+
"",
154+
blockers,
155+
userName,
156+
taskId,
157+
taskTitle,
158+
mockEnv
159+
);
111160

112161
assertFetchCall(url, bodyObj, mockEnv);
113162
});
114163

115164
test("should send the task update to discord tracking channel when only completed and planned are present", async () => {
116165
const url = config(mockEnv).TRACKING_CHANNEL_URL;
117166
const formattedString =
118-
`${userName} added an update to their task: <${taskUrl}>\n` +
167+
`**${userName}** added an update to their task: [${taskTitle}](<${taskUrl}>)\n` +
119168
`\n**Completed**\n${completed}\n\n` +
120169
`**Planned**\n${planned}\n\n` +
121170
`**Blockers**\n`;
@@ -127,15 +176,23 @@ describe("sendTaskUpdate function", () => {
127176
.spyOn(global, "fetch")
128177
.mockImplementation(() => Promise.resolve(new JSONResponse("")));
129178

130-
await sendTaskUpdate(completed, planned, "", userName, taskId, mockEnv);
179+
await sendTaskUpdate(
180+
completed,
181+
planned,
182+
"",
183+
userName,
184+
taskId,
185+
taskTitle,
186+
mockEnv
187+
);
131188

132189
assertFetchCall(url, bodyObj, mockEnv);
133190
});
134191

135192
test("should send the task update to discord tracking channel when only completed and blockers are present", async () => {
136193
const url = config(mockEnv).TRACKING_CHANNEL_URL;
137194
const formattedString =
138-
`${userName} added an update to their task: <${taskUrl}>\n` +
195+
`**${userName}** added an update to their task: [${taskTitle}](<${taskUrl}>)\n` +
139196
`\n**Completed**\n${completed}\n\n` +
140197
`**Planned**\n\n\n` +
141198
`**Blockers**\n${blockers}`;
@@ -147,15 +204,23 @@ describe("sendTaskUpdate function", () => {
147204
.spyOn(global, "fetch")
148205
.mockImplementation(() => Promise.resolve(new JSONResponse("")));
149206

150-
await sendTaskUpdate(completed, "", blockers, userName, taskId, mockEnv);
207+
await sendTaskUpdate(
208+
completed,
209+
"",
210+
blockers,
211+
userName,
212+
taskId,
213+
taskTitle,
214+
mockEnv
215+
);
151216

152217
assertFetchCall(url, bodyObj, mockEnv);
153218
});
154219

155220
test("should send the task update to discord tracking channel when only planned and blockers are present", async () => {
156221
const url = config(mockEnv).TRACKING_CHANNEL_URL;
157222
const formattedString =
158-
`${userName} added an update to their task: <${taskUrl}>\n` +
223+
`**${userName}** added an update to their task: [${taskTitle}](<${taskUrl}>)\n` +
159224
`\n**Completed**\n\n\n` +
160225
`**Planned**\n${planned}\n\n` +
161226
`**Blockers**\n${blockers}`;
@@ -167,7 +232,15 @@ describe("sendTaskUpdate function", () => {
167232
.spyOn(global, "fetch")
168233
.mockImplementation(() => Promise.resolve(new JSONResponse("")));
169234

170-
await sendTaskUpdate("", planned, blockers, userName, taskId, mockEnv);
235+
await sendTaskUpdate(
236+
"",
237+
planned,
238+
blockers,
239+
userName,
240+
taskId,
241+
taskTitle,
242+
mockEnv
243+
);
171244

172245
assertFetchCall(url, bodyObj, mockEnv);
173246
});

0 commit comments

Comments
 (0)