Files
Erupe/server/channelserver/handlers_scenario_test.go
Houmgaor 6c0269d21f test(channelserver): add unit tests for helpers, kouryou, scenario, seibattle, and distitem handlers
Cover previously untested handler files with mock-based unit tests:
- handlers_helpers: load/save character data, ack helpers, updateRights
- handlers_kouryou: get/add/exchange points with success and error paths
- handlers_scenario: scenario counter serialization, 128-entry trim, category exchange flags
- handlers_seibattle: all type codes, Earth response format, data size validation
- handlers_distitem: enumerate/apply/acquire distributions, description retrieval
2026-02-22 18:55:31 +01:00

178 lines
4.5 KiB
Go

package channelserver
import (
"encoding/binary"
"errors"
"testing"
"erupe-ce/network/mhfpacket"
)
// --- mockScenarioRepo ---
type mockScenarioRepo struct {
scenarios []Scenario
err error
}
func (m *mockScenarioRepo) GetCounters() ([]Scenario, error) {
return m.scenarios, m.err
}
func TestHandleMsgMhfInfoScenarioCounter_Empty(t *testing.T) {
server := createMockServer()
server.scenarioRepo = &mockScenarioRepo{}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfInfoScenarioCounter{AckHandle: 100}
handleMsgMhfInfoScenarioCounter(session, pkt)
select {
case p := <-session.sendPackets:
_, errCode, ackData := parseAckBufData(t, p.data)
if errCode != 0 {
t.Errorf("ErrorCode = %d, want 0", errCode)
}
if len(ackData) < 1 {
t.Fatal("AckData too short")
}
if ackData[0] != 0 {
t.Errorf("scenario count = %d, want 0", ackData[0])
}
default:
t.Fatal("No response queued")
}
}
func TestHandleMsgMhfInfoScenarioCounter_WithScenarios(t *testing.T) {
server := createMockServer()
server.scenarioRepo = &mockScenarioRepo{
scenarios: []Scenario{
{MainID: 1000, CategoryID: 0},
{MainID: 2000, CategoryID: 3},
{MainID: 3000, CategoryID: 6},
{MainID: 4000, CategoryID: 7},
{MainID: 5000, CategoryID: 1},
},
}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfInfoScenarioCounter{AckHandle: 100}
handleMsgMhfInfoScenarioCounter(session, pkt)
select {
case p := <-session.sendPackets:
_, _, data := parseAckBufData(t, p.data)
if len(data) < 1 {
t.Fatal("AckData too short")
}
count := data[0]
if count != 5 {
t.Errorf("scenario count = %d, want 5", count)
}
// Each scenario: mainID(4) + exchange(1) + categoryID(1) = 6 bytes
expectedLen := 1 + 5*6
if len(data) != expectedLen {
t.Errorf("AckData len = %d, want %d", len(data), expectedLen)
}
// Verify first scenario (categoryID=0, exchange=false)
mainID := binary.BigEndian.Uint32(data[1:5])
if mainID != 1000 {
t.Errorf("first mainID = %d, want 1000", mainID)
}
if data[5] != 0 {
t.Errorf("categoryID=0 should have exchange=false, got %d", data[5])
}
// Verify second scenario (categoryID=3, exchange=true)
if data[5+6] != 1 {
t.Errorf("categoryID=3 should have exchange=true, got %d", data[5+6])
}
default:
t.Fatal("No response queued")
}
}
func TestHandleMsgMhfInfoScenarioCounter_TrimTo128(t *testing.T) {
server := createMockServer()
scenarios := make([]Scenario, 200)
for i := range scenarios {
scenarios[i] = Scenario{MainID: uint32(i), CategoryID: 0}
}
server.scenarioRepo = &mockScenarioRepo{scenarios: scenarios}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfInfoScenarioCounter{AckHandle: 100}
handleMsgMhfInfoScenarioCounter(session, pkt)
select {
case p := <-session.sendPackets:
_, _, data := parseAckBufData(t, p.data)
if data[0] != 128 {
t.Errorf("scenario count = %d, want 128 (trimmed)", data[0])
}
default:
t.Fatal("No response queued")
}
}
func TestHandleMsgMhfInfoScenarioCounter_DBError(t *testing.T) {
server := createMockServer()
server.scenarioRepo = &mockScenarioRepo{err: errors.New("db error")}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfInfoScenarioCounter{AckHandle: 100}
handleMsgMhfInfoScenarioCounter(session, pkt)
select {
case p := <-session.sendPackets:
if len(p.data) == 0 {
t.Fatal("Should still respond on error")
}
default:
t.Fatal("No response queued")
}
}
func TestHandleMsgMhfInfoScenarioCounter_CategoryExchangeFlags(t *testing.T) {
tests := []struct {
name string
categoryID uint8
wantExch bool
}{
{"Basic", 0, false},
{"Veteran", 1, false},
{"Other (exchange)", 3, true},
{"Pallone (exchange)", 6, true},
{"Diva (exchange)", 7, true},
{"Unknown category 2", 2, false},
{"Unknown category 4", 4, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
server := createMockServer()
server.scenarioRepo = &mockScenarioRepo{
scenarios: []Scenario{{MainID: 1, CategoryID: tt.categoryID}},
}
session := createMockSession(1, server)
pkt := &mhfpacket.MsgMhfInfoScenarioCounter{AckHandle: 100}
handleMsgMhfInfoScenarioCounter(session, pkt)
select {
case p := <-session.sendPackets:
_, _, data := parseAckBufData(t, p.data)
isExchange := data[5] != 0
if isExchange != tt.wantExch {
t.Errorf("exchange = %v, want %v for categoryID=%d", isExchange, tt.wantExch, tt.categoryID)
}
default:
t.Fatal("No response queued")
}
})
}
}