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.
This commit is contained in:
@@ -0,0 +1,445 @@
|
||||
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 setupSessionTestEnv(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)
|
||||
require.NoError(t, models.MigrateStructure())
|
||||
gin.SetMode(gin.TestMode)
|
||||
}
|
||||
|
||||
const testUserIDSession = uint(4)
|
||||
|
||||
func createTestSession(t *testing.T) string {
|
||||
t.Helper()
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/api/characters/create-session", nil)
|
||||
|
||||
CreateCharacterSession(c)
|
||||
require.Equal(t, http.StatusCreated, w.Code)
|
||||
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
sessionID, ok := resp["session_id"].(string)
|
||||
require.True(t, ok, "session_id should be a string")
|
||||
return sessionID
|
||||
}
|
||||
|
||||
func TestCreateCharacterSession(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/api/characters/create-session", nil)
|
||||
|
||||
CreateCharacterSession(c)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.NotEmpty(t, resp["session_id"])
|
||||
assert.NotEmpty(t, resp["expires_at"])
|
||||
}
|
||||
|
||||
func TestCreateCharacterSessionUnauthorized(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
// userID NOT set - simulates missing authentication
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/api/characters/create-session", nil)
|
||||
|
||||
CreateCharacterSession(c)
|
||||
|
||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||
}
|
||||
|
||||
func TestListCharacterSessions(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
// Create a session first
|
||||
createTestSession(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/api/characters/create-sessions", nil)
|
||||
|
||||
ListCharacterSessions(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.NotNil(t, resp["sessions"])
|
||||
count, ok := resp["count"].(float64)
|
||||
assert.True(t, ok)
|
||||
assert.GreaterOrEqual(t, int(count), 1)
|
||||
}
|
||||
|
||||
func TestGetCharacterSession(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/api/characters/create-session/"+sessionID, nil)
|
||||
|
||||
GetCharacterSession(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp models.CharacterCreationSession
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Equal(t, sessionID, resp.ID)
|
||||
}
|
||||
|
||||
func TestGetCharacterSessionNotFound(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: "nonexistent_session_id"}}
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
|
||||
GetCharacterSession(c)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdateCharacterBasicInfo(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"name": "Torin Eisenstein",
|
||||
"geschlecht": "male",
|
||||
"rasse": "Mensch",
|
||||
"typ": "Kr",
|
||||
"herkunft": "Norden",
|
||||
"stand": "Händler",
|
||||
"glaube": "Gott1",
|
||||
}
|
||||
body, _ := json.Marshal(reqBody)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateCharacterBasicInfo(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(2), resp["current_step"])
|
||||
}
|
||||
|
||||
func TestUpdateCharacterBasicInfoMissingField(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
|
||||
// Missing required fields
|
||||
reqBody := map[string]interface{}{
|
||||
"name": "Incomplete",
|
||||
}
|
||||
body, _ := json.Marshal(reqBody)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateCharacterBasicInfo(c)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdateCharacterAttributes(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"st": 50, "gs": 40, "gw": 45,
|
||||
"ko": 55, "in": 60, "zt": 30, "au": 35,
|
||||
}
|
||||
body, _ := json.Marshal(reqBody)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateCharacterAttributes(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(3), resp["current_step"])
|
||||
}
|
||||
|
||||
func TestUpdateCharacterAttributesOutOfRange(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
|
||||
// Value out of range (max 100)
|
||||
reqBody := map[string]interface{}{
|
||||
"st": 150, "gs": 40, "gw": 45,
|
||||
"ko": 55, "in": 60, "zt": 30, "au": 35,
|
||||
}
|
||||
body, _ := json.Marshal(reqBody)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateCharacterAttributes(c)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdateCharacterDerivedValues(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"pa": 10,
|
||||
"wk": 8,
|
||||
"lp_max": 20,
|
||||
"ap_max": 100,
|
||||
"b_max": 10,
|
||||
"resistenz_koerper": 5,
|
||||
"resistenz_geist": 5,
|
||||
"resistenz_bonus_koerper": 0,
|
||||
"resistenz_bonus_geist": 0,
|
||||
"abwehr": 5,
|
||||
"abwehr_bonus": 0,
|
||||
"ausdauer_bonus": 0,
|
||||
"angriffs_bonus": 0,
|
||||
"zaubern": 5,
|
||||
"zauber_bonus": 0,
|
||||
"raufen": 5,
|
||||
"schadens_bonus": 0,
|
||||
"sg": 3,
|
||||
"gg": 0,
|
||||
"gp": 0,
|
||||
}
|
||||
body, _ := json.Marshal(reqBody)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateCharacterDerivedValues(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(4), resp["current_step"])
|
||||
}
|
||||
|
||||
func TestUpdateCharacterSkills(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"skills": []map[string]interface{}{
|
||||
{"name": "Athletik", "level": 5, "category": "Körper"},
|
||||
},
|
||||
"spells": []map[string]interface{}{},
|
||||
"skill_points": map[string]interface{}{},
|
||||
}
|
||||
body, _ := json.Marshal(reqBody)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateCharacterSkills(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(5), resp["current_step"])
|
||||
}
|
||||
|
||||
func TestDeleteCharacterSession(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodDelete, "/api/characters/create-session/"+sessionID, nil)
|
||||
|
||||
DeleteCharacterSession(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, "Session gelöscht", resp["message"])
|
||||
|
||||
// Verify session no longer exists
|
||||
var count int64
|
||||
database.DB.Model(&models.CharacterCreationSession{}).Where("id = ?", sessionID).Count(&count)
|
||||
assert.Equal(t, int64(0), count)
|
||||
}
|
||||
|
||||
func TestDeleteCharacterSessionNotFound(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: "nonexistent_session"}}
|
||||
c.Request = httptest.NewRequest(http.MethodDelete, "/", nil)
|
||||
|
||||
DeleteCharacterSession(c)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestFinalizeCharacterCreationIncomplete(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
// Session is at step 1 (incomplete)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/", nil)
|
||||
|
||||
FinalizeCharacterCreation(c)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "not complete")
|
||||
}
|
||||
|
||||
func TestFinalizeCharacterCreationViaSteps(t *testing.T) {
|
||||
setupSessionTestEnv(t)
|
||||
|
||||
sessionID := createTestSession(t)
|
||||
|
||||
// Progress through all steps
|
||||
steps := []struct {
|
||||
handler func(*gin.Context)
|
||||
body map[string]interface{}
|
||||
}{
|
||||
{
|
||||
UpdateCharacterBasicInfo,
|
||||
map[string]interface{}{
|
||||
"name": "Torin Test", "geschlecht": "male",
|
||||
"rasse": "Mensch", "typ": "Kr",
|
||||
"herkunft": "Norden", "stand": "Händler",
|
||||
},
|
||||
},
|
||||
{
|
||||
UpdateCharacterAttributes,
|
||||
map[string]interface{}{
|
||||
"st": 50, "gs": 40, "gw": 45,
|
||||
"ko": 55, "in": 60, "zt": 30, "au": 35,
|
||||
},
|
||||
},
|
||||
{
|
||||
UpdateCharacterDerivedValues,
|
||||
map[string]interface{}{
|
||||
"pa": 10, "wk": 8, "lp_max": 20, "ap_max": 100,
|
||||
"b_max": 10, "resistenz_koerper": 5, "resistenz_geist": 5,
|
||||
"resistenz_bonus_koerper": 0, "resistenz_bonus_geist": 0,
|
||||
"abwehr": 5, "abwehr_bonus": 0, "ausdauer_bonus": 0,
|
||||
"angriffs_bonus": 0, "zaubern": 5, "zauber_bonus": 0,
|
||||
"raufen": 5, "schadens_bonus": 0, "sg": 3, "gg": 0, "gp": 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
UpdateCharacterSkills,
|
||||
map[string]interface{}{
|
||||
"skills": []map[string]interface{}{},
|
||||
"spells": []map[string]interface{}{},
|
||||
"skill_points": map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, step := range steps {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
body, _ := json.Marshal(step.body)
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
step.handler(c)
|
||||
require.Equal(t, http.StatusOK, w.Code, fmt.Sprintf("Step failed: %s", w.Body.String()))
|
||||
}
|
||||
|
||||
// Now finalize
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", testUserIDSession)
|
||||
c.Params = gin.Params{{Key: "sessionId", Value: sessionID}}
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/", nil)
|
||||
|
||||
FinalizeCharacterCreation(c)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, w.Code, "Finalize response: "+w.Body.String())
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.NotNil(t, resp["character_id"])
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
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 setupCRUDTestEnv(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 TestCreateCharacter(t *testing.T) {
|
||||
setupCRUDTestEnv(t)
|
||||
|
||||
char := map[string]interface{}{
|
||||
"name": "Test Krieger",
|
||||
"rasse": "Mensch",
|
||||
"typ": "Kr",
|
||||
"userID": 4,
|
||||
}
|
||||
body, _ := json.Marshal(char)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/api/characters", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
CreateCharacter(c)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
var resp models.Char
|
||||
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Test Krieger", resp.Name)
|
||||
}
|
||||
|
||||
func TestCreateCharacterInvalidJSON(t *testing.T) {
|
||||
setupCRUDTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/api/characters", bytes.NewBufferString("invalid json"))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
CreateCharacter(c)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
|
||||
func TestGetCharacter(t *testing.T) {
|
||||
setupCRUDTestEnv(t)
|
||||
|
||||
// Create a character to retrieve
|
||||
char := &models.Char{
|
||||
BamortBase: models.BamortBase{Name: "Fanjo Test"},
|
||||
UserID: 4,
|
||||
Rasse: "Mensch",
|
||||
Typ: "Kr",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(char).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
|
||||
|
||||
GetCharacter(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp models.FeChar
|
||||
err := json.Unmarshal(w.Body.Bytes(), &resp)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "Fanjo Test", resp.Name)
|
||||
}
|
||||
|
||||
func TestGetCharacterNotFound(t *testing.T) {
|
||||
setupCRUDTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "id", Value: "99999"}}
|
||||
|
||||
GetCharacter(c)
|
||||
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdateCharacter(t *testing.T) {
|
||||
setupCRUDTestEnv(t)
|
||||
|
||||
// Create a character to update
|
||||
char := &models.Char{
|
||||
BamortBase: models.BamortBase{Name: "Original Name"},
|
||||
UserID: 4,
|
||||
Rasse: "Mensch",
|
||||
Typ: "Kr",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(char).Error)
|
||||
|
||||
updateData := map[string]interface{}{
|
||||
"name": "Updated Name",
|
||||
"rasse": "Elb",
|
||||
"typ": "Kr",
|
||||
"userID": 4,
|
||||
}
|
||||
body, _ := json.Marshal(updateData)
|
||||
|
||||
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), bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateCharacter(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdateCharacterNotOwner(t *testing.T) {
|
||||
setupCRUDTestEnv(t)
|
||||
|
||||
// Create a character owned by user 4
|
||||
char := &models.Char{
|
||||
BamortBase: models.BamortBase{Name: "Other User Char"},
|
||||
UserID: 4,
|
||||
Rasse: "Mensch",
|
||||
Typ: "Kr",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(char).Error)
|
||||
|
||||
updateData := map[string]interface{}{"name": "Hacked Name"}
|
||||
body, _ := json.Marshal(updateData)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(99)) // Different user
|
||||
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), bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateCharacter(c)
|
||||
|
||||
assert.Equal(t, http.StatusForbidden, w.Code)
|
||||
}
|
||||
|
||||
func TestDeleteCharacter(t *testing.T) {
|
||||
setupCRUDTestEnv(t)
|
||||
|
||||
// Create a character to delete
|
||||
char := &models.Char{
|
||||
BamortBase: models.BamortBase{Name: "To Delete"},
|
||||
UserID: 4,
|
||||
Rasse: "Mensch",
|
||||
Typ: "Kr",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(char).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
|
||||
|
||||
DeleteCharacter(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "deleted successfully")
|
||||
|
||||
// Verify character is actually deleted
|
||||
var count int64
|
||||
database.DB.Model(&models.Char{}).Where("id = ?", char.ID).Count(&count)
|
||||
assert.Equal(t, int64(0), count)
|
||||
}
|
||||
|
||||
func TestDeleteCharacterNotOwner(t *testing.T) {
|
||||
setupCRUDTestEnv(t)
|
||||
|
||||
char := &models.Char{
|
||||
BamortBase: models.BamortBase{Name: "Protected"},
|
||||
UserID: 4,
|
||||
Rasse: "Mensch",
|
||||
Typ: "Kr",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(char).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(99))
|
||||
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", char.ID)}}
|
||||
|
||||
DeleteCharacter(c)
|
||||
|
||||
assert.Equal(t, http.StatusForbidden, w.Code)
|
||||
}
|
||||
|
||||
func TestDeleteCharacterNotFound(t *testing.T) {
|
||||
setupCRUDTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "id", Value: "99999"}}
|
||||
|
||||
DeleteCharacter(c)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
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"])
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
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 setupPPTestEnv(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)
|
||||
require.NoError(t, models.MigrateStructure())
|
||||
gin.SetMode(gin.TestMode)
|
||||
}
|
||||
|
||||
func createCharWithSkillPP(t *testing.T, skillName string, ppAmount int) *models.Char {
|
||||
t.Helper()
|
||||
char := &models.Char{
|
||||
BamortBase: models.BamortBase{Name: "PP Test Char"},
|
||||
UserID: 4,
|
||||
Rasse: "Mensch",
|
||||
Typ: "Kr",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(char).Error)
|
||||
|
||||
skill := &models.SkFertigkeit{
|
||||
BamortCharTrait: models.BamortCharTrait{
|
||||
BamortBase: models.BamortBase{Name: skillName},
|
||||
CharacterID: char.ID,
|
||||
UserID: 4,
|
||||
},
|
||||
Fertigkeitswert: 5,
|
||||
Pp: ppAmount,
|
||||
Improvable: true,
|
||||
}
|
||||
require.NoError(t, database.DB.Create(skill).Error)
|
||||
|
||||
return char
|
||||
}
|
||||
|
||||
func TestGetPracticePoints(t *testing.T) {
|
||||
setupPPTestEnv(t)
|
||||
|
||||
char := createCharWithSkillPP(t, "Athletik", 3)
|
||||
|
||||
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, "/", nil)
|
||||
|
||||
GetPracticePoints(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp []PracticePointResponse
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
require.Len(t, resp, 1)
|
||||
assert.Equal(t, "Athletik", resp[0].SkillName)
|
||||
assert.Equal(t, 3, resp[0].Amount)
|
||||
}
|
||||
|
||||
func TestGetPracticePointsEmpty(t *testing.T) {
|
||||
setupPPTestEnv(t)
|
||||
|
||||
// A character with zero PP skills
|
||||
char := createCharWithSkillPP(t, "Athletik", 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, "/", nil)
|
||||
|
||||
GetPracticePoints(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
// Should return null or empty
|
||||
body := w.Body.String()
|
||||
assert.True(t, body == "null" || body == "[]", "Empty PP list should return null or empty array, got: "+body)
|
||||
}
|
||||
|
||||
func TestGetPracticePointsCharNotFound(t *testing.T) {
|
||||
setupPPTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "id", Value: "99999"}}
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
|
||||
GetPracticePoints(c)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdatePracticePoints(t *testing.T) {
|
||||
setupPPTestEnv(t)
|
||||
|
||||
char := createCharWithSkillPP(t, "Athletik", 1)
|
||||
|
||||
updates := []PracticePointResponse{
|
||||
{SkillName: "Athletik", Amount: 5},
|
||||
}
|
||||
body, _ := json.Marshal(updates)
|
||||
|
||||
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")
|
||||
|
||||
UpdatePracticePoints(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdatePracticePointsNotOwner(t *testing.T) {
|
||||
setupPPTestEnv(t)
|
||||
|
||||
char := createCharWithSkillPP(t, "Athletik", 1)
|
||||
|
||||
updates := []PracticePointResponse{{SkillName: "Athletik", Amount: 5}}
|
||||
body, _ := json.Marshal(updates)
|
||||
|
||||
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")
|
||||
|
||||
UpdatePracticePoints(c)
|
||||
|
||||
assert.Equal(t, http.StatusForbidden, w.Code)
|
||||
}
|
||||
|
||||
func TestAddPracticePoint(t *testing.T) {
|
||||
setupPPTestEnv(t)
|
||||
|
||||
char := createCharWithSkillPP(t, "Athletik", 0)
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"skill_name": "Athletik",
|
||||
"amount": 1,
|
||||
}
|
||||
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.MethodPost, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
AddPracticePoint(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp PracticePointActionResponse
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.True(t, resp.Success)
|
||||
assert.Equal(t, "Athletik", resp.TargetSkill)
|
||||
}
|
||||
|
||||
func TestAddPracticePointSkillNotFound(t *testing.T) {
|
||||
setupPPTestEnv(t)
|
||||
|
||||
char := createCharWithSkillPP(t, "Athletik", 0)
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"skill_name": "Zauberei",
|
||||
"amount": 1,
|
||||
}
|
||||
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.MethodPost, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
AddPracticePoint(c)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
|
||||
func TestUsePracticePoint(t *testing.T) {
|
||||
setupPPTestEnv(t)
|
||||
|
||||
char := createCharWithSkillPP(t, "Athletik", 3)
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"skill_name": "Athletik",
|
||||
"amount": 1,
|
||||
}
|
||||
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.MethodPost, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UsePracticePoint(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp PracticePointActionResponse
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.True(t, resp.Success)
|
||||
}
|
||||
|
||||
func TestUsePracticePointInsufficientPP(t *testing.T) {
|
||||
setupPPTestEnv(t)
|
||||
|
||||
char := createCharWithSkillPP(t, "Athletik", 0)
|
||||
|
||||
reqBody := map[string]interface{}{
|
||||
"skill_name": "Athletik",
|
||||
"amount": 5,
|
||||
}
|
||||
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.MethodPost, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UsePracticePoint(c)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package character
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"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 setupRefDataTestEnv(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)
|
||||
require.NoError(t, models.MigrateStructure())
|
||||
gin.SetMode(gin.TestMode)
|
||||
}
|
||||
|
||||
func TestGetRaces(t *testing.T) {
|
||||
setupRefDataTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/api/characters/races", nil)
|
||||
|
||||
GetRaces(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
races, ok := resp["races"]
|
||||
assert.True(t, ok, "Response should contain 'races' key")
|
||||
assert.NotEmpty(t, races)
|
||||
}
|
||||
|
||||
func TestGetCharacterClasses(t *testing.T) {
|
||||
setupRefDataTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/api/characters/classes", nil)
|
||||
|
||||
GetCharacterClasses(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.NotNil(t, resp)
|
||||
}
|
||||
|
||||
func TestGetOrigins(t *testing.T) {
|
||||
setupRefDataTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/api/characters/origins", nil)
|
||||
|
||||
GetOrigins(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.NotNil(t, resp)
|
||||
}
|
||||
|
||||
func TestGetSkillCategoriesHandlerStatic(t *testing.T) {
|
||||
setupRefDataTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/api/characters/skill-categories", nil)
|
||||
|
||||
GetSkillCategoriesHandlerStatic(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
categories, ok := resp["skill_categories"]
|
||||
assert.True(t, ok, "Response should contain 'skill_categories' key")
|
||||
catMap, ok := categories.(map[string]interface{})
|
||||
assert.True(t, ok)
|
||||
assert.Contains(t, catMap, "Alltag")
|
||||
}
|
||||
|
||||
func TestGetRewardTypesStaticImprove(t *testing.T) {
|
||||
setupRefDataTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Params = gin.Params{{Key: "id", Value: "1"}}
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/characters/reward-types?learning_type=improve&skill_name=Athletik&skill_type=skill", nil)
|
||||
c.Request = req
|
||||
|
||||
GetRewardTypesStatic(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.NotNil(t, resp["reward_types"])
|
||||
assert.Equal(t, "improve", resp["learning_type"])
|
||||
}
|
||||
|
||||
func TestGetRewardTypesStaticLearn(t *testing.T) {
|
||||
setupRefDataTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Params = gin.Params{{Key: "id", Value: "1"}}
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/characters/reward-types?learning_type=learn&skill_name=Athletik", nil)
|
||||
c.Request = req
|
||||
|
||||
GetRewardTypesStatic(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
rewardTypes, ok := resp["reward_types"].([]interface{})
|
||||
assert.True(t, ok)
|
||||
assert.GreaterOrEqual(t, len(rewardTypes), 1)
|
||||
}
|
||||
|
||||
func TestGetRewardTypesStaticSpell(t *testing.T) {
|
||||
setupRefDataTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Params = gin.Params{{Key: "id", Value: "1"}}
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/characters/reward-types?learning_type=spell", nil)
|
||||
c.Request = req
|
||||
|
||||
GetRewardTypesStatic(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, "spell", resp["learning_type"])
|
||||
}
|
||||
|
||||
func TestGetSpellDetailsNotFound(t *testing.T) {
|
||||
setupRefDataTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/characters/spell-details?name=NonExistentSpellXYZ", nil)
|
||||
c.Request = req
|
||||
|
||||
GetSpellDetails(c)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestGetSpellDetailsMissingName(t *testing.T) {
|
||||
setupRefDataTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/characters/spell-details", nil)
|
||||
c.Request = req
|
||||
|
||||
GetSpellDetails(c)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
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 setupSharesTestEnv(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)
|
||||
require.NoError(t, models.MigrateStructure())
|
||||
gin.SetMode(gin.TestMode)
|
||||
}
|
||||
|
||||
func createTestCharForShares(t *testing.T) *models.Char {
|
||||
t.Helper()
|
||||
char := &models.Char{
|
||||
BamortBase: models.BamortBase{Name: "Share Test Char"},
|
||||
UserID: 4,
|
||||
Rasse: "Mensch",
|
||||
Typ: "Kr",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(char).Error)
|
||||
return char
|
||||
}
|
||||
|
||||
func TestGetCharacterSharesEmpty(t *testing.T) {
|
||||
setupSharesTestEnv(t)
|
||||
|
||||
char := createTestCharForShares(t)
|
||||
|
||||
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, "/", nil)
|
||||
|
||||
GetCharacterShares(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
body := w.Body.String()
|
||||
assert.True(t, body == "null" || body == "[]", "Empty shares should return null or []")
|
||||
}
|
||||
|
||||
func TestGetCharacterSharesNotOwner(t *testing.T) {
|
||||
setupSharesTestEnv(t)
|
||||
|
||||
char := createTestCharForShares(t)
|
||||
|
||||
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.MethodGet, "/", nil)
|
||||
|
||||
GetCharacterShares(c)
|
||||
|
||||
assert.Equal(t, http.StatusForbidden, w.Code)
|
||||
}
|
||||
|
||||
func TestGetCharacterSharesNotFound(t *testing.T) {
|
||||
setupSharesTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "id", Value: "99999"}}
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
|
||||
GetCharacterShares(c)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdateCharacterShares(t *testing.T) {
|
||||
setupSharesTestEnv(t)
|
||||
|
||||
char := createTestCharForShares(t)
|
||||
|
||||
// Share with user 1 (different from owner user 4)
|
||||
reqBody := map[string]interface{}{
|
||||
"user_ids": []uint{1},
|
||||
}
|
||||
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")
|
||||
|
||||
UpdateCharacterShares(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "updated successfully")
|
||||
|
||||
// Verify the share was created
|
||||
var count int64
|
||||
database.DB.Model(&models.CharShare{}).Where("character_id = ? AND user_id = ?", char.ID, 1).Count(&count)
|
||||
assert.Equal(t, int64(1), count)
|
||||
}
|
||||
|
||||
func TestUpdateCharacterSharesClearAll(t *testing.T) {
|
||||
setupSharesTestEnv(t)
|
||||
|
||||
char := createTestCharForShares(t)
|
||||
|
||||
// First add a share
|
||||
share := &models.CharShare{
|
||||
CharacterID: char.ID,
|
||||
UserID: 1,
|
||||
Permission: "read",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(share).Error)
|
||||
|
||||
// Now clear all shares
|
||||
reqBody := map[string]interface{}{
|
||||
"user_ids": []uint{},
|
||||
}
|
||||
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")
|
||||
|
||||
UpdateCharacterShares(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
// Verify all shares removed
|
||||
var count int64
|
||||
database.DB.Model(&models.CharShare{}).Where("character_id = ?", char.ID).Count(&count)
|
||||
assert.Equal(t, int64(0), count)
|
||||
}
|
||||
|
||||
func TestUpdateCharacterSharesNotOwner(t *testing.T) {
|
||||
setupSharesTestEnv(t)
|
||||
|
||||
char := createTestCharForShares(t)
|
||||
|
||||
reqBody := map[string]interface{}{"user_ids": []uint{1}}
|
||||
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")
|
||||
|
||||
UpdateCharacterShares(c)
|
||||
|
||||
assert.Equal(t, http.StatusForbidden, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdateCharacterSharesInvalidBody(t *testing.T) {
|
||||
setupSharesTestEnv(t)
|
||||
|
||||
char := createTestCharForShares(t)
|
||||
|
||||
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("invalid json"))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateCharacterShares(c)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
package equipment
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"bamort/database"
|
||||
"bamort/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func setupWaffeTestEnv(t *testing.T) {
|
||||
t.Helper()
|
||||
database.SetupTestDB(true)
|
||||
t.Cleanup(database.ResetTestDB)
|
||||
gin.SetMode(gin.TestMode)
|
||||
}
|
||||
|
||||
func newWaffe(characterID, userID uint, name string) models.EqWaffe {
|
||||
return models.EqWaffe{
|
||||
BamortCharTrait: models.BamortCharTrait{
|
||||
BamortBase: models.BamortBase{Name: name},
|
||||
CharacterID: characterID,
|
||||
UserID: userID,
|
||||
},
|
||||
Beschreibung: "Test Waffe",
|
||||
Gewicht: 1.5,
|
||||
Wert: 80.0,
|
||||
Anb: 5,
|
||||
Abwb: 3,
|
||||
}
|
||||
}
|
||||
|
||||
func createTestCharForWaffe(t *testing.T) *models.Char {
|
||||
t.Helper()
|
||||
require.NoError(t, models.MigrateStructure())
|
||||
char := &models.Char{
|
||||
BamortBase: models.BamortBase{Name: "Waffe Owner"},
|
||||
UserID: 4,
|
||||
Rasse: "Mensch",
|
||||
Typ: "Kr",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(char).Error)
|
||||
return char
|
||||
}
|
||||
|
||||
func TestCreateWaffe(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
char := createTestCharForWaffe(t)
|
||||
|
||||
waffe := newWaffe(char.ID, 4, "Test Schwert")
|
||||
body, _ := json.Marshal(waffe)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/api/weapons", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
CreateWaffe(c)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
var resp models.EqWaffe
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Equal(t, "Test Schwert", resp.Name)
|
||||
assert.Equal(t, char.ID, resp.CharacterID)
|
||||
}
|
||||
|
||||
func TestCreateWaffeNotOwner(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
char := createTestCharForWaffe(t)
|
||||
|
||||
waffe := newWaffe(char.ID, 4, "Stolen Sword")
|
||||
body, _ := json.Marshal(waffe)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(99)) // Different user
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/api/weapons", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
CreateWaffe(c)
|
||||
|
||||
assert.Equal(t, http.StatusForbidden, w.Code)
|
||||
}
|
||||
|
||||
func TestCreateWaffeInvalidJSON(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Request = httptest.NewRequest(http.MethodPost, "/api/weapons", bytes.NewBufferString("bad json"))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
CreateWaffe(c)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
|
||||
func TestListWaffen(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
char := createTestCharForWaffe(t)
|
||||
|
||||
// Create test waffe
|
||||
waffe := newWaffe(char.ID, 4, "List Schwert")
|
||||
require.NoError(t, database.DB.Create(&waffe).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "character_id", Value: fmt.Sprintf("%d", char.ID)}}
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/api/weapons/character/"+fmt.Sprintf("%d", char.ID), nil)
|
||||
|
||||
ListWaffen(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp []models.EqWaffe
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Len(t, resp, 1)
|
||||
assert.Equal(t, "List Schwert", resp[0].Name)
|
||||
}
|
||||
|
||||
func TestListWaffenEmpty(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "character_id", Value: "99999"}}
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/api/weapons/character/99999", nil)
|
||||
|
||||
ListWaffen(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp []models.EqWaffe
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Empty(t, resp)
|
||||
}
|
||||
|
||||
func TestUpdateWaffe(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
char := createTestCharForWaffe(t)
|
||||
|
||||
// Create test waffe
|
||||
waffe := newWaffe(char.ID, 4, "Old Name")
|
||||
require.NoError(t, database.DB.Create(&waffe).Error)
|
||||
|
||||
// Update it
|
||||
waffe.Name = "New Name"
|
||||
body, _ := json.Marshal(waffe)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "waffe_id", Value: fmt.Sprintf("%d", waffe.ID)}}
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/api/weapons/"+fmt.Sprintf("%d", waffe.ID), bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateWaffe(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp models.EqWaffe
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.Equal(t, "New Name", resp.Name)
|
||||
}
|
||||
|
||||
func TestUpdateWaffeNotOwner(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
char := createTestCharForWaffe(t)
|
||||
|
||||
waffe := newWaffe(char.ID, 4, "Protected Waffe")
|
||||
require.NoError(t, database.DB.Create(&waffe).Error)
|
||||
|
||||
waffe.Name = "Hacked"
|
||||
body, _ := json.Marshal(waffe)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(99))
|
||||
c.Params = gin.Params{{Key: "waffe_id", Value: fmt.Sprintf("%d", waffe.ID)}}
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBuffer(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateWaffe(c)
|
||||
|
||||
assert.Equal(t, http.StatusForbidden, w.Code)
|
||||
}
|
||||
|
||||
func TestUpdateWaffeNotFound(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "waffe_id", Value: "99999"}}
|
||||
c.Request = httptest.NewRequest(http.MethodPut, "/", bytes.NewBufferString("{}"))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
UpdateWaffe(c)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestDeleteWaffe(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
char := createTestCharForWaffe(t)
|
||||
|
||||
waffe := newWaffe(char.ID, 4, "Delete Me Waffe")
|
||||
require.NoError(t, database.DB.Create(&waffe).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "waffe_id", Value: fmt.Sprintf("%d", waffe.ID)}}
|
||||
c.Request = httptest.NewRequest(http.MethodDelete, "/", nil)
|
||||
|
||||
DeleteWaffe(c)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "deleted successfully")
|
||||
|
||||
// Verify deletion
|
||||
var count int64
|
||||
database.DB.Model(&models.EqWaffe{}).Where("id = ?", waffe.ID).Count(&count)
|
||||
assert.Equal(t, int64(0), count)
|
||||
}
|
||||
|
||||
func TestDeleteWaffeNotOwner(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
char := createTestCharForWaffe(t)
|
||||
|
||||
waffe := newWaffe(char.ID, 4, "Protected Delete Waffe")
|
||||
require.NoError(t, database.DB.Create(&waffe).Error)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(99))
|
||||
c.Params = gin.Params{{Key: "waffe_id", Value: fmt.Sprintf("%d", waffe.ID)}}
|
||||
c.Request = httptest.NewRequest(http.MethodDelete, "/", nil)
|
||||
|
||||
DeleteWaffe(c)
|
||||
|
||||
assert.Equal(t, http.StatusForbidden, w.Code)
|
||||
}
|
||||
|
||||
func TestDeleteWaffeNotFound(t *testing.T) {
|
||||
setupWaffeTestEnv(t)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Set("userID", uint(4))
|
||||
c.Params = gin.Params{{Key: "waffe_id", Value: "99999"}}
|
||||
c.Request = httptest.NewRequest(http.MethodDelete, "/", nil)
|
||||
|
||||
DeleteWaffe(c)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package importer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"bamort/database"
|
||||
"bamort/models"
|
||||
"bamort/router"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func setupExportTestEnv(t *testing.T) *models.Char {
|
||||
t.Helper()
|
||||
database.SetupTestDB(true)
|
||||
t.Cleanup(database.ResetTestDB)
|
||||
|
||||
err := models.MigrateStructure()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create test character
|
||||
char := &models.Char{
|
||||
BamortBase: models.BamortBase{Name: "Export Test Char"},
|
||||
UserID: 4,
|
||||
Rasse: "Mensch",
|
||||
Typ: "Kr",
|
||||
}
|
||||
require.NoError(t, database.DB.Create(char).Error)
|
||||
return char
|
||||
}
|
||||
|
||||
func setupExportRouter() *gin.Engine {
|
||||
r := gin.Default()
|
||||
router.SetupGin(r)
|
||||
protected := router.BaseRouterGrp(r)
|
||||
RegisterRoutes(protected)
|
||||
return r
|
||||
}
|
||||
|
||||
func TestExportCharacterVTTHandler(t *testing.T) {
|
||||
char := setupExportTestEnv(t)
|
||||
|
||||
r := setupExportRouter()
|
||||
token := getAuthToken()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/importer/export/vtt/"+uintToStr(char.ID), nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
var resp map[string]interface{}
|
||||
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
|
||||
assert.NotNil(t, resp)
|
||||
}
|
||||
|
||||
func TestExportCharacterVTTHandlerNotFound(t *testing.T) {
|
||||
setupExportTestEnv(t)
|
||||
|
||||
r := setupExportRouter()
|
||||
token := getAuthToken()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/importer/export/vtt/99999", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestExportCharacterVTTFileHandler(t *testing.T) {
|
||||
char := setupExportTestEnv(t)
|
||||
|
||||
r := setupExportRouter()
|
||||
token := getAuthToken()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/importer/export/vtt/"+uintToStr(char.ID)+"/file", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
contentDisposition := w.Header().Get("Content-Disposition")
|
||||
assert.Contains(t, contentDisposition, "attachment")
|
||||
}
|
||||
|
||||
func TestExportCharacterVTTFileHandlerNotFound(t *testing.T) {
|
||||
setupExportTestEnv(t)
|
||||
|
||||
r := setupExportRouter()
|
||||
token := getAuthToken()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/importer/export/vtt/99999/file", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestExportCharacterCSVHandler(t *testing.T) {
|
||||
char := setupExportTestEnv(t)
|
||||
|
||||
r := setupExportRouter()
|
||||
token := getAuthToken()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/importer/export/csv/"+uintToStr(char.ID), nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
contentDisposition := w.Header().Get("Content-Disposition")
|
||||
assert.Contains(t, contentDisposition, "attachment")
|
||||
}
|
||||
|
||||
func TestExportCharacterCSVHandlerNotFound(t *testing.T) {
|
||||
setupExportTestEnv(t)
|
||||
|
||||
r := setupExportRouter()
|
||||
token := getAuthToken()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/importer/export/csv/99999", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||
}
|
||||
|
||||
func TestExportSpellsCSVHandler(t *testing.T) {
|
||||
setupExportTestEnv(t)
|
||||
|
||||
r := setupExportRouter()
|
||||
token := getAuthToken()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/importer/export/spells/csv", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
// Should be a file attachment
|
||||
contentDisposition := w.Header().Get("Content-Disposition")
|
||||
assert.Contains(t, contentDisposition, "attachment")
|
||||
}
|
||||
|
||||
func uintToStr(id uint) string {
|
||||
return fmt.Sprintf("%d", id)
|
||||
}
|
||||
Reference in New Issue
Block a user