package collections import ( "testing" "eq2emu/internal/database" ) func TestNew(t *testing.T) { db, err := database.NewSQLite("file::memory:?mode=memory&cache=shared") if err != nil { t.Fatalf("Failed to create test database: %v", err) } defer db.Close() // Test creating a new collection collection := New(db) if collection == nil { t.Fatal("New returned nil") } if !collection.IsNew() { t.Error("New collection should be marked as new") } if len(collection.CollectionItems) != 0 { t.Error("New collection should have empty items slice") } if len(collection.RewardItems) != 0 { t.Error("New collection should have empty reward items slice") } } func TestNewWithData(t *testing.T) { db, err := database.NewSQLite("file::memory:?mode=memory&cache=shared") if err != nil { t.Fatalf("Failed to create test database: %v", err) } defer db.Close() collection := NewWithData(100, "Test Collection", "Heritage", 20, db) if collection == nil { t.Fatal("NewWithData returned nil") } if collection.GetID() != 100 { t.Errorf("Expected ID 100, got %d", collection.GetID()) } if collection.GetName() != "Test Collection" { t.Errorf("Expected name 'Test Collection', got '%s'", collection.GetName()) } if collection.GetCategory() != "Heritage" { t.Errorf("Expected category 'Heritage', got '%s'", collection.GetCategory()) } if collection.GetLevel() != 20 { t.Errorf("Expected level 20, got %d", collection.GetLevel()) } if !collection.IsNew() { t.Error("NewWithData should create new collection") } } func TestCollectionItems(t *testing.T) { db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") defer db.Close() collection := NewWithData(100, "Test", "Heritage", 20, db) // Add collection items collection.CollectionItems = append(collection.CollectionItems, CollectionItem{ ItemID: 12345, Index: 0, Found: ItemNotFound, }) collection.CollectionItems = append(collection.CollectionItems, CollectionItem{ ItemID: 12346, Index: 1, Found: ItemNotFound, }) // Test NeedsItem if !collection.NeedsItem(12345) { t.Error("Collection should need item 12345") } if collection.NeedsItem(99999) { t.Error("Collection should not need item 99999") } // Test GetCollectionItemByItemID item := collection.GetCollectionItemByItemID(12345) if item == nil { t.Error("Should find collection item by ID") } if item.ItemID != 12345 { t.Errorf("Expected item ID 12345, got %d", item.ItemID) } // Test MarkItemFound if !collection.MarkItemFound(12345) { t.Error("Should successfully mark item as found") } // Verify item is now marked as found if collection.CollectionItems[0].Found != ItemFound { t.Error("Item should be marked as found") } if !collection.SaveNeeded { t.Error("Collection should be marked as needing save") } // Test that marking the same item again fails if collection.MarkItemFound(12345) { t.Error("Should not mark already found item again") } } func TestCollectionProgress(t *testing.T) { db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") defer db.Close() collection := NewWithData(100, "Test", "Heritage", 20, db) // Add collection items for i := 0; i < 4; i++ { collection.CollectionItems = append(collection.CollectionItems, CollectionItem{ ItemID: int32(12345 + i), Index: int8(i), Found: ItemNotFound, }) } // Initially 0% progress if progress := collection.GetProgress(); progress != 0.0 { t.Errorf("Expected 0%% progress, got %.1f%%", progress) } // Not ready to turn in if collection.GetIsReadyToTurnIn() { t.Error("Collection should not be ready to turn in") } // Mark some items found collection.MarkItemFound(12345) // 25% collection.MarkItemFound(12346) // 50% if progress := collection.GetProgress(); progress != 50.0 { t.Errorf("Expected 50%% progress, got %.1f%%", progress) } // Still not ready if collection.GetIsReadyToTurnIn() { t.Error("Collection should not be ready to turn in at 50%") } // Mark remaining items collection.MarkItemFound(12347) // 75% collection.MarkItemFound(12348) // 100% if progress := collection.GetProgress(); progress != 100.0 { t.Errorf("Expected 100%% progress, got %.1f%%", progress) } // Now ready to turn in if !collection.GetIsReadyToTurnIn() { t.Error("Collection should be ready to turn in at 100%") } } func TestCollectionRewards(t *testing.T) { db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") defer db.Close() collection := NewWithData(100, "Test", "Heritage", 20, db) // Set coin and XP rewards collection.RewardCoin = 1000 collection.RewardXP = 500 // Add item rewards collection.RewardItems = append(collection.RewardItems, CollectionRewardItem{ ItemID: 50001, Quantity: 1, }) collection.SelectableRewardItems = append(collection.SelectableRewardItems, CollectionRewardItem{ ItemID: 50002, Quantity: 1, }) collection.SelectableRewardItems = append(collection.SelectableRewardItems, CollectionRewardItem{ ItemID: 50003, Quantity: 1, }) if collection.RewardCoin != 1000 { t.Errorf("Expected 1000 coin reward, got %d", collection.RewardCoin) } if collection.RewardXP != 500 { t.Errorf("Expected 500 XP reward, got %d", collection.RewardXP) } if len(collection.RewardItems) != 1 { t.Errorf("Expected 1 reward item, got %d", len(collection.RewardItems)) } if len(collection.SelectableRewardItems) != 2 { t.Errorf("Expected 2 selectable reward items, got %d", len(collection.SelectableRewardItems)) } } func TestCollectionClone(t *testing.T) { db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") defer db.Close() original := NewWithData(500, "Original Collection", "Heritage", 30, db) original.RewardCoin = 2000 original.RewardXP = 1000 // Add some items original.CollectionItems = append(original.CollectionItems, CollectionItem{ ItemID: 12345, Index: 0, Found: ItemFound, }) original.RewardItems = append(original.RewardItems, CollectionRewardItem{ ItemID: 50001, Quantity: 2, }) clone := original.Clone() if clone == nil { t.Fatal("Clone returned nil") } if clone == original { t.Error("Clone returned same pointer as original") } // Test that all fields are copied if clone.GetID() != original.GetID() { t.Errorf("Clone ID = %v, want %v", clone.GetID(), original.GetID()) } if clone.GetName() != original.GetName() { t.Errorf("Clone Name = %v, want %v", clone.GetName(), original.GetName()) } if clone.RewardCoin != original.RewardCoin { t.Errorf("Clone RewardCoin = %v, want %v", clone.RewardCoin, original.RewardCoin) } if len(clone.CollectionItems) != len(original.CollectionItems) { t.Errorf("Clone items length = %v, want %v", len(clone.CollectionItems), len(original.CollectionItems)) } if len(clone.RewardItems) != len(original.RewardItems) { t.Errorf("Clone reward items length = %v, want %v", len(clone.RewardItems), len(original.RewardItems)) } if !clone.IsNew() { t.Error("Clone should always be marked as new") } // Verify modification independence clone.Name = "Modified Clone" if original.GetName() == "Modified Clone" { t.Error("Modifying clone affected original") } // Verify slice independence if len(original.CollectionItems) > 0 && len(clone.CollectionItems) > 0 { clone.CollectionItems[0].Found = ItemNotFound if original.CollectionItems[0].Found == ItemNotFound { t.Error("Modifying clone items affected original") } } } func TestCollectionCompletion(t *testing.T) { db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") defer db.Close() collection := NewWithData(100, "Test", "Heritage", 20, db) // Add items collection.CollectionItems = append(collection.CollectionItems, CollectionItem{ ItemID: 12345, Index: 0, Found: ItemNotFound, }) // Not ready when incomplete if collection.GetIsReadyToTurnIn() { t.Error("Incomplete collection should not be ready to turn in") } // Mark as completed collection.Completed = true // Completed collections are never ready to turn in if collection.GetIsReadyToTurnIn() { t.Error("Completed collection should not be ready to turn in") } // Mark item found and set not completed collection.Completed = false collection.MarkItemFound(12345) // Now should be ready if !collection.GetIsReadyToTurnIn() { t.Error("Collection with all items found should be ready to turn in") } }