package services import ( "os" "path/filepath" "testing" "arma3-web-server/internal/models" ) func TestListWorkshopMods_Empty(t *testing.T) { dir := t.TempDir() mods := ListWorkshopMods(dir) if len(mods) != 0 { t.Fatalf("expected 0 mods, got %d", len(mods)) } } func TestListWorkshopMods_WithMods(t *testing.T) { dir := t.TempDir() workshopDir := filepath.Join(dir, "steamapps", "workshop", "content", "107410") if err := os.MkdirAll(filepath.Join(workshopDir, "123456"), 0755); err != nil { t.Fatal(err) } if err := os.MkdirAll(filepath.Join(workshopDir, "789012"), 0755); err != nil { t.Fatal(err) } mods := ListWorkshopMods(dir) if len(mods) != 2 { t.Fatalf("expected 2 mods, got %d", len(mods)) } ids := map[string]bool{} for _, m := range mods { ids[m.ID] = true if m.Source != "workshop" { t.Errorf("expected source 'workshop', got %q", m.Source) } } if !ids["123456"] || !ids["789012"] { t.Errorf("expected both mod IDs, got %v", ids) } } func TestListWorkshopMods_SkipsFiles(t *testing.T) { dir := t.TempDir() workshopDir := filepath.Join(dir, "steamapps", "workshop", "content", "107410") if err := os.MkdirAll(workshopDir, 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(workshopDir, "notadir.txt"), []byte("hi"), 0644); err != nil { t.Fatal(err) } if err := os.MkdirAll(filepath.Join(workshopDir, "111111"), 0755); err != nil { t.Fatal(err) } mods := ListWorkshopMods(dir) if len(mods) != 1 { t.Fatalf("expected 1 mod, got %d", len(mods)) } if mods[0].ID != "111111" { t.Errorf("expected ID '111111', got %q", mods[0].ID) } } func TestListLocalMods_Empty(t *testing.T) { dir := t.TempDir() mods := ListLocalMods(dir) if len(mods) != 0 { t.Fatalf("expected 0 mods, got %d", len(mods)) } } func TestListLocalMods_WithMods(t *testing.T) { dir := t.TempDir() if err := os.MkdirAll(filepath.Join(dir, "@ACE3"), 0755); err != nil { t.Fatal(err) } if err := os.MkdirAll(filepath.Join(dir, "@TFAR"), 0755); err != nil { t.Fatal(err) } mods := ListLocalMods(dir) if len(mods) != 2 { t.Fatalf("expected 2 mods, got %d", len(mods)) } for _, m := range mods { if m.Source != "local" { t.Errorf("expected source 'local', got %q", m.Source) } if len(m.Name) > 0 && m.Name[0] != '@' { t.Errorf("expected name to start with '@', got %q", m.Name) } } } func TestListLocalMods_SkipsFiles(t *testing.T) { dir := t.TempDir() if err := os.WriteFile(filepath.Join(dir, "readme.txt"), []byte("hi"), 0644); err != nil { t.Fatal(err) } if err := os.MkdirAll(filepath.Join(dir, "@Mod"), 0755); err != nil { t.Fatal(err) } mods := ListLocalMods(dir) if len(mods) != 1 { t.Fatalf("expected 1 mod, got %d", len(mods)) } } func TestBuildUsageMap(t *testing.T) { dataDir := t.TempDir() mm := NewModlistManager(dataDir) ml, err := mm.Create("Test List") if err != nil { t.Fatal(err) } ml, err = mm.Update(ml.ID, ml.Name, []models.ModEntry{ {ID: "111111", Name: "ACE3", Enabled: true}, {ID: "222222", Name: "", Enabled: true}, }) if err != nil { t.Fatal(err) } _ = ml usedWorkshop, usedLocal := BuildUsageMap(mm) if lists, ok := usedWorkshop["111111"]; !ok || len(lists) == 0 { t.Errorf("expected workshop mod 111111 to be in use") } if _, ok := usedWorkshop["222222"]; !ok { t.Errorf("expected workshop mod 222222 to be in use") } if _, ok := usedLocal["ACE3"]; !ok { t.Errorf("expected local mod ACE3 to be in use") } if _, ok := usedLocal["@ACE3"]; !ok { t.Errorf("expected local mod @ACE3 to be in use") } } func TestBuildUsageMap_Empty(t *testing.T) { dataDir := t.TempDir() mm := NewModlistManager(dataDir) usedWorkshop, usedLocal := BuildUsageMap(mm) if len(usedWorkshop) != 0 || len(usedLocal) != 0 { t.Errorf("expected empty maps, got workshop=%v local=%v", usedWorkshop, usedLocal) } } func TestRemoveMod(t *testing.T) { dir := t.TempDir() modDir := filepath.Join(dir, "@TestMod") if err := os.MkdirAll(modDir, 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(modDir, "config.cpp"), []byte("x"), 0644); err != nil { t.Fatal(err) } if err := RemoveMod(modDir); err != nil { t.Fatalf("RemoveMod failed: %v", err) } if _, err := os.Stat(modDir); !os.IsNotExist(err) { t.Errorf("expected directory to be removed") } } func TestRemoveMod_Nonexistent(t *testing.T) { err := RemoveMod("/nonexistent/path/that/does/not/exist") if err != nil { t.Errorf("RemoveMod on nonexistent path should not error, got: %v", err) } } func TestDirSize(t *testing.T) { dir := t.TempDir() if err := os.WriteFile(filepath.Join(dir, "a.txt"), []byte("hello"), 0644); err != nil { t.Fatal(err) } sub := filepath.Join(dir, "sub") if err := os.MkdirAll(sub, 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(sub, "b.txt"), []byte("world!"), 0644); err != nil { t.Fatal(err) } size := dirSize(dir) if size != 11 { t.Errorf("expected size 11, got %d", size) } } func TestDirSize_Empty(t *testing.T) { dir := t.TempDir() size := dirSize(dir) if size != 0 { t.Errorf("expected size 0, got %d", size) } }