-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
test(structures): add tests for several structures #11407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ab0ac16
9150192
0076364
796cc30
3358806
8cfd831
b490868
72e530d
4070470
d90aef7
594fd3e
fd322ea
3e2d411
ce7288f
066c274
a6e5c24
40c8eb9
a328ab4
7298cdd
0966e7a
a3b18d9
b40214a
fc71f99
84fb36b
6a6eb07
ff425f1
1b19c9c
2e9c8fc
f9f1abd
f66b194
c700ecb
e3dc077
ebb37ab
130850e
fea8e7b
822acd1
c767a89
edaa3ea
535b534
b639eb9
1eec4f0
b56b658
6746d7c
56c4c26
c825d51
7a0edd2
f6eac8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| 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.js'; | ||
|
|
||
| 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); | ||
| expect(instance.triggerType).toBe(data.trigger_type); | ||
| }); | ||
|
|
||
| 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(10); | ||
|
|
||
| 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(AutoModerationActionType.Timeout); | ||
|
|
||
| expect(patched.toJSON()).toEqual(instance.toJSON()); | ||
| }); | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
|
|
||
| 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); | ||
| }); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| 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); | ||
|
|
||
| const createdTimestamp = DiscordSnowflake.timestampFrom(data.id!); | ||
| expect(instance.createdTimestamp).toBe(createdTimestamp); | ||
| expect(instance.createdAt!.valueOf()).toBe(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).toBeFalsy(); | ||
|
|
||
| expect(patched.toJSON()).not.toEqual(data); | ||
Qjuh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| expect(patched).toBe(instance); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,65 @@ | ||||||||||||||||||
| 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); | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check if other test files also create shared instances outside test blocks that get mutated
rg -n 'const instance = new' packages/structures/__tests__/*.test.ts | head -30Repository: discordjs/discord.js Length of output: 2794 🏁 Script executed: cat -n packages/structures/__tests__/entitlement.test.tsRepository: discordjs/discord.js Length of output: 2641 🏁 Script executed: # Also check webhook.test.ts since it also has line 18 instance creation (appears top-level)
cat -n packages/structures/__tests__/webhook.test.ts | head -50Repository: discordjs/discord.js Length of output: 2110 Shared mutable instance may cause test order dependency. The Proposed fix using beforeEach for test isolation-const instance = new Entitlement(data);
+let instance: Entitlement;
+
+beforeEach(() => {
+ instance = new Entitlement(data);
+});This requires importing -import { describe, expect, test } from 'vitest';
+import { beforeEach, describe, expect, test } from 'vitest';📝 Committable suggestion
Suggested change
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| 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.consumed).toBe(data.consumed); | ||||||||||||||||||
| expect(instance.deleted).toBe(data.deleted); | ||||||||||||||||||
| expect(instance.guildId).toBeUndefined(); | ||||||||||||||||||
|
|
||||||||||||||||||
| const createdTimestamp = DiscordSnowflake.timestampFrom(instance.id!); | ||||||||||||||||||
| expect(instance.createdTimestamp).toBe(createdTimestamp); | ||||||||||||||||||
| expect(instance.createdAt!.valueOf()).toBe(createdTimestamp); | ||||||||||||||||||
|
|
||||||||||||||||||
| const startsTimestamp = Date.parse(data.starts_at!); | ||||||||||||||||||
| expect(instance.startsTimestamp).toBe(startsTimestamp); | ||||||||||||||||||
| expect(instance.startsAt!.valueOf()).toBe(startsTimestamp); | ||||||||||||||||||
|
|
||||||||||||||||||
| const endsTimestamp = Date.parse(data.ends_at!); | ||||||||||||||||||
| expect(instance.endsTimestamp).toBe(endsTimestamp); | ||||||||||||||||||
| expect(instance.endsAt!.valueOf()).toBe(endsTimestamp); | ||||||||||||||||||
| }); | ||||||||||||||||||
|
|
||||||||||||||||||
| 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).toEqual(guildId); | ||||||||||||||||||
| expect(patched.consumed).toEqual(consumed); | ||||||||||||||||||
|
|
||||||||||||||||||
| expect(patched.toJSON()).not.toEqual(data); | ||||||||||||||||||
| expect(patched).toBe(instance); | ||||||||||||||||||
| }); | ||||||||||||||||||
| }); | ||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.