254 lines
7.1 KiB
Go
254 lines
7.1 KiB
Go
package appearances
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"eq2emu/internal/database"
|
|
)
|
|
|
|
func TestAppearanceBasics(t *testing.T) {
|
|
appearance := &Appearance{
|
|
ID: 1472,
|
|
Name: "ec/pc/human/human_male",
|
|
MinClient: 283,
|
|
}
|
|
|
|
if appearance.GetID() != 1472 {
|
|
t.Errorf("Expected ID 1472, got %d", appearance.GetID())
|
|
}
|
|
|
|
if appearance.GetName() != "ec/pc/human/human_male" {
|
|
t.Errorf("Expected name 'ec/pc/human/human_male', got %s", appearance.GetName())
|
|
}
|
|
|
|
if appearance.GetNameString() != "ec/pc/human/human_male" {
|
|
t.Errorf("Expected name string 'ec/pc/human/human_male', got %s", appearance.GetNameString())
|
|
}
|
|
|
|
if appearance.GetMinClientVersion() != 283 {
|
|
t.Errorf("Expected min client 283, got %d", appearance.GetMinClientVersion())
|
|
}
|
|
|
|
// Test compatibility
|
|
if !appearance.IsCompatibleWithClient(283) {
|
|
t.Error("Expected compatibility with client version 283")
|
|
}
|
|
|
|
if !appearance.IsCompatibleWithClient(500) {
|
|
t.Error("Expected compatibility with client version 500")
|
|
}
|
|
|
|
if appearance.IsCompatibleWithClient(200) {
|
|
t.Error("Expected incompatibility with client version 200")
|
|
}
|
|
}
|
|
|
|
func TestManagerCreation(t *testing.T) {
|
|
// Create mock database
|
|
db := &database.Database{}
|
|
manager := NewManager(db)
|
|
|
|
if manager == nil {
|
|
t.Fatal("Manager creation failed")
|
|
}
|
|
|
|
if manager.GetAppearanceCount() != 0 {
|
|
t.Errorf("Expected 0 appearances, got %d", manager.GetAppearanceCount())
|
|
}
|
|
|
|
stats := manager.GetStatistics()
|
|
if stats["total_appearances"].(int32) != 0 {
|
|
t.Errorf("Expected 0 total appearances in stats, got %d", stats["total_appearances"])
|
|
}
|
|
}
|
|
|
|
func TestAppearanceLookup(t *testing.T) {
|
|
manager := NewManager(&database.Database{})
|
|
|
|
// Manually add test appearances (simulating database load)
|
|
manager.mutex.Lock()
|
|
testAppearances := []*Appearance{
|
|
{ID: 1472, Name: "ec/pc/human/human_male", MinClient: 283},
|
|
{ID: 1473, Name: "ec/pc/human/human_female", MinClient: 283},
|
|
{ID: 1500, Name: "ec/pc/elf/elf_male", MinClient: 283},
|
|
{ID: 2000, Name: "accessories/hair/hair_01", MinClient: 283},
|
|
{ID: 3000, Name: "test_ghost_appearance", MinClient: 283},
|
|
}
|
|
|
|
for _, appearance := range testAppearances {
|
|
manager.appearances[appearance.ID] = appearance
|
|
manager.updateNameIndex(appearance, true)
|
|
}
|
|
manager.mutex.Unlock()
|
|
|
|
// Test FindAppearanceByID (C++ API compatibility)
|
|
found := manager.FindAppearanceByID(1472)
|
|
if found == nil {
|
|
t.Fatal("Expected to find appearance with ID 1472")
|
|
}
|
|
if found.Name != "ec/pc/human/human_male" {
|
|
t.Errorf("Expected name 'ec/pc/human/human_male', got %s", found.Name)
|
|
}
|
|
|
|
// Test GetAppearanceID (C++ API compatibility)
|
|
id := manager.GetAppearanceID("ec/pc/human/human_male")
|
|
if id != 1472 {
|
|
t.Errorf("Expected ID 1472, got %d", id)
|
|
}
|
|
|
|
// Test GetAppearanceName (C++ API compatibility)
|
|
name := manager.GetAppearanceName(1472)
|
|
if name != "ec/pc/human/human_male" {
|
|
t.Errorf("Expected name 'ec/pc/human/human_male', got %s", name)
|
|
}
|
|
|
|
// Test GetAppearanceIDsLikeName (C++ API compatibility)
|
|
ids := manager.GetAppearanceIDsLikeName("human", false)
|
|
if len(ids) != 2 {
|
|
t.Errorf("Expected 2 human appearances, got %d", len(ids))
|
|
}
|
|
|
|
// Test filtering
|
|
idsFiltered := manager.GetAppearanceIDsLikeName("ghost", true)
|
|
if len(idsFiltered) != 0 {
|
|
t.Errorf("Expected 0 ghost appearances after filtering, got %d", len(idsFiltered))
|
|
}
|
|
|
|
idsUnfiltered := manager.GetAppearanceIDsLikeName("ghost", false)
|
|
if len(idsUnfiltered) != 1 {
|
|
t.Errorf("Expected 1 ghost appearance without filtering, got %d", len(idsUnfiltered))
|
|
}
|
|
|
|
// Test path component indexing
|
|
hairIDs := manager.GetAppearanceIDsLikeName("hair", false)
|
|
if len(hairIDs) != 1 {
|
|
t.Errorf("Expected 1 hair appearance, got %d", len(hairIDs))
|
|
}
|
|
}
|
|
|
|
func TestCompatibilityFiltering(t *testing.T) {
|
|
manager := NewManager(&database.Database{})
|
|
|
|
// Add test appearances with different client versions
|
|
manager.mutex.Lock()
|
|
testAppearances := []*Appearance{
|
|
{ID: 1, Name: "old_appearance", MinClient: 100},
|
|
{ID: 2, Name: "current_appearance", MinClient: 283},
|
|
{ID: 3, Name: "new_appearance", MinClient: 500},
|
|
}
|
|
|
|
for _, appearance := range testAppearances {
|
|
manager.appearances[appearance.ID] = appearance
|
|
}
|
|
manager.mutex.Unlock()
|
|
|
|
// Test compatibility filtering
|
|
compatible := manager.GetCompatibleAppearances(283)
|
|
if len(compatible) != 2 {
|
|
t.Errorf("Expected 2 compatible appearances for client 283, got %d", len(compatible))
|
|
}
|
|
|
|
compatible = manager.GetCompatibleAppearances(100)
|
|
if len(compatible) != 1 {
|
|
t.Errorf("Expected 1 compatible appearance for client 100, got %d", len(compatible))
|
|
}
|
|
|
|
compatible = manager.GetCompatibleAppearances(600)
|
|
if len(compatible) != 3 {
|
|
t.Errorf("Expected 3 compatible appearances for client 600, got %d", len(compatible))
|
|
}
|
|
}
|
|
|
|
func TestPacketBuilding(t *testing.T) {
|
|
manager := NewManager(&database.Database{})
|
|
|
|
// Test packet building (will fail gracefully if DressingRoom packet not found)
|
|
clientVersion := uint32(283)
|
|
characterID := int32(12345)
|
|
|
|
_, err := manager.ShowDressingRoom(characterID, clientVersion, 1, 1472, 100, 200)
|
|
if err == nil {
|
|
t.Error("Expected error due to missing packet fields")
|
|
}
|
|
|
|
// Verify error contains expected message about packet building
|
|
if err != nil && !contains(err.Error(), "failed to build dressing room packet") && !contains(err.Error(), "packet not found") {
|
|
t.Errorf("Expected packet-related error, got: %v", err)
|
|
}
|
|
|
|
// Test statistics update
|
|
stats := manager.GetStatistics()
|
|
if stats["packet_errors"].(int32) == 0 {
|
|
t.Error("Expected packet error to be recorded in statistics")
|
|
}
|
|
|
|
t.Logf("Packet integration working: found DressingRoom packet structure but needs proper field mapping")
|
|
}
|
|
|
|
func TestGlobalFunctions(t *testing.T) {
|
|
// Test global functions work without initialized manager
|
|
appearance := FindAppearanceByID(1)
|
|
if appearance != nil {
|
|
t.Error("Expected nil appearance when manager not initialized")
|
|
}
|
|
|
|
id := GetAppearanceID("test")
|
|
if id != 0 {
|
|
t.Errorf("Expected ID 0 when manager not initialized, got %d", id)
|
|
}
|
|
|
|
name := GetAppearanceName(1)
|
|
if name != "" {
|
|
t.Errorf("Expected empty name when manager not initialized, got %s", name)
|
|
}
|
|
|
|
ids := GetAppearanceIDsLikeName("test", false)
|
|
if ids != nil {
|
|
t.Error("Expected nil slice when manager not initialized")
|
|
}
|
|
}
|
|
|
|
func TestFilteringLogic(t *testing.T) {
|
|
manager := NewManager(&database.Database{})
|
|
|
|
// Test filtering logic
|
|
testCases := []struct {
|
|
name string
|
|
expected bool
|
|
}{
|
|
{"normal_appearance", true},
|
|
{"ghost_appearance", false},
|
|
{"headless_horseman", false},
|
|
{"elemental_form", false},
|
|
{"test_model", false},
|
|
{"zombie_skin", false},
|
|
{"vampire_teeth", false},
|
|
{"GHOST_uppercase", false}, // Should be case-insensitive
|
|
{"valid_model", true},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
result := manager.isFilteredAppearance(tc.name)
|
|
if result != tc.expected {
|
|
t.Errorf("Filter test for '%s': expected %v, got %v", tc.name, tc.expected, result)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Helper function to check if string contains substring
|
|
func contains(str, substr string) bool {
|
|
if len(substr) == 0 {
|
|
return true
|
|
}
|
|
if len(str) < len(substr) {
|
|
return false
|
|
}
|
|
|
|
for i := 0; i <= len(str)-len(substr); i++ {
|
|
if str[i:i+len(substr)] == substr {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
} |