1 |
import { generateEmbed, guildInfo, userInfo } from "@/utils/embed"; |
2 |
import { faker } from "@faker-js/faker"; |
3 |
import { |
4 |
ChatInputCommandInteraction, |
5 |
ColorResolvable, |
6 |
Colors, |
7 |
EmbedBuilder, |
8 |
User |
9 |
} from "discord.js"; |
10 |
import { beforeEach, describe, expect, it } from "vitest"; |
11 |
import { createClient } from "../mocks/client.mock"; |
12 |
import { createGuild, createInvite } from "../mocks/guild.mock"; |
13 |
import { randomSnowflake } from "../mocks/snowflakes"; |
14 |
|
15 |
describe("generateEmbed", () => { |
16 |
let authorIconURL: string; |
17 |
let footerIconURL: string; |
18 |
let thumbnailURL: string; |
19 |
let imageURL: string; |
20 |
let videoURL: string; |
21 |
let timestamp: Date; |
22 |
|
23 |
let options: ChatInputCommandInteraction["options"]; |
24 |
|
25 |
beforeEach(() => { |
26 |
authorIconURL = faker.image.avatar(); |
27 |
footerIconURL = faker.image.avatar(); |
28 |
thumbnailURL = faker.image.avatar(); |
29 |
imageURL = faker.image.avatar(); |
30 |
videoURL = faker.internet.url() + "1.mp4"; |
31 |
timestamp = new Date(); |
32 |
|
33 |
options = { |
34 |
getString: (field: string) => { |
35 |
switch (field) { |
36 |
case "author_name": |
37 |
return "author"; |
38 |
case "author_icon_url": |
39 |
return authorIconURL; |
40 |
case "footer_text": |
41 |
return "footer"; |
42 |
case "footer_icon_url": |
43 |
return footerIconURL; |
44 |
case "color": |
45 |
return Colors.Red satisfies ColorResolvable; |
46 |
case "title": |
47 |
return "title"; |
48 |
case "description": |
49 |
return "description"; |
50 |
case "thumbnail": |
51 |
return thumbnailURL; |
52 |
case "image": |
53 |
return imageURL; |
54 |
case "video": |
55 |
return videoURL; |
56 |
case "timestamp": |
57 |
return timestamp.toISOString(); |
58 |
case "fields": |
59 |
return "name: value"; |
60 |
default: |
61 |
return undefined; |
62 |
} |
63 |
} |
64 |
} as ChatInputCommandInteraction["options"]; |
65 |
}); |
66 |
|
67 |
it("should generate an embed", () => { |
68 |
const embed = generateEmbed(options); |
69 |
|
70 |
expect(embed).toEqual({ |
71 |
embed: new EmbedBuilder({ |
72 |
video: { |
73 |
url: videoURL |
74 |
} |
75 |
}) |
76 |
.setAuthor({ |
77 |
name: "author", |
78 |
iconURL: authorIconURL |
79 |
}) |
80 |
.setTitle("title") |
81 |
.setDescription("description") |
82 |
.setThumbnail(thumbnailURL) |
83 |
.setImage(imageURL) |
84 |
|
85 |
.setFooter({ |
86 |
text: "footer", |
87 |
iconURL: footerIconURL |
88 |
}) |
89 |
.setTimestamp(timestamp) |
90 |
.addFields({ |
91 |
name: "name", |
92 |
value: "value" |
93 |
}) |
94 |
.setColor(Colors.Red) |
95 |
}); |
96 |
}); |
97 |
|
98 |
it("should return an error if the color is invalid", () => { |
99 |
const original = options.getString; |
100 |
|
101 |
options.getString = ((field: string) => { |
102 |
if (field === "color") { |
103 |
return "invalid"; |
104 |
} |
105 |
|
106 |
return original(field); |
107 |
}) as typeof options.getString; |
108 |
|
109 |
const embed = generateEmbed(options); |
110 |
|
111 |
expect(embed).toEqual({ |
112 |
error: "Invalid color given." |
113 |
}); |
114 |
}); |
115 |
|
116 |
it("should set the timestamp to the current date if the timestamp is 'current'", () => { |
117 |
const original = options.getString; |
118 |
|
119 |
options.getString = ((field: string) => { |
120 |
if (field === "timestamp") { |
121 |
return "current"; |
122 |
} |
123 |
|
124 |
return original(field); |
125 |
}) as typeof options.getString; |
126 |
|
127 |
const startTime = Date.now(); |
128 |
const embed = generateEmbed(options); |
129 |
const endTime = Date.now(); |
130 |
|
131 |
expect(new Date(embed.embed?.toJSON().timestamp ?? "").getTime()).greaterThanOrEqual( |
132 |
startTime |
133 |
); |
134 |
expect(new Date(embed.embed?.toJSON().timestamp ?? "").getTime()).lessThanOrEqual(endTime); |
135 |
}); |
136 |
}); |
137 |
|
138 |
describe("userInfo", () => { |
139 |
it("should return the user info", () => { |
140 |
const id = randomSnowflake(); |
141 |
const user = { |
142 |
id, |
143 |
username: faker.internet.userName(), |
144 |
client: createClient(), |
145 |
toString() { |
146 |
return `<@${id}>`; |
147 |
} |
148 |
} as unknown as User; |
149 |
|
150 |
const info = userInfo(user); |
151 |
expect(info).toBe( |
152 |
`ID: ${user.id}\nUsername: ${user.username}\nMention: ${user.toString()}` |
153 |
); |
154 |
}); |
155 |
|
156 |
it("should return the system user info if the user is the bot", () => { |
157 |
const user = createClient().user; |
158 |
|
159 |
const info1 = userInfo(user, true); |
160 |
const info2 = userInfo(user, false); |
161 |
|
162 |
expect(info1).toBe("System"); |
163 |
expect(info2).toBe(`Type: __System__\nMention: ${user.toString()}`); |
164 |
}); |
165 |
}); |
166 |
|
167 |
describe("guildInfo", () => { |
168 |
it("should return the guild info", () => { |
169 |
const guild = createGuild(); |
170 |
const invite = createInvite(); |
171 |
|
172 |
guild.id = "123456789"; |
173 |
guild.name = "Test Guild"; |
174 |
guild.invites.cache.set("inviteCode", invite); |
175 |
|
176 |
const info = guildInfo(guild); |
177 |
|
178 |
expect(info).toBe(`ID: 123456789\nName: Test Guild\nInvite: ${invite.url}`); |
179 |
}); |
180 |
|
181 |
it("should return 'Unavailable' if the guild invite is not available", () => { |
182 |
const guild = createGuild(); |
183 |
|
184 |
guild.id = "987654321"; |
185 |
guild.name = "Another Guild"; |
186 |
|
187 |
const info = guildInfo(guild); |
188 |
|
189 |
expect(info).toBe("ID: 987654321\nName: Another Guild\nInvite: *Unavailable*"); |
190 |
}); |
191 |
}); |