diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index becaeb570..62fd2cf7c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,12 +4,12 @@ on: types: labeled jobs: test: - if: github.event.label.name == 'run-tests' runs-on: ubuntu-latest + if: github.event.label.name == 'run-tests' steps: - uses: actions/checkout@v2 - uses: denolib/setup-deno@v2 - name: Run test script - run: deno test --allow-net --allow-env - env: - DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }} + run: deno test --allow-net --allow-env ./test + env: + DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }} diff --git a/tests/deps.ts b/test/deps.ts similarity index 100% rename from tests/deps.ts rename to test/deps.ts diff --git a/test/mod.test.ts b/test/mod.test.ts new file mode 100644 index 000000000..a82632bf5 --- /dev/null +++ b/test/mod.test.ts @@ -0,0 +1,344 @@ +import { + deleteChannel, + deleteRole, + deleteServer, + getChannel, +} from "../src/api/handlers/guild.ts"; +import { + addReaction, + assertEquals, + assertExists, + botID, + cache, + Channel, + channelOverwriteHasPermission, + createGuildChannel, + createGuildRole, + createServer, + delay, + deleteMessageByID, + editChannel, + editRole, + getMessage, + getPins, + Guild, + Intents, + OverwriteType, + pin, + removeReaction, + Role, + sendMessage, + startBot, + unpin, +} from "./deps.ts"; + +const token = Deno.env.get("DISCORD_TOKEN"); +if (!token) throw new Error("Token is not provided"); + +startBot({ + token, + intents: [Intents.GUILD_MESSAGES, Intents.GUILDS], +}); + +// Default options for tests +export const defaultTestOptions = { + sanitizeOps: false, + sanitizeResources: false, +}; + +// Temporary data +export const tempData = { + guildID: "", + roleID: "", + channelID: "", + messageID: "", +}; + +// Main +Deno.test({ + name: "[main] connect to gateway", + fn: async () => { + // Delay the execution by 5 seconds + await delay(5000); + + // Assertions + assertExists(botID); + }, + ...defaultTestOptions, +}); + +// Guild + +Deno.test({ + name: "[guild] create a new guild", + async fn() { + const guild = await createServer({ + name: "Discordeno Test", + }) as Guild; + + // Assertions + assertExists(guild); + + tempData.guildID = guild.id; + + // Delay the execution by 5 seconds to allow GUILD_CREATE event to be processed + await delay(5000); + }, + ...defaultTestOptions, +}); + +// Role + +Deno.test({ + name: "[role] create a role in a guild", + async fn() { + if (!tempData.guildID) { + throw new Error("guildID not present in temporary data"); + } + + const name = "Discordeno Test"; + const role = await createGuildRole(tempData.guildID, { + name, + }); + + // Assertions + assertExists(role); + assertEquals(role.name, name); + + tempData.roleID = role.id; + }, + ...defaultTestOptions, +}); + +Deno.test({ + name: "[role] edit a role in a guild", + async fn() { + const name = "Discordeno Test Edited"; + const color = 4320244; + const role = await editRole(tempData.guildID, tempData.roleID, { + name, + color, + hoist: false, + mentionable: false, + }) as Role; + + // Assertions + assertExists(role); + assertEquals(role.name, name); + assertEquals(role.color, color); + assertEquals(role.hoist, false); + assertEquals(role.mentionable, false); + + tempData.roleID = role.id; + }, + ...defaultTestOptions, +}); + +// Channel + +Deno.test({ + name: "[channel] create a channel in a guild", + async fn() { + const guild = cache.guilds.get(tempData.guildID); + if (!guild) throw new Error("Guild not found"); + + const channel = await createGuildChannel(guild, "test"); + + // Assertions + assertExists(channel); + + tempData.channelID = channel.id; + }, + ...defaultTestOptions, +}); + +Deno.test({ + name: "[channel] get a channel in a guild", + async fn() { + const channel = await getChannel(tempData.channelID); + + // Assertions + assertExists(channel); + assertEquals(channel.id, tempData.channelID); + }, + ...defaultTestOptions, +}); + +Deno.test({ + name: "[channel] edit a channel in a guild", + async fn() { + const channel = await editChannel(tempData.channelID, { + name: "discordeno-test-edited", + overwrites: [ + { + id: tempData.roleID, + type: OverwriteType.ROLE, + allow: ["VIEW_CHANNEL", "SEND_MESSAGES"], + deny: ["USE_EXTERNAL_EMOJIS"], + }, + ], + }) as Channel; + + // Wait 5s for CHANNEL_UPDATE to fire + await delay(5000); + + // Assertions + assertExists(channel); + assertEquals(channel.name, "discordeno-test-edited"); + }, +}); + +Deno.test({ + name: "[channel] channel overwrite has permission", + fn() { + const channel = cache.channels.get(tempData.channelID); + if (!channel) throw new Error("Channel not found"); + if (!channel.permissionOverwrites) { + throw new Error("permissionOverwrites not found"); + } + + const hasPerm = channelOverwriteHasPermission( + tempData.guildID, + tempData.roleID, + channel.permissionOverwrites, + ["VIEW_CHANNEL", "SEND_MESSAGES"], + ); + const missingPerm = channelOverwriteHasPermission( + tempData.guildID, + tempData.roleID, + channel.permissionOverwrites, + ["USE_EXTERNAL_EMOJIS"], + ); + + assertEquals(hasPerm, true); + assertEquals(missingPerm, false); + }, + ...defaultTestOptions, +}); + +// Message + +Deno.test({ + name: "[message] send a message in a text channel", + async fn() { + const message = await sendMessage(tempData.channelID, { + embed: { + title: "Discordeno Test", + }, + }); + + // Assertions + assertExists(message); + assertEquals(message.embeds[0].title, "Discordeno Test"); + + tempData.messageID = message.id; + }, + ...defaultTestOptions, +}); + +Deno.test({ + name: "[message] get a message in a guild", + async fn() { + const message = await getMessage(tempData.channelID, tempData.messageID); + + // Assertions + assertExists(message); + assertEquals(message.embeds[0].title, "Discordeno Test"); + }, +}); + +Deno.test({ + name: "[message] pin a message in a channel", + fn() { + pin(tempData.channelID, tempData.messageID); + }, + ...defaultTestOptions, +}); + +Deno.test({ + name: "[message] get pinned message in a channel", + async fn() { + const [msg] = await getPins(tempData.channelID); + + // Assertions + assertExists(msg); + assertEquals(msg.id, tempData.messageID); + assertEquals(msg.pinned, true); + }, + ...defaultTestOptions, +}); + +Deno.test({ + name: "[message] unpin a message", + fn() { + unpin(tempData.channelID, tempData.messageID); + }, + ...defaultTestOptions, +}); + +Deno.test({ + name: "[message] add a reaction to a message", + fn() { + // TODO: add tests for a guild emoji ― <:name:id> + + addReaction(tempData.channelID, tempData.messageID, "👍"); + }, + ...defaultTestOptions, +}); + +// TODO(ayntee): add unit tests for getReactions() + +Deno.test({ + name: "[message] remove a reaction to a message", + fn() { + removeReaction(tempData.channelID, tempData.messageID, "👍"); + }, + ...defaultTestOptions, +}); + +// Cleanup + +Deno.test({ + name: "[message] delete a message by channel ID", + fn() { + deleteMessageByID(tempData.channelID, tempData.messageID); + }, + ...defaultTestOptions, +}); + +Deno.test({ + name: "[channel] delete a channel in a guild", + fn() { + deleteChannel(tempData.guildID, tempData.channelID); + }, + ...defaultTestOptions, +}); + +Deno.test({ + name: "[role] delete a role in a guild", + fn() { + deleteRole(tempData.guildID, tempData.roleID); + }, +}); + +Deno.test({ + name: "[guild] delete a guild", + fn() { + deleteServer(tempData.guildID); + + // TODO(ayntee): remove this weird shit lol + // TODO(ayntee): check if the GUILD_DELETE event is fired + tempData.guildID = ""; + assertEquals(tempData.guildID, ""); + }, + ...defaultTestOptions, +}); + +// Forcefully exit the Deno process once all tests are done. +Deno.test({ + name: "exit the process forcefully after all the tests are done\n", + fn() { + Deno.exit(); + }, + ...defaultTestOptions, +}); diff --git a/tests/01_main.ts b/tests/01_main.ts deleted file mode 100644 index 5e279a474..000000000 --- a/tests/01_main.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { assertExists, botID, delay, Intents, startBot } from "./deps.ts"; - -const token = Deno.env.get("DISCORD_TOKEN"); -if (!token) throw new Error("Token is not provided"); - -startBot({ - token, - intents: [Intents.GUILD_MESSAGES, Intents.GUILDS], -}); - -// Default options for tests -export const defaultTestOptions = { - sanitizeOps: false, - sanitizeResources: false, -}; - -// Temporary data -export const tempData = { - guildID: "", - roleID: "", - channelID: "", - messageID: "", -}; - -Deno.test({ - name: "[main] connect to gateway", - fn: async () => { - // Delay the execution by 5 seconds - await delay(5000); - - // Assertions - assertExists(botID); - }, - ...defaultTestOptions, -}); diff --git a/tests/02_guild.ts b/tests/02_guild.ts deleted file mode 100644 index a0df1855c..000000000 --- a/tests/02_guild.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { defaultTestOptions, tempData } from "./01_main.ts"; -import { assertExists, createServer, delay, Guild } from "./deps.ts"; - -Deno.test({ - name: "[guild] create a new guild", - async fn() { - const guild = await createServer({ - name: "Discordeno Test", - }) as Guild; - - // Assertions - assertExists(guild); - - tempData.guildID = guild.id; - - // Delay the execution by 5 seconds to allow GUILD_CREATE event to be processed - await delay(5000); - }, - ...defaultTestOptions, -}); diff --git a/tests/03_role.ts b/tests/03_role.ts deleted file mode 100644 index 5d685eb3c..000000000 --- a/tests/03_role.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { defaultTestOptions, tempData } from "./01_main.ts"; -import { - assertEquals, - assertExists, - createGuildRole, - editRole, - Role, -} from "./deps.ts"; - -Deno.test({ - name: "[role] create a role in a guild", - async fn() { - if (!tempData.guildID) { - throw new Error("guildID not present in temporary data"); - } - - const name = "Discordeno Test"; - const role = await createGuildRole(tempData.guildID, { - name, - }); - - // Assertions - assertExists(role); - assertEquals(role.name, name); - - tempData.roleID = role.id; - }, - ...defaultTestOptions, -}); - -Deno.test({ - name: "[role] edit a role in a guild", - async fn() { - const name = "Discordeno Test Edited"; - const color = 4320244; - const role = await editRole(tempData.guildID, tempData.roleID, { - name, - color, - hoist: false, - mentionable: false, - }) as Role; - - // Assertions - assertExists(role); - assertEquals(role.name, name); - assertEquals(role.color, color); - assertEquals(role.hoist, false); - assertEquals(role.mentionable, false); - - tempData.roleID = role.id; - }, - ...defaultTestOptions, -}); diff --git a/tests/04_channel.ts b/tests/04_channel.ts deleted file mode 100644 index 824f9e1cf..000000000 --- a/tests/04_channel.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Channel } from "../src/api/structures/mod.ts"; -import { defaultTestOptions, tempData } from "./01_main.ts"; -import { - assertEquals, - assertExists, - cache, - channelOverwriteHasPermission, - createGuildChannel, - delay, - editChannel, - getChannel, - OverwriteType, -} from "./deps.ts"; - -Deno.test({ - name: "[channel] create a channel in a guild", - async fn() { - const guild = cache.guilds.get(tempData.guildID); - if (!guild) throw new Error("Guild not found"); - - const channel = await createGuildChannel(guild, "test"); - - // Assertions - assertExists(channel); - - tempData.channelID = channel.id; - }, - ...defaultTestOptions, -}); - -Deno.test({ - name: "[channel] get a channel in a guild", - async fn() { - const channel = await getChannel(tempData.channelID); - - // Assertions - assertExists(channel); - assertEquals(channel.id, tempData.channelID); - }, - ...defaultTestOptions, -}); - -Deno.test({ - name: "[channel] edit a channel in a guild", - async fn() { - const channel = await editChannel(tempData.channelID, { - name: "discordeno-test-edited", - overwrites: [ - { - id: tempData.roleID, - type: OverwriteType.ROLE, - allow: ["VIEW_CHANNEL", "SEND_MESSAGES"], - deny: ["USE_EXTERNAL_EMOJIS"], - }, - ], - }) as Channel; - - // Wait 5s for CHANNEL_UPDATE to fire - await delay(5000); - - // Assertions - assertExists(channel); - assertEquals(channel.name, "discordeno-test-edited"); - }, -}); - -Deno.test({ - name: "[channel] channel overwrite has permission", - fn() { - const channel = cache.channels.get(tempData.channelID); - if (!channel) throw new Error("Channel not found"); - if (!channel.permissionOverwrites) { - throw new Error("permissionOverwrites not found"); - } - - const hasPerm = channelOverwriteHasPermission( - tempData.guildID, - tempData.roleID, - channel.permissionOverwrites, - ["VIEW_CHANNEL", "SEND_MESSAGES"], - ); - const missingPerm = channelOverwriteHasPermission( - tempData.guildID, - tempData.roleID, - channel.permissionOverwrites, - ["USE_EXTERNAL_EMOJIS"], - ); - - assertEquals(hasPerm, true); - assertEquals(missingPerm, false); - }, - ...defaultTestOptions, -}); diff --git a/tests/05_message.ts b/tests/05_message.ts deleted file mode 100644 index 1657cef96..000000000 --- a/tests/05_message.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { defaultTestOptions, tempData } from "./01_main.ts"; -import { - addReaction, - assertEquals, - assertExists, - getMessage, - getPins, - pin, - removeReaction, - sendMessage, - unpin, -} from "./deps.ts"; - -Deno.test({ - name: "[message] send a message in a text channel", - async fn() { - const message = await sendMessage(tempData.channelID, { - embed: { - title: "Discordeno Test", - }, - }); - - // Assertions - assertExists(message); - assertEquals(message.embeds[0].title, "Discordeno Test"); - - tempData.messageID = message.id; - }, - ...defaultTestOptions, -}); - -Deno.test({ - name: "[message] get a message in a guild", - async fn() { - const message = await getMessage(tempData.channelID, tempData.messageID); - - // Assertions - assertExists(message); - assertEquals(message.embeds[0].title, "Discordeno Test"); - }, -}); - -Deno.test({ - name: "[message] pin a message in a channel", - fn() { - pin(tempData.channelID, tempData.messageID); - }, - ...defaultTestOptions, -}); - -Deno.test({ - name: "[message] get pinned message in a channel", - async fn() { - const [msg] = await getPins(tempData.channelID); - - // Assertions - assertExists(msg); - assertEquals(msg.id, tempData.messageID); - assertEquals(msg.pinned, true); - }, - ...defaultTestOptions, -}); - -Deno.test({ - name: "[message] unpin a message", - fn() { - unpin(tempData.channelID, tempData.messageID); - }, - ...defaultTestOptions, -}); - -Deno.test({ - name: "[message] add a reaction to a message", - fn() { - // TODO: add tests for a guild emoji ― <:name:id> - - addReaction(tempData.channelID, tempData.messageID, "👍"); - }, - ...defaultTestOptions, -}); - -// TODO(ayntee): add unit tests for getReactions() - -Deno.test({ - name: "[message] remove a reaction to a message", - fn() { - removeReaction(tempData.channelID, tempData.messageID, "👍"); - }, - ...defaultTestOptions, -}); diff --git a/tests/06_cleanup.ts b/tests/06_cleanup.ts deleted file mode 100644 index 92d3b4b2b..000000000 --- a/tests/06_cleanup.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { deleteMessageByID } from "../src/api/handlers/message.ts"; -import { defaultTestOptions, tempData } from "./01_main.ts"; -import { - assertEquals, - deleteChannel, - deleteRole, - deleteServer, -} from "./deps.ts"; - -Deno.test({ - name: "[message] delete a message by channel ID", - fn() { - deleteMessageByID(tempData.channelID, tempData.messageID); - }, - ...defaultTestOptions, -}); - -Deno.test({ - name: "[channel] delete a channel in a guild", - fn() { - deleteChannel(tempData.guildID, tempData.channelID); - }, - ...defaultTestOptions, -}); - -Deno.test({ - name: "[role] delete a role in a guild", - fn() { - deleteRole(tempData.guildID, tempData.roleID); - }, -}); - -Deno.test({ - name: "[guild] delete a guild", - fn() { - deleteServer(tempData.guildID); - - // TODO(ayntee): remove this weird shit lol - // TODO(ayntee): check if the GUILD_DELETE event is fired - tempData.guildID = ""; - assertEquals(tempData.guildID, ""); - }, - ...defaultTestOptions, -}); - -// Forcefully exit the Deno process once all tests are done. -Deno.test({ - name: "exit the process forcefully after all the tests are done\n", - fn() { - Deno.exit(); - }, - ...defaultTestOptions, -}); diff --git a/tests/mod.test.ts b/tests/mod.test.ts deleted file mode 100644 index a08f401d8..000000000 --- a/tests/mod.test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import "./01_main.ts"; -import "./02_guild.ts"; -import "./03_role.ts"; -import "./04_channel.ts"; -import "./05_message.ts"; -import "./06_cleanup.ts";