From 706e8f608642863fca4dab21a17f971378f683c4 Mon Sep 17 00:00:00 2001 From: Ayyan Date: Sun, 10 Jan 2021 22:44:00 +0400 Subject: [PATCH 1/3] ci(test): run workflow on label assignment (#367) * ci(test): run workflow on label assignment * ci(test): remove paths * ci(test): run workflow on label assignment --- .github/workflows/test.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cfe64b2b6..995ccb625 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,7 +1,10 @@ name: Test -on: [push, pull_request] +on: + pull_request: + types: labeled jobs: test: + if: github.event.label.name == 'run-tests' runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -9,7 +12,6 @@ jobs: - name: Cache dependencies run: deno cache mod.ts - name: Run test script - if: github.event.label.name == 'run-tests' run: deno test --allow-net --allow-env env: DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }} From 1ee7b5a1b1abeccbf9cf22959f3e6f5b3d8b23a8 Mon Sep 17 00:00:00 2001 From: Ayyan Date: Mon, 11 Jan 2021 10:57:27 +0400 Subject: [PATCH 2/3] ci: add "check" workflow (#370) * ci: add "check" workflow * ci: add check workflow * idk * ci(check): rename to "Type-check" --- .github/workflows/check.yml | 10 ++++++++++ .github/workflows/test.yml | 2 -- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/check.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 000000000..2f44654f5 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,10 @@ +name: Type-check +on: [push, pull_request] +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: denolib/setup-deno@v2 + - name: Cache dependencies + run: deno cache mod.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 995ccb625..becaeb570 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,8 +9,6 @@ jobs: steps: - uses: actions/checkout@v2 - uses: denolib/setup-deno@v2 - - name: Cache dependencies - run: deno cache mod.ts - name: Run test script run: deno test --allow-net --allow-env env: From 823b9d2cef97fcafc22388a7e439f5182a53834b Mon Sep 17 00:00:00 2001 From: Ayyan Date: Mon, 11 Jan 2021 19:09:56 +0400 Subject: [PATCH 3/3] refactor(tests): separate tests into categories (#369) * refactor(tests): seperate tests into categories * idk --- tests/01_main.ts | 35 ++++++ tests/02_guild.ts | 20 ++++ tests/03_role.ts | 53 +++++++++ tests/04_channel.ts | 93 ++++++++++++++++ tests/05_message.ts | 31 ++++++ tests/06_cleanup.ts | 53 +++++++++ tests/deps.ts | 3 +- tests/mod.test.ts | 260 +------------------------------------------- 8 files changed, 293 insertions(+), 255 deletions(-) create mode 100644 tests/01_main.ts create mode 100644 tests/02_guild.ts create mode 100644 tests/03_role.ts create mode 100644 tests/04_channel.ts create mode 100644 tests/05_message.ts create mode 100644 tests/06_cleanup.ts diff --git a/tests/01_main.ts b/tests/01_main.ts new file mode 100644 index 000000000..5e279a474 --- /dev/null +++ b/tests/01_main.ts @@ -0,0 +1,35 @@ +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 new file mode 100644 index 000000000..a0df1855c --- /dev/null +++ b/tests/02_guild.ts @@ -0,0 +1,20 @@ +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 new file mode 100644 index 000000000..5d685eb3c --- /dev/null +++ b/tests/03_role.ts @@ -0,0 +1,53 @@ +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 new file mode 100644 index 000000000..824f9e1cf --- /dev/null +++ b/tests/04_channel.ts @@ -0,0 +1,93 @@ +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 new file mode 100644 index 000000000..145e7ae87 --- /dev/null +++ b/tests/05_message.ts @@ -0,0 +1,31 @@ +import { defaultTestOptions, tempData } from "./01_main.ts"; +import { assertEquals, assertExists, getMessage, sendMessage } 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"); + }, +}); diff --git a/tests/06_cleanup.ts b/tests/06_cleanup.ts new file mode 100644 index 000000000..92d3b4b2b --- /dev/null +++ b/tests/06_cleanup.ts @@ -0,0 +1,53 @@ +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/deps.ts b/tests/deps.ts index db792fa2c..34bf09d90 100644 --- a/tests/deps.ts +++ b/tests/deps.ts @@ -1,5 +1,6 @@ export { - assert, assertArrayIncludes, assertEquals, + assertExists, } from "https://deno.land/std@0.81.0/testing/asserts.ts"; +export * from "../mod.ts"; diff --git a/tests/mod.test.ts b/tests/mod.test.ts index 2c828802c..a08f401d8 100644 --- a/tests/mod.test.ts +++ b/tests/mod.test.ts @@ -1,254 +1,6 @@ -import { - botID, - cache, - channelOverwriteHasPermission, - createGuildChannel, - createGuildRole, - createServer, - delay, - deleteChannel, - deleteRole, - deleteServer, - editChannel, - editRole, - getChannel, - getMessage, - Guild, - Intents, - OverwriteType, - Role, - sendMessage, - startBot, -} from "../mod.ts"; -import { assert, assertEquals } from "./deps.ts"; - -const token = Deno.env.get("DISCORD_TOKEN"); -if (!token) throw "Token is not provided"; - -startBot({ - token, - intents: [Intents.GUILD_MESSAGES, Intents.GUILDS], -}); - -// Default options for all test cases -const testOptions = { - sanitizeOps: false, - sanitizeResources: false, -}; - -Deno.test({ - name: "connect to the gateway", - fn: async () => { - // Delay the execution by 10 seconds (15000 ms) - await delay(10000); - - // Check whether botID is nil or not - assert(botID); - }, - ...testOptions, -}); - -const data = { - guildID: "", - roleID: "", - channelID: "", -}; - -Deno.test({ - name: "create a guild", - async fn() { - // Create a guild "Discordeno Test" - const createdGuild = (await createServer({ - name: "Discordeno Test", - })) as Guild; - - // Check whether createdGuild is nil or not - assert(createdGuild); - - data.guildID = createdGuild.id; - - // Delay the execution by 5 seconds to allow the guild create event to be received - await delay(5000); - }, - ...testOptions, -}); - -// Role - -Deno.test({ - name: "create a role in a guild", - async fn() { - // Create a role "Role 1" in the guild "Discordeno Test" - const createdRole = await createGuildRole(data.guildID, { - name: "Role 1", - }); - - // Check whether the created role is nil or not - assert(createdRole); - - data.roleID = createdRole.id; - }, - ...testOptions, -}); - -Deno.test({ - name: "edit a role in a guild", - async fn() { - // Edit a role "Role 1" in the guild "Discordeno Test" - const editedRole = (await editRole(data.guildID, data.roleID, { - name: "Edited Role", - color: 4320244, - hoist: false, - mentionable: false, - })) as Role; - - // Assertions - assert(editedRole); - assertEquals(editedRole.name, "Edited Role"); - assertEquals(editedRole.color, 4320244); - assertEquals(editedRole.hoist, false); - assertEquals(editedRole.mentionable, false); - - data.roleID = editedRole.id; - }, - ...testOptions, -}); - -// Channel - -Deno.test({ - name: "create a channel in a guild", - async fn() { - const guild = cache.guilds.get(data.guildID); - if (!guild) throw "Guild not found"; - const createdChannel = await createGuildChannel(guild, "test"); - - // Check whether the created channel is nil or not - assert(createdChannel); - - data.channelID = createdChannel.id; - }, - ...testOptions, -}); - -Deno.test({ - name: "get a channel in a guild", - async fn() { - const channel = await getChannel(data.channelID); - - assertEquals(channel.id, data.channelID); - }, - ...testOptions, -}); - -Deno.test({ - name: "edit a channel in a guild", - async fn() { - await editChannel(data.channelID, { - name: "edited-channel", - overwrites: [ - { - id: data.roleID, - type: OverwriteType.ROLE, - allow: ["VIEW_CHANNEL", "SEND_MESSAGES"], - deny: ["USE_EXTERNAL_EMOJIS"], - }, - ], - }); - // Wait 5 seconds for it to update - await delay(5000); - const editedChannel = await getChannel(data.channelID); - - assertEquals(editedChannel.name, "edited-channel"); - }, -}); - -Deno.test({ - name: "channel overwrite has permission", - fn() { - const channel = cache.channels.get(data.channelID); - if (!channel) throw "Channel not found"; - - if (!channel.permissionOverwrites) throw "Channel overwrites not found."; - - const hasPerm = channelOverwriteHasPermission( - data.guildID, - data.roleID, - channel.permissionOverwrites, - ["VIEW_CHANNEL", "SEND_MESSAGES"], - ); - const missingPerm = channelOverwriteHasPermission( - data.guildID, - data.roleID, - channel.permissionOverwrites, - ["USE_EXTERNAL_EMOJIS"], - ); - - assertEquals(hasPerm, true); - assertEquals(missingPerm, false); - }, - ...testOptions, -}); - -// Message - -let messageID: string; - -Deno.test({ - name: "create a message in a guild", - async fn() { - const createdMessage = await sendMessage(data.channelID, "test"); - - // Check whether the created message is nil or not - assert(createdMessage); - - messageID = createdMessage.id; - }, -}); - -Deno.test({ - name: "get a message in a guild", - async fn() { - const message = await getMessage(data.channelID, messageID); - - assertEquals(messageID, message.id); - }, -}); - -// Clean up - -Deno.test({ - name: "delete a role from the guild", - async fn() { - await deleteRole(data.guildID, data.roleID); - data.roleID = ""; - assertEquals(data.roleID, ""); - }, -}); - -Deno.test({ - name: "delete a channel in the guild", - async fn() { - await deleteChannel(data.guildID, data.channelID); - }, - ...testOptions, -}); - -Deno.test({ - name: "delete a guild", - async fn() { - await deleteServer(data.guildID); - data.guildID = ""; - assertEquals(data.guildID, ""); - }, - ...testOptions, -}); - -// This is meant to be the final test that forcefully crashes the bot -Deno.test({ - name: "exit the process forcefully after all the tests are done", - fn() { - Deno.exit(); - }, - ...testOptions, -}); +import "./01_main.ts"; +import "./02_guild.ts"; +import "./03_role.ts"; +import "./04_channel.ts"; +import "./05_message.ts"; +import "./06_cleanup.ts";