refactor(guild): introduce service layer for guild member operations

Extract business logic from handleMsgMhfOperateGuildMember into
GuildService.OperateMember, establishing the handler→service→repo
layering pattern. The handler is now ~20 lines of protocol glue
(type-assert, map action, call service, send ACK, notify).

GuildService owns authorization checks, repo coordination, mail
composition, and best-effort mail delivery. It accepts plain Go
types (no mhfpacket or Session imports), making it fully testable
with mock repos. Cross-channel notification stays in the handler
since it requires Session.

Adds 7 table-driven service-level tests covering accept/reject/kick,
authorization, repo errors, mail errors, and unknown actions.
This commit is contained in:
Houmgaor
2026-02-23 23:26:46 +01:00
parent 48639942f6
commit 2abca9fb23
6 changed files with 313 additions and 48 deletions

View File

@@ -448,6 +448,7 @@ func TestOperateGuildMember_Accept(t *testing.T) {
guildMock.guild.LeaderCharID = 1
server.guildRepo = guildMock
server.mailRepo = mailMock
ensureGuildService(server)
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfOperateGuildMember{
@@ -486,6 +487,7 @@ func TestOperateGuildMember_Reject(t *testing.T) {
guildMock.guild.LeaderCharID = 1
server.guildRepo = guildMock
server.mailRepo = mailMock
ensureGuildService(server)
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfOperateGuildMember{
@@ -515,6 +517,7 @@ func TestOperateGuildMember_Kick(t *testing.T) {
guildMock.guild.LeaderCharID = 1
server.guildRepo = guildMock
server.mailRepo = mailMock
ensureGuildService(server)
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfOperateGuildMember{
@@ -544,6 +547,7 @@ func TestOperateGuildMember_MailError(t *testing.T) {
guildMock.guild.LeaderCharID = 1
server.guildRepo = guildMock
server.mailRepo = mailMock
ensureGuildService(server)
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfOperateGuildMember{
@@ -572,6 +576,7 @@ func TestOperateGuildMember_NotLeaderOrSub(t *testing.T) {
guildMock.guild.LeaderCharID = 999 // not the session char
server.guildRepo = guildMock
server.mailRepo = &mockMailRepo{}
ensureGuildService(server)
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfOperateGuildMember{