Skip to content

Commit 452aca3

Browse files
MathyouMBAJaccP
andcommitted
Add fun fact
Co-authored-by: AJaccP <paditya1708@gmail.com>
1 parent e8b275f commit 452aca3

9 files changed

Lines changed: 106 additions & 48 deletions

src/infrastructure/facts.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import axios from "axios";
2+
import { Err, Ok, Result } from "ts-results";
3+
4+
export const fetchFact = async (): Promise<Result<string, Error>> => {
5+
try {
6+
const response = await axios.get("https://api.api-ninjas.com/v1/facts", {
7+
headers: {
8+
"X-Api-Key": "OW3TaucPc4fGSrBpJe9KuQ==c0GNDiePYzdFuHYm",
9+
},
10+
});
11+
const data = response.data;
12+
return Ok(data[0].fact);
13+
} catch (error) {
14+
return Err(new Error("Failed to fetch fact"));
15+
}
16+
};

src/reminders/messages/completeTaskReportMessage.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,25 @@ interface Props {
77
upcomingItems: Item[];
88
}
99

10-
export const completeTaskReportMessage = ({
10+
export const completeTaskReportMessage = async ({
1111
urgentItems,
1212
unassignedItems,
1313
upcomingItems,
14-
}: Props): DiscordItemMessage => {
14+
}: Props): Promise<DiscordItemMessage> => {
15+
const hasUrgent = urgentItems.length > 0;
16+
const hasUpcoming = upcomingItems.length > 0;
17+
const hasUnassigned = unassignedItems.length > 0;
18+
19+
const baseMessage =
20+
!hasUrgent && hasUpcoming && !hasUnassigned
21+
? "Nothing urgent or unassigned upcoming! 🐀🥂"
22+
: "Check out all upcoming tasks [here.](https://github.com/orgs/CarletonComputerScienceSociety/projects/18) 🐀🐀";
23+
1524
return {
1625
title: "Biweekly Tasks Reminder ☀️🌱",
17-
message:
18-
urgentItems.length === 0 &&
19-
upcomingItems.length &&
20-
unassignedItems.length === 0
21-
? "Nothing urgent or unassigned upcoming! 🐀🥂"
22-
: "Check out all upcoming tasks [here.](https://github.com/orgs/CarletonComputerScienceSociety/projects/18) 🐀🐀",
26+
message: `${baseMessage}`,
2327
sections: [
24-
...(urgentItems.length > 0
28+
...(hasUrgent
2529
? [
2630
{
2731
title: "🔥 Urgent & Overdue",
@@ -30,7 +34,7 @@ export const completeTaskReportMessage = ({
3034
},
3135
]
3236
: []),
33-
...(upcomingItems.length > 0
37+
...(hasUpcoming
3438
? [
3539
{
3640
title: "📅 Assigned Items",
@@ -39,7 +43,7 @@ export const completeTaskReportMessage = ({
3943
},
4044
]
4145
: []),
42-
...(unassignedItems.length > 0
46+
...(hasUnassigned
4347
? [
4448
{
4549
title: "📥 Unassigned Items",

src/reminders/messages/simpleTaskReportMessage.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,34 @@
11
import { Item } from "@src/items";
22
import { DiscordItemMessage } from "@infrastructure/discord";
33
import { EMOJIS } from "@src/constants";
4+
import { fetchFact } from "@infrastructure/facts";
45

56
interface Props {
67
urgentItems: Item[];
78
unassignedItems: Item[];
89
}
910

10-
export const simpleTaskReportMessage = ({
11+
export const simpleTaskReportMessage = async ({
1112
urgentItems,
1213
unassignedItems,
13-
}: Props): DiscordItemMessage => {
14+
}: Props): Promise<DiscordItemMessage> => {
15+
const factResult = await fetchFact();
16+
const randomFact = factResult.ok ? factResult.val : "*Error fetching fact*";
1417
const randomEmoji = EMOJIS[Math.floor(Math.random() * EMOJIS.length)];
1518

19+
const hasUrgent = urgentItems.length > 0;
20+
const hasUnassigned = unassignedItems.length > 0;
21+
22+
const baseMessage =
23+
!hasUrgent && !hasUnassigned
24+
? "Nothing urgent or unassigned today! 🐀🥂"
25+
: "Check out all upcoming tasks [here.](https://github.com/orgs/CarletonComputerScienceSociety/projects/18) 👀";
26+
1627
return {
1728
title: `Daily Task Reminder ${randomEmoji}`,
18-
message:
19-
urgentItems.length === 0 && unassignedItems.length === 0
20-
? "Nothing urgent or unassigned today! 🐀🥂"
21-
: "Check out all upcoming tasks [here.](https://github.com/orgs/CarletonComputerScienceSociety/projects/18) 👀",
29+
message: `${baseMessage}\n\n💡 **Fun Fact**: ${randomFact}.`,
2230
sections: [
23-
...(urgentItems.length > 0
31+
...(hasUrgent
2432
? [
2533
{
2634
title: "🔥 Urgent & Overdue",
@@ -29,7 +37,7 @@ export const simpleTaskReportMessage = ({
2937
},
3038
]
3139
: []),
32-
...(unassignedItems.length > 0
40+
...(hasUnassigned
3341
? [
3442
{
3543
title: "📥 Unassigned Items",

src/reminders/messages/urgentPromotionMessage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ interface Props {
55
promotionItems: Item[];
66
}
77

8-
export const urgentPromotionMessage = ({
8+
export const urgentPromotionMessage = async ({
99
promotionItems,
10-
}: Props): DiscordItemMessage => {
10+
}: Props): Promise<DiscordItemMessage> => {
1111
return {
1212
title: "Urgent Promotional Items Reminder 📬‼️",
1313
message:

src/reminders/tasks/dailyTasksReminder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ export const dailyTasksReminder = async () => {
3838
const urgentItems = filterForUrgentItems(nonBacklogItems);
3939

4040
const message = isCompleteReportDay()
41-
? completeTaskReportMessage({
41+
? await completeTaskReportMessage({
4242
urgentItems,
4343
unassignedItems,
4444
upcomingItems,
4545
})
46-
: simpleTaskReportMessage({
46+
: await simpleTaskReportMessage({
4747
urgentItems,
4848
unassignedItems,
4949
});

src/reminders/tasks/promotionReminder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const promotionReminder = async () => {
3434
return null;
3535
}
3636

37-
const message = urgentPromotionMessage({
37+
const message = await urgentPromotionMessage({
3838
promotionItems: itemsWithLabels,
3939
});
4040

test/reminders/messages/completeTaskReportMessage.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { itemFactory } from "../../factories/itemFactory";
33
import { Item } from "@src/items";
44

55
describe("completeTaskReportMessage", () => {
6-
it("will show the default message when there are no urgent or unassigned items", () => {
6+
it("will show the default message when there are no urgent or unassigned items", async () => {
77
const urgentItems: Item[] = [];
88
const unassignedItems: Item[] = [];
99
const upcomingItems: Item[] = [itemFactory()];
1010

11-
const result = completeTaskReportMessage({
11+
const result = await completeTaskReportMessage({
1212
urgentItems,
1313
unassignedItems,
1414
upcomingItems,
@@ -25,12 +25,12 @@ describe("completeTaskReportMessage", () => {
2525
]);
2626
});
2727

28-
it("will include the urgent section when there are urgent items", () => {
28+
it("will include the urgent section when there are urgent items", async () => {
2929
const urgentItems: Item[] = [itemFactory()];
3030
const unassignedItems: Item[] = [];
3131
const upcomingItems: Item[] = [];
3232

33-
const result = completeTaskReportMessage({
33+
const result = await completeTaskReportMessage({
3434
urgentItems,
3535
unassignedItems,
3636
upcomingItems,
@@ -46,12 +46,12 @@ describe("completeTaskReportMessage", () => {
4646
]);
4747
});
4848

49-
it("will include the unassigned section when there are unassigned items", () => {
49+
it("will include the unassigned section when there are unassigned items", async () => {
5050
const urgentItems: Item[] = [];
5151
const unassignedItems: Item[] = [itemFactory()];
5252
const upcomingItems: Item[] = [];
5353

54-
const result = completeTaskReportMessage({
54+
const result = await completeTaskReportMessage({
5555
urgentItems,
5656
unassignedItems,
5757
upcomingItems,
@@ -66,12 +66,12 @@ describe("completeTaskReportMessage", () => {
6666
]);
6767
});
6868

69-
it("includes all sections when all item types are present", () => {
69+
it("includes all sections when all item types are present", async () => {
7070
const urgentItems: Item[] = [itemFactory()];
7171
const unassignedItems: Item[] = [itemFactory()];
7272
const upcomingItems: Item[] = [itemFactory()];
7373

74-
const result = completeTaskReportMessage({
74+
const result = await completeTaskReportMessage({
7575
urgentItems,
7676
unassignedItems,
7777
upcomingItems,
@@ -96,8 +96,8 @@ describe("completeTaskReportMessage", () => {
9696
]);
9797
});
9898

99-
it("returns no sections and default message when all item arrays are empty", () => {
100-
const result = completeTaskReportMessage({
99+
it("returns no sections and default message when all item arrays are empty", async () => {
100+
const result = await completeTaskReportMessage({
101101
urgentItems: [],
102102
unassignedItems: [],
103103
upcomingItems: [],

test/reminders/messages/simpleTaskReportMessage.test.ts

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it, jest } from "@jest/globals";
1+
import { describe, expect, it, jest, beforeEach } from "@jest/globals";
22
import { simpleTaskReportMessage } from "@src/reminders/messages";
33
import { itemFactory } from "../../factories/itemFactory";
44

@@ -7,27 +7,51 @@ jest.mock("@src/constants", () => ({
77
EMOJIS: ["🧪"],
88
}));
99

10+
// Mock @infrastructure/facts
11+
jest.mock("@infrastructure/facts", () => ({
12+
fetchFact: jest.fn(),
13+
}));
14+
15+
import { fetchFact } from "@infrastructure/facts";
16+
1017
describe("simpleTaskReportMessage", () => {
11-
it("will return default message when both urgent and unassigned are empty", () => {
12-
const result = simpleTaskReportMessage({
18+
// Define the mocked return shape explicitly
19+
beforeEach(() => {
20+
// @ts-ignore – mocking return type to match Result<string, Error>
21+
(fetchFact as jest.Mock).mockResolvedValue({
22+
ok: true,
23+
val: "Fun facts make reports better",
24+
});
25+
});
26+
27+
it("returns default message when both urgent and unassigned are empty", async () => {
28+
const result = await simpleTaskReportMessage({
1329
urgentItems: [],
1430
unassignedItems: [],
1531
});
1632

1733
expect(result.title).toBe("Daily Task Reminder 🧪");
18-
expect(result.message).toBe("Nothing urgent or unassigned today! 🐀🥂");
34+
expect(result.message).toContain(
35+
"Nothing urgent or unassigned today! 🐀🥂",
36+
);
37+
expect(result.message).toContain(
38+
"💡 **Fun Fact**: Fun facts make reports better.",
39+
);
1940
expect(result.sections).toEqual([]);
2041
});
2142

22-
it("will include urgent section when there are urgent items", () => {
43+
it("includes urgent section when there are urgent items", async () => {
2344
const urgent = [itemFactory()];
2445

25-
const result = simpleTaskReportMessage({
46+
const result = await simpleTaskReportMessage({
2647
urgentItems: urgent,
2748
unassignedItems: [],
2849
});
2950

3051
expect(result.message).toContain("Check out all upcoming tasks");
52+
expect(result.message).toContain(
53+
"💡 **Fun Fact**: Fun facts make reports better.",
54+
);
3155
expect(result.sections).toEqual([
3256
{
3357
title: "🔥 Urgent & Overdue",
@@ -37,10 +61,10 @@ describe("simpleTaskReportMessage", () => {
3761
]);
3862
});
3963

40-
it("will include unassigned section when there are unassigned items", () => {
64+
it("includes unassigned section when there are unassigned items", async () => {
4165
const unassigned = [itemFactory()];
4266

43-
const result = simpleTaskReportMessage({
67+
const result = await simpleTaskReportMessage({
4468
urgentItems: [],
4569
unassignedItems: unassigned,
4670
});
@@ -52,13 +76,16 @@ describe("simpleTaskReportMessage", () => {
5276
includeLinks: false,
5377
},
5478
]);
79+
expect(result.message).toContain(
80+
"💡 **Fun Fact**: Fun facts make reports better.",
81+
);
5582
});
5683

57-
it("will include both sections when both item types are present", () => {
84+
it("includes both sections when both item types are present", async () => {
5885
const urgent = [itemFactory()];
5986
const unassigned = [itemFactory()];
6087

61-
const result = simpleTaskReportMessage({
88+
const result = await simpleTaskReportMessage({
6289
urgentItems: urgent,
6390
unassignedItems: unassigned,
6491
});
@@ -75,5 +102,8 @@ describe("simpleTaskReportMessage", () => {
75102
includeLinks: false,
76103
},
77104
]);
105+
expect(result.message).toContain(
106+
"💡 **Fun Fact**: Fun facts make reports better.",
107+
);
78108
});
79109
});

test/reminders/messages/urgentPromotionMessage.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { urgentPromotionMessage } from "@src/reminders/messages";
33
import { itemFactory } from "../../factories/itemFactory";
44

55
describe("urgentPromotionMessage", () => {
6-
it("will return message without sections when there are no promotion items", () => {
7-
const result = urgentPromotionMessage({ promotionItems: [] });
6+
it("will return message without sections when there are no promotion items", async () => {
7+
const result = await urgentPromotionMessage({ promotionItems: [] });
88

99
expect(result.title).toBe("Urgent Promotional Items Reminder 📬‼️");
1010
expect(result.message).toBe(
@@ -13,10 +13,10 @@ describe("urgentPromotionMessage", () => {
1313
expect(result.sections).toEqual([]);
1414
});
1515

16-
it("will include promotion section when promotion items are present", () => {
16+
it("will include promotion section when promotion items are present", async () => {
1717
const promotionItems = [itemFactory(), itemFactory()];
1818

19-
const result = urgentPromotionMessage({ promotionItems });
19+
const result = await urgentPromotionMessage({ promotionItems });
2020

2121
expect(result.sections).toEqual([
2222
{

0 commit comments

Comments
 (0)