Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions packages/structures/__tests__/automoderation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import {
type APIAutoModerationAction,
type APIAutoModerationActionMetadata,
type APIAutoModerationRule,
type APIAutoModerationRuleTriggerMetadata,
AutoModerationActionType,
AutoModerationRuleEventType,
AutoModerationRuleTriggerType,
} from 'discord-api-types/v10';
import { describe, expect, test } from 'vitest';
import {
AutoModerationAction,
AutoModerationActionMetadata,
AutoModerationRule,
AutoModerationRuleTriggerMetadata,
} from '../src/automoderation/index.js';
import { kPatch } from '../src/utils/symbols';

/**
* For tests they should check
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should've said "don't quote me on that"
when I said this 😂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I'll be sure to remove that :)

*
* correct values of all getters,
* equality of the result of toJSON to the api data used to construct the structure,
* expected return value of helper methods like url(), createdAt, flags, etc.
* maybe for nullable fields patch() working as expected
*/

const ruleTriggerMetadataData: APIAutoModerationRuleTriggerMetadata = {
mention_total_limit: 5,
};

const actionMetadataData: APIAutoModerationActionMetadata = {
channel_id: '1',
custom_message: 'go away.',
};

const actions: APIAutoModerationAction[] = [
{
type: AutoModerationActionType.BlockMessage,
metadata: actionMetadataData,
},
];

const ruleData: APIAutoModerationRule = {
id: '1',
guild_id: '2',
name: 'ruleName',
creator_id: '1',
event_type: AutoModerationRuleEventType.MessageSend,
trigger_metadata: ruleTriggerMetadataData,
trigger_type: AutoModerationRuleTriggerType.MentionSpam,
enabled: true,
actions,
exempt_channels: ['1'],
exempt_roles: [],
};

describe('AutoModerationRule structure', () => {
const instance = new AutoModerationRule(ruleData);
const data = ruleData;

test('correct value for all getters', () => {
expect(instance.id).toBe(data.id);
expect(instance.guildId).toBe(data.guild_id);
expect(instance.name).toBe(data.name);
expect(instance.creatorId).toBe(data.creator_id);
expect(instance.eventType).toBe(data.event_type);
expect(instance.enabled).toBe(data.enabled);
});

test('toJSON() correctly mirrors API data', () => {
expect(instance.toJSON()).toStrictEqual(data);
});

test('Patching the AutoModerationRule works in place', () => {
const patched = instance[kPatch]({
exempt_channels: ['2'],
exempt_roles: ['1', '2', '3'],
});

expect(patched.toJSON()).not.toEqual(data);
expect(instance.toJSON()).toEqual(patched.toJSON());
});

describe('AutoModerationRuleTriggerMetadata sub-structure', () => {
const instance = new AutoModerationRuleTriggerMetadata(ruleTriggerMetadataData);
const data = ruleTriggerMetadataData;

test('getters return correct values', () => {
expect(instance.allowList).toBe(data.allow_list);
expect(instance.keywordFilter).toBe(data.keyword_filter);
expect(instance.mentionRaidProtectionEnabled).toBe(data.mention_raid_protection_enabled);
expect(instance.mentionTotalLimit).toBe(data.mention_total_limit);
expect(instance.presets).toBe(data.presets);
expect(instance.regexPatterns).toBe(data.regex_patterns);
});

test('toJSON() returns expected API data', () => {
expect(instance.toJSON()).toStrictEqual(data);
});

test('patching the structure works in place', () => {
const patched = instance[kPatch]({
mention_total_limit: 10,
});

expect(patched.mentionTotalLimit).toBe(patched.mentionTotalLimit);

expect(patched.toJSON()).toEqual(instance.toJSON());
});
});

describe('AutoModerationAction structure', () => {
const instance = new AutoModerationAction(actions[0] as APIAutoModerationAction);
const data = actions[0];

test('correct value for all getters', () => {
expect(instance.type).toBe(data!.type);
});

test('toJSON() returns expected API data', () => {
expect(instance.toJSON()).toStrictEqual(data);
});

test('patching the structure works in place', () => {
const patched = instance[kPatch]({
type: AutoModerationActionType.Timeout,
});

expect(instance.type).toBe(patched.type);

expect(patched.toJSON()).toEqual(instance.toJSON());
});
});

describe('AutoModerationActionMetadata sub-structure', () => {
const instance = new AutoModerationActionMetadata(actionMetadataData);
const data = actionMetadataData;

test('all getters working as expected', () => {
expect(instance.channelId).toBe(data.channel_id);
expect(instance.customMessage).toBe(data.custom_message);
expect(instance.durationSeconds).toBe(data.duration_seconds);
});

test('toJSON() returns expected results', () => {
expect(instance.toJSON()).toStrictEqual(data);
});

test('patching the structure works in place', () => {
const patched = instance[kPatch]({
custom_message: 'noo come back',
duration_seconds: 100,
});

expect(patched.toJSON()).toStrictEqual(instance.toJSON());
expect(patched.customMessage).toBe(instance.customMessage);
expect(patched.durationSeconds).toBe(instance.durationSeconds);
});
});
});
55 changes: 55 additions & 0 deletions packages/structures/__tests__/emoji.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { DiscordSnowflake } from '@sapphire/snowflake';
import type { APIEmoji, APIUser } from 'discord-api-types/v10';
import { describe, expect, test } from 'vitest';
import { Emoji } from '../src/emojis/Emoji.js';
import { kPatch } from '../src/utils/symbols.js';

describe('Emoji structure', () => {
const user: APIUser = {
id: '1',
username: 'username',
discriminator: '0000',
global_name: 'djs.structures.user.global_name',
avatar: 'djs.structures.user.avatar',
};

const data: APIEmoji = {
id: '1',
name: 'name',
roles: ['1', '2', '3'],
user,
require_colons: true,
managed: true,
animated: true,
available: true,
};

const instance = new Emoji(data);

test('Emoji has all properties', () => {
expect(instance.id).toBe(data.id);
expect(instance.name).toBe(data.name);
expect(instance.requireColons).toBe(data.require_colons);
expect(instance.managed).toBe(data.managed);
expect(instance.animated).toBe(data.animated);
expect(instance.available).toBe(data.available);

expect(instance.createdTimestamp).toBe(DiscordSnowflake.timestampFrom(instance.id!));
expect(instance.createdAt).toEqual(new Date(instance.createdTimestamp!));
});

test('toJSON() is accurate', () => {
expect(instance.toJSON()).toStrictEqual(data);
});

test('Patching the Emoji works in place', () => {
const patched = instance[kPatch]({
available: false,
});

expect(patched.available).toEqual(false);

expect(patched.toJSON()).not.toEqual(data);
expect(patched).toBe(instance);
});
});
57 changes: 57 additions & 0 deletions packages/structures/__tests__/entitlement.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { DiscordSnowflake } from '@sapphire/snowflake';
import { type APIEntitlement, EntitlementType } from 'discord-api-types/v10';
import { describe, expect, test } from 'vitest';
import { Entitlement } from '../src/entitlements/Entitlement.js';
import { kPatch } from '../src/utils/symbols.js';

describe('Entitlement structure', () => {
const data: APIEntitlement = {
id: '1',
sku_id: '1',
application_id: '1',
user_id: '1',
type: EntitlementType.Purchase,
deleted: false,
starts_at: '2020-10-10T13:50:17.209000+00:00',
ends_at: '2020-10-10T15:50:17.209000+00:00',
consumed: false,
// note guild_id is missing (to test kPatch)
};

const instance = new Entitlement(data);

test('Entitlement has all properties', () => {
expect(instance.id).toBe(data.id);
expect(instance.skuId).toBe(data.sku_id);
expect(instance.applicationId).toBe(data.application_id);
expect(instance.userId).toBe(data.user_id);
expect(instance.type).toBe(data.type);
expect(instance.guildId).toBe(data.guild_id);
expect(instance.consumed).toBe(data.consumed);
Comment on lines +29 to +30
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically correct, but i'd rather be more explicit with what we're checking

Suggested change
expect(instance.guildId).toBe(data.guild_id);
expect(instance.consumed).toBe(data.consumed);
expect(instance.consumed).toBe(data.consumed);
expect(instance.guildId).toBeUndefined();


expect(instance.createdTimestamp).toBe(DiscordSnowflake.timestampFrom(instance.id!));
expect(instance.createdAt).toEqual(new Date(instance.createdTimestamp!));
});

test('toJSON() is accurate', () => {
expect(instance.toJSON()).toStrictEqual(data);
});

test('Patching the Entitlement works in place', () => {
const guildId = '111111';
const consumed = true;

const patched = instance[kPatch]({
guild_id: guildId,
consumed,
});

expect(patched.guildId).toBe(instance.guildId);

expect(patched.guildId).toEqual(guildId);
expect(patched.consumed).toEqual(consumed);

expect(patched.toJSON()).not.toEqual(data);
expect(patched).toBe(instance);
});
});