TestCopyLiveDatabaseToFile now runs

after connection to local MySQL database is working for go tests
This commit is contained in:
2026-01-02 12:07:28 +01:00
parent 5ce28bb79b
commit a547d850a2
10 changed files with 58 additions and 25 deletions
+7 -7
View File
@@ -193,10 +193,10 @@ func splitSkills(object []models.SkFertigkeit) ([]models.SkFertigkeit, []models.
type ExperienceAndWealthResponse struct {
ExperiencePoints int `json:"experience_points"`
Wealth struct {
Goldstücke int `json:"gold_coins"` // GS
Silberstücke int `json:"silver_coins"` // SS
Kupferstücke int `json:"copper_coins"` // KS
TotalInGS int `json:"total_in_ss"` // Gesamt in Silberstücken
Goldstuecke int `json:"gold_coins"` // GS
Silberstuecke int `json:"silver_coins"` // SS
Kupferstuecke int `json:"copper_coins"` // KS
TotalInGS int `json:"total_in_ss"` // Gesamt in Silberstücken
} `json:"wealth"`
}
@@ -225,9 +225,9 @@ func GetCharacterExperienceAndWealth(c *gin.Context) {
response := ExperienceAndWealthResponse{
ExperiencePoints: character.Erfahrungsschatz.EP,
}
response.Wealth.Goldstücke = gs
response.Wealth.Silberstücke = ss
response.Wealth.Kupferstücke = ks
response.Wealth.Goldstuecke = gs
response.Wealth.Silberstuecke = ss
response.Wealth.Kupferstuecke = ks
response.Wealth.TotalInGS = totalInSS
c.JSON(http.StatusOK, response)
+1
View File
@@ -599,6 +599,7 @@ func TestFinalizeCharacterCreation(t *testing.T) {
UserID: 1,
Username: "bebe",
Email: "frank@wuenscheonline.de",
Role: "admin",
}
err = database.DB.Create(&testUser).Error
assert.NoError(t, err)
+4
View File
@@ -145,6 +145,10 @@ func LoadConfig() *Config {
// loadEnvFile lädt eine .env-Datei falls vorhanden
func loadEnvFile() {
envFiles := []string{".env", ".env.local"}
configFile := os.Getenv("CONFIG_FILE")
if configFile != "" {
envFiles = append(envFiles, configFile)
}
for _, envFile := range envFiles {
if _, err := os.Stat(envFile); err == nil {
+1 -1
View File
@@ -70,7 +70,7 @@ func ConnectDatabaseOrig() *gorm.DB {
// Falls keine URL konfiguriert ist, verwende Standard-MySQL-Konfiguration als Fallback
dbURL := cfg.DatabaseURL
if dbURL == "" {
dbURL = "bamort:bG4)efozrc@tcp(192.168.0.5:3306)/bamort?charset=utf8mb4&parseTime=True&loc=Local"
dbURL = "bamort:bG4)efozrc@tcp(localhost:3306)/bamort?charset=utf8mb4&parseTime=True&loc=Local"
logger.Warn("Keine DATABASE_URL konfiguriert, verwende Standard-MySQL-Konfiguration")
cfg.DatabaseType = "mysql"
}
+8 -4
View File
@@ -43,7 +43,9 @@ func TestMaintSetupCheck(t *testing.T) {
}
func TestGetMasterData(t *testing.T) {
database.SetupTestDB() //(false)
// Ensure fresh database connection
database.DB = nil
database.SetupTestDB()
// Initialize a Gin router
r := gin.Default()
router.SetupGin(r)
@@ -56,7 +58,9 @@ func TestGetMasterData(t *testing.T) {
c.JSON(http.StatusOK, gin.H{"status": "Test OK"})
})
u := user.User{}
u.FirstId(1)
err := u.FirstId(1)
require.NoError(t, err, "Failed to load user with ID 1")
require.Equal(t, "admin", u.Role, "User 1 should be admin")
// Create a test HTTP request
req, _ := http.NewRequest("GET", "/api/maintenance", nil)
@@ -82,8 +86,8 @@ func TestGetMasterData(t *testing.T) {
Weapons []models.Weapon `json:"weapons"`
}
var dta dtaStruct
err := json.Unmarshal(respRecorder.Body.Bytes(), &dta)
assert.NoError(t, err)
errUnmarshal := json.Unmarshal(respRecorder.Body.Bytes(), &dta)
assert.NoError(t, errUnmarshal)
}
func TestGetMDSkillCategories(t *testing.T) {
+8 -2
View File
@@ -1,6 +1,7 @@
package maintenance
import (
"bamort/config"
"bamort/database"
"bamort/models"
"bamort/user"
@@ -20,8 +21,13 @@ func TestCopyLiveDatabaseToFile(t *testing.T) {
// Setup
tempDir := t.TempDir()
targetFile := filepath.Join(tempDir, "empty_backup.db")
envpath, _ := filepath.Abs("../.env.test")
os.Setenv("CONFIG_FILE", envpath)
// Create empty live database (only migrate structures, no data)
config.Cfg = config.LoadConfig()
// Reset database connection to ensure we use environment config
database.DB = nil
database.ConnectDatabase()
liveDB := database.DB
require.NotNil(t, liveDB, "Live database should be connected")
@@ -51,7 +57,7 @@ func TestCopyLiveDatabaseToFile(t *testing.T) {
var userCount int64
err = targetDB.Model(&user.User{}).Count(&userCount).Error
require.NoError(t, err, "Should be able to count users")
assert.Equal(t, int64(2), userCount, "User table should be empty")
assert.GreaterOrEqual(t, userCount, int64(2), "User table should have more that 2 users")
// Copy target file to database.PreparedTestDB for permanent storage
// Close the database connection before copying
+18 -6
View File
@@ -10,6 +10,7 @@ import (
"net/http"
"os"
"path/filepath"
"reflect"
"strings"
"github.com/gin-gonic/gin"
@@ -299,19 +300,30 @@ func copyTableData(sourceDB, targetDB *gorm.DB, model interface{}) error {
batchSize := 100
totalBatches := (int(count) + batchSize - 1) / batchSize
// Get the element type for creating slice of records
modelType := reflect.TypeOf(model).Elem()
for offset := 0; offset < int(count); offset += batchSize {
batchNum := (offset / batchSize) + 1
logger.Debug("Kopiere Batch %d/%d für %s (Offset: %d, Limit: %d)", batchNum, totalBatches, tableName, offset, batchSize)
var records []map[string]interface{}
// Create a slice of the model type using reflection
sliceType := reflect.SliceOf(modelType)
recordsValue := reflect.MakeSlice(sliceType, 0, batchSize)
recordsPtr := reflect.New(sliceType)
recordsPtr.Elem().Set(recordsValue)
// Batch aus MariaDB lesen
if err := sourceDB.Model(model).Offset(offset).Limit(batchSize).Find(&records).Error; err != nil {
// Batch aus MariaDB lesen (use proper struct type instead of map)
if err := sourceDB.Model(model).Offset(offset).Limit(batchSize).Find(recordsPtr.Interface()).Error; err != nil {
logger.Error("Fehler beim Lesen von Batch %d für %s: %s", batchNum, tableName, err.Error())
return err
}
if len(records) == 0 {
// Get the actual records from reflection
records := recordsPtr.Elem().Interface()
recordsLen := recordsPtr.Elem().Len()
if recordsLen == 0 {
logger.Debug("Keine weiteren Datensätze für %s", tableName)
break
}
@@ -320,12 +332,12 @@ func copyTableData(sourceDB, targetDB *gorm.DB, model interface{}) error {
// Verwende Clauses.OnConflict um bestehende Datensätze zu ersetzen
if err := targetDB.Model(model).Clauses(clause.OnConflict{
UpdateAll: true,
}).Create(&records).Error; err != nil {
}).Create(records).Error; err != nil {
logger.Error("Fehler beim Einfügen von Batch %d für %s: %s", batchNum, tableName, err.Error())
return err
}
logger.Debug("Batch %d/%d für %s erfolgreich kopiert (%d Datensätze)", batchNum, totalBatches, tableName, len(records))
logger.Debug("Batch %d/%d für %s erfolgreich kopiert (%d Datensätze)", batchNum, totalBatches, tableName, recordsLen)
}
logger.Info("Tabelle %s erfolgreich kopiert (%d Datensätze total)", tableName, count)
+3 -3
View File
@@ -69,9 +69,9 @@ type Bennies struct {
type Vermoegen struct {
BamortCharTrait
Goldstuecke int `json:"goldstücke"` // GS
Silberstuecke int `json:"silberstücke"` // SS
Kupferstuecke int `json:"kupferstücke"` // KS
Goldstuecke int `gorm:"column:goldstuecke" json:"goldstücke"` // GS
Silberstuecke int `gorm:"column:silberstuecke" json:"silberstücke"` // SS
Kupferstuecke int `gorm:"column:kupferstuecke" json:"kupferstücke"` // KS
}
type Char struct {
+6
View File
@@ -565,6 +565,7 @@ func TestRegisterUser(t *testing.T) {
Username: "bebe",
PasswordHash: "osiris",
Email: "frank@wuenscheonline.de",
Role: "admin",
}
hashedPassword := md5.Sum([]byte(usr.PasswordHash))
@@ -576,6 +577,7 @@ func TestRegisterUser(t *testing.T) {
Username: "bubnu",
PasswordHash: "osiris",
Email: "spacer@wuenscheonline.de",
Role: "standard",
}
hashedPassword = md5.Sum([]byte(usr2.PasswordHash))
usr2.PasswordHash = hex.EncodeToString(hashedPassword[:])
@@ -591,6 +593,7 @@ func TestLoginUser(t *testing.T) {
Username: "logintest",
PasswordHash: "osiris",
Email: "login@test.com",
Role: "standard",
}
hashedPassword := md5.Sum([]byte(usr.PasswordHash))
usr.PasswordHash = hex.EncodeToString(hashedPassword[:])
@@ -686,6 +689,7 @@ func TestUser_EdgeCases(t *testing.T) {
Username: "",
PasswordHash: "",
Email: "",
Role: "standard",
}
err := user.Save()
assert.NoError(t, err, "Should save user with empty strings")
@@ -704,6 +708,7 @@ func TestUser_EdgeCases(t *testing.T) {
Username: "longuser",
PasswordHash: longString,
Email: "long@example.com",
Role: "standard",
}
err = user2.Create()
assert.NoError(t, err, "Should create user with long password hash")
@@ -717,6 +722,7 @@ func TestUser_ConcurrentAccess(t *testing.T) {
Username: "concurrentuser",
PasswordHash: "hash",
Email: "concurrent@example.com",
Role: "standard",
}
err := user.Create()
require.NoError(t, err, "Should be able to create test user")
+2 -2
View File
@@ -48,8 +48,8 @@ services:
image: mariadb:11.4
container_name: bamort-mariadb-dev
restart: unless-stopped
#ports:
# - "3306:3306"
ports:
- "3306:3306"
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD:-secure_root_password}
MARIADB_DATABASE: ${MARIADB_DATABASE:-bamort}