Skip to content

Commit

Permalink
tests: resolved multiple issues
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranet committed Oct 2, 2023
1 parent 0b14991 commit 228f8bf
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 119 deletions.
17 changes: 9 additions & 8 deletions src/lib/util/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,6 @@ export function getAttachment(message: Message): ImageAttachment | null {
}

for (const embed of message.embeds) {
if (embed.type === 'image') {
return {
url: embed.thumbnail!.url,
proxyURL: embed.thumbnail!.proxyURL!,
height: embed.thumbnail!.height!,
width: embed.thumbnail!.width!
};
}
if (embed.image) {
return {
url: embed.image.url,
Expand All @@ -114,6 +106,15 @@ export function getAttachment(message: Message): ImageAttachment | null {
width: embed.image.width!
};
}

if (embed.thumbnail) {
return {
url: embed.thumbnail.url,
proxyURL: embed.thumbnail.proxyURL!,
height: embed.thumbnail.height!,
width: embed.thumbnail.width!
};
}
}

return null;
Expand Down
177 changes: 75 additions & 102 deletions tests/lib/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { Collection } from '@discordjs/collection';
import type { DeepPartial } from '@sapphire/utilities';
import { Message, MessageAttachment, MessageEmbed } from 'discord.js';
import { mockRandom, resetMockRandom } from 'jest-mock-random';
import { readFile } from 'node:fs/promises';
import { resolve } from 'node:path';

describe('Utils', () => {
describe('IMAGE_EXTENSION', () => {
Expand Down Expand Up @@ -41,7 +39,7 @@ describe('Utils', () => {
});

test('GIVEN negative rational number THEN returns level 0 (😪)', () => {
expect(utils.oneToTen(2 / 3)).toStrictEqual({ color: 5968128, emoji: '😪' });
expect(utils.oneToTen(-2 / 3)).toStrictEqual({ color: 5968128, emoji: '😪' });
});

test('GIVEN positive integer number THEN returns level 2 (😫)', () => {
Expand Down Expand Up @@ -200,117 +198,92 @@ describe('Utils', () => {
});

describe('getImage', () => {
test('GIVEN message w/ attachments w/ image w/o proxyURL attachment THEN returns url', async () => {
const filePath = resolve(__dirname, '..', 'mocks', 'image.png');
const buffer = await readFile(filePath);
const fakeAttachment = new MessageAttachment(buffer, 'image.png');
fakeAttachment.url = filePath;
fakeAttachment.height = 32;
fakeAttachment.width = 32;

const fakeMessage: DeepPartial<Message> = {
attachments: new Collection<string, MessageAttachment>([['image.png', fakeAttachment]]),
embeds: []
};

const _Query = new URLSearchParams({
ex: '651c15b6',
is: '651ac436',
hm: 'b0227f7dce067d2f83880cd01f59a5856885af9204940f8c666dd81f257796c6'
}).toString();

function createAttachment(name: 'image.png' | 'text.txt'): MessageAttachment {
const Data =
name === 'image.png'
? {
id: '1111111111111111111',
filename: 'image.png',
content_type: 'image/png',
url: `https://cdn.discordapp.com/attachments/111111111111111111/111111111111111111/image.png?${_Query}&`,
proxy_url: `https://media.discordapp.net/attachments/111111111111111111/111111111111111111/image.png?${_Query}&`,
size: 2463,
width: 32,
height: 32
}
: {
id: '1111111111111111111',
filename: 'text.txt',
content_type: 'text/plain; charset=utf-8',
url: `https://cdn.discordapp.com/attachments/111111111111111111/111111111111111111/text.txt?${_Query}&`,
proxy_url: `https://media.discordapp.net/attachments/111111111111111111/111111111111111111/text.txt?${_Query}&`,
size: 4
};
return new MessageAttachment(Data.url, Data.filename, Data);
}

function createAttachments(attachment: MessageAttachment | null) {
const collection = new Collection<string, MessageAttachment>();
if (attachment) collection.set(attachment.id, attachment);
return collection;
}

function createEmbed(name: 'image' | 'thumbnail'): MessageEmbed {
return new MessageEmbed({
[name]: {
url: `https://cdn.discordapp.com/attachments/222222222222222222/222222222222222222/image.png?${_Query}&`,
proxy_url: `https://media.discordapp.net/attachments/222222222222222222/222222222222222222/image.png?${_Query}&`,
width: 32,
height: 32
}
} as const);
}

function getImage(message: DeepPartial<Message>) {
// @ts-expect-error We're only passing partial data to not mock an entire message
expect(utils.getImage(fakeMessage)).toEqual(filePath);
});
return utils.getImage(message);
}

test('GIVEN message w/ attachments w/ image w/ proxyURL attachment THEN returns url', async () => {
const filePath = resolve(__dirname, '..', 'mocks', 'image.png');
const buffer = await readFile(filePath);
const fakeAttachment = new MessageAttachment(buffer, 'image.png');
fakeAttachment.url = filePath;
fakeAttachment.proxyURL = filePath;
fakeAttachment.height = 32;
fakeAttachment.width = 32;

const fakeMessage: DeepPartial<Message> = {
attachments: new Collection<string, MessageAttachment>([['image.png', fakeAttachment]]),
test('GIVEN message WITH image attachment THEN returns url', () => {
const attachment = createAttachment('image.png');
const message: DeepPartial<Message> = {
attachments: createAttachments(attachment),
embeds: []
};

// @ts-expect-error We're only passing partial data to not mock an entire message
expect(utils.getImage(fakeMessage)).toEqual(filePath);
});

test('GIVEN message w/ attachments w/o image attachment THEN passes through to embed checking', async () => {
const filePath = resolve(__dirname, '..', 'mocks', 'image.png');
const buffer = await readFile(filePath);
const fakeAttachment = new MessageAttachment(buffer, 'image.png');
fakeAttachment.url = 'not_an_image';
fakeAttachment.proxyURL = 'not_an_image';
fakeAttachment.height = 32;
fakeAttachment.width = 32;

const fakeMessage: DeepPartial<Message> = {
attachments: new Collection<string, MessageAttachment>([['image.png', fakeAttachment]]),
embeds: [
{
type: 'image',
thumbnail: { url: 'image.png', proxyURL: 'image.png', height: 32, width: 32 }
}
]
};

// @ts-expect-error We're only passing partial data to not mock an entire message
expect(utils.getImage(fakeMessage)).toEqual('image.png');
});

test('GIVEN message w/o attachments w/ embed type === image THEN returns embedded image url', () => {
const fakeMessage: DeepPartial<Message> = {
attachments: new Collection<string, MessageAttachment>(),
embeds: [
{
type: 'image',
thumbnail: { url: 'image.png', proxyURL: 'image.png', height: 32, width: 32 }
}
]
};
expect(getImage(message)).toEqual(attachment.proxyURL);
});

// @ts-expect-error We're only passing partial data to not mock an entire message
expect(utils.getImage(fakeMessage)).toEqual('image.png');
});

test('GIVEN message w/o attachments w/ embed w/ image THEN returns embedded image url', () => {
const fakeMessage: DeepPartial<Message> = {
attachments: new Collection<string, MessageAttachment>(),
embeds: [
{
type: 'not_image',
image: { url: 'image.png', proxyURL: 'image.png', height: 32, width: 32 }
}
]
test.each([
{ attachment: null, description: 'no' },
{ attachment: createAttachment('text.txt'), description: 'non-image' }
])('GIVEN message WITH $description attachment AND image embed THEN returns embed image url', ({ attachment }) => {
const embed = createEmbed('image');
const message: DeepPartial<Message> = {
attachments: createAttachments(attachment),
embeds: [embed]
};

// @ts-expect-error We're only passing partial data to not mock an entire message
expect(utils.getImage(fakeMessage)).toEqual('image.png');
});

test('GIVEN message w/o attachments w/ embed w/o image THEN returns null', () => {
const fakeMessage: DeepPartial<Message> = {
attachments: new Collection<string, MessageAttachment>(),
embeds: [
{
type: 'not_image',
image: undefined
}
]
};

// @ts-expect-error We're only passing partial data to not mock an entire message
expect(utils.getImage(fakeMessage)).toBeNull();
expect(getImage(message)).toEqual(embed.image!.proxyURL);
});

test('GIVEN message w/o attachments w/o embed THEN returns null', () => {
const fakeMessage: DeepPartial<Message> = {
attachments: new Collection<string, MessageAttachment>(),
embeds: []
test.each([
{ attachment: null, description: 'no' },
{ attachment: createAttachment('text.txt'), description: 'non-image' }
])('GIVEN message WITH $description attachment AND thumbnail embed THEN returns embed thumbnail url', ({ attachment }) => {
const embed = createEmbed('thumbnail');
const message: DeepPartial<Message> = {
attachments: createAttachments(attachment),
embeds: [embed]
};

// @ts-expect-error We're only passing partial data to not mock an entire message
expect(utils.getImage(fakeMessage)).toBeNull();
expect(getImage(message)).toEqual(embed.thumbnail!.proxyURL);
});
});

Expand Down
34 changes: 25 additions & 9 deletions tests/mocks/MockInstances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@ import { LanguageKeys } from '#lib/i18n/languageKeys';
import { SkyraCommand } from '#lib/structures';
import { CLIENT_OPTIONS } from '#root/config';
import { SapphireClient } from '@sapphire/framework';
import { APIChannel, APIGuild, APIGuildMember, APIRole, APIUser, ChannelType, GuildFeature, GuildNSFWLevel } from 'discord-api-types/v9';
import {
APIChannel,
APIGuild,
APIGuildMember,
APIRole,
APIUser,
ChannelType,
GuildFeature,
GuildNSFWLevel,
GuildSystemChannelFlags
} from 'discord-api-types/v9';
import { Guild, GuildMember, Role, TextChannel, User } from 'discord.js';
import { resolve } from 'node:path';

Expand All @@ -16,7 +26,7 @@ export const userData: APIUser = {
};

export function createUser(data: Partial<APIUser> = {}) {
return new User(client, { ...userData, ...data });
return Reflect.construct(User, [client, { ...userData, ...data }]) as User;
}

export const guildMemberData: APIGuildMember = {
Expand All @@ -30,7 +40,11 @@ export const guildMemberData: APIGuildMember = {
};

export function createGuildMember(data: Partial<APIGuildMember> = {}, g: Guild = guild) {
return new GuildMember(client, { ...guildMemberData, ...data, user: { ...guildMemberData.user, ...data.user! } }, g);
return Reflect.construct(GuildMember, [
client,
{ ...guildMemberData, ...data, user: { ...guildMemberData.user, ...data.user! } },
g
]) as GuildMember;
}

export const roleData: APIRole = {
Expand All @@ -45,7 +59,7 @@ export const roleData: APIRole = {
};

export function createRole(data: Partial<APIRole> = {}, g: Guild = guild) {
const role = new Role(client, { ...roleData, ...data }, g);
const role = Reflect.construct(Role, [client, { ...roleData, ...data }, g]) as Role;
g.roles.cache.set(role.id, role);
return role;
}
Expand Down Expand Up @@ -79,14 +93,16 @@ export const guildData: APIGuild = {
owner_id: '242043489611808769',
preferred_locale: 'en-US',
premium_subscription_count: 3,
premium_progress_bar_enabled: false,
premium_tier: 1,
public_updates_channel_id: '700806874294911067',
region: 'eu-central',
roles: [roleData],
rules_channel_id: '409663610780909569',
splash: null,
hub_type: null,
stickers: [],
system_channel_flags: 0,
system_channel_flags: GuildSystemChannelFlags.SuppressJoinNotifications,
system_channel_id: '254360814063058944',
vanity_url_code: null,
verification_level: 2,
Expand All @@ -95,7 +111,7 @@ export const guildData: APIGuild = {
};

export function createGuild(data: Partial<APIGuild> = {}) {
const g = new Guild(client, { ...guildData, ...data });
const g = Reflect.construct(Guild, [client, { ...guildData, ...data }]) as Guild;
client.guilds.cache.set(g.id, g);
return g;
}
Expand All @@ -117,7 +133,7 @@ export const textChannelData: APIChannel = {
};

export function createTextChannel(data: Partial<APIChannel> = {}, g: Guild = guild) {
const c = new TextChannel(guild, { ...textChannelData, ...data });
const c = Reflect.construct(TextChannel, [guild, { ...textChannelData, ...data }]) as TextChannel;
g.channels.cache.set(c.id, c);
g.client.channels.cache.set(c.id, c);
return c;
Expand Down Expand Up @@ -175,8 +191,8 @@ addCommand(
root: '/home/skyra/commands'
},
{
description: LanguageKeys.Commands.Tools.DefineDescription,
detailedDescription: LanguageKeys.Commands.Tools.DefineExtended,
description: LanguageKeys.Commands.Tools.AvatarDescription,
detailedDescription: LanguageKeys.Commands.Tools.AvatarExtended,
aliases: ['def', 'definition', 'defination', 'dictionary'],
fullCategory: ['Tools', 'Dictionary']
}
Expand Down

0 comments on commit 228f8bf

Please sign in to comment.