Skip to content

Commit

Permalink
feat: 限界ポイントロールをかわえもんから自動で外すように (#234)
Browse files Browse the repository at this point in the history
* feat: Add removeRole

* feat: Remove role on updated name into 限界ポイント

* test: Add test of dropping role

* fix: Enforce test

* feat: Add reason field
And refactor into shouldBeDropped

* test: Update test
  • Loading branch information
MikuroXina authored Jun 7, 2022
1 parent a6c6e76 commit 883b364
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 11 deletions.
9 changes: 9 additions & 0 deletions src/adaptor/discord-role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,13 @@ export class DiscordRoleManager implements RoleManager {
const member = await guild.members.fetch(targetMember);
await member.roles.add(newRoleId);
}

async removeRole(
targetMember: Snowflake,
removingRoleId: Snowflake
): Promise<void> {
const guild = await this.client.guilds.fetch(this.guildId);
const member = await guild.members.fetch(targetMember);
await member.roles.remove(removingRoleId);
}
}
6 changes: 5 additions & 1 deletion src/adaptor/role-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import type { Snowflake } from '../model/id';
type AllRoleModel = NewRole;

const map: (role: Role) => AllRoleModel = (role) => ({
roleId: role.id as Snowflake
roleId: role.id as Snowflake,
name: role.name
});

export const roleProxy = (
client: Client,
runner: RoleResponseRunner<AllRoleModel>
) => {
client.on('roleCreate', (role) => runner.triggerEvent('CREATE', map(role)));
client.on('roleUpdate', (_, role) =>
runner.triggerEvent('UPDATE', map(role))
);
};
2 changes: 1 addition & 1 deletion src/runner/role.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type RoleEvent = 'CREATE';
export type RoleEvent = 'CREATE' | 'UPDATE';

export interface RoleEventResponder<R> {
on(event: RoleEvent, role: R): Promise<void>;
Expand Down
58 changes: 56 additions & 2 deletions src/service/kawaemon-has-all-roles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,74 @@ const KAWAEMON_ID = '391857452360007680' as Snowflake;
test('kawaemon get a new role', async () => {
const newRoleId = '18475613045613281703151' as Snowflake;
const addRole = jest.fn(() => Promise.resolve());
const removeRole = jest.fn(() => Promise.resolve());
const sendEmbed = jest.fn(() => Promise.resolve());
const responder = new KawaemonHasAllRoles(
KAWAEMON_ID,
{ addRole },
{ addRole, removeRole },
{ sendEmbed }
);

await responder.on('CREATE', {
roleId: newRoleId
roleId: newRoleId,
name: 'hoge'
});

expect(addRole).toHaveBeenCalledWith(KAWAEMON_ID, newRoleId);
expect(removeRole).not.toHaveBeenCalled();
expect(sendEmbed).toHaveBeenCalledWith({
title: '***Kawaemon has given a new role***',
description: `<@&18475613045613281703151>をかわえもんにもつけといたよ。`
});
});

test('kawaemon drop a new role', async () => {
const updatedRoleId = '18475613045613281703151' as Snowflake;
const addRole = jest.fn(() => Promise.resolve());
const removeRole = jest.fn(() => Promise.resolve());
const sendEmbed = jest.fn(() => Promise.resolve());
const responder = new KawaemonHasAllRoles(
KAWAEMON_ID,
{ addRole, removeRole },
{ sendEmbed }
);

await responder.on('UPDATE', {
roleId: updatedRoleId,
name: '限界ポイント8000超え'
});

expect(addRole).not.toHaveBeenCalled();
expect(removeRole).toHaveBeenCalledWith(KAWAEMON_ID, updatedRoleId);
expect(sendEmbed).toHaveBeenCalledWith({
title: '***Kawaemon has dropped a new role***',
description: `<@&18475613045613281703151>をかわえもんからはずしといたよ。`,
fields: [
{
name: '理由',
value: '限界ポイントと名のつくロールは自動で外すよ。'
}
]
});
});

test('must not drop a new role', async () => {
const updatedRoleId = '18475613045613281703151' as Snowflake;
const addRole = jest.fn(() => Promise.resolve());
const removeRole = jest.fn(() => Promise.resolve());
const sendEmbed = jest.fn(() => Promise.resolve());
const responder = new KawaemonHasAllRoles(
KAWAEMON_ID,
{ addRole, removeRole },
{ sendEmbed }
);

await responder.on('UPDATE', {
roleId: updatedRoleId,
name: 'YEAH'
});

expect(addRole).not.toHaveBeenCalled();
expect(removeRole).not.toHaveBeenCalled();
expect(sendEmbed).not.toHaveBeenCalled();
});
46 changes: 39 additions & 7 deletions src/service/kawaemon-has-all-roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import type { StandardOutput } from './output';

export interface NewRole {
roleId: Snowflake;
name: string;
}

export interface RoleManager {
addRole(targetMember: Snowflake, newRoleId: Snowflake): Promise<void>;
removeRole(targetMember: Snowflake, removingRoleId: Snowflake): Promise<void>;
}

export class KawaemonHasAllRoles implements RoleEventResponder<NewRole> {
Expand All @@ -18,13 +20,43 @@ export class KawaemonHasAllRoles implements RoleEventResponder<NewRole> {
) {}

async on(event: RoleEvent, role: NewRole): Promise<void> {
if (event !== 'CREATE') {
return;
switch (event) {
case 'CREATE':
await this.manager.addRole(this.kawaemonId, role.roleId);
await this.output.sendEmbed({
title: '***Kawaemon has given a new role***',
description: `<@&${role.roleId}>をかわえもんにもつけといたよ。`
});
return;
case 'UPDATE': {
const shouldBeDropped = this.shouldBeDropped(role.name);
if (!shouldBeDropped[0]) {
return;
}
const [, reason] = shouldBeDropped;
await this.manager.removeRole(this.kawaemonId, role.roleId);
await this.output.sendEmbed({
title: '***Kawaemon has dropped a new role***',
description: `<@&${role.roleId}>をかわえもんからはずしといたよ。`,
fields: [
{
name: '理由',
value: reason
}
]
});
return;
}
}
await this.manager.addRole(this.kawaemonId, role.roleId);
await this.output.sendEmbed({
title: '***Kawaemon has given a new role***',
description: `<@&${role.roleId}>をかわえもんにもつけといたよ。`
});
}

shouldBeDropped(
roleName: string
): [should: true, reason: string] | [should: false] {
// 限界ポイント1000超えなどはこの形式で始まる. 詳細: https://github.com/approvers/OreOreBot2/issues/155
if (roleName.startsWith('限界ポイント')) {
return [true, '限界ポイントと名のつくロールは自動で外すよ。'];
}
return [false];
}
}

0 comments on commit 883b364

Please sign in to comment.