Files
bamort/backend/importer/exporter_test.go

343 lines
13 KiB
Go

package importer
import (
"bamort/database"
"bamort/models"
"encoding/json"
"fmt"
"os"
"testing"
"github.com/stretchr/testify/assert"
)
func TestExportChar2VTT(t *testing.T) {
database.SetupTestDB()
defer database.ResetTestDB()
// Import a test character first
fileName := fmt.Sprintf("../testdata/%s", "VTT_Import1.json")
char, err := ImportVTTJSON(fileName, 1)
assert.NoError(t, err, "Expected no error when importing char")
// Export the character back to VTT format
exportedChar, err := ExportCharToVTT(char)
assert.NoError(t, err, "Expected no error when exporting char")
// Basic validations
assert.Equal(t, char.UserID, uint(1))
assert.Equal(t, char.Name, exportedChar.Name)
assert.Equal(t, char.Rasse, exportedChar.Rasse)
assert.Equal(t, char.Typ, exportedChar.Typ)
assert.Equal(t, char.Alter, exportedChar.Alter)
assert.Equal(t, char.Grad, exportedChar.Grad)
assert.Equal(t, char.Groesse, exportedChar.Groesse)
assert.Equal(t, char.Gewicht, exportedChar.Gewicht)
assert.Equal(t, char.Glaube, exportedChar.Glaube)
assert.Equal(t, char.Hand, exportedChar.Hand)
// Check LP
assert.Equal(t, char.Lp.Max, exportedChar.Lp.Max)
assert.Equal(t, char.Lp.Value, exportedChar.Lp.Value)
// Check AP
assert.Equal(t, char.Ap.Max, exportedChar.Ap.Max)
assert.Equal(t, char.Ap.Value, exportedChar.Ap.Value)
// Check Eigenschaften
eigenschaftenMap := getEigenschaftenMap(char)
assert.Equal(t, eigenschaftenMap["Au"], exportedChar.Eigenschaften.Au)
assert.Equal(t, eigenschaftenMap["Gs"], exportedChar.Eigenschaften.Gs)
assert.Equal(t, eigenschaftenMap["Gw"], exportedChar.Eigenschaften.Gw)
assert.Equal(t, eigenschaftenMap["In"], exportedChar.Eigenschaften.In)
assert.Equal(t, eigenschaftenMap["Ko"], exportedChar.Eigenschaften.Ko)
assert.Equal(t, eigenschaftenMap["PA"], exportedChar.Eigenschaften.Pa)
assert.Equal(t, eigenschaftenMap["St"], exportedChar.Eigenschaften.St)
assert.Equal(t, eigenschaftenMap["Wk"], exportedChar.Eigenschaften.Wk)
assert.Equal(t, eigenschaftenMap["Zt"], exportedChar.Eigenschaften.Zt)
// Check Fertigkeiten exist
assert.Greater(t, len(exportedChar.Fertigkeiten), 0, "Should have fertigkeiten")
// Check Waffenfertigkeiten exist
assert.Greater(t, len(exportedChar.Waffenfertigkeiten), 0, "Should have waffenfertigkeiten")
}
func TestExportChar2VTTRoundTrip(t *testing.T) {
database.SetupTestDB()
defer database.ResetTestDB()
// Import original
fileName := fmt.Sprintf("../testdata/%s", "VTT_Import1.json")
char1, err := ImportVTTJSON(fileName, 1)
assert.NoError(t, err, "Expected no error when importing char")
// Export to VTT
exportedChar, err := ExportCharToVTT(char1)
assert.NoError(t, err, "Expected no error when exporting char")
// Write to temp file
tempFile, err := os.CreateTemp("", "vtt_export_*.json")
assert.NoError(t, err, "Expected no error creating temp file")
defer os.Remove(tempFile.Name())
encoder := json.NewEncoder(tempFile)
encoder.SetIndent("", " ")
err = encoder.Encode(exportedChar)
assert.NoError(t, err, "Expected no error encoding JSON")
tempFile.Close()
// Re-import the exported file
char2, err := ImportVTTJSON(tempFile.Name(), 6)
assert.NoError(t, err, "Expected no error when re-importing char")
// Compare key fields
assert.Equal(t, char1.UserID, uint(1), "UserID should match 1 as set in first import")
assert.Equal(t, char2.UserID, uint(6), "UserID should match 6 as set in re-import")
assert.Equal(t, char1.Name, char2.Name)
assert.Equal(t, char1.Rasse, char2.Rasse)
assert.Equal(t, char1.Typ, char2.Typ)
assert.Equal(t, char1.Alter, char2.Alter)
assert.Equal(t, char1.Grad, char2.Grad)
assert.Equal(t, char1.Lp.Max, char2.Lp.Max)
assert.Equal(t, char1.Ap.Max, char2.Ap.Max)
}
// Helper function to convert char eigenschaften array to map
func getEigenschaftenMap(char *models.Char) map[string]int {
m := make(map[string]int)
for _, e := range char.Eigenschaften {
m[e.Name] = e.Value
}
return m
}
func TestExportSpellsToCSV(t *testing.T) {
database.SetupTestDB()
defer database.ResetTestDB()
// Get some spells from master data
var spells []models.Spell
database.DB.Limit(10).Find(&spells)
if len(spells) == 0 {
t.Skip("No spells in test database")
}
// Export to CSV
tempFile, err := os.CreateTemp("", "spell_export_*.csv")
assert.NoError(t, err, "Expected no error creating temp file")
defer os.Remove(tempFile.Name())
tempFile.Close()
err = ExportSpellsToCSV(spells, tempFile.Name())
assert.NoError(t, err, "Expected no error exporting spells to CSV")
// Verify file exists and has content
data, err := os.ReadFile(tempFile.Name())
assert.NoError(t, err, "Expected no error reading CSV file")
assert.Greater(t, len(data), 0, "CSV file should have content")
// Verify CSV has header
content := string(data)
assert.Contains(t, content, "game_system")
assert.Contains(t, content, "name")
assert.Contains(t, content, "Beschreibung")
}
func TestExportCharToCSV(t *testing.T) {
database.SetupTestDB()
defer database.ResetTestDB()
// Import a test character first
fileName := fmt.Sprintf("../testdata/%s", "VTT_Import1.json")
char, err := ImportVTTJSON(fileName, 1)
assert.NoError(t, err, "Expected no error when importing char")
// Export to CSV
tempFile, err := os.CreateTemp("", "char_export_*.csv")
assert.NoError(t, err, "Expected no error creating temp file")
defer os.Remove(tempFile.Name())
tempFile.Close()
err = ExportCharToCSV(char, tempFile.Name())
assert.NoError(t, err, "Expected no error exporting character to CSV")
// Verify file exists and has content
data, err := os.ReadFile(tempFile.Name())
assert.NoError(t, err, "Expected no error reading CSV file")
assert.Greater(t, len(data), 0, "CSV file should have content")
// Verify CSV has expected sections
content := string(data)
assert.Contains(t, content, char.Name, "Should contain character name")
assert.Contains(t, content, "Basiseigenschaften", "Should contain base attributes section")
assert.Contains(t, content, "Fertigkeit", "Should contain skills section")
assert.Contains(t, content, "Waffe", "Should contain weapons section")
assert.Contains(t, content, "Erfahrung", "Should contain experience section")
}
func TestExportImportWithoutMasterData(t *testing.T) {
database.SetupTestDB()
defer database.ResetTestDB()
// Import a test character first
fileName := fmt.Sprintf("../testdata/%s", "VTT_Import1.json")
char1, err := ImportVTTJSON(fileName, 1)
assert.NoError(t, err, "Expected no error when importing char")
// Export to VTT
vttChar, err := ExportCharToVTT(char1)
assert.NoError(t, err, "Expected no error when exporting char")
// Write to temp file
tempFile, err := os.CreateTemp("", "vtt_export_*.json")
assert.NoError(t, err, "Expected no error creating temp file")
defer os.Remove(tempFile.Name())
encoder := json.NewEncoder(tempFile)
encoder.SetIndent("", " ")
err = encoder.Encode(vttChar)
assert.NoError(t, err, "Expected no error encoding JSON")
tempFile.Close()
// Clear all master data tables
database.DB.Exec("DELETE FROM gsm_skills")
database.DB.Exec("DELETE FROM gsm_weaponskills")
database.DB.Exec("DELETE FROM gsm_spells")
database.DB.Exec("DELETE FROM gsm_weapons")
database.DB.Exec("DELETE FROM gsm_equipments")
database.DB.Exec("DELETE FROM gsm_containers")
database.DB.Exec("DELETE FROM gsm_transportations")
database.DB.Exec("DELETE FROM gsm_believes")
database.DB.Exec("DELETE FROM sqlite_sequence WHERE name LIKE 'gsm_%'")
// Re-import without master data
char2, err := ImportVTTJSON(tempFile.Name(), 1)
assert.NoError(t, err, "Expected no error when re-importing without master data")
assert.NotNil(t, char2, "Character should be imported")
// Verify critical data was preserved
assert.Equal(t, char1.Name, char2.Name, "Name should match")
assert.Equal(t, char1.Rasse, char2.Rasse, "Race should match")
assert.Equal(t, char1.Typ, char2.Typ, "Type should match")
assert.Equal(t, char1.Grad, char2.Grad, "Grade should match")
// Verify LP/AP
assert.Equal(t, char1.Lp.Max, char2.Lp.Max, "LP Max should match")
assert.Equal(t, char1.Ap.Max, char2.Ap.Max, "AP Max should match")
// Verify skills were imported
assert.Greater(t, len(char2.Fertigkeiten), 0, "Should have skills after reimport")
assert.Greater(t, len(char2.Waffenfertigkeiten), 0, "Should have weapon skills after reimport")
// Verify weapons were imported
assert.Greater(t, len(char2.Waffen), 0, "Should have weapons after reimport")
// Verify master data was created
var skillCount, weaponSkillCount, weaponCount int64
database.DB.Model(&models.Skill{}).Count(&skillCount)
database.DB.Model(&models.WeaponSkill{}).Count(&weaponSkillCount)
database.DB.Model(&models.Weapon{}).Count(&weaponCount)
assert.Greater(t, skillCount, int64(0), "Master data should be created for skills")
assert.Greater(t, weaponSkillCount, int64(0), "Master data should be created for weapon skills")
assert.Greater(t, weaponCount, int64(0), "Master data should be created for weapons")
}
func TestExportImportPreservesCharacterData(t *testing.T) {
database.SetupTestDB()
defer database.ResetTestDB()
// Import a test character
fileName := fmt.Sprintf("../testdata/%s", "VTT_Import1.json")
char1, err := ImportVTTJSON(fileName, 1)
assert.NoError(t, err, "Expected no error when importing char")
// Store original counts and values
originalSkillCount := len(char1.Fertigkeiten)
originalWeaponSkillCount := len(char1.Waffenfertigkeiten)
originalSpellCount := len(char1.Zauber)
originalWeaponCount := len(char1.Waffen)
originalEquipmentCount := len(char1.Ausruestung)
originalContainerCount := len(char1.Behaeltnisse)
originalTransportCount := len(char1.Transportmittel)
// Export to VTT
vttChar, err := ExportCharToVTT(char1)
assert.NoError(t, err, "Expected no error when exporting char")
// Verify export has all data
assert.Equal(t, originalSkillCount, len(vttChar.Fertigkeiten), "All skills should be exported")
assert.Equal(t, originalWeaponSkillCount, len(vttChar.Waffenfertigkeiten), "All weapon skills should be exported")
assert.Equal(t, originalSpellCount, len(vttChar.Zauber), "All spells should be exported")
assert.Equal(t, originalWeaponCount, len(vttChar.Waffen), "All weapons should be exported")
assert.Equal(t, originalEquipmentCount, len(vttChar.Ausruestung), "All equipment should be exported")
assert.Equal(t, originalContainerCount, len(vttChar.Behaeltnisse), "All containers should be exported")
assert.Equal(t, originalTransportCount, len(vttChar.Transportmittel), "All transportation should be exported")
// Verify specific skill data is preserved
if originalSkillCount > 0 {
assert.NotEmpty(t, vttChar.Fertigkeiten[0].Name, "Skill name should be exported")
assert.GreaterOrEqual(t, vttChar.Fertigkeiten[0].Fertigkeitswert, 0, "Skill value should be exported")
}
// Verify weapon data is preserved
if originalWeaponCount > 0 {
assert.NotEmpty(t, vttChar.Waffen[0].Name, "Weapon name should be exported")
assert.GreaterOrEqual(t, vttChar.Waffen[0].Gewicht, float64(0), "Weapon weight should be exported")
}
// Write to temp file
tempFile, err := os.CreateTemp("", "vtt_export_*.json")
assert.NoError(t, err, "Expected no error creating temp file")
defer os.Remove(tempFile.Name())
encoder := json.NewEncoder(tempFile)
encoder.SetIndent("", " ")
err = encoder.Encode(vttChar)
assert.NoError(t, err, "Expected no error encoding JSON")
tempFile.Close()
// Clear master data
database.DB.Exec("DELETE FROM gsm_skills")
database.DB.Exec("DELETE FROM gsm_weaponskills")
database.DB.Exec("DELETE FROM gsm_spells")
database.DB.Exec("DELETE FROM gsm_weapons")
database.DB.Exec("DELETE FROM gsm_equipments")
database.DB.Exec("DELETE FROM gsm_containers")
database.DB.Exec("DELETE FROM gsm_transportations")
// Re-import
char2, err := ImportVTTJSON(tempFile.Name(), 1)
assert.NoError(t, err, "Expected no error when re-importing")
// Verify all data was preserved
assert.Equal(t, originalSkillCount, len(char2.Fertigkeiten), "All skills should be reimported")
assert.Equal(t, originalWeaponSkillCount, len(char2.Waffenfertigkeiten), "All weapon skills should be reimported")
assert.Equal(t, originalSpellCount, len(char2.Zauber), "All spells should be reimported")
assert.Equal(t, originalWeaponCount, len(char2.Waffen), "All weapons should be reimported")
assert.Equal(t, originalEquipmentCount, len(char2.Ausruestung), "All equipment should be reimported")
assert.Equal(t, originalContainerCount, len(char2.Behaeltnisse), "All containers should be reimported")
assert.Equal(t, originalTransportCount, len(char2.Transportmittel), "All transportation should be reimported")
// Verify specific values match
if originalSkillCount > 0 {
skill1 := findSkillByName(char1.Fertigkeiten, char1.Fertigkeiten[0].Name)
skill2 := findSkillByName(char2.Fertigkeiten, char1.Fertigkeiten[0].Name)
assert.NotNil(t, skill1, "Original skill should exist")
assert.NotNil(t, skill2, "Reimported skill should exist")
assert.Equal(t, skill1.Fertigkeitswert, skill2.Fertigkeitswert, "Skill values should match")
}
}
// Helper function to find skill by name
func findSkillByName(skills []models.SkFertigkeit, name string) *models.SkFertigkeit {
for i := range skills {
if skills[i].Name == name {
return &skills[i]
}
}
return nil
}