Cover the two most complex untested handlers in handlers_session.go:
- logoutPlayer (8 tests): basic logout, character save path, cafe course
RP accrual, stage cleanup, host disconnect with MsgSysStageDestruct,
error resilience for ReadInt/LoadSaveData failures, concurrent logout
- saveAllCharacterData (4 tests): nil save data, load error propagation,
RP capping logic, playtime accumulation
- handleMsgMhfTransitMessage (6 tests): search by charID (found/not
found), search by name, search by lobby (IP+port+stageID), party
finder with stage prefix and rank filtering, localhost IP rewrite
Move ~300 test functions from 21 catch-all files (handlers_core_test.go,
handlers_coverage*_test.go, *_coverage_test.go) into the *_test.go file
matching each handler's source file. This makes tests discoverable by
convention: tests for handlers_guild.go live in handlers_guild_test.go.
New files: handlers_guild_mission_test.go, sys_time_test.go.
No test logic changed — pure file reorganization.
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.
main.go always sets both Channels and Registry together, making the
Channels fallback paths dead code. This removes:
- Server.Channels field from the Server struct
- 3 if/else fallback blocks in handlers_session.go (replaced with
Registry.FindChannelForStage, SearchSessions, SearchStages)
- 1 if/else fallback block in handlers_guild_ops.go (replaced with
Registry.NotifyMailToCharID)
- 3 method fallbacks in sys_channel_server.go (WorldcastMHF,
FindSessionByCharID, DisconnectUser now delegate directly)
Updates anti-patterns.md #6 to "accepted design" — Session struct is
appropriate for this game server's handler pattern, and cross-channel
coupling is now fully routed through the ChannelRegistry interface.
Cover critical paths that previously had no test coverage:
- Session: login success/error paths, ping, logkey, record log,
global sema lock/unlock, rights reload, announce
- Gacha: point queries, coin deduction, item receive with overflow
and freeze, normal/stepup/box gacha play, stepup status lifecycle,
weighted random selection
- Shop: enumeration across all shop types, exchange purchases,
fpoint-to-item and item-to-fpoint exchange, fpoint exchange list
with Z2 vs ZZ encoding
- Plate: load/save for platedata, platebox, platemyset with
oversized payload rejection, diff path, and cache invalidation
Add mockSessionRepo, mockGachaRepo, mockShopRepo, and
mockUserRepoGacha to support the new test scenarios. Add
loadColumnErr field to mockCharacterRepo for diff-path error
testing.