added Tests for changing gsmaster.Believe

This commit is contained in:
2026-01-27 08:19:18 +01:00
parent 65d301542e
commit 05867a93aa
6 changed files with 223 additions and 16 deletions
+1 -1
View File
@@ -3130,7 +3130,7 @@ func SearchBeliefs(c *gin.Context) {
}
// Get game system from query parameter, default to "midgard"
gameSystem := c.DefaultQuery("game_system", "midgard")
gameSystem := c.DefaultQuery("game_system", "")
// Load beliefs from database
believes, err := models.GetBelievesByActiveSources(gameSystem)
+82
View File
@@ -1115,3 +1115,85 @@ func TestGetDatasheetOptions_CharacterNotFound(t *testing.T) {
// Assert error response
assert.Equal(t, http.StatusNotFound, w.Code)
}
func TestSearchBeliefs(t *testing.T) {
// Setup test environment
original := os.Getenv("ENVIRONMENT")
os.Setenv("ENVIRONMENT", "test")
t.Cleanup(func() {
if original != "" {
os.Setenv("ENVIRONMENT", original)
} else {
os.Unsetenv("ENVIRONMENT")
}
})
// Setup test database
database.SetupTestDB(true)
defer database.ResetTestDB()
err := models.MigrateStructure()
assert.NoError(t, err)
// Ensure game systems exist in the test DB
// Ensure game system rows exist (use INSERT OR IGNORE to avoid unique constraint errors)
database.DB.Exec("INSERT OR IGNORE INTO game_systems(code,name,description,is_active,created_at,modified_at) VALUES (?,?,?,?,strftime('%s','now'),strftime('%s','now'))", "M5", "M5", "", true)
//database.DB.Exec("INSERT OR IGNORE INTO game_systems(code,name,description,is_active,created_at,modified_at) VALUES (?,?,?,?,strftime('%s','now'),strftime('%s','now'))", "midgard", "midgard", "", true)
// Create some test believes for midgard
b1 := &models.Believe{GameSystem: "midgard", Name: "TestFaithOne", SourceID: 1}
b2 := &models.Believe{GameSystem: "midgard", Name: "OtherFaith", SourceID: 1}
err = b1.Create()
assert.NoError(t, err)
err = b2.Create()
assert.NoError(t, err)
gin.SetMode(gin.TestMode)
tests := []struct {
name string
q string
gameSystem string
expectHits int
expectError bool
}{
//{name: "GameSystem midgard", q: "Test", gameSystem: "midgard", expectHits: 1, expectError: false},
//{name: "GameSystem M5", q: "Test", gameSystem: "M5", expectHits: 2, expectError: false},
{name: "GameSystem XYZ", q: "Test", gameSystem: "XYZ", expectHits: 0, expectError: true},
//{name: "GameSystem not set (default)", q: "Test", gameSystem: "", expectHits: 0, expectError: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Build request URL with query params
url := "/api/characters/beliefs?q=" + tt.q
if tt.gameSystem != "" {
url = url + "&game_system=" + tt.gameSystem
}
req, _ := http.NewRequest("GET", url, nil)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = req
SearchBeliefs(c)
if tt.expectError {
assert.NotEqual(t, http.StatusOK, w.Code)
return
} else {
assert.Equal(t, http.StatusOK, w.Code)
}
var resp map[string][]string
err := json.Unmarshal(w.Body.Bytes(), &resp)
assert.NoError(t, err)
beliefs, ok := resp["beliefs"]
assert.True(t, ok, "response should contain beliefs")
assert.IsType(t, []string{}, beliefs)
if tt.expectHits > 0 {
assert.Greater(t, len(beliefs), 0)
}
})
}
}
+21 -1
View File
@@ -15,7 +15,11 @@ func MigrateStructure(db ...*gorm.DB) error {
targetDB = database.DB
}
err := gsMasterMigrateStructure(targetDB)
err := gameSystemMigrateStructure(targetDB)
if err != nil {
return err
}
err = gsMasterMigrateStructure(targetDB)
if err != nil {
return err
}
@@ -42,7 +46,23 @@ func MigrateStructure(db ...*gorm.DB) error {
return nil
}
func gameSystemMigrateStructure(db ...*gorm.DB) error {
// Use provided DB or default to database.DB
var targetDB *gorm.DB
if len(db) > 0 && db[0] != nil {
targetDB = db[0]
} else {
targetDB = database.DB
}
err := targetDB.AutoMigrate(
&GameSystem{},
)
if err != nil {
return err
}
return nil
}
func gsMasterMigrateStructure(db ...*gorm.DB) error {
// Use provided DB or default to database.DB
var targetDB *gorm.DB
+10 -4
View File
@@ -17,14 +17,20 @@ func (GameSystem) TableName() string {
return "game_systems"
}
func (gs *GameSystem) GetDefault() error {
return database.DB.First(gs, "code = ?", "M5").Error
}
func (gs *GameSystem) FirstByCode(code string) error {
if code == "" {
return gs.GetDefault()
}
return database.DB.First(gs, "code = ?", code).Error
}
func (gs *GameSystem) GetDefault() error {
return database.DB.First(gs, "is_active = ?", true).Error
}
func (gs *GameSystem) FirstByName(name string) error {
if name == "" {
return gs.GetDefault()
}
return database.DB.First(gs, "name = ?", name).Error
}
+68
View File
@@ -0,0 +1,68 @@
package models
import (
"testing"
"bamort/database"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGameSystem_Methods(t *testing.T) {
// Initialize test DB and migrations
database.SetupTestDB(true)
defer database.ResetTestDB()
// Ensure default exists (use FirstOrCreate to avoid unique constraint)
defaultGS := GameSystem{}
database.DB.Where(GameSystem{Code: "M5"}).FirstOrCreate(&defaultGS, GameSystem{Code: "M5", Name: "M5", IsActive: true})
t.Run("FirstByCode returns matching record", func(t *testing.T) {
gs := GameSystem{Code: "TESTCODE", Name: "Test System", IsActive: true}
err := database.DB.Create(&gs).Error
require.NoError(t, err)
var found GameSystem
err = found.FirstByCode("TESTCODE")
assert.NoError(t, err)
assert.Equal(t, "TESTCODE", found.Code)
assert.Equal(t, "Test System", found.Name)
})
t.Run("GetDefault returns M5", func(t *testing.T) {
var found GameSystem
err := found.GetDefault()
assert.NoError(t, err)
assert.Equal(t, "M5", found.Code)
})
t.Run("FirstByName behaviour", func(t *testing.T) {
// existing name
gs := GameSystem{Code: "CUSTOM", Name: "CustomSys", IsActive: true}
err := database.DB.Create(&gs).Error
require.NoError(t, err)
var byName GameSystem
err = byName.FirstByName("CustomSys")
assert.NoError(t, err)
assert.Equal(t, "CustomSys", byName.Name)
// empty name should fallback to default
byName = GameSystem{}
err = byName.FirstByName("")
assert.NoError(t, err)
assert.Equal(t, "M5", byName.Code)
// empty name should fallback to default
byName = GameSystem{}
err = byName.FirstByName("midgard")
assert.NoError(t, err)
assert.Equal(t, "M5", byName.Code)
// non-existent name should return an error
var notFound GameSystem
err = notFound.FirstByName("NoSuchSystem")
assert.Error(t, err)
})
}
+41 -10
View File
@@ -126,6 +126,7 @@ type Believe struct {
Quelle string `json:"quelle"` // Deprecated: Für Rückwärtskompatibilität
SourceID uint `gorm:"index" json:"source_id,omitempty"` // Verweis auf strukturierte Quelle
PageNumber int `json:"page_number,omitempty"` // Seitenzahl im Quellenbuch
GameSystemId uint `json:"game_system_id,omitempty"`
}
// MiscLookup represents miscellaneous lookup values like gender, race, origin, etc.
@@ -622,12 +623,16 @@ func (object *Believe) TableName() string {
return dbPrefix + "_" + "believes"
}
func (stamm *Believe) Create() error {
gameSystem := "midgard"
stamm.GameSystem = gameSystem
func (object *Believe) Create() error {
if object.GameSystemId == 0 {
gs := GameSystem{}
gs.FirstByName(object.GameSystem)
object.GameSystemId = gs.ID
object.GameSystem = gs.Name
}
err := database.DB.Transaction(func(tx *gorm.DB) error {
// Save the main character record
if err := tx.Create(&stamm).Error; err != nil {
if err := tx.Create(&object).Error; err != nil {
return fmt.Errorf("failed to save Lookup: %w", err)
}
return nil
@@ -637,8 +642,13 @@ func (stamm *Believe) Create() error {
}
func (object *Believe) FirstId(value uint) error {
gameSystem := "midgard"
err := database.DB.First(&object, "game_system=? AND id = ?", gameSystem, value).Error
if object.GameSystemId == 0 {
gs := GameSystem{}
gs.FirstByName(object.GameSystem)
object.GameSystemId = gs.ID
object.GameSystem = gs.Name
}
err := database.DB.First(&object, "(game_system=? OR game_system_id=?) AND id = ?", object.GameSystem, object.GameSystemId, value).Error
if err != nil {
// zauber found
return err
@@ -646,12 +656,17 @@ func (object *Believe) FirstId(value uint) error {
return nil
}
func (stamm *Believe) First(name string) error {
func (object *Believe) First(name string) error {
if name == "" {
return fmt.Errorf("name cannot be empty")
}
gameSystem := "midgard"
err := database.DB.First(&stamm, "game_system=? AND name = ?", gameSystem, name).Error
if object.GameSystemId == 0 {
gs := GameSystem{}
gs.FirstByName(object.GameSystem)
object.GameSystemId = gs.ID
object.GameSystem = gs.Name
}
err := database.DB.First(&object, "(game_system=? OR game_system_id=?) AND name = ?", object.GameSystem, object.GameSystemId, name).Error
if err != nil {
// zauber found
return err
@@ -660,6 +675,12 @@ func (stamm *Believe) First(name string) error {
}
func (object *Believe) Save() error {
if object.GameSystemId == 0 {
gs := GameSystem{}
gs.FirstByName(object.GameSystem)
object.GameSystemId = gs.ID
object.GameSystem = gs.Name
}
err := database.DB.Save(&object).Error
if err != nil {
// zauber found
@@ -671,9 +692,19 @@ func (object *Believe) Save() error {
// GetBelievesByActiveSources gibt Glaubensrichtungen nach aktiven Quellen zurück
func GetBelievesByActiveSources(gameSystem string) ([]Believe, error) {
var believes []Believe
gs := GameSystem{}
//if gameSystem="midgard" it should return recordset id 1
gs.FirstByName(gameSystem)
if gs.ID == 0 {
gs.FirstByCode(gameSystem)
if gs.ID == 0 {
// return empty slice if no valid game system found
return believes, fmt.Errorf("No GameSystem ID or Name found for %s", gameSystem)
}
}
err := database.DB.
Joins("LEFT JOIN gsm_lit_sources ON gsm_believes.source_id = gsm_lit_sources.id").
Where("gsm_believes.game_system = ? AND (gsm_lit_sources.is_active = ? OR gsm_believes.source_id IS NULL)", gameSystem, true).
Where("(gsm_believes.game_system = ? or gsm_believes.game_system_id=?) AND (gsm_lit_sources.is_active = ? OR gsm_believes.source_id IS NULL)", gs.Name, gs.ID, true).
Order("gsm_believes.name ASC").
Find(&believes).Error
return believes, err