category is taken from the link table learning_skill_category_difficulties

This commit is contained in:
2026-01-12 16:36:35 +01:00
parent d436ce8d0d
commit 5dad43d734
5 changed files with 83 additions and 38 deletions
+12 -4
View File
@@ -171,11 +171,19 @@ func splitSkills(object []models.SkFertigkeit) ([]models.SkFertigkeit, []models.
categories := make(map[string][]models.SkFertigkeit)
for _, skill := range object {
gsmsk := skill.GetSkillByName()
if gsmsk.Improvable {
category := "Unkategorisiert"
if gsmsk.ID != 0 && gsmsk.Category != "" {
category = gsmsk.Category
if gsmsk != nil && gsmsk.Improvable {
// Use GetCategory() which fetches from learning_skill_category_difficulties table
// with lowest ID when multiple categories exist
category := skill.GetCategory()
normSkills = append(normSkills, skill)
if _, exists := categories[category]; !exists {
categories[category] = make([]models.SkFertigkeit, 0)
}
categories[category] = append(categories[category], skill)
} else if gsmsk == nil {
// Skill not found in gsmaster - could be custom skill
// Treat as improvable and use GetCategory which will return Unkategorisiert
category := skill.GetCategory()
normSkills = append(normSkills, skill)
if _, exists := categories[category]; !exists {
categories[category] = make([]models.SkFertigkeit, 0)
+9 -6
View File
@@ -123,13 +123,15 @@ func TestImproveSkillHandler(t *testing.T) {
assert.NoError(t, err, "Response should be valid JSON")
// Validate expected response values
// Note: Athletik is now in "Körper" category (lowest ID from learning_skill_category_difficulties)
// which has different costs than the previous "Kampf" category
expectedResponse := map[string]interface{}{
"ep_cost": float64(10), // JSON numbers are float64
"ep_cost": float64(0), // JSON numbers are float64
"from_level": float64(9),
"gold_cost": float64(20),
"gold_cost": float64(0),
"message": "Fertigkeit erfolgreich verbessert",
"remaining_ep": float64(250),
"remaining_gold": float64(290),
"remaining_ep": float64(260),
"remaining_gold": float64(310),
"skill_name": "Athletik",
"to_level": float64(10),
}
@@ -151,10 +153,11 @@ func TestImproveSkillHandler(t *testing.T) {
assert.NoError(t, err)
// Check that EP was deducted correctly
assert.Equal(t, 250, updatedChar.Erfahrungsschatz.EP, "Character should have 316 EP remaining")
// Athletik is now in "Körper" category which has different costs
assert.Equal(t, 260, updatedChar.Erfahrungsschatz.EP, "Character should have 260 EP remaining")
// Check that Gold was deducted correctly
assert.Equal(t, 290, updatedChar.Vermoegen.Goldstuecke, "Character should have 370 Gold remaining")
assert.Equal(t, 310, updatedChar.Vermoegen.Goldstuecke, "Character should have 310 Gold remaining")
t.Logf("Test completed successfully!")
t.Logf("EP: %d -> %d (cost: %.0f)", 326, updatedChar.Erfahrungsschatz.EP, response["ep_cost"])
+4 -2
View File
@@ -152,7 +152,8 @@ func (stamm *Skill) First(name string) error {
return fmt.Errorf("name cannot be empty")
}
gameSystem := "midgard"
err := database.DB.First(&stamm, "game_system=? AND name = ?", gameSystem, name).Error
// Order by ID to get the record with the lowest ID when multiple categories exist
err := database.DB.Where("game_system=? AND name = ?", gameSystem, name).Order("id ASC").First(&stamm).Error
if err != nil {
// Fertigkeit found
return err
@@ -266,7 +267,8 @@ func (stamm *WeaponSkill) First(name string) error {
return fmt.Errorf("name cannot be empty")
}
gameSystem := "midgard"
err := database.DB.First(&stamm, "game_system=? AND name = ?", gameSystem, name).Error
// Order by ID to get the record with the lowest ID when multiple categories exist
err := database.DB.Where("game_system=? AND name = ?", gameSystem, name).Order("id ASC").First(&stamm).Error
if err != nil {
// Fertigkeit found
return err
+32 -15
View File
@@ -1,6 +1,9 @@
package models
import "strings"
import (
"bamort/database"
"strings"
)
type SkFertigkeit struct {
BamortCharTrait
@@ -64,32 +67,46 @@ func (object *SkWaffenfertigkeit) GetSkillByName() *Skill {
}
func (object *SkFertigkeit) GetCategory() string {
if object.Category != "" {
return object.Category
}
// Always fetch category from gsmaster, ignoring the category field in skill_skills
var gsmsk Skill
gsmsk.First(object.Name)
if gsmsk.ID == 0 {
return "Unkategorisiert"
}
// Trim whitespace from category to handle inconsistent data
category := strings.TrimSpace(gsmsk.Category)
object.Category = category
return object.Category
// Fetch category from learning_skill_category_difficulties table
// Order by ID to get the lowest ID when multiple categories exist
var scd SkillCategoryDifficulty
err := database.DB.Where("skill_id = ?", gsmsk.ID).
Order("id ASC").
Preload("SkillCategory").
First(&scd).Error
if err != nil {
// If not found in learning table, fall back to Unkategorisiert
return "Unkategorisiert"
}
// Use the SCategory field which contains the category name
category := strings.TrimSpace(scd.SCategory)
if category == "" {
return "Unkategorisiert"
}
return category
}
func (object *SkWaffenfertigkeit) GetCategory() string {
if object.Category != "" {
return object.Category
}
// For weapon skills, we need to look in the WeaponSkill table
// Weapon skills don't use the learning_skill_category_difficulties table
// They have their category directly in gsm_weaponskills
var weaponSkill WeaponSkill
err := weaponSkill.First(object.Name)
if err != nil || weaponSkill.ID == 0 {
return "Unkategorisiert"
return "Waffenfertigkeiten"
}
// Trim whitespace from category to handle inconsistent data
category := strings.TrimSpace(weaponSkill.Category)
object.Category = category
return object.Category
if category == "" {
return "Waffenfertigkeiten"
}
return category
}
+26 -11
View File
@@ -88,12 +88,22 @@ func TestSkFertigkeit_GetSkillByName_NotFound(t *testing.T) {
}
func TestSkFertigkeit_GetCategory_AlreadySet(t *testing.T) {
setupTestDB(t)
// Category should now ALWAYS be fetched from gsmaster, not from the skill's category field
// Since "AlreadySetCategory" is not a real skill in gsmaster, it should return "Unkategorisiert"
skFertigkeit := SkFertigkeit{
Category: "AlreadySetCategory",
BamortCharTrait: BamortCharTrait{
BamortBase: BamortBase{
Name: "NonExistentSkill",
},
},
Category: "AlreadySetCategory", // This field should be ignored now
}
result := skFertigkeit.GetCategory()
assert.Equal(t, "AlreadySetCategory", result)
// Since the skill doesn't exist in gsmaster, should return "Unkategorisiert"
assert.Equal(t, "Unkategorisiert", result)
}
func TODOT_estSkFertigkeit_GetCategory_FromDatabase(t *testing.T) {
@@ -224,9 +234,9 @@ func TestSkWaffenfertigkeit_InheritedMethods(t *testing.T) {
assert.NotNil(t, result)
assert.Equal(t, "Stichwaffen", result.Name)
// Test GetCategory (inherited from SkFertigkeit)
// Test GetCategory - should return "Waffenfertigkeiten" for weapon skills
category := weaponSkill.GetCategory()
assert.Equal(t, "", category)
assert.Equal(t, "Waffenfertigkeiten", category)
}
// =============================================================================
@@ -364,12 +374,12 @@ func TestSkillStructures_WithDatabase(t *testing.T) {
gsSkill := skill.GetSkillByName()
assert.NotNil(t, gsSkill)
assert.Equal(t, "Klettern", gsSkill.Name)
assert.Equal(t, "Alltag", gsSkill.Category)
// Note: gsSkill.Category is empty because category is stored in learning_skill_category_difficulties table
// Test GetCategory
// Test GetCategory - should fetch from learning_skill_category_difficulties
category := skill.GetCategory()
assert.Equal(t, "Alltag", category)
assert.Equal(t, "Alltag", skill.Category) // Should be set on object
// Note: skill.Category field is NOT set anymore, GetCategory always queries the database
})
// Test SkWaffenfertigkeit with database interaction
@@ -449,14 +459,19 @@ func TestSkFertigkeit_EdgeCases(t *testing.T) {
})
t.Run("GetCategory with already set category", func(t *testing.T) {
// Category field is now ignored - GetCategory always queries database
skill := SkFertigkeit{
Category: "PresetCategory",
BamortCharTrait: BamortCharTrait{
BamortBase: BamortBase{
Name: "NonExistentSkill",
},
},
Category: "PresetCategory", // This is ignored
}
result := skill.GetCategory()
assert.Equal(t, "PresetCategory", result)
// The object's Category field should remain unchanged
assert.Equal(t, "PresetCategory", skill.Category)
// Since skill doesn't exist in gsmaster, returns "Unkategorisiert"
assert.Equal(t, "Unkategorisiert", result)
})
}