mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-04-05 15:32:29 +02:00
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
This commit is contained in:
186
server/channelserver/handlers_kouryou_test.go
Normal file
186
server/channelserver/handlers_kouryou_test.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package channelserver
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"erupe-ce/network/mhfpacket"
|
||||
)
|
||||
|
||||
// parseAckBufData extracts AckData from a serialized MsgSysAck buffer response.
|
||||
// Wire format: opcode(2) + ackHandle(4) + isBuffer(1) + errorCode(1) + dataLen(2) + data(N)
|
||||
func parseAckBufData(t *testing.T, raw []byte) (ackHandle uint32, errorCode uint8, ackData []byte) {
|
||||
t.Helper()
|
||||
if len(raw) < 10 {
|
||||
t.Fatalf("raw packet too short: %d bytes", len(raw))
|
||||
}
|
||||
ackHandle = binary.BigEndian.Uint32(raw[2:6])
|
||||
isBuffer := raw[6]
|
||||
errorCode = raw[7]
|
||||
if isBuffer == 0 {
|
||||
t.Fatal("Expected buffer response, got simple ack")
|
||||
}
|
||||
dataLen := binary.BigEndian.Uint16(raw[8:10])
|
||||
if int(dataLen) > len(raw)-10 {
|
||||
t.Fatalf("data len %d exceeds remaining bytes %d", dataLen, len(raw)-10)
|
||||
}
|
||||
ackData = raw[10 : 10+dataLen]
|
||||
return
|
||||
}
|
||||
|
||||
func TestHandleMsgMhfGetKouryouPoint(t *testing.T) {
|
||||
server := createMockServer()
|
||||
charRepo := newMockCharacterRepo()
|
||||
charRepo.ints["kouryou_point"] = 500
|
||||
server.charRepo = charRepo
|
||||
session := createMockSession(1, server)
|
||||
|
||||
pkt := &mhfpacket.MsgMhfGetKouryouPoint{AckHandle: 100}
|
||||
handleMsgMhfGetKouryouPoint(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) < 4 {
|
||||
t.Fatal("AckData too short")
|
||||
}
|
||||
points := binary.BigEndian.Uint32(ackData[:4])
|
||||
if points != 500 {
|
||||
t.Errorf("points = %d, want 500", points)
|
||||
}
|
||||
default:
|
||||
t.Fatal("No response queued")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleMsgMhfGetKouryouPoint_Error(t *testing.T) {
|
||||
server := createMockServer()
|
||||
charRepo := newMockCharacterRepo()
|
||||
charRepo.readErr = errors.New("db error")
|
||||
server.charRepo = charRepo
|
||||
session := createMockSession(1, server)
|
||||
|
||||
pkt := &mhfpacket.MsgMhfGetKouryouPoint{AckHandle: 100}
|
||||
handleMsgMhfGetKouryouPoint(session, pkt)
|
||||
|
||||
select {
|
||||
case p := <-session.sendPackets:
|
||||
_, _, ackData := parseAckBufData(t, p.data)
|
||||
points := binary.BigEndian.Uint32(ackData[:4])
|
||||
if points != 0 {
|
||||
t.Errorf("points = %d, want 0 on error", points)
|
||||
}
|
||||
default:
|
||||
t.Fatal("No response queued")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleMsgMhfAddKouryouPoint(t *testing.T) {
|
||||
server := createMockServer()
|
||||
charRepo := newMockCharacterRepo()
|
||||
charRepo.ints["kouryou_point"] = 100
|
||||
server.charRepo = charRepo
|
||||
session := createMockSession(1, server)
|
||||
|
||||
pkt := &mhfpacket.MsgMhfAddKouryouPoint{
|
||||
AckHandle: 200,
|
||||
KouryouPoints: 50,
|
||||
}
|
||||
handleMsgMhfAddKouryouPoint(session, pkt)
|
||||
|
||||
if charRepo.ints["kouryou_point"] != 150 {
|
||||
t.Errorf("kouryou_point = %d, want 150", charRepo.ints["kouryou_point"])
|
||||
}
|
||||
|
||||
select {
|
||||
case p := <-session.sendPackets:
|
||||
_, _, ackData := parseAckBufData(t, p.data)
|
||||
points := binary.BigEndian.Uint32(ackData[:4])
|
||||
if points != 150 {
|
||||
t.Errorf("response points = %d, want 150", points)
|
||||
}
|
||||
default:
|
||||
t.Fatal("No response queued")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleMsgMhfAddKouryouPoint_Error(t *testing.T) {
|
||||
server := createMockServer()
|
||||
charRepo := newMockCharacterRepo()
|
||||
charRepo.adjustErr = errors.New("db error")
|
||||
server.charRepo = charRepo
|
||||
session := createMockSession(1, server)
|
||||
|
||||
pkt := &mhfpacket.MsgMhfAddKouryouPoint{
|
||||
AckHandle: 200,
|
||||
KouryouPoints: 50,
|
||||
}
|
||||
handleMsgMhfAddKouryouPoint(session, pkt)
|
||||
|
||||
select {
|
||||
case p := <-session.sendPackets:
|
||||
_, _, ackData := parseAckBufData(t, p.data)
|
||||
points := binary.BigEndian.Uint32(ackData[:4])
|
||||
if points != 0 {
|
||||
t.Errorf("response points = %d, want 0 on error", points)
|
||||
}
|
||||
default:
|
||||
t.Fatal("No response queued")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleMsgMhfExchangeKouryouPoint(t *testing.T) {
|
||||
server := createMockServer()
|
||||
charRepo := newMockCharacterRepo()
|
||||
charRepo.ints["kouryou_point"] = 10000
|
||||
server.charRepo = charRepo
|
||||
session := createMockSession(1, server)
|
||||
|
||||
pkt := &mhfpacket.MsgMhfExchangeKouryouPoint{
|
||||
AckHandle: 300,
|
||||
KouryouPoints: 10000,
|
||||
}
|
||||
handleMsgMhfExchangeKouryouPoint(session, pkt)
|
||||
|
||||
if charRepo.ints["kouryou_point"] != 0 {
|
||||
t.Errorf("kouryou_point = %d, want 0 after exchange", charRepo.ints["kouryou_point"])
|
||||
}
|
||||
|
||||
select {
|
||||
case p := <-session.sendPackets:
|
||||
_, _, ackData := parseAckBufData(t, p.data)
|
||||
points := binary.BigEndian.Uint32(ackData[:4])
|
||||
if points != 0 {
|
||||
t.Errorf("response points = %d, want 0", points)
|
||||
}
|
||||
default:
|
||||
t.Fatal("No response queued")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleMsgMhfExchangeKouryouPoint_Error(t *testing.T) {
|
||||
server := createMockServer()
|
||||
charRepo := newMockCharacterRepo()
|
||||
charRepo.adjustErr = errors.New("db error")
|
||||
server.charRepo = charRepo
|
||||
session := createMockSession(1, server)
|
||||
|
||||
pkt := &mhfpacket.MsgMhfExchangeKouryouPoint{
|
||||
AckHandle: 300,
|
||||
KouryouPoints: 5000,
|
||||
}
|
||||
handleMsgMhfExchangeKouryouPoint(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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user