package control import ( "os" "testing" "dk/internal/database" ) func setupTestDB(t *testing.T) *database.DB { testDB := "test_control.db" t.Cleanup(func() { os.Remove(testDB) }) db, err := database.Open(testDB) if err != nil { t.Fatalf("Failed to open test database: %v", err) } // Create control table createTable := `CREATE TABLE control ( id INTEGER PRIMARY KEY AUTOINCREMENT, world_size INTEGER NOT NULL DEFAULT 250, open INTEGER NOT NULL DEFAULT 1, admin_email TEXT NOT NULL DEFAULT '', class_1_name TEXT NOT NULL DEFAULT '', class_2_name TEXT NOT NULL DEFAULT '', class_3_name TEXT NOT NULL DEFAULT '' )` if err := db.Exec(createTable); err != nil { t.Fatalf("Failed to create control table: %v", err) } // Insert default control record insertControl := `INSERT INTO control VALUES (1, 250, 1, 'admin@example.com', 'Mage', 'Warrior', 'Paladin')` if err := db.Exec(insertControl); err != nil { t.Fatalf("Failed to insert test control: %v", err) } return db } func TestFind(t *testing.T) { db := setupTestDB(t) defer db.Close() // Test finding existing control record control, err := Find(db, 1) if err != nil { t.Fatalf("Failed to find control: %v", err) } if control.ID != 1 { t.Errorf("Expected ID 1, got %d", control.ID) } if control.WorldSize != 250 { t.Errorf("Expected world size 250, got %d", control.WorldSize) } if control.Open != 1 { t.Errorf("Expected open 1, got %d", control.Open) } if control.AdminEmail != "admin@example.com" { t.Errorf("Expected admin email 'admin@example.com', got '%s'", control.AdminEmail) } if control.Class1Name != "Mage" { t.Errorf("Expected class 1 name 'Mage', got '%s'", control.Class1Name) } if control.Class2Name != "Warrior" { t.Errorf("Expected class 2 name 'Warrior', got '%s'", control.Class2Name) } if control.Class3Name != "Paladin" { t.Errorf("Expected class 3 name 'Paladin', got '%s'", control.Class3Name) } // Test finding non-existent control record _, err = Find(db, 999) if err == nil { t.Error("Expected error when finding non-existent control") } } func TestGet(t *testing.T) { db := setupTestDB(t) defer db.Close() // Test getting main control record control, err := Get(db) if err != nil { t.Fatalf("Failed to get control: %v", err) } if control.ID != 1 { t.Errorf("Expected ID 1, got %d", control.ID) } if control.WorldSize != 250 { t.Errorf("Expected world size 250, got %d", control.WorldSize) } } func TestSave(t *testing.T) { db := setupTestDB(t) defer db.Close() control, err := Get(db) if err != nil { t.Fatalf("Failed to get control: %v", err) } // Modify control settings control.WorldSize = 500 control.Open = 0 control.AdminEmail = "newadmin@example.com" control.Class1Name = "Wizard" control.Class2Name = "Knight" control.Class3Name = "Cleric" // Save changes err = control.Save() if err != nil { t.Fatalf("Failed to save control: %v", err) } // Verify changes were saved updatedControl, err := Get(db) if err != nil { t.Fatalf("Failed to get updated control: %v", err) } if updatedControl.WorldSize != 500 { t.Errorf("Expected updated world size 500, got %d", updatedControl.WorldSize) } if updatedControl.Open != 0 { t.Errorf("Expected updated open 0, got %d", updatedControl.Open) } if updatedControl.AdminEmail != "newadmin@example.com" { t.Errorf("Expected updated admin email 'newadmin@example.com', got '%s'", updatedControl.AdminEmail) } if updatedControl.Class1Name != "Wizard" { t.Errorf("Expected updated class 1 name 'Wizard', got '%s'", updatedControl.Class1Name) } if updatedControl.Class2Name != "Knight" { t.Errorf("Expected updated class 2 name 'Knight', got '%s'", updatedControl.Class2Name) } if updatedControl.Class3Name != "Cleric" { t.Errorf("Expected updated class 3 name 'Cleric', got '%s'", updatedControl.Class3Name) } } func TestOpenMethods(t *testing.T) { db := setupTestDB(t) defer db.Close() control, _ := Get(db) // Test IsOpen if !control.IsOpen() { t.Error("Expected control to be open initially") } // Test SetOpen control.SetOpen(false) if control.IsOpen() { t.Error("Expected control to be closed after SetOpen(false)") } control.SetOpen(true) if !control.IsOpen() { t.Error("Expected control to be open after SetOpen(true)") } // Test Close control.Close() if control.IsOpen() { t.Error("Expected control to be closed after Close()") } // Test OpenWorld control.OpenWorld() if !control.IsOpen() { t.Error("Expected control to be open after OpenWorld()") } } func TestClassMethods(t *testing.T) { db := setupTestDB(t) defer db.Close() control, _ := Get(db) // Test GetClassNames classNames := control.GetClassNames() expectedNames := []string{"Mage", "Warrior", "Paladin"} if len(classNames) != len(expectedNames) { t.Errorf("Expected %d class names, got %d", len(expectedNames), len(classNames)) } for i, expected := range expectedNames { if i < len(classNames) && classNames[i] != expected { t.Errorf("Expected class name '%s' at position %d, got '%s'", expected, i, classNames[i]) } } // Test SetClassNames newClasses := []string{"Sorcerer", "Barbarian", "Monk"} control.SetClassNames(newClasses) if control.Class1Name != "Sorcerer" { t.Errorf("Expected class 1 name 'Sorcerer', got '%s'", control.Class1Name) } if control.Class2Name != "Barbarian" { t.Errorf("Expected class 2 name 'Barbarian', got '%s'", control.Class2Name) } if control.Class3Name != "Monk" { t.Errorf("Expected class 3 name 'Monk', got '%s'", control.Class3Name) } // Test SetClassNames with fewer than 3 classes twoClasses := []string{"Ranger", "Druid"} control.SetClassNames(twoClasses) if control.Class1Name != "Ranger" { t.Errorf("Expected class 1 name 'Ranger', got '%s'", control.Class1Name) } if control.Class2Name != "Druid" { t.Errorf("Expected class 2 name 'Druid', got '%s'", control.Class2Name) } if control.Class3Name != "" { t.Errorf("Expected class 3 name to be empty, got '%s'", control.Class3Name) } // Test GetClassName if control.GetClassName(1) != "Ranger" { t.Errorf("Expected class 1 name 'Ranger', got '%s'", control.GetClassName(1)) } if control.GetClassName(2) != "Druid" { t.Errorf("Expected class 2 name 'Druid', got '%s'", control.GetClassName(2)) } if control.GetClassName(3) != "" { t.Errorf("Expected class 3 name to be empty, got '%s'", control.GetClassName(3)) } if control.GetClassName(4) != "" { t.Errorf("Expected invalid class number to return empty string, got '%s'", control.GetClassName(4)) } // Test SetClassName if !control.SetClassName(3, "Rogue") { t.Error("Expected SetClassName(3, 'Rogue') to return true") } if control.Class3Name != "Rogue" { t.Errorf("Expected class 3 name 'Rogue', got '%s'", control.Class3Name) } if control.SetClassName(4, "Invalid") { t.Error("Expected SetClassName(4, 'Invalid') to return false") } // Test IsValidClassName if !control.IsValidClassName("Ranger") { t.Error("Expected 'Ranger' to be a valid class name") } if !control.IsValidClassName("Druid") { t.Error("Expected 'Druid' to be a valid class name") } if !control.IsValidClassName("Rogue") { t.Error("Expected 'Rogue' to be a valid class name") } if control.IsValidClassName("Bard") { t.Error("Expected 'Bard' not to be a valid class name") } if control.IsValidClassName("") { t.Error("Expected empty string not to be a valid class name") } // Test GetClassNumber if control.GetClassNumber("Ranger") != 1 { t.Errorf("Expected 'Ranger' to be class number 1, got %d", control.GetClassNumber("Ranger")) } if control.GetClassNumber("Druid") != 2 { t.Errorf("Expected 'Druid' to be class number 2, got %d", control.GetClassNumber("Druid")) } if control.GetClassNumber("Rogue") != 3 { t.Errorf("Expected 'Rogue' to be class number 3, got %d", control.GetClassNumber("Rogue")) } if control.GetClassNumber("Bard") != 0 { t.Errorf("Expected 'Bard' to return class number 0, got %d", control.GetClassNumber("Bard")) } if control.GetClassNumber("") != 0 { t.Errorf("Expected empty string to return class number 0, got %d", control.GetClassNumber("")) } } func TestEmailMethods(t *testing.T) { db := setupTestDB(t) defer db.Close() control, _ := Get(db) // Test HasAdminEmail (should be true initially) if !control.HasAdminEmail() { t.Error("Expected control to have admin email initially") } // Test with empty email control.AdminEmail = "" if control.HasAdminEmail() { t.Error("Expected control not to have admin email when empty") } } func TestWorldSizeMethods(t *testing.T) { db := setupTestDB(t) defer db.Close() control, _ := Get(db) // Test IsWorldSizeValid if !control.IsWorldSizeValid() { t.Error("Expected world size 250 to be valid") } control.WorldSize = 0 if control.IsWorldSizeValid() { t.Error("Expected world size 0 to be invalid") } control.WorldSize = 10001 if control.IsWorldSizeValid() { t.Error("Expected world size 10001 to be invalid") } control.WorldSize = 1000 if !control.IsWorldSizeValid() { t.Error("Expected world size 1000 to be valid") } // Test GetWorldRadius expectedRadius := 500 if control.GetWorldRadius() != expectedRadius { t.Errorf("Expected world radius %d, got %d", expectedRadius, control.GetWorldRadius()) } // Test IsWithinWorldBounds if !control.IsWithinWorldBounds(0, 0) { t.Error("Expected (0,0) to be within world bounds") } if !control.IsWithinWorldBounds(500, 500) { t.Error("Expected (500,500) to be within world bounds") } if !control.IsWithinWorldBounds(-500, -500) { t.Error("Expected (-500,-500) to be within world bounds") } if control.IsWithinWorldBounds(501, 0) { t.Error("Expected (501,0) to be outside world bounds") } if control.IsWithinWorldBounds(0, 501) { t.Error("Expected (0,501) to be outside world bounds") } if control.IsWithinWorldBounds(-501, 0) { t.Error("Expected (-501,0) to be outside world bounds") } if control.IsWithinWorldBounds(0, -501) { t.Error("Expected (0,-501) to be outside world bounds") } // Test GetWorldBounds minX, minY, maxX, maxY := control.GetWorldBounds() expectedMin, expectedMax := -500, 500 if minX != expectedMin { t.Errorf("Expected minX %d, got %d", expectedMin, minX) } if minY != expectedMin { t.Errorf("Expected minY %d, got %d", expectedMin, minY) } if maxX != expectedMax { t.Errorf("Expected maxX %d, got %d", expectedMax, maxX) } if maxY != expectedMax { t.Errorf("Expected maxY %d, got %d", expectedMax, maxY) } } func TestEmptyClassHandling(t *testing.T) { db := setupTestDB(t) defer db.Close() control, _ := Get(db) // Set some classes to empty control.Class2Name = "" control.Class3Name = "" // Test GetClassNames with empty classes classNames := control.GetClassNames() expectedCount := 1 // Only Class1Name should be included if len(classNames) != expectedCount { t.Errorf("Expected %d non-empty class names, got %d", expectedCount, len(classNames)) } if len(classNames) > 0 && classNames[0] != "Mage" { t.Errorf("Expected first class name 'Mage', got '%s'", classNames[0]) } // Test IsValidClassName with empty string if control.IsValidClassName("") { t.Error("Expected empty string not to be valid class name") } // Test GetClassNumber with empty class names if control.GetClassNumber("Warrior") != 0 { t.Error("Expected empty class 2 not to match 'Warrior'") } }