This commit is contained in:
Skillz
2021-01-14 12:22:00 -05:00
10 changed files with 307 additions and 259 deletions

10
.github/workflows/check.yml vendored Normal file
View File

@@ -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

View File

@@ -1,15 +1,15 @@
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
- uses: denolib/setup-deno@v2
- 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 }}

35
tests/01_main.ts Normal file
View File

@@ -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,
});

20
tests/02_guild.ts Normal file
View File

@@ -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,
});

53
tests/03_role.ts Normal file
View File

@@ -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,
});

93
tests/04_channel.ts Normal file
View File

@@ -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,
});

31
tests/05_message.ts Normal file
View File

@@ -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");
},
});

53
tests/06_cleanup.ts Normal file
View File

@@ -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,
});

View File

@@ -1,5 +1,6 @@
export {
assert,
assertArrayIncludes,
assertEquals,
assertExists,
} from "https://deno.land/std@0.81.0/testing/asserts.ts";
export * from "../mod.ts";

View File

@@ -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";