feat: add booster eligibility role and logging functionality
- Added BOOSTER_ELIGIBILITY_ROLE_ID and LOG_LEVEL to .env.example and README.md - Updated GitHub Actions workflow to include new environment variables - Enhanced configuration loading to support booster eligibility role - Implemented role checking logic in bot handlers and guild member updates - Introduced logging using Winston for better traceability of actions - Created tests for guild member update handling to ensure correct role removal - Refactored DiscordRoleRepository to simplify role position resolution
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { handleGuildMemberUpdate } from "./guildMemberUpdate";
|
||||
|
||||
class FakeService {
|
||||
removed: Array<{ guildId: string; userId: string }> = [];
|
||||
|
||||
async removeRoleForLostBoost(input: { guildId: string; userId: string }): Promise<void> {
|
||||
this.removed.push(input);
|
||||
}
|
||||
}
|
||||
|
||||
function member(hasRole: boolean) {
|
||||
return {
|
||||
id: "user",
|
||||
guild: { id: "guild" },
|
||||
roles: { cache: { has: (roleId: string) => roleId === "booster-role" && hasRole } }
|
||||
};
|
||||
}
|
||||
|
||||
describe("handleGuildMemberUpdate", () => {
|
||||
test("removes custom role when booster eligibility role is removed", async () => {
|
||||
const service = new FakeService();
|
||||
|
||||
await handleGuildMemberUpdate(member(true), member(false), service, "booster-role");
|
||||
|
||||
expect(service.removed).toEqual([{ guildId: "guild", userId: "user" }]);
|
||||
});
|
||||
|
||||
test("does nothing while booster eligibility role remains", async () => {
|
||||
const service = new FakeService();
|
||||
|
||||
await handleGuildMemberUpdate(member(true), member(true), service, "booster-role");
|
||||
|
||||
expect(service.removed).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -1,16 +1,23 @@
|
||||
import type { BoosterRoleService } from "../../services/boosterRoleService";
|
||||
|
||||
type GuildMemberLike = {
|
||||
id: string;
|
||||
premiumSince: Date | null;
|
||||
guild: { id: string };
|
||||
roles: { cache: { has(roleId: string): boolean } };
|
||||
};
|
||||
|
||||
export async function handleGuildMemberUpdate(oldMember: GuildMemberLike, newMember: GuildMemberLike, service: BoosterRoleService): Promise<void> {
|
||||
const hadBoost = Boolean(oldMember.premiumSince);
|
||||
const hasBoost = Boolean(newMember.premiumSince);
|
||||
type BoosterRoleRemovalService = {
|
||||
removeRoleForLostBoost(input: { guildId: string; userId: string }): Promise<void>;
|
||||
};
|
||||
|
||||
if (hadBoost && !hasBoost) {
|
||||
export async function handleGuildMemberUpdate(
|
||||
oldMember: GuildMemberLike,
|
||||
newMember: GuildMemberLike,
|
||||
service: BoosterRoleRemovalService,
|
||||
boosterEligibilityRoleId: string
|
||||
): Promise<void> {
|
||||
const hadBoosterRole = oldMember.roles.cache.has(boosterEligibilityRoleId);
|
||||
const hasBoosterRole = newMember.roles.cache.has(boosterEligibilityRoleId);
|
||||
|
||||
if (hadBoosterRole && !hasBoosterRole) {
|
||||
await service.removeRoleForLostBoost({ guildId: newMember.guild.id, userId: newMember.id });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user