mockGuildRepoForMail and mockGuildRepoOps each implemented different
subsets of the 68-method GuildRepo interface. Adding any new method
required updating both mocks. Merged into a single mockGuildRepo with
configurable struct fields for error injection and no-op defaults for
the rest.
Introduce MailService as a convenience layer between handlers/services
and MailRepo. Provides Send, SendSystem, SendGuildInvite, and
BroadcastToGuild methods that encapsulate the boolean flag combinations.
GuildService now depends on MailService instead of MailRepo directly,
simplifying its mail-sending calls from verbose SendMail(..., false, true)
to clean SendSystem(recipientID, subject, body).
Guild mail broadcast logic moved from handleMsgMhfSendMail into
MailService.BroadcastToGuild.
Leverage the new repository interfaces to test handler logic without
a database. Adds shared mock implementations (achievement, mail,
character, goocoo, guild) and 32 new handler tests covering
achievement, mail, cafe/boost, and goocoo handlers.
Port test files from v9.2.x-stable branch to increase channelserver
coverage from 13.8% to 25.6% (556 tests passing).
Adapted all files to main's struct definitions: config import alias,
Airou/CatDefinition rename, packet field mismatches, Raviente struct
differences, and maxPlayers defaults. Removed tests referencing
production code not yet on main (Player, FestivalColour, etc.).
Excluded handlers_register_test.go (Raviente completely redesigned).