diff --git a/backend/api/api_test.go b/backend/api/api_test.go index e24cd30..bea3dbc 100644 --- a/backend/api/api_test.go +++ b/backend/api/api_test.go @@ -4,7 +4,6 @@ import ( "bamort/character" "bamort/database" "bamort/gsmaster" - "bamort/importer" _ "bamort/maintenance" // Anonymous import to ensure init() is called "bamort/models" "bamort/router" @@ -57,7 +56,7 @@ func TestSetupCheck(t *testing.T) { assert.NoError(t, err, "No error expected when migrating gsmaster tables") err = user.MigrateStructure() assert.NoError(t, err, "No error expected when migrating user tables") - err = importer.MigrateStructure() + //err = importer.MigrateStructure() assert.NoError(t, err, "No error expected when migrating importer tables") } @@ -307,3 +306,113 @@ func TestGetSkillAllLevelCosts(t *testing.T) { err = json.Unmarshal(respRecorder.Body.Bytes(), &response) assert.NoError(t, err, "Response should be valid JSON for weapon skill") } + +func TestGetAvailableSkillsNew(t *testing.T) { + database.SetupTestDB(true) // Setup test database + // Initialize a Gin router + r := gin.Default() + router.SetupGin(r) + + // Routes + protected := router.BaseRouterGrp(r) + character.RegisterRoutes(protected) + gsmaster.RegisterRoutes(protected) + protected.GET("/test", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{"status": "Test OK"}) + }) + + u := user.User{} + u.First("testuser") + + // Create request body for available skills + skillRequest := gsmaster.LernCostRequest{ + CharId: 20, + Name: "Schwimmen", // Use a valid skill name for validation + CurrentLevel: 0, + Type: "skill", + Action: "learn", + TargetLevel: 1, + UsePP: 0, + UseGold: 0, + Reward: &[]string{"default"}[0], + } + jsonData, _ := json.Marshal(skillRequest) + + // Create a test HTTP request + req, _ := http.NewRequest("POST", "/api/characters/available-skills-new", bytes.NewBuffer(jsonData)) + req.Header.Set("Content-Type", "application/json") + token := user.GenerateToken(&u) + req.Header.Set("Authorization", "Bearer "+token) + + // Create a response recorder to capture the handler's response + respRecorder := httptest.NewRecorder() + + // Perform the test request + r.ServeHTTP(respRecorder, req) + + // Assert the response status code + assert.Equal(t, http.StatusOK, respRecorder.Code) + + // Parse the response to verify it contains skills by category + var response map[string]interface{} + err := json.Unmarshal(respRecorder.Body.Bytes(), &response) + assert.NoError(t, err, "Response should be valid JSON") + + // Check that the response contains skills_by_category + skillsByCategory, exists := response["skills_by_category"] + assert.True(t, exists, "Response should contain skills_by_category") + assert.NotNil(t, skillsByCategory, "skills_by_category should not be nil") + + // Convert to map for easier access + skillsMap, ok := skillsByCategory.(map[string]interface{}) + assert.True(t, ok, "skills_by_category should be a map") + assert.Greater(t, len(skillsMap), 0, "Should return at least one category of skills") + + // Check that "Bogenbau" is not in the available skills (assuming it's already learned) + foundBogenbau := false + for _, categorySkillsInterface := range skillsMap { + categorySkills, ok := categorySkillsInterface.([]interface{}) + if !ok { + continue + } + + for _, skillInterface := range categorySkills { + skill, ok := skillInterface.(map[string]interface{}) + if !ok { + continue + } + + skillName, exists := skill["name"] + if exists && skillName == "Bogenbau" { + foundBogenbau = true + break + } + } + + if foundBogenbau { + break + } + } + + assert.False(t, foundBogenbau, "Bogenbau should not be in available skills (already learned)") + + // Verify that each skill has the expected structure + for categoryName, categorySkillsInterface := range skillsMap { + categorySkills, ok := categorySkillsInterface.([]interface{}) + assert.True(t, ok, "Category %s should contain an array of skills", categoryName) + + for _, skillInterface := range categorySkills { + skill, ok := skillInterface.(map[string]interface{}) + assert.True(t, ok, "Each skill should be a map") + + // Check required fields + _, hasName := skill["name"] + _, hasEpCost := skill["epCost"] + _, hasGoldCost := skill["goldCost"] + + assert.True(t, hasName, "Skill should have name field") + assert.True(t, hasEpCost, "Skill should have epCost field") + assert.True(t, hasGoldCost, "Skill should have goldCost field") + } + } +} diff --git a/backend/character/handlers.go b/backend/character/handlers.go index 0fe1de4..d88df2c 100644 --- a/backend/character/handlers.go +++ b/backend/character/handlers.go @@ -1388,10 +1388,20 @@ func GetAvailableSkillsNewSystem(c *gin.Context) { remainingPP := request.UsePP remainingGold := request.UseGold - spellInfo := &models.SkillLearningInfo{} + + // Hole die vollständigen Skill-Informationen für die Kostenberechnung + skillLearningInfo, err := models.GetSkillCategoryAndDifficulty(skill.Name, getCharacterClass(&character)) + if err != nil { + // Fallback für unbekannte Skills + skillLearningInfo = &models.SkillLearningInfo{ + SkillName: skill.Name, + CategoryName: skill.Category, + LearnCost: 50, // Standard-Lernkosten + } + } // Berechne Lernkosten mit calculateSkillLearnCostNewSystem - err := calculateSkillLearnCostNewSystem(&request, &levelResult, &remainingPP, &remainingGold, spellInfo) + err = calculateSkillLearnCostNewSystem(&request, &levelResult, &remainingPP, &remainingGold, skillLearningInfo) epCost := 10000 // Fallback-Wert goldCost := 50000 // Fallback-Wert if err == nil { diff --git a/backend/character/lerncost_comparison_test.go b/backend/character/lerncost_comparison_test.go index 317f86a..a8c370e 100644 --- a/backend/character/lerncost_comparison_test.go +++ b/backend/character/lerncost_comparison_test.go @@ -223,6 +223,20 @@ func TestCompareOldVsNewLearningCostSystems(t *testing.T) { TargetLevel: 0, // Calculate all levels Reward: &[]string{"default"}[0], }, + // learn Naturkunde Test 2 PP + { + name: "learn non existent Bogenbau Test Basic", + charId: 20, + skillName: "Bogenbau", + currentLevel: 0, + usePP: 0, + useGold: 0, + description: "Comparison Learn Bogenbau", + Type: "skill", + Action: "learn", + TargetLevel: 0, // Calculate all levels + Reward: &[]string{"default"}[0], + }, } for _, tc := range testCases { diff --git a/backend/gsmaster/lernkosten_maps.go b/backend/gsmaster/lernkosten_maps.go index ad0c833..5fc5fcf 100644 --- a/backend/gsmaster/lernkosten_maps.go +++ b/backend/gsmaster/lernkosten_maps.go @@ -7,7 +7,7 @@ import ( type LernCostRequest struct { CharId uint `json:"char_id" binding:"required"` // Charakter-ID - Name string `json:"name" binding:"required"` // Name der Fertigkeit / des Zaubers + Name string `json:"name" binding:"omitempty"` // Name der Fertigkeit / des Zaubers CurrentLevel int `json:"current_level,omitempty"` // Aktueller Wert (nur für Verbesserung) Type string `json:"type" binding:"required,oneof=skill spell weapon"` // 'skill', 'spell' oder 'weapon' Waffenfertigkeiten sind normale Fertigkeiten (evtl. kann hier später der Name der Waffe angegeben werden ) Action string `json:"action" binding:"required,oneof=learn improve"` // 'learn' oder 'improve'