Files
bamort/backend/character/experience_wealth_audit_test.go
T
Frank 2cac1cc41d Create tests for ALL API entpoints in ALL packages
Based on current data. Ensure that all API endpoints used in frontend are tested. These tests are crucial for the next refactoring tasks.
2026-04-11 23:37:40 +02:00

271 lines
7.2 KiB
Go

package character
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"os"
"testing"
"bamort/database"
"bamort/models"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func setupExpWealthTestEnv(t *testing.T) {
t.Helper()
original := os.Getenv("ENVIRONMENT")
os.Setenv("ENVIRONMENT", "test")
t.Cleanup(func() {
if original != "" {
os.Setenv("ENVIRONMENT", original)
} else {
os.Unsetenv("ENVIRONMENT")
}
})
database.SetupTestDB(true, true)
t.Cleanup(database.ResetTestDB)
err := models.MigrateStructure()
require.NoError(t, err)
gin.SetMode(gin.TestMode)
}
func createTestCharWithEP(t *testing.T, ep int, gold int) *models.Char {
t.Helper()
char := &models.Char{
BamortBase: models.BamortBase{Name: "Test Char EP"},
UserID: 4,
Rasse: "Mensch",
Typ: "Kr",
}
require.NoError(t, database.DB.Create(char).Error)
erfahrung := &models.Erfahrungsschatz{
BamortCharTrait: models.BamortCharTrait{
BamortBase: models.BamortBase{},
CharacterID: char.ID,
UserID: 4,
},
EP: ep,
}
require.NoError(t, database.DB.Create(erfahrung).Error)
vermoegen := &models.Vermoegen{
BamortCharTrait: models.BamortCharTrait{
BamortBase: models.BamortBase{},
CharacterID: char.ID,
UserID: 4,
},
Goldstuecke: gold,
}
require.NoError(t, database.DB.Create(vermoegen).Error)
return char
}
func TestGetCharacterExperienceAndWealth(t *testing.T) {
setupExpWealthTestEnv(t)
char := createTestCharWithEP(t, 500, 100)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(4))
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
GetCharacterExperienceAndWealth(c)
assert.Equal(t, http.StatusOK, w.Code)
var resp map[string]interface{}
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
assert.Equal(t, float64(500), resp["experience_points"])
assert.NotNil(t, resp["wealth"])
}
func TestGetCharacterExperienceAndWealthNotFound(t *testing.T) {
setupExpWealthTestEnv(t)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(4))
c.Params = gin.Params{{Key: "id", Value: "99999"}}
GetCharacterExperienceAndWealth(c)
assert.Equal(t, http.StatusNotFound, w.Code)
}
func TestUpdateCharacterExperience(t *testing.T) {
setupExpWealthTestEnv(t)
char := createTestCharWithEP(t, 300, 0)
reqBody := map[string]interface{}{
"experience_points": 400,
}
body, _ := json.Marshal(reqBody)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(4))
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
c.Request = httptest.NewRequest(http.MethodPut, "/api/characters/"+fmt.Sprintf("%d", char.ID)+"/experience", bytes.NewBuffer(body))
c.Request.Header.Set("Content-Type", "application/json")
UpdateCharacterExperience(c)
assert.Equal(t, http.StatusOK, w.Code)
var resp map[string]interface{}
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
assert.Equal(t, float64(400), resp["experience_points"])
}
func TestUpdateCharacterExperienceNotOwner(t *testing.T) {
setupExpWealthTestEnv(t)
char := createTestCharWithEP(t, 300, 0)
reqBody := map[string]interface{}{"experience_points": 100}
body, _ := json.Marshal(reqBody)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(99))
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
c.Request.Header.Set("Content-Type", "application/json")
UpdateCharacterExperience(c)
assert.Equal(t, http.StatusForbidden, w.Code)
}
func TestUpdateCharacterExperienceInvalidBody(t *testing.T) {
setupExpWealthTestEnv(t)
char := createTestCharWithEP(t, 300, 0)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(4))
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBufferString("bad json"))
c.Request.Header.Set("Content-Type", "application/json")
UpdateCharacterExperience(c)
assert.Equal(t, http.StatusBadRequest, w.Code)
}
func TestUpdateCharacterWealth(t *testing.T) {
setupExpWealthTestEnv(t)
char := createTestCharWithEP(t, 0, 50)
gold := 200
silver := 30
reqBody := map[string]interface{}{
"goldstücke": gold,
"silberstücke": silver,
}
body, _ := json.Marshal(reqBody)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(4))
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
c.Request.Header.Set("Content-Type", "application/json")
UpdateCharacterWealth(c)
assert.Equal(t, http.StatusOK, w.Code)
var resp map[string]interface{}
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
assert.Equal(t, "Wealth updated successfully", resp["message"])
}
func TestUpdateCharacterWealthNotOwner(t *testing.T) {
setupExpWealthTestEnv(t)
char := createTestCharWithEP(t, 0, 50)
gold := 999
reqBody := map[string]interface{}{"goldstücke": gold}
body, _ := json.Marshal(reqBody)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(99))
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
c.Request.Header.Set("Content-Type", "application/json")
UpdateCharacterWealth(c)
assert.Equal(t, http.StatusForbidden, w.Code)
}
func TestGetCharacterAuditLog(t *testing.T) {
setupExpWealthTestEnv(t)
char := createTestCharWithEP(t, 100, 0)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(4))
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
c.Request = httptest.NewRequest(http.MethodGet, "/api/characters/"+fmt.Sprintf("%d", char.ID)+"/audit-log", nil)
GetCharacterAuditLog(c)
assert.Equal(t, http.StatusOK, w.Code)
var resp map[string]interface{}
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
assert.Equal(t, float64(char.ID), resp["character_id"])
assert.NotNil(t, resp["entries"])
}
func TestGetCharacterAuditLogInvalidID(t *testing.T) {
setupExpWealthTestEnv(t)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(4))
c.Params = gin.Params{{Key: "id", Value: "notanumber"}}
c.Request = httptest.NewRequest(http.MethodGet, "/", nil)
GetCharacterAuditLog(c)
assert.Equal(t, http.StatusBadRequest, w.Code)
}
func TestGetAuditLogStats(t *testing.T) {
setupExpWealthTestEnv(t)
char := createTestCharWithEP(t, 100, 0)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Set("userID", uint(4))
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
c.Request = httptest.NewRequest(http.MethodGet, "/api/characters/"+fmt.Sprintf("%d", char.ID)+"/audit-log/stats", nil)
GetAuditLogStats(c)
assert.Equal(t, http.StatusOK, w.Code)
var resp map[string]interface{}
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
stats, ok := resp["stats"].(map[string]interface{})
require.True(t, ok, "Response should contain 'stats' key")
assert.NotNil(t, stats["total_changes"])
assert.NotNil(t, stats["by_field"])
assert.NotNil(t, stats["by_reason"])
}