From 09d12d3d8c6775dfb91f6380be97c097021a2f6b Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 27 Feb 2026 11:59:16 +0100 Subject: [PATCH] extra learn_categories added to spell maintenance --- backend/gsmaster/routes.go | 1 + backend/gsmaster/spell_enhanced_handlers.go | 46 +++++- .../gsmaster/spell_enhanced_handlers_test.go | 153 ++++++++++++++++++ backend/models/model_gsmaster.go | 16 ++ .../src/components/maintenance/SpellView.vue | 27 +++- frontend/src/locales/de | 1 + frontend/src/locales/en | 1 + 7 files changed, 240 insertions(+), 5 deletions(-) create mode 100644 backend/gsmaster/spell_enhanced_handlers_test.go diff --git a/backend/gsmaster/routes.go b/backend/gsmaster/routes.go index be9c905..df2bf4d 100644 --- a/backend/gsmaster/routes.go +++ b/backend/gsmaster/routes.go @@ -47,6 +47,7 @@ func RegisterRoutes(r *gin.RouterGroup) { maintGrp.PUT("/spells/:id", UpdateMDSpell) maintGrp.PUT("/spells-enhanced/:id", UpdateEnhancedMDSpell) // New enhanced endpoint maintGrp.POST("/spells", AddSpell) + maintGrp.POST("/spells-enhanced", CreateEnhancedMDSpell) // New enhanced endpoint maintGrp.DELETE("/spells/:id", DeleteMDSpell) maintGrp.PUT("/equipment/:id", UpdateMDEquipment) diff --git a/backend/gsmaster/spell_enhanced_handlers.go b/backend/gsmaster/spell_enhanced_handlers.go index e13f17a..c3d7839 100644 --- a/backend/gsmaster/spell_enhanced_handlers.go +++ b/backend/gsmaster/spell_enhanced_handlers.go @@ -66,6 +66,15 @@ func UpdateSpellWithCategories(spellID uint, req SpellUpdateRequest) error { }) } +// CreateSpellWithCategories creates a new spell +func CreateSpellWithCategories(req SpellUpdateRequest) (*models.Spell, error) { + spell := req.Spell + if err := database.DB.Create(&spell).Error; err != nil { + return nil, err + } + return &spell, nil +} + // ===== Handler Functions ===== // GetEnhancedMDSpells returns spells with enhanced information @@ -87,11 +96,18 @@ func GetEnhancedMDSpells(c *gin.Context) { respondWithError(c, http.StatusInternalServerError, "Failed to retrieve spell categories: "+err.Error()) return } + // Get spell Learn_categories + learnCategories, err := spell.GetSpellLearnCategories() + if err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to retrieve spell learn categories: "+err.Error()) + return + } c.JSON(http.StatusOK, gin.H{ - "spells": spells, - "sources": sources, - "categories": categories, + "spells": spells, + "sources": sources, + "categories": categories, + "learnCategories": learnCategories, }) } @@ -145,3 +161,27 @@ func UpdateEnhancedMDSpell(c *gin.Context) { c.JSON(http.StatusOK, spell) } + +// CreateEnhancedMDSpell creates a new spell +func CreateEnhancedMDSpell(c *gin.Context) { + var req SpellUpdateRequest + if err := c.ShouldBindJSON(&req); err != nil { + respondWithError(c, http.StatusBadRequest, "Invalid request: "+err.Error()) + return + } + + spell, err := CreateSpellWithCategories(req) + if err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to create spell: "+err.Error()) + return + } + + // Return created spell with enhanced information + spellWithCats, err := GetSpellWithCategories(spell.ID) + if err != nil { + respondWithError(c, http.StatusInternalServerError, "Failed to retrieve created spell") + return + } + + c.JSON(http.StatusCreated, spellWithCats) +} diff --git a/backend/gsmaster/spell_enhanced_handlers_test.go b/backend/gsmaster/spell_enhanced_handlers_test.go new file mode 100644 index 0000000..52f05eb --- /dev/null +++ b/backend/gsmaster/spell_enhanced_handlers_test.go @@ -0,0 +1,153 @@ +package gsmaster + +import ( + "bamort/database" + "bamort/models" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUpdateSpellWithLearningCategory(t *testing.T) { + // Set test environment + setupTestEnvironment(t) + + database.SetupTestDB(true) + defer database.ResetTestDB() + + // Create a test spell + spell := models.Spell{ + Name: "Testzauber", + Category: "Wunder", + LearningCategory: "", + Stufe: 1, + GameSystem: "midgard", + } + err := database.DB.Create(&spell).Error + require.NoError(t, err, "Failed to create test spell") + + // Test 1: Update learning_category + spell.LearningCategory = "Wundertat" + updateReq := SpellUpdateRequest{Spell: spell} + err = UpdateSpellWithCategories(spell.ID, updateReq) + assert.NoError(t, err, "Failed to update spell with learning_category") + + // Verify update + var updated models.Spell + err = database.DB.First(&updated, spell.ID).Error + require.NoError(t, err) + assert.Equal(t, "Wundertat", updated.LearningCategory, "Learning category not updated correctly") + assert.Equal(t, "Wunder", updated.Category, "Category should remain unchanged") + + // Test 2: Update both categories + updated.Category = "Verändern" + updated.LearningCategory = "Zauberlied" + updateReq2 := SpellUpdateRequest{Spell: updated} + err = UpdateSpellWithCategories(updated.ID, updateReq2) + assert.NoError(t, err, "Failed to update both categories") + + // Verify both were updated + var final models.Spell + err = database.DB.First(&final, updated.ID).Error + require.NoError(t, err) + assert.Equal(t, "Verändern", final.Category, "Category not updated") + assert.Equal(t, "Zauberlied", final.LearningCategory, "Learning category not updated") +} + +func TestCreateSpellWithLearningCategory(t *testing.T) { + setupTestEnvironment(t) + + database.SetupTestDB(true) + defer database.ResetTestDB() + + // Test: Create spell with learning_category + spell := models.Spell{ + Name: "Neuer Zauber", + Category: "Beherrschen", + LearningCategory: "Runenstab", + Stufe: 2, + GameSystem: "midgard", + AP: "3", + } + + err := database.DB.Create(&spell).Error + require.NoError(t, err, "Failed to create spell with learning_category") + + // Verify creation + var created models.Spell + err = database.DB.Where("name = ?", "Neuer Zauber").First(&created).Error + require.NoError(t, err) + assert.Equal(t, "Beherrschen", created.Category) + assert.Equal(t, "Runenstab", created.LearningCategory) + assert.Equal(t, 2, created.Stufe) +} + +func TestLearningCategoryDefaultEmpty(t *testing.T) { + setupTestEnvironment(t) + + database.SetupTestDB(true) + defer database.ResetTestDB() + + // Test: Create spell without learning_category + spell := models.Spell{ + Name: "Zauber ohne LearningCategory", + Category: "Normal", + Stufe: 1, + GameSystem: "midgard", + } + + err := database.DB.Create(&spell).Error + require.NoError(t, err) + + // Verify learning_category is empty (not nil) + var created models.Spell + err = database.DB.First(&created, spell.ID).Error + require.NoError(t, err) + assert.Equal(t, "", created.LearningCategory, "Learning category should be empty string by default") + assert.Equal(t, "Normal", created.Category) +} + +func TestCreateEnhancedMDSpellEndpoint(t *testing.T) { + setupTestEnvironment(t) + database.SetupTestDB(true) + defer database.ResetTestDB() + + // Test: Create spell with learning_category via endpoint + spell := models.Spell{ + Name: "Test Endpoint Zauber", + Category: "Erkennen", + LearningCategory: "Erkenntnismagie", + Stufe: 3, + GameSystem: "midgard", + AP: "2", + } + + req := SpellUpdateRequest{Spell: spell} + created, err := CreateSpellWithCategories(req) + require.NoError(t, err, "Failed to create spell") + assert.NotZero(t, created.ID, "Created spell should have an ID") + assert.Equal(t, "Erkennen", created.Category) + assert.Equal(t, "Erkenntnismagie", created.LearningCategory) + assert.Equal(t, 3, created.Stufe) +} + +func TestGetSpellLearningCategories(t *testing.T) { + setupTestEnvironment(t) + database.SetupTestDB(true) + defer database.ResetTestDB() + var spell models.Spell + + learningCategories, err := spell.GetSpellLearnCategories() + require.NoError(t, err, "Failed to get spell learning categories") + assert.Contains(t, learningCategories, "Spruch", "Learning categories should include 'Spruch'") + assert.Contains(t, learningCategories, "Runenstab", "Learning categories should include 'Runenstab'") + assert.Contains(t, learningCategories, "Zauberlied", "Learning categories should include 'Zauberlied'") + assert.Contains(t, learningCategories, "Wundertat", "Learning categories should include 'Wundertat'") + assert.Contains(t, learningCategories, "Dweomer", "Learning categories should include 'Dweomer'") + assert.Contains(t, learningCategories, "Thaumatherapie", "Learning categories should include 'Thaumatherapie'") + assert.Contains(t, learningCategories, "Zaubersalz", "Learning categories should include 'Zaubersalz'") + assert.Contains(t, learningCategories, "Rune", "Learning categories should include 'Rune'") + assert.Contains(t, learningCategories, "Siegel", "Learning categories should include 'Siegel'") + +} diff --git a/backend/models/model_gsmaster.go b/backend/models/model_gsmaster.go index 6ebd0b2..20a00b6 100644 --- a/backend/models/model_gsmaster.go +++ b/backend/models/model_gsmaster.go @@ -438,6 +438,22 @@ func (object *Spell) GetSpellCategories() ([]string, error) { return categories, nil } +func (object *Spell) GetSpellLearnCategories() ([]string, error) { + var categories []string + gs := GetGameSystem(object.GameSystemId, object.GameSystem) + + result := database.DB.Model(&Spell{}). + Where("game_system = ? OR game_system_id = ?", gs.Name, gs.ID). + Distinct(). + Pluck("learning_category", &categories) + + if result.Error != nil { + return nil, result.Error + } + + return categories, nil +} + func (object *Spell) ensureGameSystem() { gs := GetGameSystem(object.GameSystemId, object.GameSystem) object.GameSystemId = gs.ID diff --git a/frontend/src/components/maintenance/SpellView.vue b/frontend/src/components/maintenance/SpellView.vue index ed8fc97..3d0a15b 100644 --- a/frontend/src/components/maintenance/SpellView.vue +++ b/frontend/src/components/maintenance/SpellView.vue @@ -129,6 +129,7 @@ {{ $t('spell.category') }} + {{ $t('spell.learning_category') || 'Learning Category' }} {{ $t('spell.name') }} @@ -150,7 +151,7 @@ New - +
@@ -165,6 +166,15 @@
+
+ + +
@@ -248,6 +258,7 @@ {{ dtaItem.id || '' }} {{ dtaItem.category|| '-' }} + {{ dtaItem.learning_category || '-' }} {{ dtaItem.name || '-' }} {{ dtaItem.level || '0' }} {{ dtaItem.ap || '0' }} @@ -267,7 +278,7 @@ - +
@@ -283,6 +294,15 @@
+
+ + +
@@ -519,6 +539,7 @@ export default { filterQuelle: '', enhancedSpells: [], availableSources: [], + availableLearnCategories: [], gameSystems: [], selectedSystemId: null, creatingNew: false, @@ -663,6 +684,7 @@ export default { const response = await API.get('/api/maintenance/spells-enhanced') this.enhancedSpells = response.data.spells || [] this.availableSources = response.data.sources || [] + this.availableLearnCategories = response.data.learnCategories || [] // Also update mdata for compatibility if (response.data.categories) { this.mdata.spellcategories = response.data.categories @@ -725,6 +747,7 @@ export default { this.newItem = { name: '', category: this.mdata.spellcategories?.[0] || '', + learning_category: '', level: 0, ap: '', zauberdauer: '', diff --git a/frontend/src/locales/de b/frontend/src/locales/de index bf9ddfd..5f532ef 100644 --- a/frontend/src/locales/de +++ b/frontend/src/locales/de @@ -177,6 +177,7 @@ export default { spell:{ id:'ID', category:'Kategorie', + learning_category:'Lernkategorie', name:'Name', description:'Beschreibung', level:'Stufe', diff --git a/frontend/src/locales/en b/frontend/src/locales/en index 9fed8a7..c3f5fc9 100644 --- a/frontend/src/locales/en +++ b/frontend/src/locales/en @@ -173,6 +173,7 @@ export default { spell:{ id:'ID', category:'Category', + learning_category:'Learning Category', name:'Name', description:'Description', level:'Level',