package config import ( "os" "path/filepath" "strings" "testing" ) // TestLoadMigratesSingleServerConfig проверяет обновление с версии, где сервер // был один: его настройки должны стать первым профилем, а старые поля — // исчезнуть из файла. func TestLoadMigratesSingleServerConfig(t *testing.T) { path := filepath.Join(t.TempDir(), "config.yaml") legacy := strings.Join([]string{ "listen: 127.0.0.1:8080", "server_name: myworld", "admin_password: hunter2", "java_memory: 8g", "extra_args:", " - -debug", }, "\n") if err := os.WriteFile(path, []byte(legacy), 0o600); err != nil { t.Fatal(err) } cfg, err := Load(path) if err != nil { t.Fatal(err) } if len(cfg.Profiles) != 1 { t.Fatalf("получено %d профилей, ожидался 1: %+v", len(cfg.Profiles), cfg.Profiles) } p := cfg.Profiles[0] if p.ID != "myworld" || p.AdminPassword != "hunter2" || p.JavaMemory != "8g" { t.Errorf("настройки не перенесены в профиль: %+v", p) } if len(p.ExtraArgs) != 1 || p.ExtraArgs[0] != "-debug" { t.Errorf("extra_args не перенесены: %v", p.ExtraArgs) } if cfg.Active != "myworld" { t.Errorf("активный профиль = %q", cfg.Active) } // Файл должен быть переписан без устаревших полей. raw, err := os.ReadFile(path) if err != nil { t.Fatal(err) } saved := string(raw) for _, key := range []string{"server_name:", "admin_password:", "java_memory:", "extra_args:"} { if strings.Contains(saved, "\n"+key) { t.Errorf("в файле осталось устаревшее поле %s:\n%s", key, saved) } } if !strings.Contains(saved, "active_profile: myworld") { t.Errorf("активный профиль не записан:\n%s", saved) } } func TestLoadCreatesDefaultProfile(t *testing.T) { path := filepath.Join(t.TempDir(), "config.yaml") cfg, err := Load(path) if err != nil { t.Fatal(err) } if len(cfg.Profiles) != 1 || cfg.Profiles[0].ID != "servertest" { t.Fatalf("профиль по умолчанию не создан: %+v", cfg.Profiles) } if cfg.ActiveProfile().ID != "servertest" { t.Errorf("активный профиль = %q", cfg.ActiveProfile().ID) } } // TestLoadRepairsDanglingActive: активный профиль могли удалить руками из // файла, панель не должна из-за этого падать. func TestLoadRepairsDanglingActive(t *testing.T) { path := filepath.Join(t.TempDir(), "config.yaml") raw := strings.Join([]string{ "active_profile: удалённый", "profiles:", " - id: vanilla", " title: Ванилла", }, "\n") if err := os.WriteFile(path, []byte(raw), 0o600); err != nil { t.Fatal(err) } cfg, err := Load(path) if err != nil { t.Fatal(err) } if cfg.Active != "vanilla" { t.Errorf("активный профиль = %q, ожидался vanilla", cfg.Active) } if cfg.Profiles[0].JavaMemory == "" { t.Error("профилю без java_memory не подставлено умолчание") } } func TestProfileCRUD(t *testing.T) { cfg := Default() if err := cfg.AddProfile(Profile{ID: "modded", Title: "С модами"}); err != nil { t.Fatal(err) } if err := cfg.AddProfile(Profile{ID: "modded"}); err == nil { t.Error("дубликат профиля принят") } if err := cfg.AddProfile(Profile{ID: "плохой id"}); err == nil { t.Error("недопустимый идентификатор принят") } if err := cfg.DeleteProfile("servertest"); err == nil { t.Error("активный профиль удалён без переключения") } if err := cfg.SetActive("modded"); err != nil { t.Fatal(err) } if err := cfg.DeleteProfile("servertest"); err != nil { t.Fatal(err) } if err := cfg.DeleteProfile("modded"); err == nil { t.Error("удалён единственный оставшийся профиль") } if err := cfg.SetActive("несуществующий"); err == nil { t.Error("активирован несуществующий профиль") } } func TestUpdateProfileKeepsID(t *testing.T) { cfg := Default() err := cfg.UpdateProfile("servertest", Profile{ID: "другой", Title: "Переименован", JavaMemory: "16g"}) if err != nil { t.Fatal(err) } p := cfg.ActiveProfile() if p.ID != "servertest" { t.Errorf("идентификатор профиля изменился: %q", p.ID) } if p.Title != "Переименован" || p.JavaMemory != "16g" { t.Errorf("настройки не сохранены: %+v", p) } } func TestProfilePaths(t *testing.T) { cfg := Default() cfg.ZomboidDir = filepath.Join("/home", "pz", "Zomboid") if got := cfg.ServerConfigPathFor("modded"); filepath.Base(got) != "modded.ini" { t.Errorf("конфиг профиля: %s", got) } if got := cfg.SandboxConfigPathFor("modded"); filepath.Base(got) != "modded_SandboxVars.lua" { t.Errorf("песочница профиля: %s", got) } if got := cfg.WorldDirFor("modded"); filepath.Base(got) != "modded" || !strings.Contains(filepath.ToSlash(got), "Saves/Multiplayer") { t.Errorf("мир профиля: %s", got) } }