eq2go/internal/collections/master_test.go

365 lines
11 KiB
Go

package collections
import (
"testing"
"eq2emu/internal/database"
)
func TestNewMasterList(t *testing.T) {
masterList := NewMasterList()
if masterList == nil {
t.Fatal("NewMasterList returned nil")
}
if masterList.GetCollectionCount() != 0 {
t.Errorf("Expected count 0, got %d", masterList.GetCollectionCount())
}
}
func TestMasterListBasicOperations(t *testing.T) {
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
defer db.Close()
masterList := NewMasterList()
// Create test collections
collection1 := NewWithData(1001, "Heritage Collection", "Heritage", 20, db)
collection2 := NewWithData(1002, "Treasured Collection", "Treasured", 30, db)
// Test adding
if !masterList.AddCollection(collection1) {
t.Error("Should successfully add collection1")
}
if !masterList.AddCollection(collection2) {
t.Error("Should successfully add collection2")
}
// Test duplicate add (should fail)
if masterList.AddCollection(collection1) {
t.Error("Should not add duplicate collection")
}
if masterList.GetCollectionCount() != 2 {
t.Errorf("Expected count 2, got %d", masterList.GetCollectionCount())
}
// Test retrieving
retrieved := masterList.GetCollection(1001)
if retrieved == nil {
t.Error("Should retrieve added collection")
}
if retrieved.GetName() != "Heritage Collection" {
t.Errorf("Expected name 'Heritage Collection', got '%s'", retrieved.GetName())
}
// Test safe retrieval
retrieved, exists := masterList.GetCollectionSafe(1001)
if !exists || retrieved == nil {
t.Error("GetCollectionSafe should return collection and true")
}
_, exists = masterList.GetCollectionSafe(9999)
if exists {
t.Error("GetCollectionSafe should return false for non-existent ID")
}
// Test HasCollection
if !masterList.HasCollection(1001) {
t.Error("HasCollection should return true for existing ID")
}
if masterList.HasCollection(9999) {
t.Error("HasCollection should return false for non-existent ID")
}
// Test removing
if !masterList.RemoveCollection(1001) {
t.Error("Should successfully remove collection")
}
if masterList.GetCollectionCount() != 1 {
t.Errorf("Expected count 1, got %d", masterList.GetCollectionCount())
}
if masterList.HasCollection(1001) {
t.Error("Collection should be removed")
}
// Test clear
masterList.ClearCollections()
if masterList.GetCollectionCount() != 0 {
t.Errorf("Expected count 0 after clear, got %d", masterList.GetCollectionCount())
}
}
func TestMasterListItemNeeds(t *testing.T) {
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
defer db.Close()
masterList := NewMasterList()
// Create collections with items
collection1 := NewWithData(1001, "Heritage Collection", "Heritage", 20, db)
collection1.CollectionItems = append(collection1.CollectionItems, CollectionItem{
ItemID: 12345,
Index: 0,
Found: ItemNotFound,
})
collection1.CollectionItems = append(collection1.CollectionItems, CollectionItem{
ItemID: 12346,
Index: 1,
Found: ItemFound, // Already found
})
collection2 := NewWithData(1002, "Treasured Collection", "Treasured", 30, db)
collection2.CollectionItems = append(collection2.CollectionItems, CollectionItem{
ItemID: 12347,
Index: 0,
Found: ItemNotFound,
})
masterList.AddCollection(collection1)
masterList.AddCollection(collection2)
// Test NeedsItem
if !masterList.NeedsItem(12345) {
t.Error("MasterList should need item 12345")
}
if masterList.NeedsItem(12346) {
t.Error("MasterList should not need item 12346 (already found)")
}
if !masterList.NeedsItem(12347) {
t.Error("MasterList should need item 12347")
}
if masterList.NeedsItem(99999) {
t.Error("MasterList should not need item 99999")
}
// Test GetCollectionsNeedingItem
needingItem := masterList.GetCollectionsNeedingItem(12345)
if len(needingItem) != 1 {
t.Errorf("Expected 1 collection needing item 12345, got %d", len(needingItem))
}
needingNone := masterList.GetCollectionsNeedingItem(99999)
if len(needingNone) != 0 {
t.Errorf("Expected 0 collections needing item 99999, got %d", len(needingNone))
}
}
func TestMasterListFiltering(t *testing.T) {
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
defer db.Close()
masterList := NewMasterList()
// Add test collections
collections := []*Collection{
NewWithData(1, "Heritage 1", "Heritage", 10, db),
NewWithData(2, "Heritage 2", "Heritage", 20, db),
NewWithData(3, "Treasured 1", "Treasured", 15, db),
NewWithData(4, "Treasured 2", "Treasured", 25, db),
NewWithData(5, "Legendary 1", "Legendary", 30, db),
}
for _, collection := range collections {
masterList.AddCollection(collection)
}
// Test FindCollectionsByCategory
heritageCollections := masterList.FindCollectionsByCategory("Heritage")
if len(heritageCollections) != 2 {
t.Errorf("FindCollectionsByCategory('Heritage') returned %v results, want 2", len(heritageCollections))
}
treasuredCollections := masterList.FindCollectionsByCategory("Treasured")
if len(treasuredCollections) != 2 {
t.Errorf("FindCollectionsByCategory('Treasured') returned %v results, want 2", len(treasuredCollections))
}
// Test FindCollectionsByLevel
lowLevel := masterList.FindCollectionsByLevel(10, 15)
if len(lowLevel) != 2 {
t.Errorf("FindCollectionsByLevel(10, 15) returned %v results, want 2", len(lowLevel))
}
midLevel := masterList.FindCollectionsByLevel(20, 25)
if len(midLevel) != 2 {
t.Errorf("FindCollectionsByLevel(20, 25) returned %v results, want 2", len(midLevel))
}
highLevel := masterList.FindCollectionsByLevel(30, 40)
if len(highLevel) != 1 {
t.Errorf("FindCollectionsByLevel(30, 40) returned %v results, want 1", len(highLevel))
}
}
func TestMasterListCategories(t *testing.T) {
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
defer db.Close()
masterList := NewMasterList()
// Add collections with different categories
masterList.AddCollection(NewWithData(1, "Test1", "Heritage", 10, db))
masterList.AddCollection(NewWithData(2, "Test2", "Heritage", 20, db))
masterList.AddCollection(NewWithData(3, "Test3", "Treasured", 15, db))
masterList.AddCollection(NewWithData(4, "Test4", "Legendary", 30, db))
categories := masterList.GetCategories()
expectedCategories := []string{"Heritage", "Treasured", "Legendary"}
if len(categories) != len(expectedCategories) {
t.Errorf("Expected %d categories, got %d", len(expectedCategories), len(categories))
}
// Check that all expected categories are present
categoryMap := make(map[string]bool)
for _, category := range categories {
categoryMap[category] = true
}
for _, expected := range expectedCategories {
if !categoryMap[expected] {
t.Errorf("Expected category '%s' not found", expected)
}
}
}
func TestMasterListGetAll(t *testing.T) {
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
defer db.Close()
masterList := NewMasterList()
// Add test collections
for i := int32(1); i <= 3; i++ {
collection := NewWithData(i*100, "Test", "Heritage", 20, db)
masterList.AddCollection(collection)
}
// Test GetAllCollections (map)
allMap := masterList.GetAllCollections()
if len(allMap) != 3 {
t.Errorf("GetAllCollections() returned %v items, want 3", len(allMap))
}
// Verify it's a copy by modifying returned map
delete(allMap, 100)
if masterList.GetCollectionCount() != 3 {
t.Error("Modifying returned map affected internal state")
}
// Test GetAllCollectionsList (slice)
allList := masterList.GetAllCollectionsList()
if len(allList) != 3 {
t.Errorf("GetAllCollectionsList() returned %v items, want 3", len(allList))
}
}
func TestMasterListValidation(t *testing.T) {
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
defer db.Close()
masterList := NewMasterList()
// Add valid collection
collection1 := NewWithData(100, "Valid Collection", "Heritage", 20, db)
collection1.CollectionItems = append(collection1.CollectionItems, CollectionItem{
ItemID: 12345,
Index: 0,
Found: ItemNotFound,
})
masterList.AddCollection(collection1)
issues := masterList.ValidateCollections()
if len(issues) != 0 {
t.Errorf("ValidateCollections() returned issues for valid data: %v", issues)
}
if !masterList.IsValid() {
t.Error("IsValid() should return true for valid data")
}
// Add invalid collection (empty name)
collection2 := NewWithData(200, "", "Heritage", 20, db)
masterList.AddCollection(collection2)
issues = masterList.ValidateCollections()
if len(issues) == 0 {
t.Error("ValidateCollections() should return issues for invalid data")
}
if masterList.IsValid() {
t.Error("IsValid() should return false for invalid data")
}
}
func TestMasterListStatistics(t *testing.T) {
db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared")
defer db.Close()
masterList := NewMasterList()
// Add collections with different categories and levels
collection1 := NewWithData(10, "Heritage1", "Heritage", 10, db)
collection1.CollectionItems = append(collection1.CollectionItems, CollectionItem{ItemID: 1, Index: 0, Found: 0})
collection1.CollectionItems = append(collection1.CollectionItems, CollectionItem{ItemID: 2, Index: 1, Found: 0})
collection1.RewardItems = append(collection1.RewardItems, CollectionRewardItem{ItemID: 1001, Quantity: 1})
collection2 := NewWithData(20, "Heritage2", "Heritage", 20, db)
collection2.CollectionItems = append(collection2.CollectionItems, CollectionItem{ItemID: 3, Index: 0, Found: 0})
collection2.RewardItems = append(collection2.RewardItems, CollectionRewardItem{ItemID: 1002, Quantity: 1})
collection2.SelectableRewardItems = append(collection2.SelectableRewardItems, CollectionRewardItem{ItemID: 1003, Quantity: 1})
collection3 := NewWithData(30, "Treasured1", "Treasured", 30, db)
collection3.CollectionItems = append(collection3.CollectionItems, CollectionItem{ItemID: 4, Index: 0, Found: 0})
masterList.AddCollection(collection1)
masterList.AddCollection(collection2)
masterList.AddCollection(collection3)
stats := masterList.GetStatistics()
if total, ok := stats["total_collections"].(int); !ok || total != 3 {
t.Errorf("total_collections = %v, want 3", stats["total_collections"])
}
if totalItems, ok := stats["total_collection_items"].(int); !ok || totalItems != 4 {
t.Errorf("total_collection_items = %v, want 4", stats["total_collection_items"])
}
if totalRewards, ok := stats["total_rewards"].(int); !ok || totalRewards != 3 {
t.Errorf("total_rewards = %v, want 3", stats["total_rewards"])
}
if minLevel, ok := stats["min_level"].(int8); !ok || minLevel != 10 {
t.Errorf("min_level = %v, want 10", stats["min_level"])
}
if maxLevel, ok := stats["max_level"].(int8); !ok || maxLevel != 30 {
t.Errorf("max_level = %v, want 30", stats["max_level"])
}
if categoryCounts, ok := stats["collections_by_category"].(map[string]int); ok {
if categoryCounts["Heritage"] != 2 {
t.Errorf("Heritage collections = %v, want 2", categoryCounts["Heritage"])
}
if categoryCounts["Treasured"] != 1 {
t.Errorf("Treasured collections = %v, want 1", categoryCounts["Treasured"])
}
} else {
t.Error("collections_by_category not found in statistics")
}
if avgItems, ok := stats["average_items_per_collection"].(float64); !ok || avgItems != float64(4)/3 {
t.Errorf("average_items_per_collection = %v, want %v", avgItems, float64(4)/3)
}
}