diff --git a/src/transformers/auditlogEntry.ts b/src/transformers/auditlogEntry.ts index 5357ed1dc..dd821a906 100644 --- a/src/transformers/auditlogEntry.ts +++ b/src/transformers/auditlogEntry.ts @@ -20,12 +20,12 @@ export function transformAuditlogEntry( return { key: change.key, new: { - id: bot.transformers.snowflake(change.new_value.id!), + id: change.new_value.id ? bot.transformers.snowflake(change.new_value.id) : undefined, name: change.new_value.name, }, old: { - id: bot.transformers.snowflake(change.old_value.id!), - name: change.old_value.name, + id: change.old_value?.id ? bot.transformers.snowflake(change.old_value.id) : undefined, + name: change.old_value?.name, }, }; case "discovery_splash_hash": diff --git a/src/types/auditLog/auditLogChange.ts b/src/types/auditLog/auditLogChange.ts index 8d6de21f8..be1453a31 100644 --- a/src/types/auditLog/auditLogChange.ts +++ b/src/types/auditLog/auditLogChange.ts @@ -63,7 +63,7 @@ export type AuditLogChange = } | { newValue: Partial; - oldValue: Partial; + oldValue?: Partial; key: "$add" | "$remove"; } | { diff --git a/tests/benchmark.ts b/tests/benchmark.ts new file mode 100644 index 000000000..5b9be3850 --- /dev/null +++ b/tests/benchmark.ts @@ -0,0 +1,11 @@ +import { bot } from "./mod.ts"; +import { memoryBenchmarks } from "../benchmarks/index.ts"; +import { sanitizeMode } from "./constants.ts"; + +Deno.test({ + name: "[Memory] Benchmark memory tests", + fn: async (t) => { + await memoryBenchmarks(bot, true); + }, + ...sanitizeMode, +}); diff --git a/tests/constants.ts b/tests/constants.ts index b02bff22a..3bfc4abca 100644 --- a/tests/constants.ts +++ b/tests/constants.ts @@ -1 +1,13 @@ export const CACHED_COMMUNITY_GUILD_ID = 907350958810480671n; + +// CHANGE TO TRUE WHEN DEBUGGING SANITIZATION ERRORS +export const sanitizeMode = { + sanitizeResources: false, + sanitizeOps: false, + sanitizeExit: false, +}; + +// USED FOR ROLE CHANGE EVENTS +export const roleChanges = new Map(); + +export const banCounters = new Map(); \ No newline at end of file diff --git a/tests/emoji/createEmoji.ts b/tests/emoji/createEmoji.ts new file mode 100644 index 000000000..da7f8ca32 --- /dev/null +++ b/tests/emoji/createEmoji.ts @@ -0,0 +1,24 @@ +import { assertExists } from "../deps.ts"; +import { bot,guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[emoji] create an emoji", + fn: async (t) => { + const emoji = await bot.helpers.createEmoji(guild.id, { + name: "blamewolf", + image: "https://cdn.discordapp.com/emojis/814955268123000832.png", + roles: [], + }); + + // Assertions + assertExists(emoji); + + // Delay the execution to allow event to be processed + await delayUntil(10000, async () => bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)); + + if (!bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)) { + throw new Error("The emoji seemed to be created but it was not cached."); + } + }, +}); diff --git a/tests/emoji/deleteEmojiWithReason.ts b/tests/emoji/deleteEmojiWithReason.ts new file mode 100644 index 000000000..c95bb1ba4 --- /dev/null +++ b/tests/emoji/deleteEmojiWithReason.ts @@ -0,0 +1,32 @@ +import { assertExists } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[emoji] delete an emoji without a reason", + fn: async (t) => { + const emoji = await bot.helpers.createEmoji(guild.id, { + name: "blamewolf", + image: "https://cdn.discordapp.com/emojis/814955268123000832.png", + roles: [], + }); + + // Assertions + assertExists(emoji); + + // Delay the execution to allow event to be processed + await delayUntil(10000, async () => bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)); + + if (!bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)) { + throw new Error("The emoji seemed to be created but it was not cached."); + } + + await bot.helpers.deleteEmoji(guild.id, emoji.id, "with a reason"); + + await delayUntil(10000, async () => !bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)); + + if (bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)) { + throw new Error("The emoji seemed to be deleted but it's still cached."); + } + }, +}); diff --git a/tests/emoji/deleteEmojiWithoutReason.ts b/tests/emoji/deleteEmojiWithoutReason.ts new file mode 100644 index 000000000..75c91c10a --- /dev/null +++ b/tests/emoji/deleteEmojiWithoutReason.ts @@ -0,0 +1,32 @@ +import { assertExists } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[emoji] delete an emoji without a reason", + fn: async (t) => { + const emoji = await bot.helpers.createEmoji(guild.id, { + name: "blamewolf", + image: "https://cdn.discordapp.com/emojis/814955268123000832.png", + roles: [], + }); + + // Assertions + assertExists(emoji); + + // Delay the execution to allow event to be processed + await delayUntil(10000, async () => bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)); + + if (!bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)) { + throw new Error("The emoji seemed to be created but it was not cached."); + } + + await bot.helpers.deleteEmoji(guild.id, emoji.id); + + await delayUntil(10000, async () => !bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)); + + if (bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)) { + throw new Error("The emoji seemed to be deleted but it's still cached."); + } + }, +}); diff --git a/tests/emoji/editEmoji.ts b/tests/emoji/editEmoji.ts new file mode 100644 index 000000000..fd226138d --- /dev/null +++ b/tests/emoji/editEmoji.ts @@ -0,0 +1,37 @@ +import { assertExists } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[emoji] edit an emoji", + fn: async (t) => { + const emoji = await bot.helpers.createEmoji(guild.id, { + name: "blamewolf", + image: "https://cdn.discordapp.com/emojis/814955268123000832.png", + roles: [], + }); + + // Assertions + assertExists(emoji); + + // Delay the execution to allow event to be processed + await delayUntil(10000, async () => bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)); + + if (!bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)) { + throw new Error("The emoji seemed to be created but it was not cached."); + } + + await bot.helpers.editEmoji(guild.id, emoji.id, { + name: "blamewolf_infinite", + }); + + await delayUntil( + 10000, + async () => bot.cache.guilds.get(guild.id)?.emojis?.get(emoji.id)?.name === "blamewolf_infinite" + ); + + if (bot.cache.guilds.get(guild.id)?.emojis?.get(emoji.id)?.name !== "blamewolf_infinite") { + throw new Error("The emoji seemed to be edited but the cache was not updated."); + } + }, +}); diff --git a/tests/emoji/getEmoji.ts b/tests/emoji/getEmoji.ts new file mode 100644 index 000000000..2f93849a1 --- /dev/null +++ b/tests/emoji/getEmoji.ts @@ -0,0 +1,31 @@ +import { assertExists } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[emoji] get an emoji", + fn: async (t) => { + const emoji = await bot.helpers.createEmoji(guild.id, { + name: "blamewolf", + image: "https://cdn.discordapp.com/emojis/814955268123000832.png", + roles: [], + }); + + // Assertions + assertExists(emoji); + + // Delay the execution to allow event to be processed + await delayUntil(10000, async () => bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)); + + if (!bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)) { + throw new Error("The emoji seemed to be created but it was not cached."); + } + + bot.cache.guilds.get(guild.id)?.emojis?.delete(emoji.id); + + const getEmoji = await bot.helpers.getEmoji(guild.id, emoji.id, true); + + // Assertions + assertExists(getEmoji); + }, +}); diff --git a/tests/emoji/getMultipleEmojis.ts b/tests/emoji/getMultipleEmojis.ts new file mode 100644 index 000000000..abdf01131 --- /dev/null +++ b/tests/emoji/getMultipleEmojis.ts @@ -0,0 +1,30 @@ +import { assertExists } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[emoji] get multiple emojis", + fn: async (t) => { + const emoji = await bot.helpers.createEmoji(guild.id, { + name: "blamewolf", + image: "https://cdn.discordapp.com/emojis/814955268123000832.png", + roles: [], + }); + + // Assertions + assertExists(emoji); + + // Delay the execution to allow event to be processed + await delayUntil(10000, async () => bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)); + + if (!bot.cache.guilds.get(guild.id)?.emojis?.has(emoji.id)) { + throw new Error("The emoji seemed to be created but it was not cached."); + } + + const emojis = await bot.helpers.getEmojis(guild.id); + + if (emojis.size === 0) { + throw new Error("The getEmojis function returned 0 emojis."); + } + }, +}); diff --git a/tests/example.ts b/tests/example.ts deleted file mode 100644 index 5848e16cd..000000000 --- a/tests/example.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { delay } from "../src/util/utils.ts"; - -// CHANGE TO TRUE WHEN DEBUGGING SANITIZATION ERRORS -const sanitizeMode = { - sanitizeResources: false, - sanitizeOps: false, - sanitizeExit: false, -}; - -Deno.test({ - name: "- Example Tests", - fn: async (t) => { - await t.step("Nested tests", async (t) => { - await t.step({ name: "this is quick", fn: () => {}, ...sanitizeMode }); - - await Promise.all([ - t.step({ - name: "[example] 1", - fn: async (t) => { - await delay(60000); - }, - ...sanitizeMode, - }), - ]) - }); - }, - ...sanitizeMode, -}); diff --git a/tests/helpers/emojis/editEmoji.ts b/tests/helpers/emojis/editEmoji.ts index 6b8b8403a..95b0a7491 100644 --- a/tests/helpers/emojis/editEmoji.ts +++ b/tests/helpers/emojis/editEmoji.ts @@ -3,32 +3,5 @@ import { assertExists } from "../../deps.ts"; import { delayUntil } from "../../utils.ts"; export async function editEmojiTest(bot: Bot, guildId: bigint, t: Deno.TestContext) { - const emoji = await bot.helpers.createEmoji(guildId, { - name: "blamewolf", - image: "https://cdn.discordapp.com/emojis/814955268123000832.png", - roles: [], - }); - - // Assertions - assertExists(emoji); - - // Delay the execution to allow event to be processed - // await delayUntil(10000, async () => bot.cache.guilds.get(guildId)?.emojis?.has(emoji.id)); - - // if (!bot.cache.guilds.get(guildId)?.emojis?.has(emoji.id)) { - // throw new Error("The emoji seemed to be created but it was not cached."); - // } - - await bot.helpers.editEmoji(guildId, emoji.id, { - name: "blamewolf_infinite", - }); - - // await delayUntil( - // 10000, - // async () => bot.cache.guilds.get(guildId)?.emojis?.get(emoji.id)?.name === "blamewolf_infinite" - // ); - - // if (bot.cache.guilds.get(guildId)?.emojis?.get(emoji.id)?.name !== "blamewolf_infinite") { - // throw new Error("The emoji seemed to be edited but the cache was not updated."); - // } + } diff --git a/tests/helpers/guilds/scheduledEvents/deleteScheduledEvent.ts b/tests/helpers/guilds/scheduledEvents/deleteScheduledEvent.ts index 2bb659d38..2d29f35b7 100644 --- a/tests/helpers/guilds/scheduledEvents/deleteScheduledEvent.ts +++ b/tests/helpers/guilds/scheduledEvents/deleteScheduledEvent.ts @@ -2,14 +2,5 @@ import { Bot } from "../../../../src/bot.ts"; import { ScheduledEventEntityType, ScheduledEventPrivacyLevel } from "../../../../src/types/guilds/scheduledEvents.ts"; export async function deleteScheduledEventTests(bot: Bot, guildId: bigint, t: Deno.TestContext) { - const event = await bot.helpers.createScheduledEvent(guildId, { - name: "lfg", - description: "itoh is an imposter", - scheduledStartTime: Date.now() + 600000, - scheduledEndTime: Date.now() + 1200000, - privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, - entityType: ScheduledEventEntityType.External, - location: "heaven", - }); - await bot.helpers.deleteScheduledEvent(guildId, event.id); + } diff --git a/tests/helpers/members/ban.ts b/tests/helpers/members/ban.ts index b1005932b..2c0365549 100644 --- a/tests/helpers/members/ban.ts +++ b/tests/helpers/members/ban.ts @@ -3,33 +3,16 @@ import { CreateGuildBan } from "../../../src/types/mod.ts"; import { assertEquals } from "../../deps.ts"; import { delayUntil } from "../../utils.ts"; -const banCounters = new Map(); + export async function banTest(bot: Bot, t: Deno.TestContext, guildId: bigint, id: bigint, options?: CreateGuildBan) { - bot.events.guildBanAdd = function (bot, user, guildId) { - banCounters.set(user.id, true); - }; - - await bot.helpers.banMember(guildId, id, options); - - await delayUntil(10000, () => banCounters.get(id)); - - assertEquals(banCounters.get(id), true); + } export async function getBansTest(bot: Bot, t: Deno.TestContext, guildId: bigint) { - const bans = await bot.helpers.getBans(guildId); - assertEquals(bans.size > 1, true); + } export async function unbanTest(bot: Bot, t: Deno.TestContext, guildId: bigint, id: bigint) { - bot.events.guildBanRemove = function (bot, user, guildId) { - banCounters.set(user.id, false); - }; - - await bot.helpers.unbanMember(guildId, id); - - await delayUntil(10000, () => !banCounters.get(id)); - - assertEquals(banCounters.get(id), false); + } diff --git a/tests/helpers/members/fetchMembers.ts b/tests/helpers/members/fetchMembers.ts index dc039defd..1bf018a87 100644 --- a/tests/helpers/members/fetchMembers.ts +++ b/tests/helpers/members/fetchMembers.ts @@ -2,11 +2,5 @@ import { Bot } from "../../../src/bot.ts"; import { assertExists } from "../../deps.ts"; export async function fetchSingleMemberTest(bot: Bot, guildId: bigint, t: Deno.TestContext) { - await bot.helpers.fetchMembers(guildId, 0, { - userIds: [bot.id], - limit: 1, - }); - - // Assertions - assertExists(bot.cache.members.get(BigInt(`${bot.id}${guildId}`))); + } diff --git a/tests/helpers/misc/discoveries.ts b/tests/helpers/misc/discoveries.ts deleted file mode 100644 index aa03a281d..000000000 --- a/tests/helpers/misc/discoveries.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Bot } from "../../../src/bot.ts"; -import { assertEquals } from "../../deps.ts"; - -export async function getDiscoveryCategoriesTest(bot: Bot, t: Deno.TestContext) { - const categories = await bot.helpers.getDiscoveryCategories(); - - assertEquals(categories.size > 0, true); -} - -export async function validDiscoveryTermTest(bot: Bot, t: Deno.TestContext) { - const valid = await bot.helpers.validDiscoveryTerm("Bots"); - - assertEquals(valid, true); -} diff --git a/tests/helpers/misc/user.ts b/tests/helpers/misc/user.ts index 0f5db25a1..1937bd024 100644 --- a/tests/helpers/misc/user.ts +++ b/tests/helpers/misc/user.ts @@ -2,8 +2,5 @@ import { Bot } from "../../../src/bot.ts"; import { assertExists } from "../../deps.ts"; export async function getUserTests(bot: Bot, t: Deno.TestContext) { - const user = await bot.helpers.getUser(bot.id); - assertExists(user); - - assertExists(bot.transformers.user(bot, user)); + } diff --git a/tests/helpers/roles/roleChanges.ts b/tests/helpers/roles/roleChanges.ts index e2ce23df1..85111936b 100644 --- a/tests/helpers/roles/roleChanges.ts +++ b/tests/helpers/roles/roleChanges.ts @@ -35,32 +35,5 @@ export async function removeRoleTest( options: { reason?: string }, t: Deno.TestContext ) { - const role = await bot.helpers.createRole(guildId, { - name: "hoti", - }); - - assertExists(role); - - // Delay the execution to allow event to be processed - await delayUntil(10000, () => bot.cache.guilds.get(guildId)?.roles.has(role.id)); - - assertExists(bot.cache.guilds.get(guildId)?.roles.has(role.id)); - - bot.events.guildMemberUpdate = function (bot, member, user) { - roleChanges.set(user.id, member.roles); - }; - - await bot.helpers.addRole(guildId, bot.id, role.id, options.reason); - - // Delay the execution to allow event to be processed - await delayUntil(10000, () => roleChanges.get(bot.id)?.includes(role.id)); - - assertEquals(roleChanges.get(bot.id)?.includes(role.id), true); - - await bot.helpers.removeRole(guildId, bot.id, role.id, options.reason); - - // Delay the execution to allow event to be processed - await delayUntil(10000, () => !roleChanges.get(bot.id)?.includes(role.id)); - - assertEquals(roleChanges.get(bot.id)?.includes(role.id), false); + } diff --git a/tests/invite/createInvite.ts b/tests/invite/createInvite.ts new file mode 100644 index 000000000..1b4e6770f --- /dev/null +++ b/tests/invite/createInvite.ts @@ -0,0 +1,17 @@ +import { assertExists } from "../deps.ts"; +import { bot, channel } from "../mod.ts"; + +Deno.test({ + name: "[invite] create an invite", + async fn(t) { + const invite = await bot.helpers.createInvite(channel.id, { + maxAge: 86400, + maxUses: 0, + temporary: false, + unique: false, + }); + + // Assertions + assertExists(invite); + }, +}); diff --git a/tests/invite/deleteInvite.ts b/tests/invite/deleteInvite.ts new file mode 100644 index 000000000..55e2ae7ab --- /dev/null +++ b/tests/invite/deleteInvite.ts @@ -0,0 +1,22 @@ +import { assertExists } from "../deps.ts"; +import { bot, channel } from "../mod.ts"; + +Deno.test({ + name: "[invite] delete an invite", + async fn(t) { + const invite = await bot.helpers.createInvite(channel.id, { + maxAge: 86400, + maxUses: 0, + temporary: false, + unique: false, + }); + + // Assertions + assertExists(invite); + + const deletedInvite = await bot.helpers.deleteInvite(invite.code); + + // Assertions + assertExists(deletedInvite); + }, +}); diff --git a/tests/invite/getChannelInvites.ts b/tests/invite/getChannelInvites.ts new file mode 100644 index 000000000..a1d61094d --- /dev/null +++ b/tests/invite/getChannelInvites.ts @@ -0,0 +1,31 @@ +import { assertEquals, assertExists } from "../deps.ts"; +import { bot, channel } from "../mod.ts"; + +Deno.test({ + name: "[invite] get channels invites", + async fn(t) { + const invite = await bot.helpers.createInvite(channel.id, { + maxAge: 86400, + maxUses: 0, + temporary: false, + unique: true, + }); + + // Assertions + assertExists(invite); + + const secondInvite = await bot.helpers.createInvite(channel.id, { + maxAge: 0, + maxUses: 2, + temporary: true, + unique: true, + }); + + // Assertions + assertExists(secondInvite); + + const invites = await bot.helpers.getChannelInvites(channel.id); + + assertEquals(invites.size > 1, true); + }, +}); diff --git a/tests/invite/getInvite.ts b/tests/invite/getInvite.ts new file mode 100644 index 000000000..90cc2db7b --- /dev/null +++ b/tests/invite/getInvite.ts @@ -0,0 +1,32 @@ +import { assertExists, assertEquals, assertNotEquals } from "../deps.ts"; +import { bot, channel, guild } from "../mod.ts"; + +Deno.test({ + name: "[invite] get invite", + async fn(t) { + const invite = await bot.helpers.createInvite(channel.id, { + maxAge: 86400, + maxUses: 0, + temporary: false, + unique: false, + }); + + // Assertions + assertExists(invite); + + const fetchedInvite = await bot.helpers.getInvite(invite.code); + + assertExists(fetchedInvite); + assertEquals(fetchedInvite.code, invite.code); + + await t.step({ + name: "[invite] get invites", + async fn() { + const fetchedInvites = await bot.helpers.getInvites(guild.id); + + assertExists(fetchedInvites); + assertNotEquals(fetchedInvites.size, 0); + }, + }); + }, +}); diff --git a/tests/invite/getInvites.ts b/tests/invite/getInvites.ts new file mode 100644 index 000000000..23cea3665 --- /dev/null +++ b/tests/invite/getInvites.ts @@ -0,0 +1,22 @@ +import { assertExists, assertNotEquals } from "../deps.ts"; +import { bot, channel, guild } from "../mod.ts"; + +Deno.test({ + name: "[invite] get invites", + async fn(t) { + const invite = await bot.helpers.createInvite(channel.id, { + maxAge: 86400, + maxUses: 0, + temporary: false, + unique: false, + }); + + // Assertions + assertExists(invite); + + const fetchedInvites = await bot.helpers.getInvites(guild.id); + + assertExists(fetchedInvites); + assertNotEquals(fetchedInvites.size, 0); + }, +}); diff --git a/tests/members/avatarlUrl.ts b/tests/members/avatarlUrl.ts new file mode 100644 index 000000000..37b75690c --- /dev/null +++ b/tests/members/avatarlUrl.ts @@ -0,0 +1,14 @@ +import { assertEquals } from "../deps.ts"; +import { bot } from "../mod.ts"; + +Deno.test({ + name: "[member] format a members avatar url", + fn: async (t) => { + assertEquals( + bot.helpers.avatarURL(130136895395987456n, 8840, { + avatar: 4055337350987360625717955448021200177333n, + }), + "https://cdn.discordapp.com/avatars/130136895395987456/eae5905ad2d18d7c8deca20478b088b5.jpg?size=128" + ); + }, + }); \ No newline at end of file diff --git a/tests/members/ban.ts b/tests/members/ban.ts new file mode 100644 index 000000000..59deb143d --- /dev/null +++ b/tests/members/ban.ts @@ -0,0 +1,93 @@ +import { banCounters } from "../constants.ts"; +import { assertExists, assertEquals } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +// THIS IS WOLF, IF ANYTHING BREAKS BLAME HIM! +const wolfID = 270273690074087427n; +// THIS IS IAN, HE PLAY'S GOLDEN SUN. BAN BEFORE HE MAKES US ADDICTED TO IT!!! +const ianID = 90339695967350784n; + +// THESE BAN TESTS SHOULD BE DONE ONE BY ONE +Deno.test({ + name: "[member] ban member test group", + fn: async (t) => { + await t.step({ + name: "[member] ban user from guild without reason", + fn: async () => { + bot.events.guildBanAdd = function (_, user) { + banCounters.set(user.id, true); + }; + + await bot.helpers.banMember(guild.id, wolfID); + + await delayUntil(10000, () => banCounters.get(wolfID)); + + assertEquals(banCounters.get(wolfID), true); + }, + }); + + await t.step({ + name: "[member] get a single user's ban", + fn: async () => { + assertExists(await bot.helpers.getBan(guild.id, 270273690074087427n)); + }, + }); + + await t.step({ + name: "[member] ban member from guild with reason", + fn: async () => { + bot.events.guildBanAdd = function (_, user) { + banCounters.set(user.id, true); + }; + + await bot.helpers.banMember(guild.id, ianID, { reason: "Blame Wolf" }); + + await delayUntil(10000, () => banCounters.get(ianID)); + + assertEquals(banCounters.get(wolfID), true); + }, + }); + + await t.step({ + name: "[member] get bans on a server", + fn: async () => { + const bans = await bot.helpers.getBans(guild.id); + assertEquals(bans.size > 1, true); + }, + }); + + await t.step({ + name: "[member] fetch a single member by id", + fn: async () => { + await bot.helpers.fetchMembers(guild.id, 0, { + userIds: [bot.id], + limit: 1, + }); + + // Assertions + assertExists(bot.cache.members.get(BigInt(`${bot.id}${guild.id}`))); + }, + }); + + await t.step({ + name: "[member] unban member from guild", + fn: async () => { + bot.events.guildBanRemove = function (bot, user, guildId) { + banCounters.set(user.id, false); + }; + + await Promise.all([bot.helpers.unbanMember(guild.id, wolfID), bot.helpers.unbanMember(guild.id, ianID)]); + + await delayUntil(10000, () => !banCounters.get(wolfID) && !banCounters.get(ianID)); + + assertEquals(banCounters.get(wolfID), false); + assertEquals(banCounters.get(ianID), false); + }, + }); + }, +}); + + + + diff --git a/tests/misc/getDiscoveryCategories.ts b/tests/misc/getDiscoveryCategories.ts new file mode 100644 index 000000000..abe3b0e5c --- /dev/null +++ b/tests/misc/getDiscoveryCategories.ts @@ -0,0 +1,11 @@ +import { assertEquals } from "../deps.ts"; +import { bot } from "../mod.ts"; + +Deno.test({ + name: "[discovery] get categories from discovery", + fn: async (t) => { + const categories = await bot.helpers.getDiscoveryCategories(); + + assertEquals(categories.size > 0, true); + }, +}); diff --git a/tests/misc/getUser.ts b/tests/misc/getUser.ts new file mode 100644 index 000000000..d21030347 --- /dev/null +++ b/tests/misc/getUser.ts @@ -0,0 +1,12 @@ +import { assertExists } from "../deps.ts"; +import { bot } from "../mod.ts"; + +Deno.test({ + name: "[User] get a user and transform", + fn: async (t) => { + const user = await bot.helpers.getUser(bot.id); + assertExists(user); + + assertExists(bot.transformers.user(bot, user)); + }, +}); diff --git a/tests/misc/snowflake.ts b/tests/misc/snowflake.ts new file mode 100644 index 000000000..ed4cffee6 --- /dev/null +++ b/tests/misc/snowflake.ts @@ -0,0 +1,9 @@ +import { assertEquals } from "../deps.ts"; +import { bot } from "../mod.ts"; + +Deno.test({ + name: "[tranform] snowflake to bigint", + fn: async (t) => { + assertEquals(130136895395987456n, bot.transformers.snowflake("130136895395987456")); + }, +}); diff --git a/tests/misc/validateDiscovery.ts b/tests/misc/validateDiscovery.ts new file mode 100644 index 000000000..878614d02 --- /dev/null +++ b/tests/misc/validateDiscovery.ts @@ -0,0 +1,11 @@ +import { assertEquals } from "../deps.ts"; +import { bot } from "../mod.ts"; + +Deno.test({ + name: "[discovery] Validate a discovery search term", + fn: async (t) => { + const valid = await bot.helpers.validDiscoveryTerm("Bots"); + + assertEquals(valid, true); + }, +}); diff --git a/tests/mod.ts b/tests/mod.ts index 6f12bb7d6..fcb13bf00 100644 --- a/tests/mod.ts +++ b/tests/mod.ts @@ -1,5 +1,4 @@ -// import { UNITTEST_TOKEN } from "../configs.ts"; -import { memoryBenchmarks } from "../benchmarks/index.ts"; +import { UNITTEST_TOKEN } from "../configs.ts"; import { createBot, createEventHandlers, ChannelTypes, OverwriteTypes, setupBot, startBot } from "../mod.ts"; import { assertEquals, assertExists, enableCachePlugin } from "./deps.ts"; import { deleteMessageWithReasonTest, deleteMessageWithoutReasonTest } from "./helpers/messages/deleteMessage.ts"; @@ -17,7 +16,6 @@ import "./local.ts"; import { getMessageTest } from "./helpers/messages/getMessage.ts"; import { addReactionTest } from "./helpers/messages/reactions.ts"; import { editMessageTest } from "./helpers/messages/editMessage.ts"; -import { fetchSingleMemberTest } from "./helpers/members/fetchMembers.ts"; import { pinMessageTests } from "./helpers/messages/pin.ts"; import { removeAllReactionTests, removeReactionEmojiTest, removeReactionTest } from "./helpers/messages/reactions.ts"; import { createInviteTest } from "./helpers/invites/createInvite.ts"; @@ -27,18 +25,6 @@ import { getInviteTest } from "./helpers/invites/getInvite.ts"; import { getInvitesTest } from "./helpers/invites/getInvites.ts"; import { createChannelTests } from "./helpers/channels/createChannel.ts"; import { deleteChannelTests } from "./helpers/channels/deleteChannel.ts"; -import { createEmojiTest } from "./helpers/emojis/createEmoji.ts"; -import { deleteEmojiWithoutReasonTest, deleteEmojiWithReasonTest } from "./helpers/emojis/deleteEmoji.ts"; -import { editEmojiTest } from "./helpers/emojis/editEmoji.ts"; -import { getEmojiTest } from "./helpers/emojis/getEmoji.ts"; -import { getEmojisTest } from "./helpers/emojis/getEmojis.ts"; -import { getBansTest, unbanTest, banTest } from "./helpers/members/ban.ts"; -import { createRoleTests } from "./helpers/roles/createRole.ts"; -import { deleteRoleTests } from "./helpers/roles/deleteRole.ts"; -import { getRolesTest } from "./helpers/roles/getRoles.ts"; -import { editRoleTests } from "./helpers/roles/editRole.ts"; -import { addRoleTest, removeRoleTest } from "./helpers/roles/roleChanges.ts"; -import { getUserTests } from "./helpers/misc/user.ts"; import { createGuildTests } from "./helpers/guilds/createGuild.ts"; import { deleteGuildTests } from "./helpers/guilds/deleteGuild.ts"; import { editGuildTests } from "./helpers/guilds/editGuild.ts"; @@ -48,33 +34,20 @@ import { getBanTests } from "./helpers/guilds/getBan.ts"; import { getBansTests } from "./helpers/guilds/getBans.ts"; import { getGuildTests } from "./helpers/guilds/getGuild.ts"; import { getVanityURLTests } from "./helpers/guilds/getVanityUrl.ts"; -import { getDiscoveryCategoriesTest, validDiscoveryTermTest } from "./helpers/misc/discoveries.ts"; import { categoryChildrenTest } from "./helpers/channels/categoryChannels.ts"; import { channelOverwriteHasPermissionTest } from "./helpers/channels/channelOverwriteHasPermission.ts"; import { cloneChannelTests } from "./helpers/channels/cloneChannel.ts"; import { deleteChannelOverwriteTests } from "./helpers/channels/deleteChannelOverwrite.ts"; import { editChannelTests } from "./helpers/channels/editChannel.ts"; -import { createScheduledEventTests } from "./helpers/guilds/scheduledEvents/createScheduledEvent.ts"; -import { ScheduledEventEntityType, ScheduledEventPrivacyLevel } from "../src/types/guilds/scheduledEvents.ts"; -import { GuildFeatures } from "../src/types/guilds/guildFeatures.ts"; -import { editScheduledEventTests } from "./helpers/guilds/scheduledEvents/editScheduledEvent.ts"; -import { deleteScheduledEventTests } from "./helpers/guilds/scheduledEvents/deleteScheduledEvent.ts"; -import { CACHED_COMMUNITY_GUILD_ID } from "./constants.ts"; +import { CACHED_COMMUNITY_GUILD_ID, sanitizeMode } from "./constants.ts"; -// CHANGE TO TRUE WHEN DEBUGGING SANITIZATION ERRORS -const sanitizeMode = { - sanitizeResources: false, - sanitizeOps: false, - sanitizeExit: false, -}; - -// const botId = BigInt(atob(UNITTEST_TOKEN.split(".")[0])); -const botId = BigInt(atob(Deno.env.get("DISCORD_TOKEN")!.split(".")[0])); +const botId = BigInt(atob(UNITTEST_TOKEN.split(".")[0])); +// const botId = BigInt(atob(Deno.env.get("DISCORD_TOKEN")!.split(".")[0])); let startedAt = 0; -const bot = createBot({ - // token: UNITTEST_TOKEN || Deno.env.get("DISCORD_TOKEN"), - token: Deno.env.get("DISCORD_TOKEN")!, +export const bot = createBot({ + token: UNITTEST_TOKEN || Deno.env.get("DISCORD_TOKEN"), + // token: Deno.env.get("DISCORD_TOKEN")!, botId, events: createEventHandlers({ ready: () => { @@ -117,7 +90,7 @@ if (bot.cache.guilds.size() <= 10) { await delayUntil(10000, () => Boolean(startedAt)); // CREATE ONE GUILD SO WE CAN REUSE LATER TO SAVE RATE LIMITS -const guild = await bot.helpers.createGuild({ name: "Discordeno Test" }); +export const guild = await bot.helpers.createGuild({ name: "Discordeno Test" }); // Assertions assertExists(guild); @@ -131,142 +104,15 @@ if (!bot.cache.guilds.has(guild.id)) { throw new Error(`The guild seemed to be created but it was not cached. ${guild.id.toString()}`); } -const channel = await bot.helpers.createChannel(guild.id, { name: "Discordeno-test" }); +export const channel = await bot.helpers.createChannel(guild.id, { name: "Discordeno-test" }); // Assertions assertExists(channel); assertEquals(channel.type, ChannelTypes.GuildText); -const message = await bot.helpers.sendMessage(channel.id, "Hello Skillz"); +export const message = await bot.helpers.sendMessage(channel.id, "Hello Skillz"); -Deno.test({ - name: "[scheduled event] create a guild scheduled event with stage entity", - fn: async (t) => { - await createScheduledEventTests( - bot, - CACHED_COMMUNITY_GUILD_ID, - { - name: "lfg", - description: "itoh is an imposter", - scheduledStartTime: Date.now() + 600000, - privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, - entityType: ScheduledEventEntityType.StageInstance, - }, - t - ); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[scheduled event] create a guild scheduled event with stage entity with an end time.", - fn: async (t) => { - await createScheduledEventTests( - bot, - CACHED_COMMUNITY_GUILD_ID, - { - name: "lfg", - description: "itoh is an imposter", - scheduledStartTime: Date.now() + 600000, - scheduledEndTime: Date.now() + (600000 + 1), - privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, - entityType: ScheduledEventEntityType.StageInstance, - }, - t - ); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[scheduled event] create a guild scheduled event with voice entity", - fn: async (t) => { - await createScheduledEventTests( - bot, - guild.id, - { - name: "lfg", - description: "itoh is an imposter", - scheduledStartTime: Date.now() + 600000, - privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, - entityType: ScheduledEventEntityType.Voice, - }, - t - ); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[scheduled event] create a guild scheduled event with voice entity with an end time.", - fn: async (t) => { - await createScheduledEventTests( - bot, - guild.id, - { - name: "lfg", - description: "itoh is an imposter", - scheduledStartTime: Date.now() + 600000, - scheduledEndTime: Date.now() + (600000 + 1), - privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, - entityType: ScheduledEventEntityType.Voice, - }, - t - ); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[scheduled event] create a guild scheduled event with external entity", - fn: async (t) => { - await createScheduledEventTests( - bot, - guild.id, - { - name: "lfg", - description: "itoh is an imposter", - scheduledStartTime: Date.now() + 600000, - scheduledEndTime: Date.now() + 1200000, - privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, - entityType: ScheduledEventEntityType.External, - location: "heaven", - }, - t - ); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[scheduled event] create a guild scheduled event with external entity with an end time.", - fn: async (t) => { - await createScheduledEventTests( - bot, - guild.id, - { - name: "lfg", - description: "itoh is an imposter", - scheduledStartTime: Date.now() + 600000, - scheduledEndTime: Date.now() + (600000 + 1), - privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, - entityType: ScheduledEventEntityType.External, - location: "heaven", - }, - t - ); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[scheduled event] edit a scheduled event", - fn: async (t) => { - await editScheduledEventTests(bot, CACHED_COMMUNITY_GUILD_ID, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[scheduled event] delete a scheduled event", - fn: async (t) => { - await deleteScheduledEventTests(bot, guild.id, t); - }, - ...sanitizeMode, -}); +import "./benchmark.ts"; Deno.test({ name: "[guild] format a guild's icon url", @@ -722,242 +568,39 @@ Deno.test({ ...sanitizeMode, }); -Deno.test({ - name: "[invite] create an invite", - async fn(t) { - await createInviteTest(bot, channel.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[invite] delete an invite", - async fn(t) { - await deleteInviteTest(bot, channel.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[invite] get channels invites", - async fn(t) { - await getChannelInvitesTest(bot, channel.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[invite] get invite", - async fn(t) { - await getInviteTest(bot, channel.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[invite] get invites", - async fn(t) { - await getInvitesTest(bot, channel.id, guild.id, t); - }, - ...sanitizeMode, -}); - -// THESE BAN TESTS SHOULD BE DONE ONE BY ONE -Deno.test({ - name: "[member] ban user from guild without reason", - fn: async (t) => { - // THIS IS WOLF, IF ANYTHING BREAKS BLAME HIM! - await banTest(bot, t, guild.id, 270273690074087427n, { reason: "Blame Wolf" }); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[member] get a single user's ban", - fn: async (t) => { - assertExists(await bot.helpers.getBan(guild.id, 270273690074087427n)); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[member] ban member from guild without reason", - fn: async (t) => { - // THIS IS IAN, HE PLAY'S GOLDEN SUN. BAN BEFORE HE MAKES US ADDICTED TO IT!!! - await banTest(bot, t, guild.id, 90339695967350784n); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[member] get bans on a server", - fn: async (t) => { - await getBansTest(bot, t, guild.id); - }, - ...sanitizeMode, -}); - -Deno.test({ - name: "[member] fetch a single member by id", - fn: async (t) => { - await fetchSingleMemberTest(bot, guild.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[member] format a members avatar url", - fn: async (t) => { - assertEquals( - bot.helpers.avatarURL(130136895395987456n, 8840, { - avatar: 4055337350987360625717955448021200177333n, - }), - "https://cdn.discordapp.com/avatars/130136895395987456/eae5905ad2d18d7c8deca20478b088b5.jpg?size=128" - ); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[member] unban member from guild", - fn: async (t) => { - await Promise.all([ - unbanTest(bot, t, guild.id, 270273690074087427n), - unbanTest(bot, t, guild.id, 90339695967350784n), - ]); - }, - ...sanitizeMode, -}); - -Deno.test({ - name: "[emoji] create an emoji", - fn: async (t) => { - await createEmojiTest(bot, guild.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[emoji] delete an emoji without a reason", - fn: async (t) => { - await deleteEmojiWithoutReasonTest(bot, guild.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[emoji] delete an emoji with a reason", - fn: async (t) => { - await deleteEmojiWithReasonTest(bot, guild.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[emoji] edit an emoji", - fn: async (t) => { - await editEmojiTest(bot, guild.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[emoji] get an emoji", - fn: async (t) => { - await getEmojiTest(bot, guild.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[emoji] get multiple emojis", - fn: async (t) => { - await getEmojisTest(bot, guild.id, t); - }, - ...sanitizeMode, -}); - -Deno.test({ - name: "[Role] get all roles on a server", - fn: async (t) => { - await getRolesTest(bot, guild.id, t); - }, - ...sanitizeMode, -}); - -Deno.test({ - name: "[Role] create a role without a reason", - fn: async (t) => { - await createRoleTests(bot, guild.id, {}, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[Role] create a role with a reason", - fn: async (t) => { - await createRoleTests(bot, guild.id, { reason: "Blame wolfy" }, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[Role] delete a role without a reason", - fn: async (t) => { - await deleteRoleTests(bot, guild.id, {}, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[Role] delete a role with a reason", - fn: async (t) => { - await deleteRoleTests(bot, guild.id, { reason: "Blame wolfy" }, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[Role] edit a role", - fn: async (t) => { - await editRoleTests(bot, guild.id, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[Role] add a role to a member", - fn: async (t) => { - await addRoleTest(bot, guild.id, { reason: "Blame wolf" }, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[Role] remove a role to a member", - fn: async (t) => { - await removeRoleTest(bot, guild.id, { reason: "Blame wolf" }, t); - }, - ...sanitizeMode, -}); - -Deno.test({ - name: "[User] get a user and transform", - fn: async (t) => { - await getUserTests(bot, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[tranform] snowflake to bigint", - fn: async (t) => { - assertEquals(130136895395987456n, bot.transformers.snowflake("130136895395987456")); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[discovery] Validate a discovery search term", - fn: async (t) => { - await validDiscoveryTermTest(bot, t); - }, - ...sanitizeMode, -}); -Deno.test({ - name: "[discovery] get categories from discovery", - fn: async (t) => { - await getDiscoveryCategoriesTest(bot, t); - }, - ...sanitizeMode, -}); - -Deno.test({ - name: "[Memory] Benchmark memory tests", - fn: async (t) => { - await memoryBenchmarks(bot, true); - }, - ...sanitizeMode, -}); - +import "./emoji/createEmoji.ts"; +import "./emoji/deleteEmojiWithReason.ts"; +import "./emoji/deleteEmojiWithoutReason.ts"; +import "./emoji/editEmoji.ts"; +import "./emoji/getEmoji.ts"; +import "./emoji/getMultipleEmojis.ts"; +import "./invite/createInvite.ts"; +import "./invite/deleteInvite.ts"; +import "./invite/getChannelInvites.ts"; +import "./invite/getInvite.ts"; +import "./invite/getInvites.ts"; +import "./members/avatarlUrl.ts"; +import "./members/ban.ts"; +import "./misc/getDiscoveryCategories.ts"; +import "./misc/getUser.ts"; +import "./misc/snowflake.ts"; +import "./misc/validateDiscovery.ts"; +import "./role/addRole.ts"; +import "./role/createRoleWithoutReason.ts"; +import "./role/createRoleWithReason.ts"; +import "./role/deleteRoleWithoutReason.ts"; +import "./role/deleteRoleWithReason.ts"; +import "./role/editRole.ts"; +import "./role/getAllRoles.ts"; +import "./role/removeRole.ts"; +import "./scheduledEvents/createExternalEventWithEndtime.ts"; +import "./scheduledEvents/createExternalEventWithoutEndtime.ts"; +import "./scheduledEvents/createStageEventWithEndtime.ts"; +import "./scheduledEvents/createStageEventWithoutEndtime.ts"; +import "./scheduledEvents/createVoiceEventWithEndtime.ts"; +import "./scheduledEvents/createVoiceEventWithoutEndtime.ts"; +import "./scheduledEvents/deleteEvent.ts"; +import "./scheduledEvents/editEvent.ts"; // await bot.helpers.deleteGuild(guild.id); // await stopBot(bot); diff --git a/tests/role/addRole.ts b/tests/role/addRole.ts new file mode 100644 index 000000000..678aae02a --- /dev/null +++ b/tests/role/addRole.ts @@ -0,0 +1,32 @@ +import { roleChanges } from "../constants.ts"; +import { assertExists, assertEquals } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + + +Deno.test({ + name: "[Role] add a role to a member", + fn: async (t) => { + const role = await bot.helpers.createRole(guild.id, { + name: "hoti", + }); + + assertExists(role); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + assertExists(bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + bot.events.guildMemberUpdate = function (bot, member, user) { + roleChanges.set(user.id, member.roles); + }; + + await bot.helpers.addRole(guild.id, bot.id, role.id, "Blame wolf"); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => roleChanges.get(bot.id)?.includes(role.id)); + + assertEquals(roleChanges.get(bot.id)?.includes(role.id), true); + }, +}); diff --git a/tests/role/createRoleWithReason.ts b/tests/role/createRoleWithReason.ts new file mode 100644 index 000000000..0f6ffee79 --- /dev/null +++ b/tests/role/createRoleWithReason.ts @@ -0,0 +1,20 @@ +import { assertExists } from "../deps.ts"; +import { createRoleTests } from "../helpers/roles/createRole.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[Role] create a role with a reason", + fn: async (t) => { + await createRoleTests(bot, guild.id, { reason: "Blame wolfy" }, t); + + const role = await bot.helpers.createRole(guild.id, { name: "hoti" }, "Blame wolfy"); + + assertExists(role); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + assertExists(bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + }, +}); diff --git a/tests/role/createRoleWithoutReason.ts b/tests/role/createRoleWithoutReason.ts new file mode 100644 index 000000000..5ea9b7483 --- /dev/null +++ b/tests/role/createRoleWithoutReason.ts @@ -0,0 +1,20 @@ +import { assertExists } from "../deps.ts"; +import { createRoleTests } from "../helpers/roles/createRole.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[Role] create a role without a reason", + fn: async (t) => { + await createRoleTests(bot, guild.id, {}, t); + + const role = await bot.helpers.createRole(guild.id, { name: "hoti" }); + + assertExists(role); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + assertExists(bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + }, +}); diff --git a/tests/role/deleteRoleWithReason.ts b/tests/role/deleteRoleWithReason.ts new file mode 100644 index 000000000..b61c56590 --- /dev/null +++ b/tests/role/deleteRoleWithReason.ts @@ -0,0 +1,26 @@ +import { assertExists } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[Role] delete a role with a reason", + fn: async (t) => { + const role = await bot.helpers.createRole(guild.id, { name: "hoti" }, "Blame wolfy"); + + assertExists(role); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + assertExists(bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + await bot.helpers.deleteRole(guild.id, role.id); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => !bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + if (bot.cache.guilds.get(guild.id)?.roles.has(role.id)) { + throw new Error(`The role should have been deleted but it is still in cache.`); + } + }, +}); diff --git a/tests/role/deleteRoleWithoutReason.ts b/tests/role/deleteRoleWithoutReason.ts new file mode 100644 index 000000000..82017215a --- /dev/null +++ b/tests/role/deleteRoleWithoutReason.ts @@ -0,0 +1,26 @@ +import { assertExists } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[Role] delete a role without a reason", + fn: async (t) => { + const role = await bot.helpers.createRole(guild.id, { name: "hoti" }); + + assertExists(role); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + assertExists(bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + await bot.helpers.deleteRole(guild.id, role.id); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => !bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + if (bot.cache.guilds.get(guild.id)?.roles.has(role.id)) { + throw new Error(`The role should have been deleted but it is still in cache.`); + } + }, +}); diff --git a/tests/role/editRole.ts b/tests/role/editRole.ts new file mode 100644 index 000000000..a4aa83455 --- /dev/null +++ b/tests/role/editRole.ts @@ -0,0 +1,30 @@ +import { assertExists,assertEquals } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[Role] edit a role", + fn: async () => { + const role = await bot.helpers.createRole(guild.id, { + name: "hoti", + }); + + assertExists(role); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + if (!bot.cache.guilds.get(guild.id)?.roles.has(role.id)) { + throw new Error(`The role seemed to be created but it was not cached.`); + } + + await bot.helpers.editRole(guild.id, role.id, { + name: "#rememberAyntee", + }); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => bot.cache.guilds.get(guild.id)?.roles.get(role.id)?.name === "#rememberAyntee"); + + assertEquals(bot.cache.guilds.get(guild.id)?.roles.get(role.id)?.name === "#rememberAyntee", true); + }, +}); diff --git a/tests/role/getAllRoles.ts b/tests/role/getAllRoles.ts new file mode 100644 index 000000000..876a2bc42 --- /dev/null +++ b/tests/role/getAllRoles.ts @@ -0,0 +1,11 @@ +import { assertEquals } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; + +Deno.test({ + name: "[Role] get all roles on a server", + fn: async (t) => { + const roles = await bot.helpers.getRoles(guild.id); + + assertEquals(bot.cache.guilds.get(guild.id)?.roles.size, roles.size); + }, +}); diff --git a/tests/role/removeRole.ts b/tests/role/removeRole.ts new file mode 100644 index 000000000..f2f38073a --- /dev/null +++ b/tests/role/removeRole.ts @@ -0,0 +1,38 @@ +import { roleChanges } from "../constants.ts"; +import { assertExists, assertEquals } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; +import { delayUntil } from "../utils.ts"; + +Deno.test({ + name: "[Role] remove a role to a member", + fn: async (t) => { + const role = await bot.helpers.createRole(guild.id, { + name: "hoti", + }); + + assertExists(role); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + assertExists(bot.cache.guilds.get(guild.id)?.roles.has(role.id)); + + bot.events.guildMemberUpdate = function (bot, member, user) { + roleChanges.set(user.id, member.roles); + }; + + await bot.helpers.addRole(guild.id, bot.id, role.id, "Blame wolfy"); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => roleChanges.get(bot.id)?.includes(role.id)); + + assertEquals(roleChanges.get(bot.id)?.includes(role.id), true); + + await bot.helpers.removeRole(guild.id, bot.id, role.id, "Blame wolfy"); + + // Delay the execution to allow event to be processed + await delayUntil(10000, () => !roleChanges.get(bot.id)?.includes(role.id)); + + assertEquals(roleChanges.get(bot.id)?.includes(role.id), false); + }, +}); diff --git a/tests/scheduledEvents/createExternalEventWithEndtime.ts b/tests/scheduledEvents/createExternalEventWithEndtime.ts new file mode 100644 index 000000000..70d725a17 --- /dev/null +++ b/tests/scheduledEvents/createExternalEventWithEndtime.ts @@ -0,0 +1,31 @@ +import { ScheduledEventPrivacyLevel, ScheduledEventEntityType } from "../../src/types/guilds/scheduledEvents.ts"; +import { assertExists, assertEquals } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; + +Deno.test({ + name: "[scheduled event] create a guild scheduled event with external entity with an end time.", + fn: async (t) => { + const options = { + name: "lfg", + description: "itoh is an imposter", + scheduledStartTime: Date.now() + 600000, + scheduledEndTime: Date.now() + (600000 + 1), + privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, + entityType: ScheduledEventEntityType.External, + location: "heaven", + }; + + const event = await bot.helpers.createScheduledEvent(guild.id, options); + + // Assertions + assertExists(event.id); + + assertEquals(event.location, options.location); + assertEquals(event.name, options.name); + assertEquals(event.description, options.description); + assertEquals(event.scheduledStartTime, options.scheduledStartTime); + assertEquals(event.scheduledEndTime, options.scheduledEndTime); + assertEquals(event.privacyLevel, options.privacyLevel); + assertEquals(event.entityType, options.entityType); + }, +}); diff --git a/tests/scheduledEvents/createExternalEventWithoutEndtime.ts b/tests/scheduledEvents/createExternalEventWithoutEndtime.ts new file mode 100644 index 000000000..9696b1f37 --- /dev/null +++ b/tests/scheduledEvents/createExternalEventWithoutEndtime.ts @@ -0,0 +1,30 @@ +import { ScheduledEventPrivacyLevel, ScheduledEventEntityType } from "../../src/types/guilds/scheduledEvents.ts"; +import { assertExists, assertEquals } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; + +Deno.test({ + name: "[scheduled event] create a guild scheduled event with external entity", + fn: async (t) => { + const options = { + name: "lfg", + description: "itoh is an imposter", + scheduledStartTime: Date.now() + 600000, + scheduledEndTime: Date.now() + 1200000, + privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, + entityType: ScheduledEventEntityType.External, + location: "heaven", + }; + + const event = await bot.helpers.createScheduledEvent(guild.id, options); + + // Assertions + assertExists(event.id); + assertEquals(event.location, options.location); + assertEquals(event.name, options.name); + assertEquals(event.description, options.description); + assertEquals(event.scheduledStartTime, options.scheduledStartTime); + assertEquals(event.scheduledEndTime, options.scheduledEndTime); + assertEquals(event.privacyLevel, options.privacyLevel); + assertEquals(event.entityType, options.entityType); + }, +}); diff --git a/tests/scheduledEvents/createStageEventWithEndtime.ts b/tests/scheduledEvents/createStageEventWithEndtime.ts new file mode 100644 index 000000000..557a5ff0e --- /dev/null +++ b/tests/scheduledEvents/createStageEventWithEndtime.ts @@ -0,0 +1,40 @@ +import { ChannelTypes } from "../../mod.ts"; +import { ScheduledEventPrivacyLevel, ScheduledEventEntityType } from "../../src/types/guilds/scheduledEvents.ts"; +import { CACHED_COMMUNITY_GUILD_ID } from "../constants.ts"; +import { assertExists, assertEquals } from "../deps.ts"; +import { bot } from "../mod.ts"; + +Deno.test({ + name: "[scheduled event] create a guild scheduled event with stage entity with an end time.", + fn: async (t) => { + const channel = await bot.helpers.createChannel(CACHED_COMMUNITY_GUILD_ID, { + name: "entity", + type: ChannelTypes.GuildStageVoice, + }); + + const options = { + name: "lfg", + description: "itoh is an imposter", + scheduledStartTime: Date.now() + 600000, + scheduledEndTime: Date.now() + (600000 + 1), + privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, + entityType: ScheduledEventEntityType.StageInstance, + channelId: channel.id, + }; + + const event = await bot.helpers.createScheduledEvent(CACHED_COMMUNITY_GUILD_ID, options); + + await bot.helpers.deleteChannel(channel.id); + + // Assertions + assertExists(event.id); + + assertEquals(event.channelId, options.channelId); + assertEquals(event.name, options.name); + assertEquals(event.description, options.description); + assertEquals(event.scheduledStartTime, options.scheduledStartTime); + assertEquals(event.scheduledEndTime, options.scheduledEndTime); + assertEquals(event.privacyLevel, options.privacyLevel); + assertEquals(event.entityType, options.entityType); + }, +}); diff --git a/tests/scheduledEvents/createStageEventWithoutEndtime.ts b/tests/scheduledEvents/createStageEventWithoutEndtime.ts new file mode 100644 index 000000000..ec7d2171b --- /dev/null +++ b/tests/scheduledEvents/createStageEventWithoutEndtime.ts @@ -0,0 +1,38 @@ +import { ChannelTypes } from "../../mod.ts"; +import { ScheduledEventPrivacyLevel, ScheduledEventEntityType } from "../../src/types/guilds/scheduledEvents.ts"; +import { CACHED_COMMUNITY_GUILD_ID } from "../constants.ts"; +import { assertExists, assertEquals } from "../deps.ts"; +import { bot } from "../mod.ts"; + +Deno.test({ + name: "[scheduled event] create a guild scheduled event with stage entity", + fn: async () => { + const channel = await bot.helpers.createChannel(CACHED_COMMUNITY_GUILD_ID, { + name: "entity", + type: ChannelTypes.GuildStageVoice, + }); + + const options = { + name: "lfg", + description: "itoh is an imposter", + scheduledStartTime: Date.now() + 600000, + privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, + entityType: ScheduledEventEntityType.StageInstance, + channelId: channel.id, + }; + + const event = await bot.helpers.createScheduledEvent(CACHED_COMMUNITY_GUILD_ID, options); + + await bot.helpers.deleteChannel(channel.id); + + // Assertions + assertExists(event.id); + + assertEquals(event.channelId, options.channelId); + assertEquals(event.name, options.name); + assertEquals(event.description, options.description); + assertEquals(event.scheduledStartTime, options.scheduledStartTime); + assertEquals(event.privacyLevel, options.privacyLevel); + assertEquals(event.entityType, options.entityType); + }, +}); diff --git a/tests/scheduledEvents/createVoiceEventWithEndtime.ts b/tests/scheduledEvents/createVoiceEventWithEndtime.ts new file mode 100644 index 000000000..46ae28c68 --- /dev/null +++ b/tests/scheduledEvents/createVoiceEventWithEndtime.ts @@ -0,0 +1,37 @@ +import { ChannelTypes } from "../../mod.ts"; +import { ScheduledEventPrivacyLevel, ScheduledEventEntityType } from "../../src/types/guilds/scheduledEvents.ts"; +import { assertExists, assertEquals } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; + +Deno.test({ + name: "[scheduled event] create a guild scheduled event with voice entity with an end time.", + fn: async (t) => { + const channel = await bot.helpers.createChannel(guild.id, { + name: "entity", + type: ChannelTypes.GuildVoice, + }); + + const options = { + name: "lfg", + description: "itoh is an imposter", + scheduledStartTime: Date.now() + 600000, + scheduledEndTime: Date.now() + (600000 + 1), + privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, + entityType: ScheduledEventEntityType.Voice, + channelId: channel.id, + }; + + const event = await bot.helpers.createScheduledEvent(guild.id, options); + + // Assertions + assertExists(event.id); + + assertEquals(event.channelId, options.channelId); + assertEquals(event.name, options.name); + assertEquals(event.description, options.description); + assertEquals(event.scheduledStartTime, options.scheduledStartTime); + assertEquals(event.scheduledEndTime, options.scheduledEndTime); + assertEquals(event.privacyLevel, options.privacyLevel); + assertEquals(event.entityType, options.entityType); + }, +}); diff --git a/tests/scheduledEvents/createVoiceEventWithoutEndtime.ts b/tests/scheduledEvents/createVoiceEventWithoutEndtime.ts new file mode 100644 index 000000000..aced4055b --- /dev/null +++ b/tests/scheduledEvents/createVoiceEventWithoutEndtime.ts @@ -0,0 +1,35 @@ +import { ChannelTypes } from "../../mod.ts"; +import { ScheduledEventPrivacyLevel, ScheduledEventEntityType } from "../../src/types/guilds/scheduledEvents.ts"; +import { assertExists, assertEquals } from "../deps.ts"; +import { bot, guild } from "../mod.ts"; + +Deno.test({ + name: "[scheduled event] create a guild scheduled event with voice entity", + fn: async () => { + const channel = await bot.helpers.createChannel(guild.id, { + name: "entity", + type: ChannelTypes.GuildVoice, + }); + + const options = { + name: "lfg", + description: "itoh is an imposter", + scheduledStartTime: Date.now() + 600000, + privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, + entityType: ScheduledEventEntityType.Voice, + channelId: channel.id, + }; + + const event = await bot.helpers.createScheduledEvent(guild.id, options); + + // Assertions + assertExists(event.id); + + assertEquals(event.channelId, options.channelId); + assertEquals(event.name, options.name); + assertEquals(event.description, options.description); + assertEquals(event.scheduledStartTime, options.scheduledStartTime); + assertEquals(event.privacyLevel, options.privacyLevel); + assertEquals(event.entityType, options.entityType); + }, +}); diff --git a/tests/scheduledEvents/deleteEvent.ts b/tests/scheduledEvents/deleteEvent.ts new file mode 100644 index 000000000..be1af4325 --- /dev/null +++ b/tests/scheduledEvents/deleteEvent.ts @@ -0,0 +1,18 @@ +import { ScheduledEventPrivacyLevel, ScheduledEventEntityType } from "../../src/types/guilds/scheduledEvents.ts"; +import { bot, guild } from "../mod.ts"; + +Deno.test({ + name: "[scheduled event] delete a scheduled event", + fn: async (t) => { + const event = await bot.helpers.createScheduledEvent(guild.id, { + name: "lfg", + description: "itoh is an imposter", + scheduledStartTime: Date.now() + 600000, + scheduledEndTime: Date.now() + 1200000, + privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, + entityType: ScheduledEventEntityType.External, + location: "heaven", + }); + await bot.helpers.deleteScheduledEvent(guild.id, event.id); + }, +}); diff --git a/tests/scheduledEvents/editEvent.ts b/tests/scheduledEvents/editEvent.ts new file mode 100644 index 000000000..f36d4ccb9 --- /dev/null +++ b/tests/scheduledEvents/editEvent.ts @@ -0,0 +1,76 @@ +import { ChannelTypes } from "../../mod.ts"; +import { ScheduledEventPrivacyLevel, ScheduledEventEntityType } from "../../src/types/guilds/scheduledEvents.ts"; +import { CACHED_COMMUNITY_GUILD_ID } from "../constants.ts"; +import { assertEquals } from "../deps.ts"; +import { bot } from "../mod.ts"; + +Deno.test({ + name: "[scheduled event] edit a scheduled event", + fn: async (t) => { + const channel = await bot.helpers.createChannel(CACHED_COMMUNITY_GUILD_ID, { + name: "entity", + type: ChannelTypes.GuildStageVoice, + }); + const event = await bot.helpers.createScheduledEvent(CACHED_COMMUNITY_GUILD_ID, { + name: "lfg", + description: "itoh is an imposter", + scheduledStartTime: Date.now() + 600000, + privacyLevel: ScheduledEventPrivacyLevel.GuildOnly, + entityType: ScheduledEventEntityType.StageInstance, + channelId: channel.id, + }); + let edited = await bot.helpers.editScheduledEvent(CACHED_COMMUNITY_GUILD_ID, event.id, { + name: "lfg2", + }); + + assertEquals(event.name, "lfg"); + assertEquals(edited.name, "lfg2"); + assertEquals(edited.description, "itoh is an imposter"); + + edited = await bot.helpers.editScheduledEvent(CACHED_COMMUNITY_GUILD_ID, event.id, { + description: "skillz is not an imposter", + }); + assertEquals(edited.description, "skillz is not an imposter"); + + let edited2 = await bot.helpers.editScheduledEvent(CACHED_COMMUNITY_GUILD_ID, event.id, { + scheduledStartTime: edited.scheduledStartTime - 60000, + }); + assertEquals(edited.scheduledStartTime > edited2.scheduledStartTime, true); + + let edited3 = await bot.helpers.editScheduledEvent(CACHED_COMMUNITY_GUILD_ID, event.id, { + scheduledStartTime: edited.scheduledStartTime + 600000, + }); + assertEquals(edited2.scheduledStartTime < edited3.scheduledStartTime, true); + + const voice = await bot.helpers.createChannel(CACHED_COMMUNITY_GUILD_ID, { + name: "xxx", + type: ChannelTypes.GuildVoice, + }); + edited2 = await bot.helpers.editScheduledEvent(CACHED_COMMUNITY_GUILD_ID, event.id, { + entityType: ScheduledEventEntityType.Voice, + channelId: voice.id, + }); + assertEquals(edited.entityType, ScheduledEventEntityType.StageInstance); + assertEquals(edited2.entityType, ScheduledEventEntityType.Voice); + + edited2 = await bot.helpers.editScheduledEvent(CACHED_COMMUNITY_GUILD_ID, event.id, { + entityType: ScheduledEventEntityType.External, + // @ts-ignore + channelId: null, + scheduledStartTime: Date.now() + 60000, + scheduledEndTime: Date.now() + 600000, + location: "heaven", + }); + assertEquals(edited2.entityType, ScheduledEventEntityType.External); + + edited3 = await bot.helpers.editScheduledEvent(CACHED_COMMUNITY_GUILD_ID, event.id, { + entityType: ScheduledEventEntityType.Voice, + channelId: voice.id, + }); + assertEquals(edited2.entityType, ScheduledEventEntityType.External); + assertEquals(edited3.entityType, ScheduledEventEntityType.Voice); + + await bot.helpers.deleteChannel(voice.id); + await bot.helpers.deleteChannel(channel.id); + }, +});