mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-27 01:53:19 +01:00
fix(channelserver): correct 3 test bugs causing 10 deterministic failures
- Use users.frontier_points instead of characters.frontier_points (column moved in 9.2 schema migration) across savedata and session lifecycle tests - Use BYTEA column (otomoairou) instead of INTEGER column (kouryou_point) in repo_character Load/SaveColumn tests - Build blocked CSV from actual auto-incremented character IDs instead of hardcoded IDs in ListMember integration test - Fix nil charRepo panic in CompleteSaveLoadCycle by using SetTestDB()
This commit is contained in:
@@ -160,22 +160,18 @@ func TestHandleMsgMhfListMember_Integration(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
blockedCSV string
|
|
||||||
wantBlockCount int
|
wantBlockCount int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "no_blocked_users",
|
name: "no_blocked_users",
|
||||||
blockedCSV: "",
|
|
||||||
wantBlockCount: 0,
|
wantBlockCount: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "single_blocked_user",
|
name: "single_blocked_user",
|
||||||
blockedCSV: "2",
|
|
||||||
wantBlockCount: 1,
|
wantBlockCount: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multiple_blocked_users",
|
name: "multiple_blocked_users",
|
||||||
blockedCSV: "2,3,4",
|
|
||||||
wantBlockCount: 3,
|
wantBlockCount: 3,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -187,17 +183,19 @@ func TestHandleMsgMhfListMember_Integration(t *testing.T) {
|
|||||||
charName := fmt.Sprintf("Char%d", i)
|
charName := fmt.Sprintf("Char%d", i)
|
||||||
charID := CreateTestCharacter(t, db, userID, charName)
|
charID := CreateTestCharacter(t, db, userID, charName)
|
||||||
|
|
||||||
// Create blocked characters
|
// Create blocked characters and build CSV from their actual IDs
|
||||||
if tt.blockedCSV != "" {
|
blockedCSV := ""
|
||||||
// Create the blocked users
|
for j := 0; j < tt.wantBlockCount; j++ {
|
||||||
for i := 2; i <= 4; i++ {
|
blockedUserID := CreateTestUser(t, db, fmt.Sprintf("blk_%s_%d", tt.name, j))
|
||||||
blockedUserID := CreateTestUser(t, db, "blocked_user_"+tt.name+"_"+string(rune(i)))
|
blockedCharID := CreateTestCharacter(t, db, blockedUserID, fmt.Sprintf("Blk%d_%d", i, j))
|
||||||
CreateTestCharacter(t, db, blockedUserID, "BlockedChar_"+string(rune(i)))
|
if blockedCSV != "" {
|
||||||
|
blockedCSV += ","
|
||||||
}
|
}
|
||||||
|
blockedCSV += fmt.Sprintf("%d", blockedCharID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set blocked list
|
// Set blocked list
|
||||||
_, err := db.Exec("UPDATE characters SET blocked = $1 WHERE id = $2", tt.blockedCSV, charID)
|
_, err := db.Exec("UPDATE characters SET blocked = $1 WHERE id = $2", blockedCSV, charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to update blocked list: %v", err)
|
t.Fatalf("Failed to update blocked list: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,25 +28,25 @@ func TestSaveLoad_RoadPoints(t *testing.T) {
|
|||||||
defer TeardownTestDB(t, db)
|
defer TeardownTestDB(t, db)
|
||||||
|
|
||||||
userID := CreateTestUser(t, db, "testuser")
|
userID := CreateTestUser(t, db, "testuser")
|
||||||
charID := CreateTestCharacter(t, db, userID, "TestChar")
|
_ = CreateTestCharacter(t, db, userID, "TestChar")
|
||||||
|
|
||||||
// Set initial Road Points
|
// Set initial Road Points (frontier_points is on the users table since 9.2 migration)
|
||||||
initialPoints := uint32(1000)
|
initialPoints := uint32(1000)
|
||||||
_, err := db.Exec("UPDATE characters SET frontier_points = $1 WHERE id = $2", initialPoints, charID)
|
_, err := db.Exec("UPDATE users SET frontier_points = $1 WHERE id = $2", initialPoints, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to set initial road points: %v", err)
|
t.Fatalf("Failed to set initial road points: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modify Road Points
|
// Modify Road Points
|
||||||
newPoints := uint32(2500)
|
newPoints := uint32(2500)
|
||||||
_, err = db.Exec("UPDATE characters SET frontier_points = $1 WHERE id = $2", newPoints, charID)
|
_, err = db.Exec("UPDATE users SET frontier_points = $1 WHERE id = $2", newPoints, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to update road points: %v", err)
|
t.Fatalf("Failed to update road points: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify Road Points persisted
|
// Verify Road Points persisted
|
||||||
var savedPoints uint32
|
var savedPoints uint32
|
||||||
err = db.QueryRow("SELECT frontier_points FROM characters WHERE id = $1", charID).Scan(&savedPoints)
|
err = db.QueryRow("SELECT frontier_points FROM users WHERE id = $1", userID).Scan(&savedPoints)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to query road points: %v", err)
|
t.Fatalf("Failed to query road points: %v", err)
|
||||||
}
|
}
|
||||||
@@ -468,9 +468,9 @@ func TestSaveLoad_CompleteSaveLoadCycle(t *testing.T) {
|
|||||||
s.Name = "SaveLoadTest"
|
s.Name = "SaveLoadTest"
|
||||||
SetTestDB(s.server, db)
|
SetTestDB(s.server, db)
|
||||||
|
|
||||||
// 1. Set Road Points
|
// 1. Set Road Points (frontier_points is on the users table since 9.2 migration)
|
||||||
rdpPoints := uint32(5000)
|
rdpPoints := uint32(5000)
|
||||||
_, err := db.Exec("UPDATE characters SET frontier_points = $1 WHERE id = $2", rdpPoints, charID)
|
_, err := db.Exec("UPDATE users SET frontier_points = $1 WHERE id = $2", rdpPoints, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to set RdP: %v", err)
|
t.Fatalf("Failed to set RdP: %v", err)
|
||||||
}
|
}
|
||||||
@@ -506,7 +506,7 @@ func TestSaveLoad_CompleteSaveLoadCycle(t *testing.T) {
|
|||||||
mock2 := &MockCryptConn{sentPackets: make([][]byte, 0)}
|
mock2 := &MockCryptConn{sentPackets: make([][]byte, 0)}
|
||||||
s2 := createTestSession(mock2)
|
s2 := createTestSession(mock2)
|
||||||
s2.charID = charID
|
s2.charID = charID
|
||||||
s2.server.db = db
|
SetTestDB(s2.server, db)
|
||||||
s2.server.userBinaryParts = make(map[userBinaryPartID][]byte)
|
s2.server.userBinaryParts = make(map[userBinaryPartID][]byte)
|
||||||
|
|
||||||
// Load character data
|
// Load character data
|
||||||
@@ -520,9 +520,9 @@ func TestSaveLoad_CompleteSaveLoadCycle(t *testing.T) {
|
|||||||
t.Errorf("Character name not loaded correctly: got %q, want %q", s2.Name, "SaveLoadTest")
|
t.Errorf("Character name not loaded correctly: got %q, want %q", s2.Name, "SaveLoadTest")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify Road Points persisted
|
// Verify Road Points persisted (frontier_points is on users table)
|
||||||
var loadedRdP uint32
|
var loadedRdP uint32
|
||||||
_ = db.QueryRow("SELECT frontier_points FROM characters WHERE id = $1", charID).Scan(&loadedRdP)
|
_ = db.QueryRow("SELECT frontier_points FROM users WHERE id = $1", userID).Scan(&loadedRdP)
|
||||||
if loadedRdP != rdpPoints {
|
if loadedRdP != rdpPoints {
|
||||||
t.Errorf("RdP not persisted: got %d, want %d (BUG CONFIRMED)", loadedRdP, rdpPoints)
|
t.Errorf("RdP not persisted: got %d, want %d (BUG CONFIRMED)", loadedRdP, rdpPoints)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ func TestLoadColumn(t *testing.T) {
|
|||||||
|
|
||||||
// Write a known blob to a column
|
// Write a known blob to a column
|
||||||
blob := []byte{0xDE, 0xAD, 0xBE, 0xEF}
|
blob := []byte{0xDE, 0xAD, 0xBE, 0xEF}
|
||||||
_, err := db.Exec("UPDATE characters SET kouryou_point=$1 WHERE id=$2", blob, charID)
|
_, err := db.Exec("UPDATE characters SET otomoairou=$1 WHERE id=$2", blob, charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Setup failed: %v", err)
|
t.Fatalf("Setup failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := repo.LoadColumn(charID, "kouryou_point")
|
data, err := repo.LoadColumn(charID, "otomoairou")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("LoadColumn failed: %v", err)
|
t.Fatalf("LoadColumn failed: %v", err)
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ func TestLoadColumnNil(t *testing.T) {
|
|||||||
repo, _, charID := setupCharRepo(t)
|
repo, _, charID := setupCharRepo(t)
|
||||||
|
|
||||||
// Column should be NULL by default
|
// Column should be NULL by default
|
||||||
data, err := repo.LoadColumn(charID, "kouryou_point")
|
data, err := repo.LoadColumn(charID, "otomoairou")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("LoadColumn failed: %v", err)
|
t.Fatalf("LoadColumn failed: %v", err)
|
||||||
}
|
}
|
||||||
@@ -53,13 +53,13 @@ func TestSaveColumn(t *testing.T) {
|
|||||||
repo, db, charID := setupCharRepo(t)
|
repo, db, charID := setupCharRepo(t)
|
||||||
|
|
||||||
blob := []byte{0x01, 0x02, 0x03}
|
blob := []byte{0x01, 0x02, 0x03}
|
||||||
if err := repo.SaveColumn(charID, "kouryou_point", blob); err != nil {
|
if err := repo.SaveColumn(charID, "otomoairou", blob); err != nil {
|
||||||
t.Fatalf("SaveColumn failed: %v", err)
|
t.Fatalf("SaveColumn failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify via direct SELECT
|
// Verify via direct SELECT
|
||||||
var got []byte
|
var got []byte
|
||||||
if err := db.QueryRow("SELECT kouryou_point FROM characters WHERE id=$1", charID).Scan(&got); err != nil {
|
if err := db.QueryRow("SELECT otomoairou FROM characters WHERE id=$1", charID).Scan(&got); err != nil {
|
||||||
t.Fatalf("Verification query failed: %v", err)
|
t.Fatalf("Verification query failed: %v", err)
|
||||||
}
|
}
|
||||||
if len(got) != 3 || got[0] != 0x01 || got[2] != 0x03 {
|
if len(got) != 3 || got[0] != 0x01 || got[2] != 0x03 {
|
||||||
|
|||||||
@@ -52,9 +52,9 @@ func TestSessionLifecycle_BasicSaveLoadCycle(t *testing.T) {
|
|||||||
session1 := createTestSessionForServerWithChar(server, charID, "LifecycleChar")
|
session1 := createTestSessionForServerWithChar(server, charID, "LifecycleChar")
|
||||||
// Note: Not calling Start() since we're testing handlers directly, not packet processing
|
// Note: Not calling Start() since we're testing handlers directly, not packet processing
|
||||||
|
|
||||||
// Modify data via packet handlers
|
// Modify data via packet handlers (frontier_points is on users table since 9.2 migration)
|
||||||
initialPoints := uint32(5000)
|
initialPoints := uint32(5000)
|
||||||
_, err := db.Exec("UPDATE characters SET frontier_points = $1 WHERE id = $2", initialPoints, charID)
|
_, err := db.Exec("UPDATE users SET frontier_points = $1 WHERE id = $2", initialPoints, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to set initial road points: %v", err)
|
t.Fatalf("Failed to set initial road points: %v", err)
|
||||||
}
|
}
|
||||||
@@ -292,9 +292,9 @@ func TestSessionLifecycle_MultipleDataTypesPersistence(t *testing.T) {
|
|||||||
// ===== SESSION 1: Modify multiple data types =====
|
// ===== SESSION 1: Modify multiple data types =====
|
||||||
session1 := createTestSessionForServerWithChar(server, charID, "MultiChar")
|
session1 := createTestSessionForServerWithChar(server, charID, "MultiChar")
|
||||||
|
|
||||||
// 1. Set Road Points
|
// 1. Set Road Points (frontier_points is on users table since 9.2 migration)
|
||||||
rdpPoints := uint32(7500)
|
rdpPoints := uint32(7500)
|
||||||
_, err := db.Exec("UPDATE characters SET frontier_points = $1 WHERE id = $2", rdpPoints, charID)
|
_, err := db.Exec("UPDATE users SET frontier_points = $1 WHERE id = $2", rdpPoints, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to set RdP: %v", err)
|
t.Fatalf("Failed to set RdP: %v", err)
|
||||||
}
|
}
|
||||||
@@ -362,9 +362,9 @@ func TestSessionLifecycle_MultipleDataTypesPersistence(t *testing.T) {
|
|||||||
|
|
||||||
allPassed := true
|
allPassed := true
|
||||||
|
|
||||||
// Verify 1: Road Points
|
// Verify 1: Road Points (frontier_points is on users table)
|
||||||
var loadedRdP uint32
|
var loadedRdP uint32
|
||||||
_ = db.QueryRow("SELECT frontier_points FROM characters WHERE id = $1", charID).Scan(&loadedRdP)
|
_ = db.QueryRow("SELECT frontier_points FROM users WHERE id = $1", userID).Scan(&loadedRdP)
|
||||||
if loadedRdP != rdpPoints {
|
if loadedRdP != rdpPoints {
|
||||||
t.Errorf("❌ RdP not persisted: got %d, want %d", loadedRdP, rdpPoints)
|
t.Errorf("❌ RdP not persisted: got %d, want %d", loadedRdP, rdpPoints)
|
||||||
allPassed = false
|
allPassed = false
|
||||||
@@ -446,9 +446,9 @@ func TestSessionLifecycle_DisconnectWithoutLogout(t *testing.T) {
|
|||||||
// ===== SESSION 1: Modify data then disconnect without explicit logout =====
|
// ===== SESSION 1: Modify data then disconnect without explicit logout =====
|
||||||
session1 := createTestSessionForServerWithChar(server, charID, "DisconnectChar")
|
session1 := createTestSessionForServerWithChar(server, charID, "DisconnectChar")
|
||||||
|
|
||||||
// Modify data
|
// Modify data (frontier_points is on users table since 9.2 migration)
|
||||||
rdpPoints := uint32(9999)
|
rdpPoints := uint32(9999)
|
||||||
_, err := db.Exec("UPDATE characters SET frontier_points = $1 WHERE id = $2", rdpPoints, charID)
|
_, err := db.Exec("UPDATE users SET frontier_points = $1 WHERE id = $2", rdpPoints, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to set RdP: %v", err)
|
t.Fatalf("Failed to set RdP: %v", err)
|
||||||
}
|
}
|
||||||
@@ -535,9 +535,9 @@ func TestSessionLifecycle_RapidReconnect(t *testing.T) {
|
|||||||
|
|
||||||
session := createTestSessionForServerWithChar(server, charID, "RapidChar")
|
session := createTestSessionForServerWithChar(server, charID, "RapidChar")
|
||||||
|
|
||||||
// Modify road points each cycle
|
// Modify road points each cycle (frontier_points is on users table since 9.2 migration)
|
||||||
points := uint32(1000 * cycle)
|
points := uint32(1000 * cycle)
|
||||||
_, err := db.Exec("UPDATE characters SET frontier_points = $1 WHERE id = $2", points, charID)
|
_, err := db.Exec("UPDATE users SET frontier_points = $1 WHERE id = $2", points, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Cycle %d: Failed to update points: %v", cycle, err)
|
t.Fatalf("Cycle %d: Failed to update points: %v", cycle, err)
|
||||||
}
|
}
|
||||||
@@ -548,7 +548,7 @@ func TestSessionLifecycle_RapidReconnect(t *testing.T) {
|
|||||||
|
|
||||||
// Verify points persisted
|
// Verify points persisted
|
||||||
var loadedPoints uint32
|
var loadedPoints uint32
|
||||||
_ = db.QueryRow("SELECT frontier_points FROM characters WHERE id = $1", charID).Scan(&loadedPoints)
|
_ = db.QueryRow("SELECT frontier_points FROM users WHERE id = $1", userID).Scan(&loadedPoints)
|
||||||
if loadedPoints != points {
|
if loadedPoints != points {
|
||||||
t.Errorf("❌ Cycle %d: Points not persisted: got %d, want %d", cycle, loadedPoints, points)
|
t.Errorf("❌ Cycle %d: Points not persisted: got %d, want %d", cycle, loadedPoints, points)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user