Spell Learn Dialog Anzeige funktioniert
This commit is contained in:
@@ -2079,7 +2079,7 @@ func GetAvailableSkillsNewSystem(c *gin.Context) {
|
||||
|
||||
// GetAvailableSpellsNewSystem gibt alle verfügbaren Zauber mit Lernkosten zurück (POST mit LernCostRequest)
|
||||
func GetAvailableSpellsNewSystem(c *gin.Context) {
|
||||
characterID := c.Param("id")
|
||||
//characterID := c.Param("id")
|
||||
|
||||
// Parse LernCostRequest aus POST body
|
||||
var baseRequest gsmaster.LernCostRequest
|
||||
@@ -2089,7 +2089,7 @@ func GetAvailableSpellsNewSystem(c *gin.Context) {
|
||||
}
|
||||
|
||||
var character models.Char
|
||||
if err := database.DB.Preload("Zauber").Preload("Erfahrungsschatz").Preload("Vermoegen").First(&character, characterID).Error; err != nil {
|
||||
if err := database.DB.Preload("Zauber").Preload("Erfahrungsschatz").Preload("Vermoegen").First(&character, baseRequest.CharId).Error; err != nil {
|
||||
respondWithError(c, http.StatusNotFound, "Character not found")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"bamort/database"
|
||||
"bamort/gsmaster"
|
||||
"bamort/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetAvailableSpellsNewSystem(t *testing.T) {
|
||||
// Setup test database with real data
|
||||
database.SetupTestDB(true, true)
|
||||
defer database.ResetTestDB()
|
||||
|
||||
// Setup Gin in test mode
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
t.Run("Get available spells for character ID 20", func(t *testing.T) {
|
||||
|
||||
// Test Request wie im Frontend
|
||||
request := gsmaster.LernCostRequest{
|
||||
CharId: 18,
|
||||
Type: "spell",
|
||||
Action: "learn",
|
||||
UsePP: 0,
|
||||
UseGold: 0,
|
||||
Reward: stringPtr("default"),
|
||||
}
|
||||
|
||||
// Convert request to JSON
|
||||
requestJSON, err := json.Marshal(request)
|
||||
assert.NoError(t, err, "Should marshal request")
|
||||
|
||||
// Create HTTP request
|
||||
req, _ := http.NewRequest("POST", "/api/characters/available-spells-new", bytes.NewBuffer(requestJSON))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// Create response recorder
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
// Create Gin context
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = req
|
||||
|
||||
fmt.Printf("Test: Get available spells for character ID 20\n")
|
||||
fmt.Printf("Request: %s\n", string(requestJSON))
|
||||
|
||||
// Call the handler function
|
||||
GetAvailableSpellsNewSystem(c)
|
||||
|
||||
// Print the response for debugging
|
||||
fmt.Printf("Response Status: %d\n", w.Code)
|
||||
fmt.Printf("Response Body: %s\n", w.Body.String())
|
||||
|
||||
// Assert response status
|
||||
assert.Equal(t, http.StatusOK, w.Code, "Status code should be 200 OK")
|
||||
|
||||
// Parse response
|
||||
var response map[string]interface{}
|
||||
err = json.Unmarshal(w.Body.Bytes(), &response)
|
||||
assert.NoError(t, err, "Response should be valid JSON")
|
||||
|
||||
// Check response structure
|
||||
assert.Contains(t, response, "spells_by_school", "Response should contain spells_by_school field")
|
||||
|
||||
// Check if spells_by_school is an object
|
||||
spellsBySchool, ok := response["spells_by_school"].(map[string]interface{})
|
||||
assert.True(t, ok, "spells_by_school should be an object")
|
||||
|
||||
fmt.Printf("Found %d spell schools\n", len(spellsBySchool))
|
||||
|
||||
// Check each school
|
||||
totalSpells := 0
|
||||
for schoolName, schoolSpells := range spellsBySchool {
|
||||
fmt.Printf("School: %s\n", schoolName)
|
||||
|
||||
spells, ok := schoolSpells.([]interface{})
|
||||
assert.True(t, ok, fmt.Sprintf("School %s should contain an array of spells", schoolName))
|
||||
|
||||
totalSpells += len(spells)
|
||||
fmt.Printf(" Spells in school: %d\n", len(spells))
|
||||
|
||||
// Check structure of first spell in school if exists
|
||||
if len(spells) > 0 {
|
||||
firstSpell, ok := spells[0].(map[string]interface{})
|
||||
assert.True(t, ok, "First spell should be an object")
|
||||
|
||||
// Check required fields
|
||||
assert.Contains(t, firstSpell, "name", "Spell should have name field")
|
||||
assert.Contains(t, firstSpell, "level", "Spell should have level field")
|
||||
assert.Contains(t, firstSpell, "epCost", "Spell should have epCost field")
|
||||
assert.Contains(t, firstSpell, "goldCost", "Spell should have goldCost field")
|
||||
|
||||
spellName, ok := firstSpell["name"].(string)
|
||||
assert.True(t, ok, "Spell name should be a string")
|
||||
assert.NotEmpty(t, spellName, "Spell name should not be empty")
|
||||
|
||||
level, ok := firstSpell["level"].(float64)
|
||||
assert.True(t, ok, "Spell level should be a number")
|
||||
assert.GreaterOrEqual(t, level, float64(0), "Spell level should be at least 0")
|
||||
|
||||
epCost, ok := firstSpell["epCost"].(float64)
|
||||
assert.True(t, ok, "EP cost should be a number")
|
||||
assert.GreaterOrEqual(t, epCost, float64(0), "EP cost should be non-negative")
|
||||
|
||||
goldCost, ok := firstSpell["goldCost"].(float64)
|
||||
assert.True(t, ok, "Gold cost should be a number")
|
||||
assert.GreaterOrEqual(t, goldCost, float64(0), "Gold cost should be non-negative")
|
||||
|
||||
fmt.Printf(" Example spell: %s (Level %v, EP: %v, Gold: %v)\n",
|
||||
spellName, level, epCost, goldCost)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Total spells found: %d\n", totalSpells)
|
||||
assert.Greater(t, totalSpells, 0, "Should have at least some spells available")
|
||||
})
|
||||
|
||||
t.Run("Test with different reward types", func(t *testing.T) {
|
||||
// Verwende existierenden Charakter
|
||||
rewardTypes := []string{"default", "noGold", "halveep", "halveepnoGold"}
|
||||
|
||||
for _, rewardType := range rewardTypes {
|
||||
t.Run(fmt.Sprintf("RewardType_%s", rewardType), func(t *testing.T) {
|
||||
request := gsmaster.LernCostRequest{
|
||||
CharId: 18,
|
||||
Type: "spell",
|
||||
Action: "learn",
|
||||
UsePP: 0,
|
||||
UseGold: 0,
|
||||
Reward: stringPtr(rewardType),
|
||||
}
|
||||
|
||||
requestJSON, err := json.Marshal(request)
|
||||
assert.NoError(t, err)
|
||||
|
||||
req, _ := http.NewRequest("POST", "/api/characters/available-spells-new", bytes.NewBuffer(requestJSON))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = req
|
||||
|
||||
GetAvailableSpellsNewSystem(c)
|
||||
|
||||
fmt.Printf("Testing reward type: %s - Status: %d\n", rewardType, w.Code)
|
||||
assert.Equal(t, http.StatusOK, w.Code, fmt.Sprintf("Should work with reward type %s", rewardType))
|
||||
|
||||
var response map[string]interface{}
|
||||
err = json.Unmarshal(w.Body.Bytes(), &response)
|
||||
assert.NoError(t, err, "Response should be valid JSON")
|
||||
assert.Contains(t, response, "spells_by_school", "Should contain spells_by_school")
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Test with invalid character ID", func(t *testing.T) {
|
||||
request := gsmaster.LernCostRequest{
|
||||
CharId: 99999, // Non-existent character
|
||||
Type: "spell",
|
||||
Action: "learn",
|
||||
UsePP: 0,
|
||||
UseGold: 0,
|
||||
Reward: stringPtr("default"),
|
||||
}
|
||||
|
||||
requestJSON, err := json.Marshal(request)
|
||||
assert.NoError(t, err)
|
||||
|
||||
req, _ := http.NewRequest("POST", "/api/characters/available-spells-new", bytes.NewBuffer(requestJSON))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = req
|
||||
|
||||
GetAvailableSpellsNewSystem(c)
|
||||
|
||||
fmt.Printf("Testing invalid character ID - Status: %d\n", w.Code)
|
||||
// Der Handler verwendet nicht den "id" Parameter aus der URL, sondern CharId aus dem Request Body
|
||||
// Daher wird kein 404 zurückgegeben, sondern ein leeres Ergebnis oder Fehler
|
||||
assert.True(t, w.Code == http.StatusNotFound || w.Code == http.StatusOK,
|
||||
"Should return 404 or 200 for non-existent character")
|
||||
})
|
||||
|
||||
t.Run("Test with invalid request format", func(t *testing.T) {
|
||||
invalidJSON := []byte(`{"invalid": "request"}`)
|
||||
|
||||
req, _ := http.NewRequest("POST", "/api/characters/available-spells-new", bytes.NewBuffer(invalidJSON))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = req
|
||||
|
||||
GetAvailableSpellsNewSystem(c)
|
||||
|
||||
fmt.Printf("Testing invalid request format - Status: %d\n", w.Code)
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code, "Should return 400 for invalid request")
|
||||
})
|
||||
|
||||
t.Run("Test excluding already learned spells", func(t *testing.T) {
|
||||
// Füge dem Charakter einen Zauber hinzu
|
||||
learnedSpell := models.SkZauber{
|
||||
BamortCharTrait: models.BamortCharTrait{
|
||||
BamortBase: models.BamortBase{
|
||||
Name: "Feuerball",
|
||||
},
|
||||
CharacterID: 20,
|
||||
},
|
||||
Beschreibung: "Ein mächtiger Feuerball",
|
||||
Bonus: 5,
|
||||
Quelle: "Test",
|
||||
}
|
||||
|
||||
err := database.DB.Create(&learnedSpell).Error
|
||||
assert.NoError(t, err, "Should create learned spell")
|
||||
|
||||
request := gsmaster.LernCostRequest{
|
||||
CharId: 18,
|
||||
Type: "spell",
|
||||
Action: "learn",
|
||||
UsePP: 0,
|
||||
UseGold: 0,
|
||||
Reward: stringPtr("default"),
|
||||
}
|
||||
|
||||
requestJSON, err := json.Marshal(request)
|
||||
assert.NoError(t, err)
|
||||
|
||||
req, _ := http.NewRequest("POST", "/api/characters/available-spells-new", bytes.NewBuffer(requestJSON))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = req
|
||||
|
||||
GetAvailableSpellsNewSystem(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code, "Should return 200 OK")
|
||||
|
||||
var response map[string]interface{}
|
||||
err = json.Unmarshal(w.Body.Bytes(), &response)
|
||||
assert.NoError(t, err)
|
||||
|
||||
spellsBySchool := response["spells_by_school"].(map[string]interface{})
|
||||
|
||||
// Prüfe, dass "Feuerball" nicht in der Liste ist
|
||||
foundFeuerball := false
|
||||
for _, schoolSpells := range spellsBySchool {
|
||||
spells := schoolSpells.([]interface{})
|
||||
for _, spell := range spells {
|
||||
spellObj := spell.(map[string]interface{})
|
||||
if spellObj["name"].(string) == "Feuerball" {
|
||||
foundFeuerball = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.False(t, foundFeuerball, "Already learned spell 'Feuerball' should not be in available spells")
|
||||
fmt.Printf("Correctly excluded already learned spell 'Feuerball'\n")
|
||||
})
|
||||
}
|
||||
|
||||
// Helper function to create string pointer
|
||||
func stringPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
@@ -37,6 +37,10 @@ var (
|
||||
)
|
||||
|
||||
func ConnectDatabase() *gorm.DB {
|
||||
SetupTestDB()
|
||||
return DB
|
||||
}
|
||||
func ConnectDatabaseOrig() *gorm.DB {
|
||||
dsn := "bamort:bG4)efozrc@tcp(192.168.0.5:3306)/bamort?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
database, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user