292 lines
8.4 KiB
Go
292 lines
8.4 KiB
Go
package character
|
|
|
|
import (
|
|
"bamort/database"
|
|
"bamort/models"
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestPracticePointsAPI(t *testing.T) {
|
|
// Setup test database
|
|
database.SetupTestDB()
|
|
defer database.ResetTestDB()
|
|
|
|
// Migrate the schema
|
|
err := models.MigrateStructure()
|
|
assert.NoError(t, err)
|
|
|
|
// Create test skill data
|
|
err = createTestSkillData()
|
|
assert.NoError(t, err)
|
|
defer cleanupTestSkillData()
|
|
|
|
// Create a test character
|
|
character := &models.Char{
|
|
BamortBase: models.BamortBase{
|
|
Name: "Test Character",
|
|
},
|
|
Rasse: "Human",
|
|
Typ: "Hx",
|
|
}
|
|
err = character.Create()
|
|
assert.NoError(t, err)
|
|
|
|
// Add a test skill to the character
|
|
testSkill := &models.SkFertigkeit{
|
|
BamortCharTrait: models.BamortCharTrait{
|
|
BamortBase: models.BamortBase{
|
|
Name: "Menschenkenntnis",
|
|
},
|
|
CharacterID: character.ID,
|
|
},
|
|
Pp: 0,
|
|
}
|
|
|
|
// Save the skill to database
|
|
result := database.GetDB().Create(testSkill)
|
|
assert.NoError(t, result.Error)
|
|
|
|
// Add a test spell to the character
|
|
testSpell := &models.SkFertigkeit{
|
|
BamortCharTrait: models.BamortCharTrait{
|
|
BamortBase: models.BamortBase{
|
|
Name: "Macht über das Selbst",
|
|
},
|
|
CharacterID: character.ID,
|
|
},
|
|
Pp: 0,
|
|
}
|
|
|
|
// Save the spell to database
|
|
result = database.GetDB().Create(testSpell)
|
|
assert.NoError(t, result.Error)
|
|
|
|
// Add the "Beherrschen" magic school as a skill since spell PP go to the magic school
|
|
beherrschenSkill := &models.SkFertigkeit{
|
|
BamortCharTrait: models.BamortCharTrait{
|
|
BamortBase: models.BamortBase{
|
|
Name: "Beherrschen",
|
|
},
|
|
CharacterID: character.ID,
|
|
},
|
|
Pp: 0,
|
|
}
|
|
|
|
// Save the magic school skill to database
|
|
result = database.GetDB().Create(beherrschenSkill)
|
|
assert.NoError(t, result.Error)
|
|
|
|
// Setup Gin router
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
|
|
// Register routes
|
|
api := router.Group("/api")
|
|
RegisterRoutes(api)
|
|
|
|
t.Run("GetPracticePoints", func(t *testing.T) {
|
|
// Test getting practice points for a character with no PP
|
|
req := httptest.NewRequest(http.MethodGet, "/api/characters/"+strconv.Itoa(int(character.ID))+"/practice-points", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var pp []PracticePointResponse
|
|
err := json.Unmarshal(w.Body.Bytes(), &pp)
|
|
assert.NoError(t, err)
|
|
assert.Empty(t, pp) // Should be empty initially
|
|
})
|
|
|
|
t.Run("AddPracticePoint", func(t *testing.T) {
|
|
// Add practice points to a specific skill
|
|
request := map[string]interface{}{
|
|
"skill_name": "Menschenkenntnis",
|
|
"amount": 3,
|
|
}
|
|
jsonData, _ := json.Marshal(request)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/characters/"+strconv.Itoa(int(character.ID))+"/practice-points/add", bytes.NewBuffer(jsonData))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
// Debug: print response body if test fails
|
|
if w.Code != http.StatusOK {
|
|
t.Logf("Response body: %s", w.Body.String())
|
|
}
|
|
|
|
var pp []PracticePointResponse
|
|
err := json.Unmarshal(w.Body.Bytes(), &pp)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, pp, 1)
|
|
assert.Equal(t, "Menschenkenntnis", pp[0].SkillName)
|
|
assert.Equal(t, 3, pp[0].Amount)
|
|
})
|
|
|
|
t.Run("UsePracticePoint", func(t *testing.T) {
|
|
// Reset skill to 0 PP first to ensure clean test
|
|
testSkill.Pp = 0
|
|
database.GetDB().Save(testSkill)
|
|
|
|
// First add practice points
|
|
addRequest := map[string]interface{}{
|
|
"skill_name": "Menschenkenntnis",
|
|
"amount": 3,
|
|
}
|
|
jsonData, _ := json.Marshal(addRequest)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/characters/"+strconv.Itoa(int(character.ID))+"/practice-points/add", bytes.NewBuffer(jsonData))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
// Verify that practice points were actually added by checking the response
|
|
var addedPP []PracticePointResponse
|
|
addErr := json.Unmarshal(w.Body.Bytes(), &addedPP)
|
|
assert.NoError(t, addErr)
|
|
assert.Len(t, addedPP, 1)
|
|
assert.Equal(t, "Menschenkenntnis", addedPP[0].SkillName)
|
|
assert.Equal(t, 3, addedPP[0].Amount)
|
|
|
|
// Then use one practice point
|
|
useRequest := map[string]interface{}{
|
|
"skill_name": "Menschenkenntnis",
|
|
"amount": 1,
|
|
}
|
|
jsonData, _ = json.Marshal(useRequest)
|
|
|
|
req = httptest.NewRequest(http.MethodPost, "/api/characters/"+strconv.Itoa(int(character.ID))+"/practice-points/use", bytes.NewBuffer(jsonData))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w = httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
// Debug: print response body if test fails
|
|
if w.Code != http.StatusOK {
|
|
t.Logf("Response body: %s", w.Body.String())
|
|
}
|
|
|
|
var pp []PracticePointResponse
|
|
err := json.Unmarshal(w.Body.Bytes(), &pp)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, pp, 1)
|
|
assert.Equal(t, "Menschenkenntnis", pp[0].SkillName)
|
|
assert.Equal(t, 2, pp[0].Amount) // Should be reduced by 1
|
|
})
|
|
|
|
t.Run("SkillCostWithPP", func(t *testing.T) {
|
|
// First check current PP status
|
|
req := httptest.NewRequest(http.MethodGet, "/api/characters/"+strconv.Itoa(int(character.ID))+"/practice-points", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
var currentPP []PracticePointResponse
|
|
json.Unmarshal(w.Body.Bytes(), ¤tPP)
|
|
t.Logf("Current PP before skill cost test: %+v", currentPP)
|
|
|
|
// Find Menschenkenntnis PP
|
|
var humanKnowledgePP int
|
|
for _, pp := range currentPP {
|
|
if pp.SkillName == "Menschenkenntnis" {
|
|
humanKnowledgePP = pp.Amount
|
|
break
|
|
}
|
|
}
|
|
|
|
// Test skill cost calculation with practice points
|
|
request := map[string]interface{}{
|
|
"name": "Menschenkenntnis",
|
|
"type": "skill",
|
|
"action": "improve",
|
|
"current_level": 10,
|
|
"use_pp": 1,
|
|
}
|
|
jsonData, _ := json.Marshal(request)
|
|
|
|
req = httptest.NewRequest(http.MethodPost, "/api/characters/"+strconv.Itoa(int(character.ID))+"/skill-cost", bytes.NewBuffer(jsonData))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w = httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var response SkillCostResponse
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify PP information is included
|
|
assert.Equal(t, 1, response.PPUsed)
|
|
assert.Equal(t, humanKnowledgePP, response.PPAvailable) // Should match current available PP
|
|
assert.Greater(t, response.OriginalCost, response.FinalCost) // Final cost should be lower
|
|
})
|
|
|
|
t.Run("SpellCostWithPP", func(t *testing.T) {
|
|
// Add PP for spell - should go to the "Beherrschen" magic school, not the specific spell
|
|
request := map[string]interface{}{
|
|
"skill_name": "Macht über das Selbst",
|
|
"amount": 2,
|
|
}
|
|
jsonData, _ := json.Marshal(request)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/characters/"+strconv.Itoa(int(character.ID))+"/practice-points/add", bytes.NewBuffer(jsonData))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
// Verify that PP were added to "Beherrschen" skill, not "Macht über das Selbst"
|
|
var ppResponse []PracticePointResponse
|
|
err := json.Unmarshal(w.Body.Bytes(), &ppResponse)
|
|
assert.NoError(t, err)
|
|
|
|
// Should have PP on "Beherrschen", not on the specific spell
|
|
found := false
|
|
for _, pp := range ppResponse {
|
|
if pp.SkillName == "Beherrschen" && pp.Amount == 2 {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
assert.True(t, found, "Practice points should be added to 'Beherrschen' magic school, not the specific spell")
|
|
|
|
// Test spell learning with practice points
|
|
spellRequest := map[string]interface{}{
|
|
"name": "Macht über das Selbst",
|
|
"type": "spell",
|
|
"action": "learn",
|
|
"use_pp": 1,
|
|
}
|
|
jsonData, _ = json.Marshal(spellRequest)
|
|
|
|
req = httptest.NewRequest(http.MethodPost, "/api/characters/"+strconv.Itoa(int(character.ID))+"/skill-cost", bytes.NewBuffer(jsonData))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
w = httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
|
|
var response SkillCostResponse
|
|
unmarshalErr := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, unmarshalErr)
|
|
|
|
// Verify PP information is included for spells
|
|
assert.Equal(t, 1, response.PPUsed)
|
|
assert.Equal(t, 2, response.PPAvailable)
|
|
})
|
|
}
|