refactor(channelserver): consolidate tests into matching source test files

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.
This commit is contained in:
Houmgaor
2026-02-26 23:41:44 +01:00
parent a68d76c55f
commit d0837e779c
53 changed files with 5922 additions and 6118 deletions

View File

@@ -597,3 +597,64 @@ func TestHandleMsgMhfAddAchievement_BoundaryID32(t *testing.T) {
t.Errorf("IncrementScore called with ID %d, want 32", mock.incrementedID)
}
}
func TestHandleMsgMhfSetCaAchievementHist_Response(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfSetCaAchievementHist{
AckHandle: 44444,
}
handleMsgMhfSetCaAchievementHist(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestEmptyHandlers_AchievementGo(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
fn func()
}{
{"handleMsgMhfDisplayedAchievement", func() {
handleMsgMhfDisplayedAchievement(session, &mhfpacket.MsgMhfDisplayedAchievement{})
}},
{"handleMsgMhfGetCaAchievementHist", func() { handleMsgMhfGetCaAchievementHist(session, nil) }},
{"handleMsgMhfSetCaAchievement", func() { handleMsgMhfSetCaAchievement(session, nil) }},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.fn()
})
}
}
func TestEmptyHandlers_MiscFiles_Achievement(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgMhfPaymentAchievement panicked: %v", r)
}
}()
handleMsgMhfPaymentAchievement(session, nil)
}

View File

@@ -1,213 +0,0 @@
package channelserver
import (
"erupe-ce/common/mhfcourse"
"erupe-ce/network/mhfpacket"
"errors"
"testing"
"time"
)
// --- Cafe Duration Bonus Info tests ---
func TestHandleMsgMhfGetCafeDurationBonusInfo_Error(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{bonusesErr: errors.New("db error")}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDurationBonusInfo{AckHandle: 1}
handleMsgMhfGetCafeDurationBonusInfo(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetCafeDurationBonusInfo_WithBonuses(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{
bonuses: []CafeBonus{
{ID: 1, TimeReq: 100, ItemType: 5, ItemID: 10, Quantity: 2, Claimed: false},
{ID: 2, TimeReq: 200, ItemType: 6, ItemID: 20, Quantity: 1, Claimed: true},
},
}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDurationBonusInfo{AckHandle: 1}
handleMsgMhfGetCafeDurationBonusInfo(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
// --- Receive Cafe Duration Bonus tests ---
func TestHandleMsgMhfReceiveCafeDurationBonus_Error(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{claimableErr: errors.New("db error")}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfReceiveCafeDurationBonus{AckHandle: 1}
handleMsgMhfReceiveCafeDurationBonus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfReceiveCafeDurationBonus_WithClaimable(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{
claimable: []CafeBonus{
{ID: 1, ItemType: 5, ItemID: 10, Quantity: 2},
},
}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
// Course 30 is required for claimable items
s.courses = []mhfcourse.Course{{ID: 30}}
pkt := &mhfpacket.MsgMhfReceiveCafeDurationBonus{AckHandle: 1}
handleMsgMhfReceiveCafeDurationBonus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
// --- Post Cafe Duration Bonus Received tests ---
func TestHandleMsgMhfPostCafeDurationBonusReceived_Empty(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostCafeDurationBonusReceived{AckHandle: 1, CafeBonusID: []uint32{}}
handleMsgMhfPostCafeDurationBonusReceived(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfPostCafeDurationBonusReceived_WithBonusIDs(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{
bonusItemType: 17, // netcafe point type
bonusItemQty: 100,
}
charRepo := newMockCharacterRepo()
charRepo.ints["netcafe_points"] = 50
srv.charRepo = charRepo
s := createMockSession(100, srv)
srv.erupeConfig.GameplayOptions.MaximumNP = 99999
pkt := &mhfpacket.MsgMhfPostCafeDurationBonusReceived{AckHandle: 1, CafeBonusID: []uint32{1, 2}}
handleMsgMhfPostCafeDurationBonusReceived(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
// --- Daily Cafe Point tests ---
func TestHandleMsgMhfCheckDailyCafepoint_Eligible(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// Set daily_time far in the past so midday.After(dailyTime) is true
charRepo.times["daily_time"] = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
charRepo.ints["netcafe_points"] = 10
srv.charRepo = charRepo
srv.erupeConfig.GameplayOptions.MaximumNP = 99999
srv.erupeConfig.GameplayOptions.BonusQuestAllowance = 10
srv.erupeConfig.GameplayOptions.DailyQuestAllowance = 5
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfCheckDailyCafepoint{AckHandle: 1}
handleMsgMhfCheckDailyCafepoint(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfCheckDailyCafepoint_NotEligible(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// Set daily_time far in the future so midday.After(dailyTime) is false
charRepo.times["daily_time"] = time.Date(2099, 12, 31, 23, 59, 59, 0, time.UTC)
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfCheckDailyCafepoint{AckHandle: 1}
handleMsgMhfCheckDailyCafepoint(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
// --- Cafe Duration tests ---
func TestHandleMsgMhfGetCafeDuration(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// cafe_reset in the future so we don't trigger reset logic
charRepo.times["cafe_reset"] = time.Date(2099, 12, 31, 0, 0, 0, 0, time.UTC)
charRepo.ints["cafe_time"] = 3600
srv.charRepo = charRepo
srv.cafeRepo = &mockCafeRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDuration{AckHandle: 1}
handleMsgMhfGetCafeDuration(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}

View File

@@ -1,52 +0,0 @@
package channelserver
import (
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
"testing"
"time"
)
func TestHandleMsgMhfGetCafeDuration_ResetPath(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// cafe_reset in the past to trigger reset logic
charRepo.times["cafe_reset"] = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
charRepo.ints["cafe_time"] = 1800
srv.charRepo = charRepo
srv.cafeRepo = &mockCafeRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDuration{AckHandle: 1}
handleMsgMhfGetCafeDuration(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetCafeDuration_NoResetTime(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// No cafe_reset set → ReadTime returns error → sets new reset time
charRepo.ints["cafe_time"] = 100
srv.charRepo = charRepo
srv.cafeRepo = &mockCafeRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDuration{AckHandle: 1}
handleMsgMhfGetCafeDuration(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetCafeDuration_ZZClient(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.RealClientMode = cfg.ZZ
charRepo := newMockCharacterRepo()
charRepo.times["cafe_reset"] = time.Date(2099, 12, 31, 0, 0, 0, 0, time.UTC)
charRepo.ints["cafe_time"] = 3600
srv.charRepo = charRepo
srv.cafeRepo = &mockCafeRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDuration{AckHandle: 1}
handleMsgMhfGetCafeDuration(s, pkt)
<-s.sendPackets
}

View File

@@ -1,10 +1,12 @@
package channelserver
import (
cfg "erupe-ce/config"
"erupe-ce/common/mhfcourse"
"erupe-ce/network/mhfpacket"
"errors"
"testing"
"time"
"erupe-ce/network/mhfpacket"
)
func TestHandleMsgMhfGetBoostTime(t *testing.T) {
@@ -334,3 +336,251 @@ func TestHandleMsgMhfGetBoostRight_NoRecord(t *testing.T) {
t.Error("No response packet queued")
}
}
// --- Cafe Duration Bonus Info tests ---
func TestHandleMsgMhfGetCafeDurationBonusInfo_Error(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{bonusesErr: errors.New("db error")}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDurationBonusInfo{AckHandle: 1}
handleMsgMhfGetCafeDurationBonusInfo(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetCafeDurationBonusInfo_WithBonuses(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{
bonuses: []CafeBonus{
{ID: 1, TimeReq: 100, ItemType: 5, ItemID: 10, Quantity: 2, Claimed: false},
{ID: 2, TimeReq: 200, ItemType: 6, ItemID: 20, Quantity: 1, Claimed: true},
},
}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDurationBonusInfo{AckHandle: 1}
handleMsgMhfGetCafeDurationBonusInfo(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
// --- Receive Cafe Duration Bonus tests ---
func TestHandleMsgMhfReceiveCafeDurationBonus_Error(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{claimableErr: errors.New("db error")}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfReceiveCafeDurationBonus{AckHandle: 1}
handleMsgMhfReceiveCafeDurationBonus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfReceiveCafeDurationBonus_WithClaimable(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{
claimable: []CafeBonus{
{ID: 1, ItemType: 5, ItemID: 10, Quantity: 2},
},
}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
// Course 30 is required for claimable items
s.courses = []mhfcourse.Course{{ID: 30}}
pkt := &mhfpacket.MsgMhfReceiveCafeDurationBonus{AckHandle: 1}
handleMsgMhfReceiveCafeDurationBonus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
// --- Post Cafe Duration Bonus Received tests ---
func TestHandleMsgMhfPostCafeDurationBonusReceived_Empty(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostCafeDurationBonusReceived{AckHandle: 1, CafeBonusID: []uint32{}}
handleMsgMhfPostCafeDurationBonusReceived(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfPostCafeDurationBonusReceived_WithBonusIDs(t *testing.T) {
srv := createMockServer()
srv.cafeRepo = &mockCafeRepo{
bonusItemType: 17, // netcafe point type
bonusItemQty: 100,
}
charRepo := newMockCharacterRepo()
charRepo.ints["netcafe_points"] = 50
srv.charRepo = charRepo
s := createMockSession(100, srv)
srv.erupeConfig.GameplayOptions.MaximumNP = 99999
pkt := &mhfpacket.MsgMhfPostCafeDurationBonusReceived{AckHandle: 1, CafeBonusID: []uint32{1, 2}}
handleMsgMhfPostCafeDurationBonusReceived(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
// --- Daily Cafe Point tests ---
func TestHandleMsgMhfCheckDailyCafepoint_Eligible(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// Set daily_time far in the past so midday.After(dailyTime) is true
charRepo.times["daily_time"] = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
charRepo.ints["netcafe_points"] = 10
srv.charRepo = charRepo
srv.erupeConfig.GameplayOptions.MaximumNP = 99999
srv.erupeConfig.GameplayOptions.BonusQuestAllowance = 10
srv.erupeConfig.GameplayOptions.DailyQuestAllowance = 5
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfCheckDailyCafepoint{AckHandle: 1}
handleMsgMhfCheckDailyCafepoint(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfCheckDailyCafepoint_NotEligible(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// Set daily_time far in the future so midday.After(dailyTime) is false
charRepo.times["daily_time"] = time.Date(2099, 12, 31, 23, 59, 59, 0, time.UTC)
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfCheckDailyCafepoint{AckHandle: 1}
handleMsgMhfCheckDailyCafepoint(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
// --- Cafe Duration tests ---
func TestHandleMsgMhfGetCafeDuration(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// cafe_reset in the future so we don't trigger reset logic
charRepo.times["cafe_reset"] = time.Date(2099, 12, 31, 0, 0, 0, 0, time.UTC)
charRepo.ints["cafe_time"] = 3600
srv.charRepo = charRepo
srv.cafeRepo = &mockCafeRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDuration{AckHandle: 1}
handleMsgMhfGetCafeDuration(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetCafeDuration_ResetPath(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// cafe_reset in the past to trigger reset logic
charRepo.times["cafe_reset"] = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
charRepo.ints["cafe_time"] = 1800
srv.charRepo = charRepo
srv.cafeRepo = &mockCafeRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDuration{AckHandle: 1}
handleMsgMhfGetCafeDuration(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetCafeDuration_NoResetTime(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// No cafe_reset set -> ReadTime returns error -> sets new reset time
charRepo.ints["cafe_time"] = 100
srv.charRepo = charRepo
srv.cafeRepo = &mockCafeRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDuration{AckHandle: 1}
handleMsgMhfGetCafeDuration(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetCafeDuration_ZZClient(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.RealClientMode = cfg.ZZ
charRepo := newMockCharacterRepo()
charRepo.times["cafe_reset"] = time.Date(2099, 12, 31, 0, 0, 0, 0, time.UTC)
charRepo.ints["cafe_time"] = 3600
srv.charRepo = charRepo
srv.cafeRepo = &mockCafeRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetCafeDuration{AckHandle: 1}
handleMsgMhfGetCafeDuration(s, pkt)
<-s.sendPackets
}

View File

@@ -68,3 +68,45 @@ func TestHandleMsgMhfApplyCampaign(t *testing.T) {
t.Error("No response packet queued")
}
}
// Tests consolidated from handlers_core_test.go
func TestHandleMsgMhfEnumerateItem(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateItem{
AckHandle: 12345,
}
handleMsgMhfEnumerateItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfAcquireItem(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfAcquireItem{
AckHandle: 12345,
}
handleMsgMhfAcquireItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}

View File

@@ -120,6 +120,54 @@ func TestHandleMsgMhfCaravanRanking(t *testing.T) {
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestNonTrivialHandlers_CaravanGo(t *testing.T) {
server := createMockServer()
tests := []struct {
name string
fn func(s *Session)
}{
{"handleMsgMhfGetRyoudama", func(s *Session) {
handleMsgMhfGetRyoudama(s, &mhfpacket.MsgMhfGetRyoudama{AckHandle: 1})
}},
{"handleMsgMhfGetTinyBin", func(s *Session) {
handleMsgMhfGetTinyBin(s, &mhfpacket.MsgMhfGetTinyBin{AckHandle: 1})
}},
{"handleMsgMhfPostTinyBin", func(s *Session) {
handleMsgMhfPostTinyBin(s, &mhfpacket.MsgMhfPostTinyBin{AckHandle: 1})
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
session := createMockSession(1, server)
tt.fn(session)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Errorf("%s: response should have data", tt.name)
}
default:
t.Errorf("%s: no response queued", tt.name)
}
})
}
}
func TestEmptyHandlers_MiscFiles_Caravan(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgMhfPostRyoudama panicked: %v", r)
}
}()
handleMsgMhfPostRyoudama(session, nil)
}
func TestHandleMsgMhfCaravanMyRank(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)

View File

@@ -711,3 +711,15 @@ func BenchmarkSlicesIndexFunc(b *testing.B) {
_ = slices.IndexFunc(courses, predicate)
}
}
func TestEmptyCastedBinaryHandler(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysCastedBinary panicked: %v", r)
}
}()
handleMsgSysCastedBinary(session, nil)
}

View File

@@ -541,6 +541,32 @@ func TestOprMember_EdgeCases_Integration(t *testing.T) {
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestEmptyHandlers_ClientsGo(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
fn func()
}{
{"handleMsgMhfShutClient", func() { handleMsgMhfShutClient(session, nil) }},
{"handleMsgSysHideClient", func() { handleMsgSysHideClient(session, nil) }},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.fn()
})
}
}
// BenchmarkEnumerateClients benchmarks client enumeration
func BenchmarkEnumerateClients(b *testing.B) {
logger, _ := zap.NewDevelopment()

View File

@@ -1,698 +0,0 @@
package channelserver
import (
"testing"
"erupe-ce/common/byteframe"
"erupe-ce/network/mhfpacket"
)
// Test empty handlers don't panic
func TestHandleMsgHead(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgHead panicked: %v", r)
}
}()
handleMsgHead(session, nil)
}
func TestHandleMsgSysExtendThreshold(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysExtendThreshold panicked: %v", r)
}
}()
handleMsgSysExtendThreshold(session, nil)
}
func TestHandleMsgSysEnd(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysEnd panicked: %v", r)
}
}()
handleMsgSysEnd(session, nil)
}
func TestHandleMsgSysNop(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysNop panicked: %v", r)
}
}()
handleMsgSysNop(session, nil)
}
func TestHandleMsgSysAck(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysAck panicked: %v", r)
}
}()
handleMsgSysAck(session, nil)
}
func TestHandleMsgCaExchangeItem(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgCaExchangeItem panicked: %v", r)
}
}()
handleMsgCaExchangeItem(session, nil)
}
func TestHandleMsgMhfServerCommand(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgMhfServerCommand panicked: %v", r)
}
}()
handleMsgMhfServerCommand(session, nil)
}
func TestHandleMsgMhfSetLoginwindow(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgMhfSetLoginwindow panicked: %v", r)
}
}()
handleMsgMhfSetLoginwindow(session, nil)
}
func TestHandleMsgSysTransBinary(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysTransBinary panicked: %v", r)
}
}()
handleMsgSysTransBinary(session, nil)
}
func TestHandleMsgSysCollectBinary(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysCollectBinary panicked: %v", r)
}
}()
handleMsgSysCollectBinary(session, nil)
}
func TestHandleMsgSysGetState(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysGetState panicked: %v", r)
}
}()
handleMsgSysGetState(session, nil)
}
func TestHandleMsgSysSerialize(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysSerialize panicked: %v", r)
}
}()
handleMsgSysSerialize(session, nil)
}
func TestHandleMsgSysEnumlobby(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysEnumlobby panicked: %v", r)
}
}()
handleMsgSysEnumlobby(session, nil)
}
func TestHandleMsgSysEnumuser(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysEnumuser panicked: %v", r)
}
}()
handleMsgSysEnumuser(session, nil)
}
func TestHandleMsgSysInfokyserver(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysInfokyserver panicked: %v", r)
}
}()
handleMsgSysInfokyserver(session, nil)
}
func TestHandleMsgMhfGetCaUniqueID(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgMhfGetCaUniqueID panicked: %v", r)
}
}()
handleMsgMhfGetCaUniqueID(session, nil)
}
func TestHandleMsgMhfEnumerateItem(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateItem{
AckHandle: 12345,
}
handleMsgMhfEnumerateItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfAcquireItem(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfAcquireItem{
AckHandle: 12345,
}
handleMsgMhfAcquireItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfGetExtraInfo(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgMhfGetExtraInfo panicked: %v", r)
}
}()
handleMsgMhfGetExtraInfo(session, nil)
}
// Test handlers that return simple responses
func TestHandleMsgMhfTransferItem(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfTransferItem{
AckHandle: 12345,
}
handleMsgMhfTransferItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumeratePrice(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumeratePrice{
AckHandle: 12345,
}
handleMsgMhfEnumeratePrice(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateOrder(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateOrder{
AckHandle: 12345,
}
handleMsgMhfEnumerateOrder(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test terminal log handler
func TestHandleMsgSysTerminalLog(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysTerminalLog{
AckHandle: 12345,
LogID: 100,
Entries: []mhfpacket.TerminalLogEntry{},
}
handleMsgSysTerminalLog(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysTerminalLog_WithEntries(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysTerminalLog{
AckHandle: 12345,
LogID: 100,
Entries: []mhfpacket.TerminalLogEntry{
{Type1: 1, Type2: 2},
{Type1: 3, Type2: 4},
},
}
handleMsgSysTerminalLog(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test ping handler
func TestHandleMsgSysPing(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysPing{
AckHandle: 12345,
}
handleMsgSysPing(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test time handler
func TestHandleMsgSysTime(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysTime{
GetRemoteTime: true,
}
handleMsgSysTime(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test issue logkey handler
func TestHandleMsgSysIssueLogkey(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysIssueLogkey{
AckHandle: 12345,
}
handleMsgSysIssueLogkey(session, pkt)
// Verify logkey was set
if len(session.logKey) != 16 {
t.Errorf("logKey length = %d, want 16", len(session.logKey))
}
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test record log handler
func TestHandleMsgSysRecordLog(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// Setup stage
stage := NewStage("test_stage")
session.stage = stage
stage.reservedClientSlots[session.charID] = true
pkt := &mhfpacket.MsgSysRecordLog{
AckHandle: 12345,
Data: make([]byte, 256), // Must be large enough for ByteFrame reads (32 offset + 176 uint8s)
}
handleMsgSysRecordLog(session, pkt)
// Verify charID removed from reserved slots
if _, exists := stage.reservedClientSlots[session.charID]; exists {
t.Error("charID should be removed from reserved slots")
}
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test unlock global sema handler
func TestHandleMsgSysUnlockGlobalSema(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysUnlockGlobalSema{
AckHandle: 12345,
}
handleMsgSysUnlockGlobalSema(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test more empty handlers
func TestHandleMsgSysSetStatus(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysSetStatus panicked: %v", r)
}
}()
handleMsgSysSetStatus(session, nil)
}
func TestHandleMsgSysEcho(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysEcho panicked: %v", r)
}
}()
handleMsgSysEcho(session, nil)
}
func TestHandleMsgSysUpdateRight(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysUpdateRight panicked: %v", r)
}
}()
handleMsgSysUpdateRight(session, nil)
}
func TestHandleMsgSysAuthQuery(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysAuthQuery panicked: %v", r)
}
}()
handleMsgSysAuthQuery(session, nil)
}
func TestHandleMsgSysAuthTerminal(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysAuthTerminal panicked: %v", r)
}
}()
handleMsgSysAuthTerminal(session, nil)
}
// Test lock global sema handler
func TestHandleMsgSysLockGlobalSema_NoMatch(t *testing.T) {
server := createMockServer()
server.GlobalID = "test-server"
server.Registry = NewLocalChannelRegistry([]*Server{})
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysLockGlobalSema{
AckHandle: 12345,
UserIDString: "user123",
ServerChannelIDString: "channel1",
}
handleMsgSysLockGlobalSema(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysLockGlobalSema_WithChannel(t *testing.T) {
server := createMockServer()
server.GlobalID = "test-server"
// Create a mock channel with stages
channel := &Server{
GlobalID: "other-server",
}
channel.stages.Store("stage_user123", NewStage("stage_user123"))
server.Registry = NewLocalChannelRegistry([]*Server{channel})
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysLockGlobalSema{
AckHandle: 12345,
UserIDString: "user123",
ServerChannelIDString: "channel1",
}
handleMsgSysLockGlobalSema(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysLockGlobalSema_SameServer(t *testing.T) {
server := createMockServer()
server.GlobalID = "test-server"
// Create a mock channel with same GlobalID
channel := &Server{
GlobalID: "test-server",
}
channel.stages.Store("stage_user456", NewStage("stage_user456"))
server.Registry = NewLocalChannelRegistry([]*Server{channel})
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysLockGlobalSema{
AckHandle: 12345,
UserIDString: "user456",
ServerChannelIDString: "channel2",
}
handleMsgSysLockGlobalSema(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfAnnounce(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfAnnounce{
AckHandle: 12345,
IPAddress: 0x7F000001, // 127.0.0.1
Port: 54001,
StageID: []byte("test_stage"),
Data: byteframe.NewByteFrameFromBytes([]byte{0x00}),
}
handleMsgMhfAnnounce(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysRightsReload(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysRightsReload{
AckHandle: 12345,
}
// This will panic due to nil db, which is expected in test
defer func() {
if r := recover(); r != nil {
t.Log("Expected panic due to nil database in test")
}
}()
handleMsgSysRightsReload(session, pkt)
}

View File

@@ -1,922 +0,0 @@
package channelserver
import (
"testing"
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
)
// Tests for guild handlers that do not require database access.
func TestHandleMsgMhfEntryRookieGuild(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEntryRookieGuild{
AckHandle: 12345,
Unk: 42,
}
handleMsgMhfEntryRookieGuild(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfGenerateUdGuildMap(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfGenerateUdGuildMap{
AckHandle: 12345,
}
handleMsgMhfGenerateUdGuildMap(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfCheckMonthlyItem(t *testing.T) {
server := createMockServer()
server.stampRepo = &mockStampRepoForItems{monthlyClaimedErr: errNotFound}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfCheckMonthlyItem{
AckHandle: 12345,
Type: 0,
}
handleMsgMhfCheckMonthlyItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfAcquireMonthlyItem(t *testing.T) {
server := createMockServer()
server.stampRepo = &mockStampRepoForItems{}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfAcquireMonthlyItem{
AckHandle: 12345,
}
handleMsgMhfAcquireMonthlyItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateInvGuild(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateInvGuild{
AckHandle: 12345,
}
handleMsgMhfEnumerateInvGuild(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfOperationInvGuild(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfOperationInvGuild{
AckHandle: 12345,
Operation: 1,
}
handleMsgMhfOperationInvGuild(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Tests for mercenary handlers that do not require database access.
func TestHandleMsgMhfMercenaryHuntdata_RequestTypeIs1(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfMercenaryHuntdata{
AckHandle: 12345,
RequestType: 1,
}
handleMsgMhfMercenaryHuntdata(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfMercenaryHuntdata_RequestTypeIs0(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfMercenaryHuntdata{
AckHandle: 12345,
RequestType: 0,
}
handleMsgMhfMercenaryHuntdata(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfMercenaryHuntdata_RequestTypeIs2(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfMercenaryHuntdata{
AckHandle: 12345,
RequestType: 2,
}
handleMsgMhfMercenaryHuntdata(session, pkt)
// RequestType=2 takes the else branch (same as 0)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Tests for festa/ranking handlers.
func TestHandleMsgMhfEnumerateRanking_DefaultBranch(t *testing.T) {
server := createMockServer()
server.erupeConfig = &cfg.Config{
DebugOptions: cfg.DebugOptions{
TournamentOverride: 0,
},
}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateRanking{
AckHandle: 99999,
}
handleMsgMhfEnumerateRanking(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateRanking_NegativeState(t *testing.T) {
server := createMockServer()
server.erupeConfig = &cfg.Config{
DebugOptions: cfg.DebugOptions{
TournamentOverride: -1,
},
}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateRanking{
AckHandle: 99999,
}
handleMsgMhfEnumerateRanking(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Tests for rengoku handlers.
func TestHandleMsgMhfGetRengokuRankingRank_ResponseData(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfGetRengokuRankingRank{
AckHandle: 55555,
}
handleMsgMhfGetRengokuRankingRank(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Tests for empty handlers that are not covered in other test files.
func TestEmptyHandlers_Coverage2(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
handler func(s *Session, p mhfpacket.MHFPacket)
}{
{"handleMsgSysCastedBinary", handleMsgSysCastedBinary},
{"handleMsgMhfResetTitle", handleMsgMhfResetTitle},
{"handleMsgMhfUpdateForceGuildRank", handleMsgMhfUpdateForceGuildRank},
{"handleMsgMhfUpdateGuild", handleMsgMhfUpdateGuild},
{"handleMsgMhfUpdateGuildcard", handleMsgMhfUpdateGuildcard},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.handler(session, nil)
})
}
}
// Tests for handlers.go - handlers that produce responses without DB access.
func TestHandleMsgSysTerminalLog_MultipleEntries(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysTerminalLog{
AckHandle: 12345,
LogID: 200,
Entries: []mhfpacket.TerminalLogEntry{
{Type1: 10, Type2: 20},
{Type1: 11, Type2: 21},
{Type1: 12, Type2: 22},
},
}
handleMsgSysTerminalLog(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysTerminalLog_ZeroLogID(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysTerminalLog{
AckHandle: 12345,
LogID: 0,
Entries: []mhfpacket.TerminalLogEntry{},
}
handleMsgSysTerminalLog(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysPing_DifferentAckHandle(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysPing{
AckHandle: 0xFFFFFFFF,
}
handleMsgSysPing(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysTime_GetRemoteTimeFalse(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysTime{
GetRemoteTime: false,
}
handleMsgSysTime(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysIssueLogkey_LogKeyGenerated(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysIssueLogkey{
AckHandle: 77777,
}
handleMsgSysIssueLogkey(session, pkt)
// Verify that the logKey was set on the session
session.Lock()
keyLen := len(session.logKey)
session.Unlock()
if keyLen != 16 {
t.Errorf("logKey length = %d, want 16", keyLen)
}
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysIssueLogkey_Uniqueness(t *testing.T) {
server := createMockServer()
// Generate two logkeys and verify they differ
session1 := createMockSession(1, server)
session2 := createMockSession(2, server)
pkt1 := &mhfpacket.MsgSysIssueLogkey{AckHandle: 1}
pkt2 := &mhfpacket.MsgSysIssueLogkey{AckHandle: 2}
handleMsgSysIssueLogkey(session1, pkt1)
handleMsgSysIssueLogkey(session2, pkt2)
// Drain send packets
<-session1.sendPackets
<-session2.sendPackets
session1.Lock()
key1 := make([]byte, len(session1.logKey))
copy(key1, session1.logKey)
session1.Unlock()
session2.Lock()
key2 := make([]byte, len(session2.logKey))
copy(key2, session2.logKey)
session2.Unlock()
if len(key1) != 16 || len(key2) != 16 {
t.Fatalf("logKeys should be 16 bytes each, got %d and %d", len(key1), len(key2))
}
same := true
for i := range key1 {
if key1[i] != key2[i] {
same = false
break
}
}
if same {
t.Error("Two generated logkeys should differ (extremely unlikely to be the same)")
}
}
// Tests for event handlers.
func TestHandleMsgMhfReleaseEvent_ErrorCode(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfReleaseEvent{
AckHandle: 88888,
}
handleMsgMhfReleaseEvent(session, pkt)
// This handler manually sends a response with error code 0x41
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateEvent_Stub(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateEvent{
AckHandle: 77777,
}
handleMsgMhfEnumerateEvent(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Tests for achievement handler.
func TestHandleMsgMhfSetCaAchievementHist_Response(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfSetCaAchievementHist{
AckHandle: 44444,
}
handleMsgMhfSetCaAchievementHist(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test concurrent handler invocations to catch potential data races.
func TestHandlersConcurrentInvocations(t *testing.T) {
server := createMockServer()
done := make(chan struct{})
const numGoroutines = 10
for i := 0; i < numGoroutines; i++ {
go func(id uint32) {
defer func() {
if r := recover(); r != nil {
t.Errorf("goroutine %d panicked: %v", id, r)
}
done <- struct{}{}
}()
session := createMockSession(id, server)
// Run several handlers concurrently
handleMsgSysPing(session, &mhfpacket.MsgSysPing{AckHandle: id})
<-session.sendPackets
handleMsgSysTime(session, &mhfpacket.MsgSysTime{GetRemoteTime: true})
<-session.sendPackets
handleMsgSysIssueLogkey(session, &mhfpacket.MsgSysIssueLogkey{AckHandle: id})
<-session.sendPackets
handleMsgMhfMercenaryHuntdata(session, &mhfpacket.MsgMhfMercenaryHuntdata{AckHandle: id, RequestType: 1})
<-session.sendPackets
handleMsgMhfEnumerateMercenaryLog(session, &mhfpacket.MsgMhfEnumerateMercenaryLog{AckHandle: id})
<-session.sendPackets
}(uint32(i + 100))
}
for i := 0; i < numGoroutines; i++ {
<-done
}
}
// Test record log handler with stage setup.
func TestHandleMsgSysRecordLog_RemovesReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
stage := NewStage("test_stage_record")
session.stage = stage
stage.reservedClientSlots[session.charID] = true
pkt := &mhfpacket.MsgSysRecordLog{
AckHandle: 55555,
Data: make([]byte, 256),
}
handleMsgSysRecordLog(session, pkt)
if _, exists := stage.reservedClientSlots[session.charID]; exists {
t.Error("charID should be removed from reserved slots after record log")
}
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgSysRecordLog_NoExistingReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
stage := NewStage("test_stage_no_reservation")
session.stage = stage
// No reservation exists for this charID
pkt := &mhfpacket.MsgSysRecordLog{
AckHandle: 55556,
Data: make([]byte, 256),
}
// Should not panic even if charID is not in reservedClientSlots
handleMsgSysRecordLog(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test unlock global sema handler.
func TestHandleMsgSysUnlockGlobalSema_Response(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysUnlockGlobalSema{
AckHandle: 66666,
}
handleMsgSysUnlockGlobalSema(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test handlers from handlers_event.go with edge cases.
func TestHandleMsgMhfSetRestrictionEvent_Response(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfSetRestrictionEvent{
AckHandle: 11111,
}
handleMsgMhfSetRestrictionEvent(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfGetRestrictionEvent_Empty(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgMhfGetRestrictionEvent panicked: %v", r)
}
}()
handleMsgMhfGetRestrictionEvent(session, nil)
}
// Test handlers from handlers_mercenary.go - legend dispatch (no DB).
func TestHandleMsgMhfLoadLegendDispatch_Response(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfLoadLegendDispatch{
AckHandle: 22222,
}
handleMsgMhfLoadLegendDispatch(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// Test multiple handler invocations on the same session to verify session state is not corrupted.
func TestMultipleHandlersOnSameSession(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// Call multiple handlers in sequence
handleMsgSysPing(session, &mhfpacket.MsgSysPing{AckHandle: 1})
select {
case <-session.sendPackets:
default:
t.Fatal("Expected packet from Ping handler")
}
handleMsgSysTime(session, &mhfpacket.MsgSysTime{GetRemoteTime: true})
select {
case <-session.sendPackets:
default:
t.Fatal("Expected packet from Time handler")
}
handleMsgMhfRegisterEvent(session, &mhfpacket.MsgMhfRegisterEvent{AckHandle: 2, WorldID: 5, LandID: 10})
select {
case <-session.sendPackets:
default:
t.Fatal("Expected packet from RegisterEvent handler")
}
handleMsgMhfReleaseEvent(session, &mhfpacket.MsgMhfReleaseEvent{AckHandle: 3})
select {
case <-session.sendPackets:
default:
t.Fatal("Expected packet from ReleaseEvent handler")
}
handleMsgMhfEnumerateEvent(session, &mhfpacket.MsgMhfEnumerateEvent{AckHandle: 4})
select {
case <-session.sendPackets:
default:
t.Fatal("Expected packet from EnumerateEvent handler")
}
handleMsgMhfSetCaAchievementHist(session, &mhfpacket.MsgMhfSetCaAchievementHist{AckHandle: 5})
select {
case <-session.sendPackets:
default:
t.Fatal("Expected packet from SetCaAchievementHist handler")
}
handleMsgMhfGetRengokuRankingRank(session, &mhfpacket.MsgMhfGetRengokuRankingRank{AckHandle: 6})
select {
case <-session.sendPackets:
default:
t.Fatal("Expected packet from GetRengokuRankingRank handler")
}
}
// Test festa timestamp generation.
func TestGenerateFestaTimestamps_Debug(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
start uint32
}{
{"Debug_Start1", 1},
{"Debug_Start2", 2},
{"Debug_Start3", 3},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
timestamps := generateFestaTimestamps(session, tt.start, true)
if len(timestamps) != 5 {
t.Errorf("Expected 5 timestamps, got %d", len(timestamps))
}
for i, ts := range timestamps {
if ts == 0 {
t.Errorf("Timestamp %d should not be zero", i)
}
}
})
}
}
func TestGenerateFestaTimestamps_NonDebug_FutureStart(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// Use a far-future start time so it does not trigger cleanup
futureStart := uint32(TimeAdjusted().Unix() + 5000000)
timestamps := generateFestaTimestamps(session, futureStart, false)
if len(timestamps) != 5 {
t.Errorf("Expected 5 timestamps, got %d", len(timestamps))
}
if timestamps[0] != futureStart {
t.Errorf("First timestamp = %d, want %d", timestamps[0], futureStart)
}
// Verify intervals
if timestamps[1] != timestamps[0]+604800 {
t.Errorf("Second timestamp should be start+604800, got %d", timestamps[1])
}
if timestamps[2] != timestamps[1]+604800 {
t.Errorf("Third timestamp should be second+604800, got %d", timestamps[2])
}
if timestamps[3] != timestamps[2]+9000 {
t.Errorf("Fourth timestamp should be third+9000, got %d", timestamps[3])
}
if timestamps[4] != timestamps[3]+1240200 {
t.Errorf("Fifth timestamp should be fourth+1240200, got %d", timestamps[4])
}
}
// Test trial struct from handlers_festa.go.
func TestFestaTrialStruct(t *testing.T) {
trial := FestaTrial{
ID: 100,
Objective: 2,
GoalID: 500,
TimesReq: 10,
Locale: 1,
Reward: 50,
}
if trial.ID != 100 {
t.Errorf("ID = %d, want 100", trial.ID)
}
if trial.Objective != 2 {
t.Errorf("Objective = %d, want 2", trial.Objective)
}
if trial.GoalID != 500 {
t.Errorf("GoalID = %d, want 500", trial.GoalID)
}
if trial.TimesReq != 10 {
t.Errorf("TimesReq = %d, want 10", trial.TimesReq)
}
}
// Test prize struct from handlers_festa.go.
func TestPrizeStruct(t *testing.T) {
prize := Prize{
ID: 1,
Tier: 2,
SoulsReq: 100,
ItemID: 0x1234,
NumItem: 5,
Claimed: 1,
}
if prize.ID != 1 {
t.Errorf("ID = %d, want 1", prize.ID)
}
if prize.Tier != 2 {
t.Errorf("Tier = %d, want 2", prize.Tier)
}
if prize.SoulsReq != 100 {
t.Errorf("SoulsReq = %d, want 100", prize.SoulsReq)
}
if prize.Claimed != 1 {
t.Errorf("Claimed = %d, want 1", prize.Claimed)
}
}
// Test Airou struct from handlers_mercenary.go.
func TestAirouStruct(t *testing.T) {
cat := Airou{
ID: 42,
Name: []byte("TestCat"),
Task: 4,
Personality: 2,
Class: 1,
Experience: 1500,
WeaponType: 6,
WeaponID: 100,
}
if cat.ID != 42 {
t.Errorf("ID = %d, want 42", cat.ID)
}
if cat.Task != 4 {
t.Errorf("Task = %d, want 4", cat.Task)
}
if cat.Experience != 1500 {
t.Errorf("Experience = %d, want 1500", cat.Experience)
}
if cat.WeaponType != 6 {
t.Errorf("WeaponType = %d, want 6", cat.WeaponType)
}
if cat.WeaponID != 100 {
t.Errorf("WeaponID = %d, want 100", cat.WeaponID)
}
}
// Test RengokuScore struct default values.
func TestRengokuScoreStruct_Fields(t *testing.T) {
score := RengokuScore{
Name: "Hunter",
Score: 99999,
}
if score.Name != "Hunter" {
t.Errorf("Name = %s, want Hunter", score.Name)
}
if score.Score != 99999 {
t.Errorf("Score = %d, want 99999", score.Score)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,246 +0,0 @@
package channelserver
import (
"testing"
"erupe-ce/network/mhfpacket"
)
// =============================================================================
// handleMsgMhfGetPaperData: 565-line pure data serialization function.
// Tests all switch cases: 0, 5, 6, >1000 (known & unknown), default <1000.
// =============================================================================
func TestHandleMsgMhfGetPaperData_Case0(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 0,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("case 0: response should have data")
}
default:
t.Error("case 0: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_Case5(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 5,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("case 5: response should have data")
}
default:
t.Error("case 5: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_Case6(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 6,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("case 6: response should have data")
}
default:
t.Error("case 6: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_GreaterThan1000_KnownKey(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// 6001 is a known key in paperGiftData
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 6001,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error(">1000 known: response should have data")
}
default:
t.Error(">1000 known: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_GreaterThan1000_UnknownKey(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// 9999 is not a known key in paperGiftData
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 9999,
})
select {
case p := <-session.sendPackets:
// Even unknown keys should produce a response (empty earth succeed)
_ = p
default:
t.Error(">1000 unknown: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_DefaultUnknownLessThan1000(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// Unknown type < 1000, hits default case then falls to else branch
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 99,
})
select {
case p := <-session.sendPackets:
_ = p
default:
t.Error("default <1000: no response queued")
}
}
// =============================================================================
// handleMsgMhfGetGachaPlayHistory and handleMsgMhfPlayFreeGacha
// =============================================================================
func TestHandleMsgMhfGetGachaPlayHistory(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetGachaPlayHistory(session, &mhfpacket.MsgMhfGetGachaPlayHistory{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfPlayFreeGacha(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfPlayFreeGacha(session, &mhfpacket.MsgMhfPlayFreeGacha{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
// Seibattle handlers: GetBreakSeibatuLevelReward, GetFixedSeibatuRankingTable,
// ReadLastWeekBeatRanking, ReadBeatLevelAllRanking, ReadBeatLevelMyRanking
// are already tested in handlers_misc_test.go and handlers_tower_test.go.
// =============================================================================
// grpToGR: pure function, no dependencies
// =============================================================================
func TestGrpToGR(t *testing.T) {
tests := []struct {
name string
input int
expected uint16
}{
{"zero", 0, 1},
{"low_value", 500, 2},
{"first_bracket", 1000, 2},
{"mid_bracket", 208750, 51},
{"second_bracket", 300000, 62},
{"high_value", 593400, 100},
{"third_bracket", 700000, 113},
{"very_high", 993400, 150},
{"above_993400", 1000000, 150},
{"fourth_bracket", 1400900, 200},
{"max_bracket", 11345900, 900},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := grpToGR(tt.input)
if got != tt.expected {
t.Errorf("grpToGR(%d) = %d, want %d", tt.input, got, tt.expected)
}
})
}
}
// =============================================================================
// dumpSaveData: test disabled path
// =============================================================================
func TestDumpSaveData_Disabled(t *testing.T) {
server := createMockServer()
server.erupeConfig.SaveDumps.Enabled = false
session := createMockSession(1, server)
// Should return immediately without error
dumpSaveData(session, []byte{0x01, 0x02, 0x03}, "test")
}
// =============================================================================
// TimeGameAbsolute
// =============================================================================
func TestTimeGameAbsolute(t *testing.T) {
result := TimeGameAbsolute()
// TimeGameAbsolute returns (adjustedUnix - 2160) % 5760
// Result should be in range [0, 5760)
if result >= 5760 {
t.Errorf("TimeGameAbsolute() = %d, should be < 5760", result)
}
}
// =============================================================================
// handleMsgSysAuthData: empty handler
// =============================================================================
func TestHandleMsgSysAuthData(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysAuthData panicked: %v", r)
}
}()
handleMsgSysAuthData(session, nil)
}

View File

@@ -1,186 +0,0 @@
package channelserver
import (
"testing"
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
)
// =============================================================================
// equipSkinHistSize: pure function, tests all 3 config branches
// =============================================================================
func TestEquipSkinHistSize_Default(t *testing.T) {
got := equipSkinHistSize(cfg.ZZ)
if got != 3200 {
t.Errorf("equipSkinHistSize(ZZ) = %d, want 3200", got)
}
}
func TestEquipSkinHistSize_Z2(t *testing.T) {
got := equipSkinHistSize(cfg.Z2)
if got != 2560 {
t.Errorf("equipSkinHistSize(Z2) = %d, want 2560", got)
}
}
func TestEquipSkinHistSize_Z1(t *testing.T) {
got := equipSkinHistSize(cfg.Z1)
if got != 1280 {
t.Errorf("equipSkinHistSize(Z1) = %d, want 1280", got)
}
}
func TestEquipSkinHistSize_OlderMode(t *testing.T) {
got := equipSkinHistSize(cfg.G1)
if got != 1280 {
t.Errorf("equipSkinHistSize(G1) = %d, want 1280", got)
}
}
// =============================================================================
// DB-free guild handlers: simple ack stubs
// =============================================================================
func TestHandleMsgMhfAddGuildMissionCount(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfAddGuildMissionCount(session, &mhfpacket.MsgMhfAddGuildMissionCount{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfSetGuildMissionTarget(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfSetGuildMissionTarget(session, &mhfpacket.MsgMhfSetGuildMissionTarget{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfCancelGuildMissionTarget(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfCancelGuildMissionTarget(session, &mhfpacket.MsgMhfCancelGuildMissionTarget{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfGetGuildMissionRecord(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetGuildMissionRecord(session, &mhfpacket.MsgMhfGetGuildMissionRecord{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfAcquireGuildTresureSouvenir(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfAcquireGuildTresureSouvenir(session, &mhfpacket.MsgMhfAcquireGuildTresureSouvenir{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfGetUdGuildMapInfo(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetUdGuildMapInfo(session, &mhfpacket.MsgMhfGetUdGuildMapInfo{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
// =============================================================================
// DB-free guild mission list handler (large static data)
// =============================================================================
func TestHandleMsgMhfGetGuildMissionList(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetGuildMissionList(session, &mhfpacket.MsgMhfGetGuildMissionList{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
// handleMsgMhfEnumerateUnionItem requires DB (calls userGetItems)
// handleMsgMhfRegistSpabiTime, handleMsgMhfKickExportForce, handleMsgMhfUseUdShopCoin
// are tested in handlers_misc_test.go
// handleMsgMhfGetUdShopCoin and handleMsgMhfGetLobbyCrowd are tested in handlers_misc_test.go
// handleMsgMhfEnumerateGuacot requires DB (calls getGoocooData)
// handleMsgMhfPostRyoudama is tested in handlers_caravan_test.go
// handleMsgMhfResetTitle is tested in handlers_coverage2_test.go

View File

@@ -1,144 +0,0 @@
package channelserver
import (
"testing"
"erupe-ce/network/mhfpacket"
)
// Tests for handlers that do NOT require database access, exercising additional
// code paths not covered by existing test files (handlers_core_test.go,
// handlers_rengoku_test.go, etc.).
// TestHandleMsgSysPing_DifferentAckHandles verifies ping works with various ack handles.
func TestHandleMsgSysPing_DifferentAckHandles(t *testing.T) {
server := createMockServer()
ackHandles := []uint32{0, 1, 99999, 0xFFFFFFFF}
for _, ack := range ackHandles {
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysPing{AckHandle: ack}
handleMsgSysPing(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Errorf("AckHandle=%d: Response packet should have data", ack)
}
default:
t.Errorf("AckHandle=%d: No response packet queued", ack)
}
}
}
// TestHandleMsgSysTerminalLog_NoEntries verifies the handler works with nil entries.
func TestHandleMsgSysTerminalLog_NoEntries(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysTerminalLog{
AckHandle: 99999,
LogID: 0,
Entries: nil,
}
handleMsgSysTerminalLog(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// TestHandleMsgSysTerminalLog_ManyEntries verifies the handler with many log entries.
func TestHandleMsgSysTerminalLog_ManyEntries(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
entries := make([]mhfpacket.TerminalLogEntry, 20)
for i := range entries {
entries[i] = mhfpacket.TerminalLogEntry{
Index: uint32(i),
Type1: uint8(i % 256),
Type2: uint8((i + 1) % 256),
}
}
pkt := &mhfpacket.MsgSysTerminalLog{
AckHandle: 55555,
LogID: 42,
Entries: entries,
}
handleMsgSysTerminalLog(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
// TestHandleMsgSysTime_MultipleCalls verifies calling time handler repeatedly.
func TestHandleMsgSysTime_MultipleCalls(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgSysTime{
GetRemoteTime: false,
Timestamp: 0,
}
for i := 0; i < 5; i++ {
handleMsgSysTime(session, pkt)
}
// Should have 5 queued responses
count := 0
for {
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
count++
default:
goto done
}
}
done:
if count != 5 {
t.Errorf("Expected 5 queued responses, got %d", count)
}
}
// TestHandleMsgMhfGetRengokuRankingRank_DifferentAck verifies rengoku ranking
// works with different ack handles.
func TestHandleMsgMhfGetRengokuRankingRank_DifferentAck(t *testing.T) {
server := createMockServer()
ackHandles := []uint32{0, 1, 54321, 0xDEADBEEF}
for _, ack := range ackHandles {
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfGetRengokuRankingRank{AckHandle: ack}
handleMsgMhfGetRengokuRankingRank(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Errorf("AckHandle=%d: Response packet should have data", ack)
}
default:
t.Errorf("AckHandle=%d: No response packet queued", ack)
}
}
}

View File

@@ -395,3 +395,157 @@ func itoa(n uint32) string {
}
return string(buf[i:])
}
// =============================================================================
// Tests consolidated from handlers_coverage4_test.go
// =============================================================================
func TestHandleMsgMhfGetPaperData_Case0(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 0,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("case 0: response should have data")
}
default:
t.Error("case 0: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_Case5(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 5,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("case 5: response should have data")
}
default:
t.Error("case 5: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_Case6(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 6,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("case 6: response should have data")
}
default:
t.Error("case 6: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_GreaterThan1000_KnownKey(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// 6001 is a known key in paperGiftData
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 6001,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error(">1000 known: response should have data")
}
default:
t.Error(">1000 known: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_GreaterThan1000_UnknownKey(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// 9999 is not a known key in paperGiftData
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 9999,
})
select {
case p := <-session.sendPackets:
// Even unknown keys should produce a response (empty earth succeed)
_ = p
default:
t.Error(">1000 unknown: no response queued")
}
}
func TestHandleMsgMhfGetPaperData_DefaultUnknownLessThan1000(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// Unknown type < 1000, hits default case then falls to else branch
handleMsgMhfGetPaperData(session, &mhfpacket.MsgMhfGetPaperData{
AckHandle: 1,
DataType: 99,
})
select {
case p := <-session.sendPackets:
_ = p
default:
t.Error("default <1000: no response queued")
}
}
func TestHandleMsgMhfGetGachaPlayHistory(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetGachaPlayHistory(session, &mhfpacket.MsgMhfGetGachaPlayHistory{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfPlayFreeGacha(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfPlayFreeGacha(session, &mhfpacket.MsgMhfPlayFreeGacha{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}

View File

@@ -651,3 +651,57 @@ func TestConcurrentSaveData_Integration(t *testing.T) {
}
}
}
// =============================================================================
// Tests consolidated from handlers_coverage4_test.go
// =============================================================================
func TestGrpToGR(t *testing.T) {
tests := []struct {
name string
input int
expected uint16
}{
{"zero", 0, 1},
{"low_value", 500, 2},
{"first_bracket", 1000, 2},
{"mid_bracket", 208750, 51},
{"second_bracket", 300000, 62},
{"high_value", 593400, 100},
{"third_bracket", 700000, 113},
{"very_high", 993400, 150},
{"above_993400", 1000000, 150},
{"fourth_bracket", 1400900, 200},
{"max_bracket", 11345900, 900},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := grpToGR(tt.input)
if got != tt.expected {
t.Errorf("grpToGR(%d) = %d, want %d", tt.input, got, tt.expected)
}
})
}
}
func TestDumpSaveData_Disabled(t *testing.T) {
server := createMockServer()
server.erupeConfig.SaveDumps.Enabled = false
session := createMockSession(1, server)
// Should return immediately without error
dumpSaveData(session, []byte{0x01, 0x02, 0x03}, "test")
}
func TestHandleMsgSysAuthData(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysAuthData panicked: %v", r)
}
}()
handleMsgSysAuthData(session, nil)
}

View File

@@ -1,91 +0,0 @@
package channelserver
import (
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
"testing"
"time"
)
func TestHandleMsgMhfGetUdSchedule_DivaOverrideZero_ZZ(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 0
srv.erupeConfig.RealClientMode = cfg.ZZ
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_DivaOverrideZero_OlderClient(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 0
srv.erupeConfig.RealClientMode = cfg.G10
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_DivaOverride1(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 1
srv.erupeConfig.RealClientMode = cfg.ZZ
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_DivaOverride2(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 2
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_DivaOverride3(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 3
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_WithExistingEvent(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{
events: []DivaEvent{{ID: 1, StartTime: uint32(time.Now().Unix())}},
}
srv.erupeConfig.DebugOptions.DivaOverride = -1
srv.erupeConfig.RealClientMode = cfg.ZZ
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_NoEvents(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = -1
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}

View File

@@ -4,6 +4,8 @@ import (
"testing"
"erupe-ce/network/mhfpacket"
"time"
cfg "erupe-ce/config"
)
func TestHandleMsgMhfGetUdInfo(t *testing.T) {
@@ -341,3 +343,86 @@ func TestGenerateDivaTimestamps_NonDebug_WithValidStart(t *testing.T) {
t.Error("Third timestamp should be second + 3900")
}
}
func TestHandleMsgMhfGetUdSchedule_DivaOverrideZero_ZZ(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 0
srv.erupeConfig.RealClientMode = cfg.ZZ
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_DivaOverrideZero_OlderClient(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 0
srv.erupeConfig.RealClientMode = cfg.G10
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_DivaOverride1(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 1
srv.erupeConfig.RealClientMode = cfg.ZZ
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_DivaOverride2(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 2
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_DivaOverride3(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = 3
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_WithExistingEvent(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{
events: []DivaEvent{{ID: 1, StartTime: uint32(time.Now().Unix())}},
}
srv.erupeConfig.DebugOptions.DivaOverride = -1
srv.erupeConfig.RealClientMode = cfg.ZZ
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetUdSchedule_NoEvents(t *testing.T) {
srv := createMockServer()
srv.divaRepo = &mockDivaRepo{}
srv.erupeConfig.DebugOptions.DivaOverride = -1
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
handleMsgMhfGetUdSchedule(s, pkt)
<-s.sendPackets
}

View File

@@ -1,226 +0,0 @@
package channelserver
import (
"erupe-ce/network/mhfpacket"
"testing"
"time"
)
func TestHandleMsgMhfGetWeeklySchedule(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{}
srv.erupeConfig.GameplayOptions.MinFeatureWeapons = 1
srv.erupeConfig.GameplayOptions.MaxFeatureWeapons = 3
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetWeeklySchedule{AckHandle: 1}
handleMsgMhfGetWeeklySchedule(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetKeepLoginBoostStatus_Disabled(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{}
srv.erupeConfig.GameplayOptions.DisableLoginBoost = true
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetKeepLoginBoostStatus{AckHandle: 1}
handleMsgMhfGetKeepLoginBoostStatus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetKeepLoginBoostStatus_EmptyBoosts(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetKeepLoginBoostStatus{AckHandle: 1}
handleMsgMhfGetKeepLoginBoostStatus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetKeepLoginBoostStatus_WithBoosts(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{
loginBoosts: []loginBoost{
{WeekReq: 1, Expiration: time.Now().Add(-7 * 24 * time.Hour)},
{WeekReq: 2, Expiration: time.Now().Add(-14 * 24 * time.Hour)},
{WeekReq: 3, Expiration: time.Now().Add(-21 * 24 * time.Hour)},
{WeekReq: 4, Expiration: time.Now().Add(-28 * 24 * time.Hour)},
{WeekReq: 5, Expiration: time.Now().Add(-35 * 24 * time.Hour)},
},
}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetKeepLoginBoostStatus{AckHandle: 1}
handleMsgMhfGetKeepLoginBoostStatus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfUseKeepLoginBoost(t *testing.T) {
tests := []struct {
name string
boostWeekUsed uint8
}{
{"week1", 1},
{"week2", 2},
{"week3", 3},
{"week4", 4},
{"week5", 5},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUseKeepLoginBoost{AckHandle: 1, BoostWeekUsed: tt.boostWeekUsed}
handleMsgMhfUseKeepLoginBoost(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
})
}
}
func TestHandleMsgMhfLoadScenarioData(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfLoadScenarioData{AckHandle: 1}
handleMsgMhfLoadScenarioData(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfSaveScenarioData(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfSaveScenarioData{AckHandle: 1, RawDataPayload: []byte{0x01, 0x02, 0x03}}
handleMsgMhfSaveScenarioData(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfListMember(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.strings["blocked"] = ""
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfListMember{AckHandle: 1}
handleMsgMhfListMember(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfOprMember_AddBlacklist(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.strings["blocked"] = ""
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOprMember{AckHandle: 1, Blacklist: true, Operation: false, CharIDs: []uint32{42}}
handleMsgMhfOprMember(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfOprMember_AddFriend(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.strings["friends"] = ""
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOprMember{AckHandle: 1, Blacklist: false, Operation: false, CharIDs: []uint32{42}}
handleMsgMhfOprMember(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfOprMember_RemoveBlacklist(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.strings["blocked"] = "42"
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOprMember{AckHandle: 1, Blacklist: true, Operation: true, CharIDs: []uint32{42}}
handleMsgMhfOprMember(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}

View File

@@ -6,6 +6,7 @@ import (
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
"time"
)
func TestHandleMsgMhfRegisterEvent(t *testing.T) {
@@ -221,6 +222,80 @@ func TestGenerateFeatureWeapons_StartTimeZero(t *testing.T) {
}
}
func TestHandleMsgMhfReleaseEvent_ErrorCode(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfReleaseEvent{
AckHandle: 88888,
}
handleMsgMhfReleaseEvent(session, pkt)
// This handler manually sends a response with error code 0x41
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateEvent_Stub(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateEvent{
AckHandle: 77777,
}
handleMsgMhfEnumerateEvent(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfSetRestrictionEvent_Response(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfSetRestrictionEvent{
AckHandle: 11111,
}
handleMsgMhfSetRestrictionEvent(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfGetRestrictionEvent_Empty(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgMhfGetRestrictionEvent panicked: %v", r)
}
}()
handleMsgMhfGetRestrictionEvent(session, nil)
}
// TestHandleMsgMhfRegisterEvent_DifferentValues tests with various Unk2/Unk4 values.
func TestHandleMsgMhfRegisterEvent_DifferentValues(t *testing.T) {
server := createMockServer()
@@ -257,3 +332,222 @@ func TestHandleMsgMhfRegisterEvent_DifferentValues(t *testing.T) {
})
}
}
func TestHandleMsgMhfGetWeeklySchedule(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{}
srv.erupeConfig.GameplayOptions.MinFeatureWeapons = 1
srv.erupeConfig.GameplayOptions.MaxFeatureWeapons = 3
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetWeeklySchedule{AckHandle: 1}
handleMsgMhfGetWeeklySchedule(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetKeepLoginBoostStatus_Disabled(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{}
srv.erupeConfig.GameplayOptions.DisableLoginBoost = true
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetKeepLoginBoostStatus{AckHandle: 1}
handleMsgMhfGetKeepLoginBoostStatus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetKeepLoginBoostStatus_EmptyBoosts(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetKeepLoginBoostStatus{AckHandle: 1}
handleMsgMhfGetKeepLoginBoostStatus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetKeepLoginBoostStatus_WithBoosts(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{
loginBoosts: []loginBoost{
{WeekReq: 1, Expiration: time.Now().Add(-7 * 24 * time.Hour)},
{WeekReq: 2, Expiration: time.Now().Add(-14 * 24 * time.Hour)},
{WeekReq: 3, Expiration: time.Now().Add(-21 * 24 * time.Hour)},
{WeekReq: 4, Expiration: time.Now().Add(-28 * 24 * time.Hour)},
{WeekReq: 5, Expiration: time.Now().Add(-35 * 24 * time.Hour)},
},
}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetKeepLoginBoostStatus{AckHandle: 1}
handleMsgMhfGetKeepLoginBoostStatus(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfUseKeepLoginBoost(t *testing.T) {
tests := []struct {
name string
boostWeekUsed uint8
}{
{"week1", 1},
{"week2", 2},
{"week3", 3},
{"week4", 4},
{"week5", 5},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
srv := createMockServer()
srv.eventRepo = &mockEventRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUseKeepLoginBoost{AckHandle: 1, BoostWeekUsed: tt.boostWeekUsed}
handleMsgMhfUseKeepLoginBoost(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
})
}
}
func TestHandleMsgMhfLoadScenarioData(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfLoadScenarioData{AckHandle: 1}
handleMsgMhfLoadScenarioData(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfSaveScenarioData(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfSaveScenarioData{AckHandle: 1, RawDataPayload: []byte{0x01, 0x02, 0x03}}
handleMsgMhfSaveScenarioData(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfListMember(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.strings["blocked"] = ""
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfListMember{AckHandle: 1}
handleMsgMhfListMember(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfOprMember_AddBlacklist(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.strings["blocked"] = ""
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOprMember{AckHandle: 1, Blacklist: true, Operation: false, CharIDs: []uint32{42}}
handleMsgMhfOprMember(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfOprMember_AddFriend(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.strings["friends"] = ""
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOprMember{AckHandle: 1, Blacklist: false, Operation: false, CharIDs: []uint32{42}}
handleMsgMhfOprMember(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfOprMember_RemoveBlacklist(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.strings["blocked"] = "42"
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOprMember{AckHandle: 1, Blacklist: true, Operation: true, CharIDs: []uint32{42}}
handleMsgMhfOprMember(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}

View File

@@ -1,301 +0,0 @@
package channelserver
import (
"erupe-ce/network/mhfpacket"
"testing"
)
func TestHandleMsgMhfSaveMezfesData(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfSaveMezfesData{AckHandle: 1, RawDataPayload: []byte{0x01, 0x02}}
handleMsgMhfSaveMezfesData(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfLoadMezfesData(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfLoadMezfesData{AckHandle: 1}
handleMsgMhfLoadMezfesData(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfVoteFesta(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfVoteFesta{AckHandle: 1, TrialID: 42}
handleMsgMhfVoteFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEntryFesta_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEntryFesta{AckHandle: 1}
handleMsgMhfEntryFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEntryFesta_WithGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{guild: &Guild{ID: 1}}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEntryFesta{AckHandle: 1}
handleMsgMhfEntryFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfChargeFesta(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
srv.guildRepo = &mockGuildRepo{guild: &Guild{ID: 1}}
ensureFestaService(srv)
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfChargeFesta{AckHandle: 1, GuildID: 1, Souls: []uint16{10, 20}}
handleMsgMhfChargeFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfAcquireFesta(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfAcquireFesta{AckHandle: 1}
handleMsgMhfAcquireFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfAcquireFestaPersonalPrize(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfAcquireFestaPersonalPrize{AckHandle: 1, PrizeID: 5}
handleMsgMhfAcquireFestaPersonalPrize(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfAcquireFestaIntermediatePrize(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfAcquireFestaIntermediatePrize{AckHandle: 1, PrizeID: 3}
handleMsgMhfAcquireFestaIntermediatePrize(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateFestaPersonalPrize(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{
prizes: []Prize{
{ID: 1, Tier: 1, SoulsReq: 100, ItemID: 5, NumItem: 1, Claimed: 0},
},
}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateFestaPersonalPrize{AckHandle: 1}
handleMsgMhfEnumerateFestaPersonalPrize(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateFestaIntermediatePrize(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateFestaIntermediatePrize{AckHandle: 1}
handleMsgMhfEnumerateFestaIntermediatePrize(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfStateFestaU_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfStateFestaU{AckHandle: 1}
handleMsgMhfStateFestaU(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfStateFestaU_WithGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{guild: &Guild{ID: 1}}
srv.festaRepo = &mockFestaRepo{charSouls: 50}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfStateFestaU{AckHandle: 1}
handleMsgMhfStateFestaU(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfStateFestaG_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfStateFestaG{AckHandle: 1}
handleMsgMhfStateFestaG(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfStateFestaG_WithGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{guild: &Guild{ID: 1, Souls: 500}}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfStateFestaG{AckHandle: 1}
handleMsgMhfStateFestaG(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateFestaMember_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateFestaMember{AckHandle: 1}
handleMsgMhfEnumerateFestaMember(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateFestaMember_WithMembers(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{
guild: &Guild{ID: 1},
members: []*GuildMember{
{CharID: 1, Souls: 100},
{CharID: 2, Souls: 50},
{CharID: 3, Souls: 0},
},
}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateFestaMember{AckHandle: 1}
handleMsgMhfEnumerateFestaMember(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}

View File

@@ -1,52 +0,0 @@
package channelserver
import (
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
"testing"
"time"
)
func TestHandleMsgMhfInfoFesta_OverrideZero(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
srv.erupeConfig.DebugOptions.FestaOverride = 0
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfInfoFesta{AckHandle: 1}
handleMsgMhfInfoFesta(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfInfoFesta_WithActiveEvent(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.DebugOptions.FestaOverride = 1
srv.erupeConfig.RealClientMode = cfg.ZZ
srv.erupeConfig.GameplayOptions.MaximumFP = 50000
srv.festaRepo = &mockFestaRepo{
events: []FestaEvent{{ID: 1, StartTime: uint32(time.Now().Add(-24 * time.Hour).Unix())}},
trials: []FestaTrial{
{ID: 1, Objective: 1, GoalID: 100, TimesReq: 5, Locale: 0, Reward: 10, Monopoly: "blue"},
},
}
ensureFestaService(srv)
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfInfoFesta{AckHandle: 1}
handleMsgMhfInfoFesta(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfInfoFesta_FutureTimestamp(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.DebugOptions.FestaOverride = -1
srv.festaRepo = &mockFestaRepo{
events: []FestaEvent{{ID: 1, StartTime: uint32(time.Now().Add(72 * time.Hour).Unix())}},
}
ensureFestaService(srv)
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfInfoFesta{AckHandle: 1}
handleMsgMhfInfoFesta(s, pkt)
<-s.sendPackets
}

View File

@@ -5,6 +5,7 @@ import (
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
"time"
)
func TestHandleMsgMhfEnumerateRanking_Default(t *testing.T) {
@@ -106,3 +107,495 @@ func TestHandleMsgMhfEnumerateRanking_State3(t *testing.T) {
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateRanking_DefaultBranch(t *testing.T) {
server := createMockServer()
server.erupeConfig = &cfg.Config{
DebugOptions: cfg.DebugOptions{
TournamentOverride: 0,
},
}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateRanking{
AckHandle: 99999,
}
handleMsgMhfEnumerateRanking(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateRanking_NegativeState(t *testing.T) {
server := createMockServer()
server.erupeConfig = &cfg.Config{
DebugOptions: cfg.DebugOptions{
TournamentOverride: -1,
},
}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateRanking{
AckHandle: 99999,
}
handleMsgMhfEnumerateRanking(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestGenerateFestaTimestamps_Debug(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
start uint32
}{
{"Debug_Start1", 1},
{"Debug_Start2", 2},
{"Debug_Start3", 3},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
timestamps := generateFestaTimestamps(session, tt.start, true)
if len(timestamps) != 5 {
t.Errorf("Expected 5 timestamps, got %d", len(timestamps))
}
for i, ts := range timestamps {
if ts == 0 {
t.Errorf("Timestamp %d should not be zero", i)
}
}
})
}
}
func TestGenerateFestaTimestamps_NonDebug_FutureStart(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
// Use a far-future start time so it does not trigger cleanup
futureStart := uint32(TimeAdjusted().Unix() + 5000000)
timestamps := generateFestaTimestamps(session, futureStart, false)
if len(timestamps) != 5 {
t.Errorf("Expected 5 timestamps, got %d", len(timestamps))
}
if timestamps[0] != futureStart {
t.Errorf("First timestamp = %d, want %d", timestamps[0], futureStart)
}
// Verify intervals
if timestamps[1] != timestamps[0]+604800 {
t.Errorf("Second timestamp should be start+604800, got %d", timestamps[1])
}
if timestamps[2] != timestamps[1]+604800 {
t.Errorf("Third timestamp should be second+604800, got %d", timestamps[2])
}
if timestamps[3] != timestamps[2]+9000 {
t.Errorf("Fourth timestamp should be third+9000, got %d", timestamps[3])
}
if timestamps[4] != timestamps[3]+1240200 {
t.Errorf("Fifth timestamp should be fourth+1240200, got %d", timestamps[4])
}
}
func TestFestaTrialStruct(t *testing.T) {
trial := FestaTrial{
ID: 100,
Objective: 2,
GoalID: 500,
TimesReq: 10,
Locale: 1,
Reward: 50,
}
if trial.ID != 100 {
t.Errorf("ID = %d, want 100", trial.ID)
}
if trial.Objective != 2 {
t.Errorf("Objective = %d, want 2", trial.Objective)
}
if trial.GoalID != 500 {
t.Errorf("GoalID = %d, want 500", trial.GoalID)
}
if trial.TimesReq != 10 {
t.Errorf("TimesReq = %d, want 10", trial.TimesReq)
}
}
func TestPrizeStruct(t *testing.T) {
prize := Prize{
ID: 1,
Tier: 2,
SoulsReq: 100,
ItemID: 0x1234,
NumItem: 5,
Claimed: 1,
}
if prize.ID != 1 {
t.Errorf("ID = %d, want 1", prize.ID)
}
if prize.Tier != 2 {
t.Errorf("Tier = %d, want 2", prize.Tier)
}
if prize.SoulsReq != 100 {
t.Errorf("SoulsReq = %d, want 100", prize.SoulsReq)
}
if prize.Claimed != 1 {
t.Errorf("Claimed = %d, want 1", prize.Claimed)
}
}
func TestHandleMsgMhfSaveMezfesData(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfSaveMezfesData{AckHandle: 1, RawDataPayload: []byte{0x01, 0x02}}
handleMsgMhfSaveMezfesData(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfLoadMezfesData(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfLoadMezfesData{AckHandle: 1}
handleMsgMhfLoadMezfesData(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfVoteFesta(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfVoteFesta{AckHandle: 1, TrialID: 42}
handleMsgMhfVoteFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEntryFesta_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEntryFesta{AckHandle: 1}
handleMsgMhfEntryFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEntryFesta_WithGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{guild: &Guild{ID: 1}}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEntryFesta{AckHandle: 1}
handleMsgMhfEntryFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfChargeFesta(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
srv.guildRepo = &mockGuildRepo{guild: &Guild{ID: 1}}
ensureFestaService(srv)
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfChargeFesta{AckHandle: 1, GuildID: 1, Souls: []uint16{10, 20}}
handleMsgMhfChargeFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfAcquireFesta(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfAcquireFesta{AckHandle: 1}
handleMsgMhfAcquireFesta(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfAcquireFestaPersonalPrize(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfAcquireFestaPersonalPrize{AckHandle: 1, PrizeID: 5}
handleMsgMhfAcquireFestaPersonalPrize(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfAcquireFestaIntermediatePrize(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfAcquireFestaIntermediatePrize{AckHandle: 1, PrizeID: 3}
handleMsgMhfAcquireFestaIntermediatePrize(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateFestaPersonalPrize(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{
prizes: []Prize{
{ID: 1, Tier: 1, SoulsReq: 100, ItemID: 5, NumItem: 1, Claimed: 0},
},
}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateFestaPersonalPrize{AckHandle: 1}
handleMsgMhfEnumerateFestaPersonalPrize(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateFestaIntermediatePrize(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateFestaIntermediatePrize{AckHandle: 1}
handleMsgMhfEnumerateFestaIntermediatePrize(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfStateFestaU_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfStateFestaU{AckHandle: 1}
handleMsgMhfStateFestaU(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfStateFestaU_WithGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{guild: &Guild{ID: 1}}
srv.festaRepo = &mockFestaRepo{charSouls: 50}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfStateFestaU{AckHandle: 1}
handleMsgMhfStateFestaU(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfStateFestaG_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfStateFestaG{AckHandle: 1}
handleMsgMhfStateFestaG(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfStateFestaG_WithGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{guild: &Guild{ID: 1, Souls: 500}}
srv.festaRepo = &mockFestaRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfStateFestaG{AckHandle: 1}
handleMsgMhfStateFestaG(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateFestaMember_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateFestaMember{AckHandle: 1}
handleMsgMhfEnumerateFestaMember(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateFestaMember_WithMembers(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{
guild: &Guild{ID: 1},
members: []*GuildMember{
{CharID: 1, Souls: 100},
{CharID: 2, Souls: 50},
{CharID: 3, Souls: 0},
},
}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateFestaMember{AckHandle: 1}
handleMsgMhfEnumerateFestaMember(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfInfoFesta_OverrideZero(t *testing.T) {
srv := createMockServer()
srv.festaRepo = &mockFestaRepo{}
srv.erupeConfig.DebugOptions.FestaOverride = 0
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfInfoFesta{AckHandle: 1}
handleMsgMhfInfoFesta(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfInfoFesta_WithActiveEvent(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.DebugOptions.FestaOverride = 1
srv.erupeConfig.RealClientMode = cfg.ZZ
srv.erupeConfig.GameplayOptions.MaximumFP = 50000
srv.festaRepo = &mockFestaRepo{
events: []FestaEvent{{ID: 1, StartTime: uint32(time.Now().Add(-24 * time.Hour).Unix())}},
trials: []FestaTrial{
{ID: 1, Objective: 1, GoalID: 100, TimesReq: 5, Locale: 0, Reward: 10, Monopoly: "blue"},
},
}
ensureFestaService(srv)
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfInfoFesta{AckHandle: 1}
handleMsgMhfInfoFesta(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfInfoFesta_FutureTimestamp(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.DebugOptions.FestaOverride = -1
srv.festaRepo = &mockFestaRepo{
events: []FestaEvent{{ID: 1, StartTime: uint32(time.Now().Add(72 * time.Hour).Unix())}},
}
ensureFestaService(srv)
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfInfoFesta{AckHandle: 1}
handleMsgMhfInfoFesta(s, pkt)
<-s.sendPackets
}

View File

@@ -1,173 +0,0 @@
package channelserver
import (
"erupe-ce/network/mhfpacket"
"testing"
)
func TestHandleMsgMhfUpdateGuildMessageBoard_CreatePost(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 0,
PostType: 0,
StampID: 1,
Title: "Test",
Body: "Hello",
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_CreatePostType1(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 0,
PostType: 1,
Title: "Notice",
Body: "Board",
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_DeletePost(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 1,
PostID: 42,
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_UpdatePost(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 2,
PostID: 1,
Title: "Updated",
Body: "New body",
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_UpdateStamp(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 3,
PostID: 1,
StampID: 5,
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_LikePost(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 4,
PostID: 1,
LikeState: true,
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_CheckNewPosts(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 5,
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{AckHandle: 1, MessageOp: 0}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_Applicant(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild, hasAppResult: true}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{AckHandle: 1, MessageOp: 0}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMessageBoard(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateGuildMessageBoard{AckHandle: 1, BoardType: 0}
handleMsgMhfEnumerateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMessageBoard_Type1(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateGuildMessageBoard{AckHandle: 1, BoardType: 1}
handleMsgMhfEnumerateGuildMessageBoard(s, pkt)
<-s.sendPackets
}

View File

@@ -239,3 +239,170 @@ func TestEnumerateGuildMessageBoard_DBError(t *testing.T) {
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfUpdateGuildMessageBoard_CreatePost(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 0,
PostType: 0,
StampID: 1,
Title: "Test",
Body: "Hello",
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_CreatePostType1(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 0,
PostType: 1,
Title: "Notice",
Body: "Board",
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_DeletePost(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 1,
PostID: 42,
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_UpdatePost(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 2,
PostID: 1,
Title: "Updated",
Body: "New body",
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_UpdateStamp(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 3,
PostID: 1,
StampID: 5,
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_LikePost(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 4,
PostID: 1,
LikeState: true,
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_CheckNewPosts(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{
AckHandle: 1,
MessageOp: 5,
}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_NoGuild(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{AckHandle: 1, MessageOp: 0}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateGuildMessageBoard_Applicant(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild, hasAppResult: true}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateGuildMessageBoard{AckHandle: 1, MessageOp: 0}
handleMsgMhfUpdateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMessageBoard(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateGuildMessageBoard{AckHandle: 1, BoardType: 0}
handleMsgMhfEnumerateGuildMessageBoard(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMessageBoard_Type1(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateGuildMessageBoard{AckHandle: 1, BoardType: 1}
handleMsgMhfEnumerateGuildMessageBoard(s, pkt)
<-s.sendPackets
}

View File

@@ -1,246 +0,0 @@
package channelserver
import (
"testing"
"erupe-ce/network/mhfpacket"
)
func TestHandleMsgMhfCreateGuild_Success(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfCreateGuild{AckHandle: 1, Name: "TestGuild"}
handleMsgMhfCreateGuild(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("expected non-empty response")
}
default:
t.Error("expected a response packet")
}
}
func TestHandleMsgMhfCreateGuild_Error(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{saveErr: errNotFound}
// Mock Create to return error - the mockGuildRepo.Create returns (0, nil)
// We need getErr to make it fail. Actually Create is a no-op stub returning nil.
// Let's use a custom approach - we need the Create method to error.
// The mock's Create always returns nil, so let's test the success path worked above
// and test ArrangeGuildMember error paths instead.
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfCreateGuild{AckHandle: 1, Name: "TestGuild"}
handleMsgMhfCreateGuild(session, pkt)
<-session.sendPackets // consume the response
}
func TestHandleMsgMhfArrangeGuildMember_Success(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, GuildLeader: GuildLeader{LeaderCharID: 100}}
server.guildRepo = &mockGuildRepo{guild: guild}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfArrangeGuildMember{
AckHandle: 1,
GuildID: 1,
CharIDs: []uint32{100, 200, 300},
}
handleMsgMhfArrangeGuildMember(session, pkt)
select {
case <-session.sendPackets:
default:
t.Error("expected response")
}
}
func TestHandleMsgMhfArrangeGuildMember_GetByIDError(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{getErr: errNotFound}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfArrangeGuildMember{AckHandle: 1, GuildID: 999}
handleMsgMhfArrangeGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfArrangeGuildMember_NotLeader(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, GuildLeader: GuildLeader{LeaderCharID: 200, LeaderName: "Other"}}
server.guildRepo = &mockGuildRepo{guild: guild}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfArrangeGuildMember{AckHandle: 1, GuildID: 1}
handleMsgMhfArrangeGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMember_GuildIDPositive(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, MemberCount: 2}
members := []*GuildMember{
{CharID: 100, Name: "Player1", HR: 50, OrderIndex: 0, WeaponType: 3},
{CharID: 200, Name: "Player2", HR: 100, OrderIndex: 1, WeaponType: 1},
}
server.guildRepo = &mockGuildRepo{guild: guild, members: members}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildMember{AckHandle: 1, GuildID: 1}
handleMsgMhfEnumerateGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMember_GuildIDZero(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, MemberCount: 1}
members := []*GuildMember{
{CharID: 100, Name: "Player1", HR: 50, OrderIndex: 0},
}
server.guildRepo = &mockGuildRepo{guild: guild, members: members}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildMember{AckHandle: 1, GuildID: 0}
handleMsgMhfEnumerateGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMember_NilGuild(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildMember{AckHandle: 1, GuildID: 0}
handleMsgMhfEnumerateGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMember_Applicant(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1}
server.guildRepo = &mockGuildRepo{guild: guild, hasAppResult: true}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildMember{AckHandle: 1, GuildID: 1}
handleMsgMhfEnumerateGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfGetGuildManageRight(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, MemberCount: 2}
members := []*GuildMember{
{CharID: 100, Recruiter: true},
{CharID: 200, Recruiter: false},
}
server.guildRepo = &mockGuildRepo{guild: guild, members: members}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfGetGuildManageRight{AckHandle: 1}
handleMsgMhfGetGuildManageRight(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfGetGuildTargetMemberNum_NilGuild(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfGetGuildTargetMemberNum{AckHandle: 1, GuildID: 0}
handleMsgMhfGetGuildTargetMemberNum(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfGetGuildTargetMemberNum_WithGuild(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, MemberCount: 5}
server.guildRepo = &mockGuildRepo{guild: guild}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfGetGuildTargetMemberNum{AckHandle: 1, GuildID: 1}
handleMsgMhfGetGuildTargetMemberNum(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildItem(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildItem{AckHandle: 1, GuildID: 1}
handleMsgMhfEnumerateGuildItem(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfUpdateGuildItem(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfUpdateGuildItem{AckHandle: 1, GuildID: 1}
handleMsgMhfUpdateGuildItem(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfUpdateGuildIcon_LeaderSuccess(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1}
membership := &GuildMember{CharID: 100, IsLeader: true}
server.guildRepo = &mockGuildRepo{guild: guild, membership: membership}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfUpdateGuildIcon{
AckHandle: 1,
GuildID: 1,
IconParts: []mhfpacket.GuildIconMsgPart{
{Index: 0, ID: 1, Page: 0, Size: 10, Rotation: 0, Red: 255, Green: 0, Blue: 0, PosX: 50, PosY: 50},
},
}
handleMsgMhfUpdateGuildIcon(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfUpdateGuildIcon_NotLeader(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1}
membership := &GuildMember{CharID: 100, IsLeader: false, OrderIndex: 5}
server.guildRepo = &mockGuildRepo{guild: guild, membership: membership}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfUpdateGuildIcon{AckHandle: 1, GuildID: 1}
handleMsgMhfUpdateGuildIcon(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfUpdateGuildIcon_GetByIDError(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{getErr: errNotFound}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfUpdateGuildIcon{AckHandle: 1, GuildID: 999}
handleMsgMhfUpdateGuildIcon(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadGuildcard(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadGuildcard{AckHandle: 1}
handleMsgMhfReadGuildcard(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSetGuildManageRight(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfSetGuildManageRight{AckHandle: 1, CharID: 200, Allowed: true}
handleMsgMhfSetGuildManageRight(session, pkt)
<-session.sendPackets
}

View File

@@ -0,0 +1,99 @@
package channelserver
import (
"testing"
"erupe-ce/network/mhfpacket"
)
// --- Guild mission handler tests ---
func TestHandleMsgMhfAddGuildMissionCount(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfAddGuildMissionCount(session, &mhfpacket.MsgMhfAddGuildMissionCount{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfSetGuildMissionTarget(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfSetGuildMissionTarget(session, &mhfpacket.MsgMhfSetGuildMissionTarget{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfCancelGuildMissionTarget(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfCancelGuildMissionTarget(session, &mhfpacket.MsgMhfCancelGuildMissionTarget{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfGetGuildMissionRecord(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetGuildMissionRecord(session, &mhfpacket.MsgMhfGetGuildMissionRecord{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
func TestHandleMsgMhfGetGuildMissionList(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetGuildMissionList(session, &mhfpacket.MsgMhfGetGuildMissionList{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}

View File

@@ -1,109 +0,0 @@
package channelserver
import (
"erupe-ce/common/byteframe"
"erupe-ce/common/stringsupport"
"erupe-ce/network/mhfpacket"
"testing"
)
func TestHandleRenamePugi_Pugi1(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
bf := byteframe.NewByteFrame()
nameBytes := stringsupport.UTF8ToSJIS("TestPugi")
bf.WriteBytes(nameBytes)
bf.WriteUint8(0) // null terminator
bf.Seek(0, 0)
handleRenamePugi(s, bf, guild, 1)
if guild.PugiName1 != "TestPugi" {
t.Errorf("PugiName1 = %q, want TestPugi", guild.PugiName1)
}
}
func TestHandleRenamePugi_Pugi2(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
bf := byteframe.NewByteFrame()
nameBytes := stringsupport.UTF8ToSJIS("Pugi2")
bf.WriteBytes(nameBytes)
bf.WriteUint8(0)
bf.Seek(0, 0)
handleRenamePugi(s, bf, guild, 2)
if guild.PugiName2 != "Pugi2" {
t.Errorf("PugiName2 = %q, want Pugi2", guild.PugiName2)
}
}
func TestHandleRenamePugi_Pugi3Default(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
bf := byteframe.NewByteFrame()
nameBytes := stringsupport.UTF8ToSJIS("Pugi3")
bf.WriteBytes(nameBytes)
bf.WriteUint8(0)
bf.Seek(0, 0)
handleRenamePugi(s, bf, guild, 3)
if guild.PugiName3 != "Pugi3" {
t.Errorf("PugiName3 = %q, want Pugi3", guild.PugiName3)
}
}
func TestHandleChangePugi_AllNums(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
handleChangePugi(s, 5, guild, 1)
if guild.PugiOutfit1 != 5 {
t.Errorf("PugiOutfit1 = %d, want 5", guild.PugiOutfit1)
}
handleChangePugi(s, 10, guild, 2)
if guild.PugiOutfit2 != 10 {
t.Errorf("PugiOutfit2 = %d, want 10", guild.PugiOutfit2)
}
handleChangePugi(s, 15, guild, 3)
if guild.PugiOutfit3 != 15 {
t.Errorf("PugiOutfit3 = %d, want 15", guild.PugiOutfit3)
}
}
func TestHandleAvoidLeadershipUpdate_Success(t *testing.T) {
srv := createMockServer()
membership := &GuildMember{CharID: 100, AvoidLeadership: false}
srv.guildRepo = &mockGuildRepo{membership: membership}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateGuild{AckHandle: 1}
handleAvoidLeadershipUpdate(s, pkt, true)
<-s.sendPackets
if !membership.AvoidLeadership {
t.Error("AvoidLeadership should be true")
}
}
func TestHandleAvoidLeadershipUpdate_GetMembershipError(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getMemberErr: errNotFound}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateGuild{AckHandle: 1}
handleAvoidLeadershipUpdate(s, pkt, true)
<-s.sendPackets
}

View File

@@ -5,6 +5,7 @@ import (
"erupe-ce/common/byteframe"
"erupe-ce/network/mhfpacket"
"erupe-ce/common/stringsupport"
)
// --- handleMsgMhfOperateGuild tests ---
@@ -618,3 +619,104 @@ func newMottoBF(sub, main uint8) *byteframe.ByteFrame {
_, _ = bf.Seek(0, 0)
return bf
}
func TestHandleRenamePugi_Pugi1(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
bf := byteframe.NewByteFrame()
nameBytes := stringsupport.UTF8ToSJIS("TestPugi")
bf.WriteBytes(nameBytes)
bf.WriteUint8(0) // null terminator
bf.Seek(0, 0)
handleRenamePugi(s, bf, guild, 1)
if guild.PugiName1 != "TestPugi" {
t.Errorf("PugiName1 = %q, want TestPugi", guild.PugiName1)
}
}
func TestHandleRenamePugi_Pugi2(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
bf := byteframe.NewByteFrame()
nameBytes := stringsupport.UTF8ToSJIS("Pugi2")
bf.WriteBytes(nameBytes)
bf.WriteUint8(0)
bf.Seek(0, 0)
handleRenamePugi(s, bf, guild, 2)
if guild.PugiName2 != "Pugi2" {
t.Errorf("PugiName2 = %q, want Pugi2", guild.PugiName2)
}
}
func TestHandleRenamePugi_Pugi3Default(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
bf := byteframe.NewByteFrame()
nameBytes := stringsupport.UTF8ToSJIS("Pugi3")
bf.WriteBytes(nameBytes)
bf.WriteUint8(0)
bf.Seek(0, 0)
handleRenamePugi(s, bf, guild, 3)
if guild.PugiName3 != "Pugi3" {
t.Errorf("PugiName3 = %q, want Pugi3", guild.PugiName3)
}
}
func TestHandleChangePugi_AllNums(t *testing.T) {
srv := createMockServer()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
handleChangePugi(s, 5, guild, 1)
if guild.PugiOutfit1 != 5 {
t.Errorf("PugiOutfit1 = %d, want 5", guild.PugiOutfit1)
}
handleChangePugi(s, 10, guild, 2)
if guild.PugiOutfit2 != 10 {
t.Errorf("PugiOutfit2 = %d, want 10", guild.PugiOutfit2)
}
handleChangePugi(s, 15, guild, 3)
if guild.PugiOutfit3 != 15 {
t.Errorf("PugiOutfit3 = %d, want 15", guild.PugiOutfit3)
}
}
func TestHandleAvoidLeadershipUpdate_Success(t *testing.T) {
srv := createMockServer()
membership := &GuildMember{CharID: 100, AvoidLeadership: false}
srv.guildRepo = &mockGuildRepo{membership: membership}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateGuild{AckHandle: 1}
handleAvoidLeadershipUpdate(s, pkt, true)
<-s.sendPackets
if !membership.AvoidLeadership {
t.Error("AvoidLeadership should be true")
}
}
func TestHandleAvoidLeadershipUpdate_GetMembershipError(t *testing.T) {
srv := createMockServer()
srv.guildRepo = &mockGuildRepo{getMemberErr: errNotFound}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateGuild{AckHandle: 1}
handleAvoidLeadershipUpdate(s, pkt, true)
<-s.sendPackets
}

View File

@@ -824,6 +824,26 @@ func TestGuildAllianceRelationship(t *testing.T) {
}
}
// --- handleMsgMhfGetUdGuildMapInfo tests ---
func TestHandleMsgMhfGetUdGuildMapInfo(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfGetUdGuildMapInfo(session, &mhfpacket.MsgMhfGetUdGuildMapInfo{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
// --- handleMsgMhfCheckMonthlyItem tests ---
func TestCheckMonthlyItem_NotClaimed(t *testing.T) {
@@ -902,6 +922,156 @@ func TestCheckMonthlyItem_UnknownType(t *testing.T) {
}
}
func TestHandleMsgMhfEntryRookieGuild(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEntryRookieGuild{
AckHandle: 12345,
Unk: 42,
}
handleMsgMhfEntryRookieGuild(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfGenerateUdGuildMap(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfGenerateUdGuildMap{
AckHandle: 12345,
}
handleMsgMhfGenerateUdGuildMap(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateInvGuild(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateInvGuild{
AckHandle: 12345,
}
handleMsgMhfEnumerateInvGuild(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfOperationInvGuild(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfOperationInvGuild{
AckHandle: 12345,
Operation: 1,
}
handleMsgMhfOperationInvGuild(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfCheckMonthlyItem_Coverage2(t *testing.T) {
server := createMockServer()
server.stampRepo = &mockStampRepoForItems{monthlyClaimedErr: errNotFound}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfCheckMonthlyItem{
AckHandle: 12345,
Type: 0,
}
handleMsgMhfCheckMonthlyItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfAcquireMonthlyItem_Coverage2(t *testing.T) {
server := createMockServer()
server.stampRepo = &mockStampRepoForItems{}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfAcquireMonthlyItem{
AckHandle: 12345,
}
handleMsgMhfAcquireMonthlyItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestEmptyGuildHandlers(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
handler func(s *Session, p mhfpacket.MHFPacket)
}{
{"handleMsgMhfUpdateForceGuildRank", handleMsgMhfUpdateForceGuildRank},
{"handleMsgMhfUpdateGuild", handleMsgMhfUpdateGuild},
{"handleMsgMhfUpdateGuildcard", handleMsgMhfUpdateGuildcard},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.handler(session, nil)
})
}
}
func TestAcquireMonthlyItem_MarksAsClaimed(t *testing.T) {
server := createMockServer()
stampMock := &mockStampRepoForItems{}
@@ -924,3 +1094,242 @@ func TestAcquireMonthlyItem_MarksAsClaimed(t *testing.T) {
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfCreateGuild_Success(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfCreateGuild{AckHandle: 1, Name: "TestGuild"}
handleMsgMhfCreateGuild(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("expected non-empty response")
}
default:
t.Error("expected a response packet")
}
}
func TestHandleMsgMhfCreateGuild_Error(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{saveErr: errNotFound}
// Mock Create to return error - the mockGuildRepo.Create returns (0, nil)
// We need getErr to make it fail. Actually Create is a no-op stub returning nil.
// Let's use a custom approach - we need the Create method to error.
// The mock's Create always returns nil, so let's test the success path worked above
// and test ArrangeGuildMember error paths instead.
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfCreateGuild{AckHandle: 1, Name: "TestGuild"}
handleMsgMhfCreateGuild(session, pkt)
<-session.sendPackets // consume the response
}
func TestHandleMsgMhfArrangeGuildMember_Success(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, GuildLeader: GuildLeader{LeaderCharID: 100}}
server.guildRepo = &mockGuildRepo{guild: guild}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfArrangeGuildMember{
AckHandle: 1,
GuildID: 1,
CharIDs: []uint32{100, 200, 300},
}
handleMsgMhfArrangeGuildMember(session, pkt)
select {
case <-session.sendPackets:
default:
t.Error("expected response")
}
}
func TestHandleMsgMhfArrangeGuildMember_GetByIDError(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{getErr: errNotFound}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfArrangeGuildMember{AckHandle: 1, GuildID: 999}
handleMsgMhfArrangeGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfArrangeGuildMember_NotLeader(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, GuildLeader: GuildLeader{LeaderCharID: 200, LeaderName: "Other"}}
server.guildRepo = &mockGuildRepo{guild: guild}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfArrangeGuildMember{AckHandle: 1, GuildID: 1}
handleMsgMhfArrangeGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMember_GuildIDPositive(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, MemberCount: 2}
members := []*GuildMember{
{CharID: 100, Name: "Player1", HR: 50, OrderIndex: 0, WeaponType: 3},
{CharID: 200, Name: "Player2", HR: 100, OrderIndex: 1, WeaponType: 1},
}
server.guildRepo = &mockGuildRepo{guild: guild, members: members}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildMember{AckHandle: 1, GuildID: 1}
handleMsgMhfEnumerateGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMember_GuildIDZero(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, MemberCount: 1}
members := []*GuildMember{
{CharID: 100, Name: "Player1", HR: 50, OrderIndex: 0},
}
server.guildRepo = &mockGuildRepo{guild: guild, members: members}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildMember{AckHandle: 1, GuildID: 0}
handleMsgMhfEnumerateGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMember_NilGuild(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildMember{AckHandle: 1, GuildID: 0}
handleMsgMhfEnumerateGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildMember_Applicant(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1}
server.guildRepo = &mockGuildRepo{guild: guild, hasAppResult: true}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildMember{AckHandle: 1, GuildID: 1}
handleMsgMhfEnumerateGuildMember(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfGetGuildManageRight(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, MemberCount: 2}
members := []*GuildMember{
{CharID: 100, Recruiter: true},
{CharID: 200, Recruiter: false},
}
server.guildRepo = &mockGuildRepo{guild: guild, members: members}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfGetGuildManageRight{AckHandle: 1}
handleMsgMhfGetGuildManageRight(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfGetGuildTargetMemberNum_NilGuild(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfGetGuildTargetMemberNum{AckHandle: 1, GuildID: 0}
handleMsgMhfGetGuildTargetMemberNum(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfGetGuildTargetMemberNum_WithGuild(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1, MemberCount: 5}
server.guildRepo = &mockGuildRepo{guild: guild}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfGetGuildTargetMemberNum{AckHandle: 1, GuildID: 1}
handleMsgMhfGetGuildTargetMemberNum(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfEnumerateGuildItem(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfEnumerateGuildItem{AckHandle: 1, GuildID: 1}
handleMsgMhfEnumerateGuildItem(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfUpdateGuildItem(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfUpdateGuildItem{AckHandle: 1, GuildID: 1}
handleMsgMhfUpdateGuildItem(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfUpdateGuildIcon_LeaderSuccess(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1}
membership := &GuildMember{CharID: 100, IsLeader: true}
server.guildRepo = &mockGuildRepo{guild: guild, membership: membership}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfUpdateGuildIcon{
AckHandle: 1,
GuildID: 1,
IconParts: []mhfpacket.GuildIconMsgPart{
{Index: 0, ID: 1, Page: 0, Size: 10, Rotation: 0, Red: 255, Green: 0, Blue: 0, PosX: 50, PosY: 50},
},
}
handleMsgMhfUpdateGuildIcon(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfUpdateGuildIcon_NotLeader(t *testing.T) {
server := createMockServer()
guild := &Guild{ID: 1}
membership := &GuildMember{CharID: 100, IsLeader: false, OrderIndex: 5}
server.guildRepo = &mockGuildRepo{guild: guild, membership: membership}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfUpdateGuildIcon{AckHandle: 1, GuildID: 1}
handleMsgMhfUpdateGuildIcon(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfUpdateGuildIcon_GetByIDError(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{getErr: errNotFound}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfUpdateGuildIcon{AckHandle: 1, GuildID: 999}
handleMsgMhfUpdateGuildIcon(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadGuildcard(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadGuildcard{AckHandle: 1}
handleMsgMhfReadGuildcard(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSetGuildManageRight(t *testing.T) {
server := createMockServer()
server.guildRepo = &mockGuildRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfSetGuildManageRight{AckHandle: 1, CharID: 200, Allowed: true}
handleMsgMhfSetGuildManageRight(session, pkt)
<-session.sendPackets
}

View File

@@ -186,6 +186,26 @@ func TestOperateGuildTresureReport_Claim(t *testing.T) {
}
}
// --- handleMsgMhfAcquireGuildTresureSouvenir tests ---
func TestHandleMsgMhfAcquireGuildTresureSouvenir(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
handleMsgMhfAcquireGuildTresureSouvenir(session, &mhfpacket.MsgMhfAcquireGuildTresureSouvenir{
AckHandle: 1,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
}
// --- handleMsgMhfGetGuildTresureSouvenir tests ---
func TestGetGuildTresureSouvenir_Empty(t *testing.T) {

View File

@@ -190,6 +190,77 @@ func TestUpdateRights(t *testing.T) {
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestStubHelpers(t *testing.T) {
server := createMockServer()
t.Run("stubEnumerateNoResults", func(t *testing.T) {
session := createMockSession(1, server)
stubEnumerateNoResults(session, 1)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("doAckBufSucceed", func(t *testing.T) {
session := createMockSession(1, server)
doAckBufSucceed(session, 1, []byte{0x01, 0x02, 0x03})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("doAckBufFail", func(t *testing.T) {
session := createMockSession(1, server)
doAckBufFail(session, 1, []byte{0x01, 0x02, 0x03})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("doAckSimpleSucceed", func(t *testing.T) {
session := createMockSession(1, server)
doAckSimpleSucceed(session, 1, []byte{0x00, 0x00, 0x00, 0x00})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("doAckSimpleFail", func(t *testing.T) {
session := createMockSession(1, server)
doAckSimpleFail(session, 1, []byte{0x00, 0x00, 0x00, 0x00})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
}
func TestUpdateRights_Error(t *testing.T) {
server := createMockServer()
userRepo := &mockUserRepoGacha{rightsErr: errors.New("db error")}

View File

@@ -1,265 +0,0 @@
package channelserver
import (
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
"testing"
)
func TestHandleMsgMhfEnumerateHouse_Method3_SearchByName(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.RealClientMode = cfg.ZZ
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 3, Name: "TestHouse"}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method4_ByCharID(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.RealClientMode = cfg.ZZ
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 4, CharID: 200}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method5_RecentVisitors(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 5}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method1_Friends(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
charRepo := newMockCharacterRepo()
charRepo.strings["friends"] = ""
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 1}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method2_GuildMembers(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 2}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method2_NoGuild(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 2}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfSaveDecoMyset_ShortPayload(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfSaveDecoMyset{AckHandle: 1, RawDataPayload: []byte{0x00, 0x01}}
handleMsgMhfSaveDecoMyset(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfSaveDecoMyset_WithData(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// Pre-populate with version byte + 0 sets
charRepo.columns["decomyset"] = []byte{0x01, 0x00}
srv.charRepo = charRepo
srv.erupeConfig.RealClientMode = cfg.ZZ
s := createMockSession(100, srv)
// Build payload: version byte + 1 set with index 0 + 76 bytes of data
payload := make([]byte, 3+2+76)
payload[0] = 0x01 // version
payload[1] = 0x01 // count
payload[2] = 0x00 // padding
pkt := &mhfpacket.MsgMhfSaveDecoMyset{AckHandle: 1, RawDataPayload: payload}
handleMsgMhfSaveDecoMyset(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfInfoTournament_Type2(t *testing.T) {
srv := createMockServer()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfInfoTournament{AckHandle: 1, QueryType: 2}
handleMsgMhfInfoTournament(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateInterior_Normal(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateInterior{AckHandle: 1, InteriorData: make([]byte, 20)}
handleMsgMhfUpdateInterior(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateInterior_TooLarge(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateInterior{AckHandle: 1, InteriorData: make([]byte, 100)}
handleMsgMhfUpdateInterior(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateMyhouseInfo_Normal(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateMyhouseInfo{AckHandle: 1, Data: make([]byte, 9)}
handleMsgMhfUpdateMyhouseInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateMyhouseInfo_TooLarge(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateMyhouseInfo{AckHandle: 1, Data: make([]byte, 600)}
handleMsgMhfUpdateMyhouseInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetMyhouseInfo(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetMyhouseInfo{AckHandle: 1}
handleMsgMhfGetMyhouseInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateTitle(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateTitle{AckHandle: 1}
handleMsgMhfEnumerateTitle(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfAcquireTitle(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfAcquireTitle{AckHandle: 1, TitleIDs: []uint16{1, 2, 3}}
handleMsgMhfAcquireTitle(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateHouse(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateHouse{AckHandle: 1, State: 2, Password: "1234"}
handleMsgMhfUpdateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op0(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 0}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op1(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 1}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op2_Rename(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 2, BoxType: 0, BoxIndex: 1, Name: "MyBox"}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op3(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 3}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op4(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 4}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateWarehouse_Items(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateWarehouse{AckHandle: 1, BoxType: 0, BoxIndex: 0}
handleMsgMhfEnumerateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateWarehouse_Equipment(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateWarehouse{AckHandle: 1, BoxType: 1, BoxIndex: 0}
handleMsgMhfEnumerateWarehouse(s, pkt)
<-s.sendPackets
}

View File

@@ -1147,3 +1147,261 @@ func BenchmarkWarehouseEquipmentMerge(b *testing.B) {
_ = finalEquip // Use finalEquip to avoid unused variable warning
}
}
func TestHandleMsgMhfEnumerateHouse_Method3_SearchByName(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.RealClientMode = cfg.ZZ
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 3, Name: "TestHouse"}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method4_ByCharID(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.RealClientMode = cfg.ZZ
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 4, CharID: 200}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method5_RecentVisitors(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 5}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method1_Friends(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
charRepo := newMockCharacterRepo()
charRepo.strings["friends"] = ""
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 1}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method2_GuildMembers(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
guild := &Guild{ID: 1}
srv.guildRepo = &mockGuildRepo{guild: guild}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 2}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateHouse_Method2_NoGuild(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
srv.guildRepo = &mockGuildRepo{getErr: errNotFound}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateHouse{AckHandle: 1, Method: 2}
handleMsgMhfEnumerateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfSaveDecoMyset_ShortPayload(t *testing.T) {
srv := createMockServer()
srv.charRepo = newMockCharacterRepo()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfSaveDecoMyset{AckHandle: 1, RawDataPayload: []byte{0x00, 0x01}}
handleMsgMhfSaveDecoMyset(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfSaveDecoMyset_WithData(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
// Pre-populate with version byte + 0 sets
charRepo.columns["decomyset"] = []byte{0x01, 0x00}
srv.charRepo = charRepo
srv.erupeConfig.RealClientMode = cfg.ZZ
s := createMockSession(100, srv)
// Build payload: version byte + 1 set with index 0 + 76 bytes of data
payload := make([]byte, 3+2+76)
payload[0] = 0x01 // version
payload[1] = 0x01 // count
payload[2] = 0x00 // padding
pkt := &mhfpacket.MsgMhfSaveDecoMyset{AckHandle: 1, RawDataPayload: payload}
handleMsgMhfSaveDecoMyset(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfInfoTournament_Type2(t *testing.T) {
srv := createMockServer()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfInfoTournament{AckHandle: 1, QueryType: 2}
handleMsgMhfInfoTournament(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateInterior_Normal(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateInterior{AckHandle: 1, InteriorData: make([]byte, 20)}
handleMsgMhfUpdateInterior(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateInterior_TooLarge(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateInterior{AckHandle: 1, InteriorData: make([]byte, 100)}
handleMsgMhfUpdateInterior(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateMyhouseInfo_Normal(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateMyhouseInfo{AckHandle: 1, Data: make([]byte, 9)}
handleMsgMhfUpdateMyhouseInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateMyhouseInfo_TooLarge(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateMyhouseInfo{AckHandle: 1, Data: make([]byte, 600)}
handleMsgMhfUpdateMyhouseInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetMyhouseInfo(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetMyhouseInfo{AckHandle: 1}
handleMsgMhfGetMyhouseInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateTitle(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateTitle{AckHandle: 1}
handleMsgMhfEnumerateTitle(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfAcquireTitle(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfAcquireTitle{AckHandle: 1, TitleIDs: []uint16{1, 2, 3}}
handleMsgMhfAcquireTitle(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfUpdateHouse(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateHouse{AckHandle: 1, State: 2, Password: "1234"}
handleMsgMhfUpdateHouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op0(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 0}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op1(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 1}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op2_Rename(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 2, BoxType: 0, BoxIndex: 1, Name: "MyBox"}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op3(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 3}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfOperateWarehouse_Op4(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfOperateWarehouse{AckHandle: 1, Operation: 4}
handleMsgMhfOperateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateWarehouse_Items(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateWarehouse{AckHandle: 1, BoxType: 0, BoxIndex: 0}
handleMsgMhfEnumerateWarehouse(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfEnumerateWarehouse_Equipment(t *testing.T) {
srv := createMockServer()
srv.houseRepo = newMockHouseRepoForItems()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfEnumerateWarehouse{AckHandle: 1, BoxType: 1, BoxIndex: 0}
handleMsgMhfEnumerateWarehouse(s, pkt)
<-s.sendPackets
}

View File

@@ -322,6 +322,51 @@ func TestExchangeWeeklyStamp_ExchangeError(t *testing.T) {
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestNonTrivialHandlers_NoDB_Items(t *testing.T) {
server := createMockServer()
t.Run("handleMsgMhfTransferItem", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfTransferItem(session, &mhfpacket.MsgMhfTransferItem{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("handleMsgMhfEnumerateOrder", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfEnumerateOrder(session, &mhfpacket.MsgMhfEnumerateOrder{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("handleMsgMhfEnumeratePrice", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfEnumeratePrice(session, &mhfpacket.MsgMhfEnumeratePrice{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
}
func TestExchangeWeeklyStamp_Yearly(t *testing.T) {
server := createMockServer()
stampMock := &mockStampRepoForItems{
@@ -362,3 +407,78 @@ func TestExchangeWeeklyStamp_Yearly(t *testing.T) {
t.Error("No response packet queued")
}
}
// Tests consolidated from handlers_core_test.go
func TestHandleMsgMhfGetExtraInfo(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgMhfGetExtraInfo panicked: %v", r)
}
}()
handleMsgMhfGetExtraInfo(session, nil)
}
func TestHandleMsgMhfTransferItem(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfTransferItem{
AckHandle: 12345,
}
handleMsgMhfTransferItem(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumeratePrice(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumeratePrice{
AckHandle: 12345,
}
handleMsgMhfEnumeratePrice(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfEnumerateOrder(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfEnumerateOrder{
AckHandle: 12345,
}
handleMsgMhfEnumerateOrder(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}

View File

@@ -1,256 +0,0 @@
package channelserver
import (
"testing"
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
)
func TestHandleMsgMhfLoadPartner(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadPartner{AckHandle: 1}
handleMsgMhfLoadPartner(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSavePartner(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfSavePartner{AckHandle: 1, RawDataPayload: []byte{1, 2, 3, 4}}
handleMsgMhfSavePartner(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfLoadHunterNavi_G8(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
server.erupeConfig.RealClientMode = cfg.G10
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadHunterNavi{AckHandle: 1}
handleMsgMhfLoadHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfLoadHunterNavi_G7(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
server.erupeConfig.RealClientMode = cfg.G7
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadHunterNavi{AckHandle: 1}
handleMsgMhfLoadHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveHunterNavi_NoDiff(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
data := make([]byte, 100)
pkt := &mhfpacket.MsgMhfSaveHunterNavi{
AckHandle: 1,
IsDataDiff: false,
RawDataPayload: data,
}
handleMsgMhfSaveHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveHunterNavi_Diff(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.columns["hunternavi"] = make([]byte, 552)
server.charRepo = charRepo
server.erupeConfig.RealClientMode = cfg.G10
session := createMockSession(100, server)
// Create a valid diff payload (deltacomp format: pairs of offset+data)
// A simple diff: zero length means no changes
diffData := make([]byte, 4) // minimal diff
pkt := &mhfpacket.MsgMhfSaveHunterNavi{
AckHandle: 1,
IsDataDiff: true,
RawDataPayload: diffData,
}
handleMsgMhfSaveHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveHunterNavi_OversizedPayload(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
data := make([]byte, 5000) // > 4096
pkt := &mhfpacket.MsgMhfSaveHunterNavi{
AckHandle: 1,
IsDataDiff: false,
RawDataPayload: data,
}
handleMsgMhfSaveHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfCreateMercenary_Success(t *testing.T) {
server := createMockServer()
server.mercenaryRepo = &mockMercenaryRepo{nextRastaID: 42}
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfCreateMercenary{AckHandle: 1}
handleMsgMhfCreateMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfCreateMercenary_Error(t *testing.T) {
server := createMockServer()
server.mercenaryRepo = &mockMercenaryRepo{rastaIDErr: errNotFound}
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfCreateMercenary{AckHandle: 1}
handleMsgMhfCreateMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveMercenary_Normal(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
mercData := make([]byte, 100)
// Write a uint32 index at the start
mercData[0] = 0
mercData[1] = 0
mercData[2] = 0
mercData[3] = 1
pkt := &mhfpacket.MsgMhfSaveMercenary{
AckHandle: 1,
GCP: 500,
PactMercID: 10,
MercData: mercData,
}
handleMsgMhfSaveMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveMercenary_Oversized(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfSaveMercenary{
AckHandle: 1,
MercData: make([]byte, 70000),
}
handleMsgMhfSaveMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryM_EmptyData(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadMercenaryM{AckHandle: 1, CharID: 200}
handleMsgMhfReadMercenaryM(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryM_WithData(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.columns["savemercenary"] = []byte{0x01, 0x02, 0x03, 0x04}
server.charRepo = charRepo
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadMercenaryM{AckHandle: 1, CharID: 100}
handleMsgMhfReadMercenaryM(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfContractMercenary_Op0(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfContractMercenary{AckHandle: 1, Op: 0, CID: 200, PactMercID: 42}
handleMsgMhfContractMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfContractMercenary_Op1(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfContractMercenary{AckHandle: 1, Op: 1}
handleMsgMhfContractMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfContractMercenary_Op2(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfContractMercenary{AckHandle: 1, Op: 2, CID: 200}
handleMsgMhfContractMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryW_NoPact(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
server.charRepo = charRepo
server.mercenaryRepo = &mockMercenaryRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadMercenaryW{AckHandle: 1, Op: 0}
handleMsgMhfReadMercenaryW(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryW_WithPact(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.ints["pact_id"] = 42
server.charRepo = charRepo
server.mercenaryRepo = &mockMercenaryRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadMercenaryW{AckHandle: 1, Op: 0}
handleMsgMhfReadMercenaryW(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryW_Op2(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
server.charRepo = charRepo
server.mercenaryRepo = &mockMercenaryRepo{}
session := createMockSession(100, server)
// Op 2 skips loan enumeration
pkt := &mhfpacket.MsgMhfReadMercenaryW{AckHandle: 1, Op: 2}
handleMsgMhfReadMercenaryW(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfLoadOtomoAirou(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadOtomoAirou{AckHandle: 1}
handleMsgMhfLoadOtomoAirou(session, pkt)
<-session.sendPackets
}

View File

@@ -7,6 +7,7 @@ import (
"erupe-ce/common/byteframe"
"erupe-ce/network/mhfpacket"
cfg "erupe-ce/config"
)
func TestHandleMsgMhfLoadLegendDispatch(t *testing.T) {
@@ -232,6 +233,119 @@ func TestGetAirouDetails_CatNamePadding(t *testing.T) {
}
}
func TestHandleMsgMhfMercenaryHuntdata_RequestTypeIs1(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfMercenaryHuntdata{
AckHandle: 12345,
RequestType: 1,
}
handleMsgMhfMercenaryHuntdata(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfMercenaryHuntdata_RequestTypeIs0(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfMercenaryHuntdata{
AckHandle: 12345,
RequestType: 0,
}
handleMsgMhfMercenaryHuntdata(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfMercenaryHuntdata_RequestTypeIs2(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfMercenaryHuntdata{
AckHandle: 12345,
RequestType: 2,
}
handleMsgMhfMercenaryHuntdata(session, pkt)
// RequestType=2 takes the else branch (same as 0)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfLoadLegendDispatch_Response(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfLoadLegendDispatch{
AckHandle: 22222,
}
handleMsgMhfLoadLegendDispatch(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestAirouStruct(t *testing.T) {
cat := Airou{
ID: 42,
Name: []byte("TestCat"),
Task: 4,
Personality: 2,
Class: 1,
Experience: 1500,
WeaponType: 6,
WeaponID: 100,
}
if cat.ID != 42 {
t.Errorf("ID = %d, want 42", cat.ID)
}
if cat.Task != 4 {
t.Errorf("Task = %d, want 4", cat.Task)
}
if cat.Experience != 1500 {
t.Errorf("Experience = %d, want 1500", cat.Experience)
}
if cat.WeaponType != 6 {
t.Errorf("WeaponType = %d, want 6", cat.WeaponType)
}
if cat.WeaponID != 100 {
t.Errorf("WeaponID = %d, want 100", cat.WeaponID)
}
}
// TestHandleMsgMhfMercenaryHuntdata_Unk0_1 tests with Unk0=1 (returns 1 byte)
func TestHandleMsgMhfMercenaryHuntdata_Unk0_1(t *testing.T) {
server := createMockServer()
@@ -296,3 +410,251 @@ func TestHandleMsgMhfEnumerateMercenaryLog(t *testing.T) {
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfLoadPartner(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadPartner{AckHandle: 1}
handleMsgMhfLoadPartner(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSavePartner(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfSavePartner{AckHandle: 1, RawDataPayload: []byte{1, 2, 3, 4}}
handleMsgMhfSavePartner(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfLoadHunterNavi_G8(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
server.erupeConfig.RealClientMode = cfg.G10
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadHunterNavi{AckHandle: 1}
handleMsgMhfLoadHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfLoadHunterNavi_G7(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
server.erupeConfig.RealClientMode = cfg.G7
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadHunterNavi{AckHandle: 1}
handleMsgMhfLoadHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveHunterNavi_NoDiff(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
data := make([]byte, 100)
pkt := &mhfpacket.MsgMhfSaveHunterNavi{
AckHandle: 1,
IsDataDiff: false,
RawDataPayload: data,
}
handleMsgMhfSaveHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveHunterNavi_Diff(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.columns["hunternavi"] = make([]byte, 552)
server.charRepo = charRepo
server.erupeConfig.RealClientMode = cfg.G10
session := createMockSession(100, server)
// Create a valid diff payload (deltacomp format: pairs of offset+data)
// A simple diff: zero length means no changes
diffData := make([]byte, 4) // minimal diff
pkt := &mhfpacket.MsgMhfSaveHunterNavi{
AckHandle: 1,
IsDataDiff: true,
RawDataPayload: diffData,
}
handleMsgMhfSaveHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveHunterNavi_OversizedPayload(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
data := make([]byte, 5000) // > 4096
pkt := &mhfpacket.MsgMhfSaveHunterNavi{
AckHandle: 1,
IsDataDiff: false,
RawDataPayload: data,
}
handleMsgMhfSaveHunterNavi(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfCreateMercenary_Success(t *testing.T) {
server := createMockServer()
server.mercenaryRepo = &mockMercenaryRepo{nextRastaID: 42}
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfCreateMercenary{AckHandle: 1}
handleMsgMhfCreateMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfCreateMercenary_Error(t *testing.T) {
server := createMockServer()
server.mercenaryRepo = &mockMercenaryRepo{rastaIDErr: errNotFound}
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfCreateMercenary{AckHandle: 1}
handleMsgMhfCreateMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveMercenary_Normal(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
mercData := make([]byte, 100)
// Write a uint32 index at the start
mercData[0] = 0
mercData[1] = 0
mercData[2] = 0
mercData[3] = 1
pkt := &mhfpacket.MsgMhfSaveMercenary{
AckHandle: 1,
GCP: 500,
PactMercID: 10,
MercData: mercData,
}
handleMsgMhfSaveMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfSaveMercenary_Oversized(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfSaveMercenary{
AckHandle: 1,
MercData: make([]byte, 70000),
}
handleMsgMhfSaveMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryM_EmptyData(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadMercenaryM{AckHandle: 1, CharID: 200}
handleMsgMhfReadMercenaryM(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryM_WithData(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.columns["savemercenary"] = []byte{0x01, 0x02, 0x03, 0x04}
server.charRepo = charRepo
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadMercenaryM{AckHandle: 1, CharID: 100}
handleMsgMhfReadMercenaryM(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfContractMercenary_Op0(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfContractMercenary{AckHandle: 1, Op: 0, CID: 200, PactMercID: 42}
handleMsgMhfContractMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfContractMercenary_Op1(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfContractMercenary{AckHandle: 1, Op: 1}
handleMsgMhfContractMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfContractMercenary_Op2(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfContractMercenary{AckHandle: 1, Op: 2, CID: 200}
handleMsgMhfContractMercenary(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryW_NoPact(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
server.charRepo = charRepo
server.mercenaryRepo = &mockMercenaryRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadMercenaryW{AckHandle: 1, Op: 0}
handleMsgMhfReadMercenaryW(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryW_WithPact(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.ints["pact_id"] = 42
server.charRepo = charRepo
server.mercenaryRepo = &mockMercenaryRepo{}
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfReadMercenaryW{AckHandle: 1, Op: 0}
handleMsgMhfReadMercenaryW(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfReadMercenaryW_Op2(t *testing.T) {
server := createMockServer()
charRepo := newMockCharacterRepo()
server.charRepo = charRepo
server.mercenaryRepo = &mockMercenaryRepo{}
session := createMockSession(100, server)
// Op 2 skips loan enumeration
pkt := &mhfpacket.MsgMhfReadMercenaryW{AckHandle: 1, Op: 2}
handleMsgMhfReadMercenaryW(session, pkt)
<-session.sendPackets
}
func TestHandleMsgMhfLoadOtomoAirou(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadOtomoAirou{AckHandle: 1}
handleMsgMhfLoadOtomoAirou(session, pkt)
<-session.sendPackets
}

View File

@@ -1,313 +0,0 @@
package channelserver
import (
"erupe-ce/network/mhfpacket"
"testing"
)
// --- Enhanced Minidata tests (in-memory store, no DB) ---
func TestHandleMsgMhfGetEnhancedMinidata_NotFound(t *testing.T) {
srv := createMockServer()
srv.minidata = NewMinidataStore()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetEnhancedMinidata{AckHandle: 1, CharID: 999}
handleMsgMhfGetEnhancedMinidata(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetEnhancedMinidata_Found(t *testing.T) {
srv := createMockServer()
srv.minidata = NewMinidataStore()
srv.minidata.Set(42, []byte{0xDE, 0xAD, 0xBE, 0xEF})
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetEnhancedMinidata{AckHandle: 1, CharID: 42}
handleMsgMhfGetEnhancedMinidata(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfSetEnhancedMinidata(t *testing.T) {
srv := createMockServer()
srv.minidata = NewMinidataStore()
s := createMockSession(100, srv)
payload := []byte{0x01, 0x02, 0x03}
pkt := &mhfpacket.MsgMhfSetEnhancedMinidata{AckHandle: 1, RawDataPayload: payload}
handleMsgMhfSetEnhancedMinidata(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
data, ok := srv.minidata.Get(100)
if !ok {
t.Fatal("Minidata not stored")
}
if len(data) != 3 || data[0] != 0x01 {
t.Errorf("Unexpected stored data: %v", data)
}
}
// --- Trend Weapon tests ---
func TestHandleMsgMhfGetTrendWeapon_Empty(t *testing.T) {
srv := createMockServer()
srv.miscRepo = &mockMiscRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTrendWeapon{AckHandle: 1}
handleMsgMhfGetTrendWeapon(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetTrendWeapon_WithWeapons(t *testing.T) {
srv := createMockServer()
srv.miscRepo = &mockMiscRepo{
trendWeapons: []uint16{100, 200, 300},
}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTrendWeapon{AckHandle: 1}
handleMsgMhfGetTrendWeapon(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfUpdateUseTrendWeaponLog(t *testing.T) {
srv := createMockServer()
srv.miscRepo = &mockMiscRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateUseTrendWeaponLog{AckHandle: 1, WeaponType: 3, WeaponID: 500}
handleMsgMhfUpdateUseTrendWeaponLog(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
// --- Etc Points tests ---
func TestHandleMsgMhfGetEtcPoints(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.etcBonusQuests = 100
charRepo.etcDailyQuests = 50
charRepo.etcPromoPoints = 25
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetEtcPoints{AckHandle: 1}
handleMsgMhfGetEtcPoints(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfUpdateEtcPoint(t *testing.T) {
tests := []struct {
name string
pointType uint8
delta int16
column string
}{
{"bonus_quests", 0, 5, "bonus_quests"},
{"daily_quests", 1, 3, "daily_quests"},
{"promo_points", 2, 1, "promo_points"},
{"invalid_type", 99, 1, ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEtcPoint{
AckHandle: 1,
PointType: tt.pointType,
Delta: tt.delta,
}
handleMsgMhfUpdateEtcPoint(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if tt.column != "" {
val := charRepo.ints[tt.column]
if val != int(tt.delta) {
t.Errorf("Expected %s=%d, got %d", tt.column, tt.delta, val)
}
}
})
}
}
func TestHandleMsgMhfUpdateEtcPoint_NegativeDelta(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.ints["bonus_quests"] = 10
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEtcPoint{AckHandle: 1, PointType: 0, Delta: -5}
handleMsgMhfUpdateEtcPoint(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if charRepo.ints["bonus_quests"] != 5 {
t.Errorf("Expected bonus_quests=5, got %d", charRepo.ints["bonus_quests"])
}
}
func TestHandleMsgMhfUpdateEtcPoint_ClampToZero(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.ints["bonus_quests"] = 3
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEtcPoint{AckHandle: 1, PointType: 0, Delta: -10}
handleMsgMhfUpdateEtcPoint(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if charRepo.ints["bonus_quests"] != 0 {
t.Errorf("Expected bonus_quests=0, got %d", charRepo.ints["bonus_quests"])
}
}
// --- Equip Skin History tests ---
func TestHandleMsgMhfGetEquipSkinHist(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetEquipSkinHist{AckHandle: 1}
handleMsgMhfGetEquipSkinHist(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfUpdateEquipSkinHist_Valid(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEquipSkinHist{AckHandle: 1, ArmourID: 10001, MogType: 0}
handleMsgMhfUpdateEquipSkinHist(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if _, ok := charRepo.columns["skin_hist"]; !ok {
t.Error("Expected skin_hist to be saved")
}
}
func TestHandleMsgMhfUpdateEquipSkinHist_LowArmourID(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEquipSkinHist{AckHandle: 1, ArmourID: 5000, MogType: 0}
handleMsgMhfUpdateEquipSkinHist(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if _, ok := charRepo.columns["skin_hist"]; ok {
t.Error("Expected skin_hist NOT to be saved for low ArmourID")
}
}
func TestHandleMsgMhfUpdateEquipSkinHist_HighMogType(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEquipSkinHist{AckHandle: 1, ArmourID: 10001, MogType: 5}
handleMsgMhfUpdateEquipSkinHist(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if _, ok := charRepo.columns["skin_hist"]; ok {
t.Error("Expected skin_hist NOT to be saved for high MogType")
}
}

View File

@@ -3,6 +3,7 @@ package channelserver
import (
"testing"
cfg "erupe-ce/config"
"erupe-ce/network/mhfpacket"
)
@@ -559,6 +560,38 @@ func TestHandleMsgMhfGetLobbyCrowd(t *testing.T) {
}
}
// =============================================================================
// equipSkinHistSize: pure function, tests all 3 config branches
// =============================================================================
func TestEquipSkinHistSize_Default(t *testing.T) {
got := equipSkinHistSize(cfg.ZZ)
if got != 3200 {
t.Errorf("equipSkinHistSize(ZZ) = %d, want 3200", got)
}
}
func TestEquipSkinHistSize_Z2(t *testing.T) {
got := equipSkinHistSize(cfg.Z2)
if got != 2560 {
t.Errorf("equipSkinHistSize(Z2) = %d, want 2560", got)
}
}
func TestEquipSkinHistSize_Z1(t *testing.T) {
got := equipSkinHistSize(cfg.Z1)
if got != 1280 {
t.Errorf("equipSkinHistSize(Z1) = %d, want 1280", got)
}
}
func TestEquipSkinHistSize_OlderMode(t *testing.T) {
got := equipSkinHistSize(cfg.G1)
if got != 1280 {
t.Errorf("equipSkinHistSize(G1) = %d, want 1280", got)
}
}
// Distribution struct tests
func TestDistributionStruct(t *testing.T) {
dist := Distribution{
@@ -599,3 +632,421 @@ func TestDistributionItemStruct(t *testing.T) {
t.Errorf("ItemID = %d, want 1234", item.ItemID)
}
}
// --- Enhanced Minidata tests (in-memory store, no DB) ---
func TestHandleMsgMhfGetEnhancedMinidata_NotFound(t *testing.T) {
srv := createMockServer()
srv.minidata = NewMinidataStore()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetEnhancedMinidata{AckHandle: 1, CharID: 999}
handleMsgMhfGetEnhancedMinidata(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetEnhancedMinidata_Found(t *testing.T) {
srv := createMockServer()
srv.minidata = NewMinidataStore()
srv.minidata.Set(42, []byte{0xDE, 0xAD, 0xBE, 0xEF})
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetEnhancedMinidata{AckHandle: 1, CharID: 42}
handleMsgMhfGetEnhancedMinidata(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfSetEnhancedMinidata(t *testing.T) {
srv := createMockServer()
srv.minidata = NewMinidataStore()
s := createMockSession(100, srv)
payload := []byte{0x01, 0x02, 0x03}
pkt := &mhfpacket.MsgMhfSetEnhancedMinidata{AckHandle: 1, RawDataPayload: payload}
handleMsgMhfSetEnhancedMinidata(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
data, ok := srv.minidata.Get(100)
if !ok {
t.Fatal("Minidata not stored")
}
if len(data) != 3 || data[0] != 0x01 {
t.Errorf("Unexpected stored data: %v", data)
}
}
// --- Trend Weapon tests ---
func TestHandleMsgMhfGetTrendWeapon_Empty(t *testing.T) {
srv := createMockServer()
srv.miscRepo = &mockMiscRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTrendWeapon{AckHandle: 1}
handleMsgMhfGetTrendWeapon(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfGetTrendWeapon_WithWeapons(t *testing.T) {
srv := createMockServer()
srv.miscRepo = &mockMiscRepo{
trendWeapons: []uint16{100, 200, 300},
}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTrendWeapon{AckHandle: 1}
handleMsgMhfGetTrendWeapon(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfUpdateUseTrendWeaponLog(t *testing.T) {
srv := createMockServer()
srv.miscRepo = &mockMiscRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateUseTrendWeaponLog{AckHandle: 1, WeaponType: 3, WeaponID: 500}
handleMsgMhfUpdateUseTrendWeaponLog(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
}
// --- Etc Points tests ---
func TestHandleMsgMhfGetEtcPoints(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.etcBonusQuests = 100
charRepo.etcDailyQuests = 50
charRepo.etcPromoPoints = 25
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetEtcPoints{AckHandle: 1}
handleMsgMhfGetEtcPoints(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfUpdateEtcPoint(t *testing.T) {
tests := []struct {
name string
pointType uint8
delta int16
column string
}{
{"bonus_quests", 0, 5, "bonus_quests"},
{"daily_quests", 1, 3, "daily_quests"},
{"promo_points", 2, 1, "promo_points"},
{"invalid_type", 99, 1, ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEtcPoint{
AckHandle: 1,
PointType: tt.pointType,
Delta: tt.delta,
}
handleMsgMhfUpdateEtcPoint(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if tt.column != "" {
val := charRepo.ints[tt.column]
if val != int(tt.delta) {
t.Errorf("Expected %s=%d, got %d", tt.column, tt.delta, val)
}
}
})
}
}
func TestHandleMsgMhfUpdateEtcPoint_NegativeDelta(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.ints["bonus_quests"] = 10
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEtcPoint{AckHandle: 1, PointType: 0, Delta: -5}
handleMsgMhfUpdateEtcPoint(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if charRepo.ints["bonus_quests"] != 5 {
t.Errorf("Expected bonus_quests=5, got %d", charRepo.ints["bonus_quests"])
}
}
func TestHandleMsgMhfUpdateEtcPoint_ClampToZero(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
charRepo.ints["bonus_quests"] = 3
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEtcPoint{AckHandle: 1, PointType: 0, Delta: -10}
handleMsgMhfUpdateEtcPoint(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if charRepo.ints["bonus_quests"] != 0 {
t.Errorf("Expected bonus_quests=0, got %d", charRepo.ints["bonus_quests"])
}
}
// --- Equip Skin History tests ---
func TestHandleMsgMhfGetEquipSkinHist(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetEquipSkinHist{AckHandle: 1}
handleMsgMhfGetEquipSkinHist(s, pkt)
select {
case p := <-s.sendPackets:
if len(p.data) == 0 {
t.Fatal("Expected non-empty response")
}
default:
t.Fatal("No response packet queued")
}
}
func TestHandleMsgMhfUpdateEquipSkinHist_Valid(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEquipSkinHist{AckHandle: 1, ArmourID: 10001, MogType: 0}
handleMsgMhfUpdateEquipSkinHist(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if _, ok := charRepo.columns["skin_hist"]; !ok {
t.Error("Expected skin_hist to be saved")
}
}
func TestHandleMsgMhfUpdateEquipSkinHist_LowArmourID(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEquipSkinHist{AckHandle: 1, ArmourID: 5000, MogType: 0}
handleMsgMhfUpdateEquipSkinHist(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if _, ok := charRepo.columns["skin_hist"]; ok {
t.Error("Expected skin_hist NOT to be saved for low ArmourID")
}
}
func TestHandleMsgMhfUpdateEquipSkinHist_HighMogType(t *testing.T) {
srv := createMockServer()
charRepo := newMockCharacterRepo()
srv.charRepo = charRepo
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfUpdateEquipSkinHist{AckHandle: 1, ArmourID: 10001, MogType: 5}
handleMsgMhfUpdateEquipSkinHist(s, pkt)
select {
case <-s.sendPackets:
default:
t.Fatal("No response packet queued")
}
if _, ok := charRepo.columns["skin_hist"]; ok {
t.Error("Expected skin_hist NOT to be saved for high MogType")
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestNonTrivialHandlers_NoDB_Misc(t *testing.T) {
server := createMockServer()
t.Run("handleMsgMhfGetEarthStatus", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfGetEarthStatus(session, &mhfpacket.MsgMhfGetEarthStatus{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("handleMsgMhfGetEarthValue_Type1", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfGetEarthValue(session, &mhfpacket.MsgMhfGetEarthValue{AckHandle: 1, ReqType: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("handleMsgMhfGetEarthValue_Type2", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfGetEarthValue(session, &mhfpacket.MsgMhfGetEarthValue{AckHandle: 1, ReqType: 2})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("handleMsgMhfGetEarthValue_Type3", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfGetEarthValue(session, &mhfpacket.MsgMhfGetEarthValue{AckHandle: 1, ReqType: 3})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("handleMsgMhfGetUdShopCoin", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfGetUdShopCoin(session, &mhfpacket.MsgMhfGetUdShopCoin{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("handleMsgMhfGetLobbyCrowd", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfGetLobbyCrowd(session, &mhfpacket.MsgMhfGetLobbyCrowd{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
}
func TestEmptyHandlers_MiscFiles_Misc(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
fn func()
}{
{"handleMsgMhfGetCogInfo", func() { handleMsgMhfGetCogInfo(session, nil) }},
{"handleMsgMhfUseUdShopCoin", func() { handleMsgMhfUseUdShopCoin(session, nil) }},
{"handleMsgMhfGetDailyMissionMaster", func() { handleMsgMhfGetDailyMissionMaster(session, nil) }},
{"handleMsgMhfGetDailyMissionPersonal", func() { handleMsgMhfGetDailyMissionPersonal(session, nil) }},
{"handleMsgMhfSetDailyMissionPersonal", func() { handleMsgMhfSetDailyMissionPersonal(session, nil) }},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.fn()
})
}
}

View File

@@ -369,3 +369,60 @@ func TestObjectHandlers_SequentialPositionUpdate(t *testing.T) {
obj.x, obj.y, obj.z)
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestEmptyHandlers_ObjectGo(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
fn func()
}{
{"handleMsgSysDeleteObject", func() { handleMsgSysDeleteObject(session, nil) }},
{"handleMsgSysRotateObject", func() { handleMsgSysRotateObject(session, nil) }},
{"handleMsgSysDuplicateObject", func() { handleMsgSysDuplicateObject(session, nil) }},
{"handleMsgSysGetObjectBinary", func() { handleMsgSysGetObjectBinary(session, nil) }},
{"handleMsgSysGetObjectOwner", func() { handleMsgSysGetObjectOwner(session, nil) }},
{"handleMsgSysUpdateObjectBinary", func() { handleMsgSysUpdateObjectBinary(session, nil) }},
{"handleMsgSysCleanupObject", func() { handleMsgSysCleanupObject(session, nil) }},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.fn()
})
}
}
func TestEmptyHandlers_MiscFiles_Object(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
fn func()
}{
{"handleMsgSysAddObject", func() { handleMsgSysAddObject(session, nil) }},
{"handleMsgSysDelObject", func() { handleMsgSysDelObject(session, nil) }},
{"handleMsgSysDispObject", func() { handleMsgSysDispObject(session, nil) }},
{"handleMsgSysHideObject", func() { handleMsgSysHideObject(session, nil) }},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.fn()
})
}
}

View File

@@ -1,40 +0,0 @@
package channelserver
import (
"testing"
"erupe-ce/network/mhfpacket"
)
func TestHandleMsgMhfLoadFavoriteQuest(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadFavoriteQuest{AckHandle: 1}
handleMsgMhfLoadFavoriteQuest(session, pkt)
select {
case <-session.sendPackets:
default:
t.Error("expected response")
}
}
func TestHandleMsgMhfSaveFavoriteQuest(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfSaveFavoriteQuest{
AckHandle: 1,
Data: []byte{0x01, 0x00, 0x01, 0x00, 0x01},
}
handleMsgMhfSaveFavoriteQuest(session, pkt)
select {
case <-session.sendPackets:
default:
t.Error("expected response")
}
}

View File

@@ -782,3 +782,36 @@ func TestHandleMsgSysGetFile_ExistingQuestFile(t *testing.T) {
t.Errorf("expected success ack (ErrorCode=0) for existing quest file, got ErrorCode=%d", errorCode)
}
}
func TestHandleMsgMhfLoadFavoriteQuest(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfLoadFavoriteQuest{AckHandle: 1}
handleMsgMhfLoadFavoriteQuest(session, pkt)
select {
case <-session.sendPackets:
default:
t.Error("expected response")
}
}
func TestHandleMsgMhfSaveFavoriteQuest(t *testing.T) {
server := createMockServer()
server.charRepo = newMockCharacterRepo()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgMhfSaveFavoriteQuest{
AckHandle: 1,
Data: []byte{0x01, 0x00, 0x01, 0x00, 0x01},
}
handleMsgMhfSaveFavoriteQuest(session, pkt)
select {
case <-session.sendPackets:
default:
t.Error("expected response")
}
}

View File

@@ -51,3 +51,79 @@ func TestRengokuScoreStruct_DefaultValues(t *testing.T) {
t.Errorf("Default Score should be 0, got %d", score.Score)
}
}
func TestHandleMsgMhfGetRengokuRankingRank_ResponseData(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfGetRengokuRankingRank{
AckHandle: 55555,
}
handleMsgMhfGetRengokuRankingRank(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("Response packet should have data")
}
default:
t.Error("No response packet queued")
}
}
func TestRengokuScoreStruct_Fields(t *testing.T) {
score := RengokuScore{
Name: "Hunter",
Score: 99999,
}
if score.Name != "Hunter" {
t.Errorf("Name = %s, want Hunter", score.Name)
}
if score.Score != 99999 {
t.Errorf("Score = %d, want 99999", score.Score)
}
}
// TestHandleMsgMhfGetRengokuRankingRank_DifferentAck verifies rengoku ranking
// works with different ack handles.
func TestHandleMsgMhfGetRengokuRankingRank_DifferentAck(t *testing.T) {
server := createMockServer()
ackHandles := []uint32{0, 1, 54321, 0xDEADBEEF}
for _, ack := range ackHandles {
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfGetRengokuRankingRank{AckHandle: ack}
handleMsgMhfGetRengokuRankingRank(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Errorf("AckHandle=%d: Response packet should have data", ack)
}
default:
t.Errorf("AckHandle=%d: No response packet queued", ack)
}
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestNonTrivialHandlers_RengokuGo(t *testing.T) {
server := createMockServer()
t.Run("handleMsgMhfGetRengokuRankingRank", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfGetRengokuRankingRank(session, &mhfpacket.MsgMhfGetRengokuRankingRank{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
}

View File

@@ -124,3 +124,92 @@ func TestHandleMsgMhfAcceptReadReward(t *testing.T) {
handleMsgMhfAcceptReadReward(session, nil)
}
// Tests consolidated from handlers_coverage3_test.go
func TestSimpleAckHandlers_RewardGo(t *testing.T) {
server := createMockServer()
tests := []struct {
name string
fn func(s *Session)
}{
{"handleMsgMhfGetRewardSong", func(s *Session) {
handleMsgMhfGetRewardSong(s, &mhfpacket.MsgMhfGetRewardSong{AckHandle: 1})
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
session := createMockSession(1, server)
tt.fn(session)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Errorf("%s: response should have data", tt.name)
}
default:
t.Errorf("%s: no response queued", tt.name)
}
})
}
}
func TestNonTrivialHandlers_RewardGo(t *testing.T) {
server := createMockServer()
tests := []struct {
name string
fn func(s *Session)
}{
{"handleMsgMhfGetAdditionalBeatReward", func(s *Session) {
handleMsgMhfGetAdditionalBeatReward(s, &mhfpacket.MsgMhfGetAdditionalBeatReward{AckHandle: 1})
}},
{"handleMsgMhfGetUdRankingRewardList", func(s *Session) {
handleMsgMhfGetUdRankingRewardList(s, &mhfpacket.MsgMhfGetUdRankingRewardList{AckHandle: 1})
}},
{"handleMsgMhfAcquireMonthlyReward", func(s *Session) {
handleMsgMhfAcquireMonthlyReward(s, &mhfpacket.MsgMhfAcquireMonthlyReward{AckHandle: 1})
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
session := createMockSession(1, server)
tt.fn(session)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Errorf("%s: response should have data", tt.name)
}
default:
t.Errorf("%s: no response queued", tt.name)
}
})
}
}
func TestEmptyHandlers_MiscFiles_Reward(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
fn func()
}{
{"handleMsgMhfUseRewardSong", func() { handleMsgMhfUseRewardSong(session, nil) }},
{"handleMsgMhfAddRewardSongCount", func() { handleMsgMhfAddRewardSongCount(session, nil) }},
{"handleMsgMhfAcceptReadReward", func() { handleMsgMhfAcceptReadReward(session, nil) }},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.fn()
})
}
}

View File

@@ -209,6 +209,55 @@ func TestHandleMsgMhfReadBeatLevelMyRanking_EmptyResponse(t *testing.T) {
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestNonTrivialHandlers_NoDB_Seibattle(t *testing.T) {
server := createMockServer()
t.Run("handleMsgMhfGetSeibattle", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfGetSeibattle(session, &mhfpacket.MsgMhfGetSeibattle{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("handleMsgMhfUpdateBeatLevel", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfUpdateBeatLevel(session, &mhfpacket.MsgMhfUpdateBeatLevel{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("handleMsgMhfReadBeatLevel", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgMhfReadBeatLevel(session, &mhfpacket.MsgMhfReadBeatLevel{
AckHandle: 1,
ValidIDCount: 2,
IDs: [16]uint32{100, 200},
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
}
func TestHandleMsgMhfReadLastWeekBeatRanking_DataSize(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)

View File

@@ -418,6 +418,172 @@ func TestSemaphoreHandlers_SequentialAcquire(t *testing.T) {
}
}
// Tests consolidated from handlers_coverage3_test.go
func TestSimpleAckHandlers_SemaphoreGo(t *testing.T) {
server := createMockServer()
t.Run("handleMsgSysCreateSemaphore", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgSysCreateSemaphore(session, &mhfpacket.MsgSysCreateSemaphore{AckHandle: 1})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("handleMsgSysCreateSemaphore: response should have data")
}
default:
t.Error("handleMsgSysCreateSemaphore: no response queued")
}
})
}
func TestHandleMsgSysCreateAcquireSemaphore_Coverage3(t *testing.T) {
server := createMockServer()
server.semaphore = make(map[string]*Semaphore)
t.Run("creates_new_semaphore", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgSysCreateAcquireSemaphore(session, &mhfpacket.MsgSysCreateAcquireSemaphore{
AckHandle: 1,
SemaphoreID: "test_sema_c3_1",
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
if _, exists := server.semaphore["test_sema_c3_1"]; !exists {
t.Error("semaphore should have been created in server map")
}
})
t.Run("acquires_existing_semaphore", func(t *testing.T) {
session := createMockSession(2, server)
handleMsgSysCreateAcquireSemaphore(session, &mhfpacket.MsgSysCreateAcquireSemaphore{
AckHandle: 2,
SemaphoreID: "test_sema_c3_1",
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("creates_ravi_semaphore", func(t *testing.T) {
session := createMockSession(3, server)
handleMsgSysCreateAcquireSemaphore(session, &mhfpacket.MsgSysCreateAcquireSemaphore{
AckHandle: 3,
SemaphoreID: "hs_l0u3B51_c3",
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
if _, exists := server.semaphore["hs_l0u3B51_c3"]; !exists {
t.Error("ravi semaphore should have been created")
}
})
}
func TestHandleMsgSysCheckSemaphore_Coverage3(t *testing.T) {
server := createMockServer()
server.semaphore = make(map[string]*Semaphore)
t.Run("semaphore_not_exists", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgSysCheckSemaphore(session, &mhfpacket.MsgSysCheckSemaphore{
AckHandle: 1,
SemaphoreID: "nonexistent_c3",
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("semaphore_exists", func(t *testing.T) {
session := createMockSession(1, server)
server.semaphore["existing_sema_c3"] = NewSemaphore(session, "existing_sema_c3", 1)
handleMsgSysCheckSemaphore(session, &mhfpacket.MsgSysCheckSemaphore{
AckHandle: 1,
SemaphoreID: "existing_sema_c3",
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
}
func TestHandleMsgSysAcquireSemaphore_Coverage3(t *testing.T) {
server := createMockServer()
server.semaphore = make(map[string]*Semaphore)
t.Run("semaphore_exists", func(t *testing.T) {
session := createMockSession(1, server)
server.semaphore["acquire_sema_c3"] = NewSemaphore(session, "acquire_sema_c3", 1)
handleMsgSysAcquireSemaphore(session, &mhfpacket.MsgSysAcquireSemaphore{
AckHandle: 1,
SemaphoreID: "acquire_sema_c3",
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
t.Run("semaphore_not_exists", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgSysAcquireSemaphore(session, &mhfpacket.MsgSysAcquireSemaphore{
AckHandle: 1,
SemaphoreID: "nonexistent_sema_c3",
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
})
}
func TestEmptyHandlers_MiscFiles_Semaphore(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
defer func() {
if r := recover(); r != nil {
t.Errorf("handleMsgSysReleaseSemaphore panicked: %v", r)
}
}()
handleMsgSysReleaseSemaphore(session, nil)
}
func TestSemaphoreHandlers_MultipleCheck(t *testing.T) {
server := createMockServer()
server.semaphore = make(map[string]*Semaphore)

File diff suppressed because it is too large Load Diff

View File

@@ -1,342 +0,0 @@
package channelserver
import (
"testing"
"erupe-ce/network/mhfpacket"
)
func TestHandleMsgSysReserveStage_NewSlot(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
select {
case <-session.sendPackets:
default:
t.Error("expected response")
}
if _, exists := stage.reservedClientSlots[100]; !exists {
t.Error("charID should be in reserved slots")
}
}
func TestHandleMsgSysReserveStage_AlreadyReservedReady1(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: true},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
if stage.reservedClientSlots[100] != false {
t.Error("ready=1 should set slot to false")
}
}
func TestHandleMsgSysReserveStage_AlreadyReservedReady17(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 17}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
if stage.reservedClientSlots[100] != true {
t.Error("ready=17 should set slot to true")
}
}
func TestHandleMsgSysReserveStage_Locked(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
locked: true,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
}
func TestHandleMsgSysReserveStage_PasswordMismatch(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
password: "secret",
}
server.stages.Store("test_stage", stage)
session.stagePass = "wrong"
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
}
func TestHandleMsgSysReserveStage_Full(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{200: false, 300: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 2,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
}
func TestHandleMsgSysReserveStage_StageNotFound(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "nonexistent", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
}
func TestHandleMsgSysUnreserveStage_WithReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
session.reservationStage = stage
pkt := &mhfpacket.MsgSysUnreserveStage{}
handleMsgSysUnreserveStage(session, pkt)
if session.reservationStage != nil {
t.Error("reservation should be cleared")
}
if _, exists := stage.reservedClientSlots[100]; exists {
t.Error("charID should be removed from reserved slots")
}
}
func TestHandleMsgSysUnreserveStage_NoReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysUnreserveStage{}
handleMsgSysUnreserveStage(session, pkt)
// Should not panic
}
func TestHandleMsgSysSetStagePass_Host(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
session.reservationStage = stage
pkt := &mhfpacket.MsgSysSetStagePass{Password: "mypass"}
handleMsgSysSetStagePass(session, pkt)
if stage.password != "mypass" {
t.Errorf("stage password = %q, want %q", stage.password, "mypass")
}
}
func TestHandleMsgSysSetStagePass_NonHost(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysSetStagePass{Password: "mypass"}
handleMsgSysSetStagePass(session, pkt)
if session.stagePass != "mypass" {
t.Errorf("session stagePass = %q, want %q", session.stagePass, "mypass")
}
}
func TestHandleMsgSysSetAndGetStageBinary(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
server.stages.Store("test_stage", stage)
// Set binary
setPkt := &mhfpacket.MsgSysSetStageBinary{
BinaryType0: 1,
BinaryType1: 2,
StageID: "test_stage",
RawDataPayload: []byte{0xDE, 0xAD, 0xBE, 0xEF},
}
handleMsgSysSetStageBinary(session, setPkt)
// Get binary
getPkt := &mhfpacket.MsgSysGetStageBinary{
AckHandle: 1,
BinaryType0: 1,
BinaryType1: 2,
StageID: "test_stage",
}
handleMsgSysGetStageBinary(session, getPkt)
<-session.sendPackets
}
func TestHandleMsgSysGetStageBinary_Type1Equals4Fallback(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
server.stages.Store("test_stage", stage)
getPkt := &mhfpacket.MsgSysGetStageBinary{
AckHandle: 1,
BinaryType0: 0,
BinaryType1: 4,
StageID: "test_stage",
}
handleMsgSysGetStageBinary(session, getPkt)
<-session.sendPackets
}
func TestHandleMsgSysGetStageBinary_MissingBinary(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
server.stages.Store("test_stage", stage)
getPkt := &mhfpacket.MsgSysGetStageBinary{
AckHandle: 1,
BinaryType0: 9,
BinaryType1: 9,
StageID: "test_stage",
}
handleMsgSysGetStageBinary(session, getPkt)
<-session.sendPackets
}
func TestHandleMsgSysGetStageBinary_MissingStage(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
getPkt := &mhfpacket.MsgSysGetStageBinary{
AckHandle: 1,
BinaryType0: 0,
BinaryType1: 0,
StageID: "nonexistent",
}
handleMsgSysGetStageBinary(session, getPkt)
<-session.sendPackets
}
func TestHandleMsgSysSetStageBinary_MissingStage(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysSetStageBinary{
BinaryType0: 1,
BinaryType1: 2,
StageID: "nonexistent",
RawDataPayload: []byte{1, 2, 3},
}
handleMsgSysSetStageBinary(session, pkt)
// Should not panic, just logs warning
}
func TestHandleMsgSysUnlockStage_WithReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
server.stages.Store("test_stage", stage)
session.reservationStage = stage
pkt := &mhfpacket.MsgSysUnlockStage{}
handleMsgSysUnlockStage(session, pkt)
if _, exists := server.stages.Get("test_stage"); exists {
t.Error("stage should have been deleted")
}
}
func TestHandleMsgSysUnlockStage_NoReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysUnlockStage{}
handleMsgSysUnlockStage(session, pkt)
// Should not panic
}

View File

@@ -684,3 +684,405 @@ func TestRaceConditionStageObjectsIteration(t *testing.T) {
t.Log(raceTestCompletionMsg)
}
func TestHandleMsgSysReserveStage_NewSlot(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
select {
case <-session.sendPackets:
default:
t.Error("expected response")
}
if _, exists := stage.reservedClientSlots[100]; !exists {
t.Error("charID should be in reserved slots")
}
}
func TestHandleMsgSysReserveStage_AlreadyReservedReady1(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: true},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
if stage.reservedClientSlots[100] != false {
t.Error("ready=1 should set slot to false")
}
}
func TestHandleMsgSysReserveStage_AlreadyReservedReady17(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 17}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
if stage.reservedClientSlots[100] != true {
t.Error("ready=17 should set slot to true")
}
}
func TestHandleMsgSysReserveStage_Locked(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
locked: true,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
}
func TestHandleMsgSysReserveStage_PasswordMismatch(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 4,
password: "secret",
}
server.stages.Store("test_stage", stage)
session.stagePass = "wrong"
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
}
func TestHandleMsgSysReserveStage_Full(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{200: false, 300: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
maxPlayers: 2,
}
server.stages.Store("test_stage", stage)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "test_stage", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
}
func TestHandleMsgSysReserveStage_StageNotFound(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysReserveStage{AckHandle: 1, StageID: "nonexistent", Ready: 1}
handleMsgSysReserveStage(session, pkt)
<-session.sendPackets
}
func TestHandleMsgSysUnreserveStage_WithReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
session.reservationStage = stage
pkt := &mhfpacket.MsgSysUnreserveStage{}
handleMsgSysUnreserveStage(session, pkt)
if session.reservationStage != nil {
t.Error("reservation should be cleared")
}
if _, exists := stage.reservedClientSlots[100]; exists {
t.Error("charID should be removed from reserved slots")
}
}
func TestHandleMsgSysUnreserveStage_NoReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysUnreserveStage{}
handleMsgSysUnreserveStage(session, pkt)
// Should not panic
}
func TestHandleMsgSysSetStagePass_Host(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
session.reservationStage = stage
pkt := &mhfpacket.MsgSysSetStagePass{Password: "mypass"}
handleMsgSysSetStagePass(session, pkt)
if stage.password != "mypass" {
t.Errorf("stage password = %q, want %q", stage.password, "mypass")
}
}
func TestHandleMsgSysSetStagePass_NonHost(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysSetStagePass{Password: "mypass"}
handleMsgSysSetStagePass(session, pkt)
if session.stagePass != "mypass" {
t.Errorf("session stagePass = %q, want %q", session.stagePass, "mypass")
}
}
func TestHandleMsgSysSetAndGetStageBinary(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
server.stages.Store("test_stage", stage)
// Set binary
setPkt := &mhfpacket.MsgSysSetStageBinary{
BinaryType0: 1,
BinaryType1: 2,
StageID: "test_stage",
RawDataPayload: []byte{0xDE, 0xAD, 0xBE, 0xEF},
}
handleMsgSysSetStageBinary(session, setPkt)
// Get binary
getPkt := &mhfpacket.MsgSysGetStageBinary{
AckHandle: 1,
BinaryType0: 1,
BinaryType1: 2,
StageID: "test_stage",
}
handleMsgSysGetStageBinary(session, getPkt)
<-session.sendPackets
}
func TestHandleMsgSysGetStageBinary_Type1Equals4Fallback(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
server.stages.Store("test_stage", stage)
getPkt := &mhfpacket.MsgSysGetStageBinary{
AckHandle: 1,
BinaryType0: 0,
BinaryType1: 4,
StageID: "test_stage",
}
handleMsgSysGetStageBinary(session, getPkt)
<-session.sendPackets
}
func TestHandleMsgSysGetStageBinary_MissingBinary(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: make(map[uint32]bool),
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
server.stages.Store("test_stage", stage)
getPkt := &mhfpacket.MsgSysGetStageBinary{
AckHandle: 1,
BinaryType0: 9,
BinaryType1: 9,
StageID: "test_stage",
}
handleMsgSysGetStageBinary(session, getPkt)
<-session.sendPackets
}
func TestHandleMsgSysGetStageBinary_MissingStage(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
getPkt := &mhfpacket.MsgSysGetStageBinary{
AckHandle: 1,
BinaryType0: 0,
BinaryType1: 0,
StageID: "nonexistent",
}
handleMsgSysGetStageBinary(session, getPkt)
<-session.sendPackets
}
func TestHandleMsgSysSetStageBinary_MissingStage(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysSetStageBinary{
BinaryType0: 1,
BinaryType1: 2,
StageID: "nonexistent",
RawDataPayload: []byte{1, 2, 3},
}
handleMsgSysSetStageBinary(session, pkt)
// Should not panic, just logs warning
}
func TestHandleMsgSysUnlockStage_WithReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
stage := &Stage{
id: "test_stage",
reservedClientSlots: map[uint32]bool{100: false},
rawBinaryData: make(map[stageBinaryKey][]byte),
clients: make(map[*Session]uint32),
}
server.stages.Store("test_stage", stage)
session.reservationStage = stage
pkt := &mhfpacket.MsgSysUnlockStage{}
handleMsgSysUnlockStage(session, pkt)
if _, exists := server.stages.Get("test_stage"); exists {
t.Error("stage should have been deleted")
}
}
func TestHandleMsgSysUnlockStage_NoReservation(t *testing.T) {
server := createMockServer()
session := createMockSession(100, server)
pkt := &mhfpacket.MsgSysUnlockStage{}
handleMsgSysUnlockStage(session, pkt)
// Should not panic
}
// Tests consolidated from handlers_coverage3_test.go
func TestEmptyHandlers_StageGo(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
fn func()
}{
{"handleMsgSysStageDestruct", func() { handleMsgSysStageDestruct(session, nil) }},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.fn()
})
}
}
func TestHandleMsgSysCreateStage_Coverage3(t *testing.T) {
server := createMockServer()
t.Run("creates_new_stage", func(t *testing.T) {
session := createMockSession(1, server)
handleMsgSysCreateStage(session, &mhfpacket.MsgSysCreateStage{
AckHandle: 1,
StageID: "test_create_stage_c3",
PlayerCount: 4,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data")
}
default:
t.Error("no response queued")
}
if _, exists := server.stages.Get("test_create_stage_c3"); !exists {
t.Error("stage should have been created")
}
})
t.Run("duplicate_stage_fails", func(t *testing.T) {
session := createMockSession(1, server)
// Stage already exists from the previous test
handleMsgSysCreateStage(session, &mhfpacket.MsgSysCreateStage{
AckHandle: 2,
StageID: "test_create_stage_c3",
PlayerCount: 4,
})
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Error("response should have data even on failure")
}
default:
t.Error("no response queued")
}
})
}

View File

@@ -191,3 +191,103 @@ func TestHandleMsgMhfGetUdTacticsLog(t *testing.T) {
handleMsgMhfGetUdTacticsLog(session, nil)
}
// Tests consolidated from handlers_coverage3_test.go
func TestSimpleAckHandlers_TacticsGo(t *testing.T) {
server := createMockServer()
tests := []struct {
name string
fn func(s *Session)
}{
{"handleMsgMhfAddUdTacticsPoint", func(s *Session) {
handleMsgMhfAddUdTacticsPoint(s, &mhfpacket.MsgMhfAddUdTacticsPoint{AckHandle: 1})
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
session := createMockSession(1, server)
tt.fn(session)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Errorf("%s: response should have data", tt.name)
}
default:
t.Errorf("%s: no response queued", tt.name)
}
})
}
}
func TestNonTrivialHandlers_TacticsGo(t *testing.T) {
server := createMockServer()
tests := []struct {
name string
fn func(s *Session)
}{
{"handleMsgMhfGetUdTacticsPoint", func(s *Session) {
handleMsgMhfGetUdTacticsPoint(s, &mhfpacket.MsgMhfGetUdTacticsPoint{AckHandle: 1})
}},
{"handleMsgMhfGetUdTacticsRewardList", func(s *Session) {
handleMsgMhfGetUdTacticsRewardList(s, &mhfpacket.MsgMhfGetUdTacticsRewardList{AckHandle: 1})
}},
{"handleMsgMhfGetUdTacticsFollower", func(s *Session) {
handleMsgMhfGetUdTacticsFollower(s, &mhfpacket.MsgMhfGetUdTacticsFollower{AckHandle: 1})
}},
{"handleMsgMhfGetUdTacticsBonusQuest", func(s *Session) {
handleMsgMhfGetUdTacticsBonusQuest(s, &mhfpacket.MsgMhfGetUdTacticsBonusQuest{AckHandle: 1})
}},
{"handleMsgMhfGetUdTacticsFirstQuestBonus", func(s *Session) {
handleMsgMhfGetUdTacticsFirstQuestBonus(s, &mhfpacket.MsgMhfGetUdTacticsFirstQuestBonus{AckHandle: 1})
}},
{"handleMsgMhfGetUdTacticsRemainingPoint", func(s *Session) {
handleMsgMhfGetUdTacticsRemainingPoint(s, &mhfpacket.MsgMhfGetUdTacticsRemainingPoint{AckHandle: 1})
}},
{"handleMsgMhfGetUdTacticsRanking", func(s *Session) {
handleMsgMhfGetUdTacticsRanking(s, &mhfpacket.MsgMhfGetUdTacticsRanking{AckHandle: 1})
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
session := createMockSession(1, server)
tt.fn(session)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Errorf("%s: response should have data", tt.name)
}
default:
t.Errorf("%s: no response queued", tt.name)
}
})
}
}
func TestEmptyHandlers_MiscFiles_Tactics(t *testing.T) {
server := createMockServer()
session := createMockSession(1, server)
tests := []struct {
name string
fn func()
}{
{"handleMsgMhfSetUdTacticsFollower", func() { handleMsgMhfSetUdTacticsFollower(session, nil) }},
{"handleMsgMhfGetUdTacticsLog", func() { handleMsgMhfGetUdTacticsLog(session, nil) }},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("%s panicked: %v", tt.name, r)
}
}()
tt.fn()
})
}
}

View File

@@ -1,106 +0,0 @@
package channelserver
import (
"erupe-ce/network/mhfpacket"
"testing"
)
func TestHandleMsgMhfGetTenrouirai_Type2_Rewards(t *testing.T) {
srv := createMockServer()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, DataType: 2}
handleMsgMhfGetTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetTenrouirai_Type4_Progress(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
ensureTowerService(srv)
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, DataType: 4, GuildID: 1}
handleMsgMhfGetTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetTenrouirai_Type5_Scores(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, DataType: 5, GuildID: 1, MissionIndex: 0}
handleMsgMhfGetTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetTenrouirai_Type6_RP(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, DataType: 6, GuildID: 1}
handleMsgMhfGetTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTowerInfo_SkillUpdate(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTowerInfo{AckHandle: 1, InfoType: 2, Skill: 3, Cost: -10}
handleMsgMhfPostTowerInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTowerInfo_ProgressUpdate(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTowerInfo{AckHandle: 1, InfoType: 1, TR: 5, TRP: 100, Cost: -20, Block1: 1}
handleMsgMhfPostTowerInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTowerInfo_ProgressType7(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTowerInfo{AckHandle: 1, InfoType: 7, TR: 10, TRP: 200}
handleMsgMhfPostTowerInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTowerInfo_QuestToolsDebug(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
srv.erupeConfig.DebugOptions.QuestTools = true
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTowerInfo{AckHandle: 1, InfoType: 2, Skill: 1}
handleMsgMhfPostTowerInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTenrouirai_Op1(t *testing.T) {
srv := createMockServer()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTenrouirai{AckHandle: 1, Op: 1}
handleMsgMhfPostTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTenrouirai_QuestToolsDebug(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.DebugOptions.QuestTools = true
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTenrouirai{AckHandle: 1, Op: 1, Floors: 10, Slays: 5}
handleMsgMhfPostTenrouirai(s, pkt)
<-s.sendPackets
}

View File

@@ -154,3 +154,142 @@ func TestHandleMsgMhfPresentBox(t *testing.T) {
t.Error("No response packet queued")
}
}
func TestHandleMsgMhfGetTenrouirai_Type2_Rewards(t *testing.T) {
srv := createMockServer()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, DataType: 2}
handleMsgMhfGetTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetTenrouirai_Type4_Progress(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
ensureTowerService(srv)
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, DataType: 4, GuildID: 1}
handleMsgMhfGetTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetTenrouirai_Type5_Scores(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, DataType: 5, GuildID: 1, MissionIndex: 0}
handleMsgMhfGetTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfGetTenrouirai_Type6_RP(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, DataType: 6, GuildID: 1}
handleMsgMhfGetTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTowerInfo_SkillUpdate(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTowerInfo{AckHandle: 1, InfoType: 2, Skill: 3, Cost: -10}
handleMsgMhfPostTowerInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTowerInfo_ProgressUpdate(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTowerInfo{AckHandle: 1, InfoType: 1, TR: 5, TRP: 100, Cost: -20, Block1: 1}
handleMsgMhfPostTowerInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTowerInfo_ProgressType7(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTowerInfo{AckHandle: 1, InfoType: 7, TR: 10, TRP: 200}
handleMsgMhfPostTowerInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTowerInfo_QuestToolsDebug(t *testing.T) {
srv := createMockServer()
srv.towerRepo = &mockTowerRepo{}
srv.erupeConfig.DebugOptions.QuestTools = true
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTowerInfo{AckHandle: 1, InfoType: 2, Skill: 1}
handleMsgMhfPostTowerInfo(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTenrouirai_Op1(t *testing.T) {
srv := createMockServer()
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTenrouirai{AckHandle: 1, Op: 1}
handleMsgMhfPostTenrouirai(s, pkt)
<-s.sendPackets
}
func TestHandleMsgMhfPostTenrouirai_QuestToolsDebug(t *testing.T) {
srv := createMockServer()
srv.erupeConfig.DebugOptions.QuestTools = true
s := createMockSession(100, srv)
pkt := &mhfpacket.MsgMhfPostTenrouirai{AckHandle: 1, Op: 1, Floors: 10, Slays: 5}
handleMsgMhfPostTenrouirai(s, pkt)
<-s.sendPackets
}
// Tests consolidated from handlers_coverage3_test.go
func TestNonTrivialHandlers_TowerGo(t *testing.T) {
server := createMockServer()
tests := []struct {
name string
fn func(s *Session)
}{
{"handleMsgMhfGetTenrouirai_Type1_C3", func(s *Session) {
handleMsgMhfGetTenrouirai(s, &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, Unk0: 1})
}},
{"handleMsgMhfGetTenrouirai_Unknown_C3", func(s *Session) {
handleMsgMhfGetTenrouirai(s, &mhfpacket.MsgMhfGetTenrouirai{AckHandle: 1, Unk0: 0, DataType: 0})
}},
{"handleMsgMhfGetWeeklySeibatuRankingReward_C3", func(s *Session) {
handleMsgMhfGetWeeklySeibatuRankingReward(s, &mhfpacket.MsgMhfGetWeeklySeibatuRankingReward{AckHandle: 1})
}},
{"handleMsgMhfPresentBox_C3", func(s *Session) {
handleMsgMhfPresentBox(s, &mhfpacket.MsgMhfPresentBox{AckHandle: 1})
}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
session := createMockSession(1, server)
tt.fn(session)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Errorf("%s: response should have data", tt.name)
}
default:
t.Errorf("%s: no response queued", tt.name)
}
})
}
}

View File

@@ -0,0 +1,13 @@
package channelserver
import "testing"
func TestTimeGameAbsolute(t *testing.T) {
result := TimeGameAbsolute()
// TimeGameAbsolute returns (adjustedUnix - 2160) % 5760
// Result should be in range [0, 5760)
if result >= 5760 {
t.Errorf("TimeGameAbsolute() = %d, should be < 5760", result)
}
}