package controllogic import ( "os" "path/filepath" "reflect" "testing" ) // TestStoreDeleteAndReload covers Delete (with trash backup), the ErrNotFound // branches, List, and load() re-reading a persisted store from disk. func TestStoreDeleteAndReload(t *testing.T) { dir := t.TempDir() s, err := NewStore(dir) if err != nil { t.Fatal(err) } g := Graph{ID: "g1", Name: "one", Enabled: true, Nodes: []Node{{ID: "n1", Kind: "trigger.timer", Params: map[string]string{"interval": "1000"}}}} if err := s.Save(g); err != nil { t.Fatalf("Save: %v", err) } if err := s.Save(Graph{ID: "g2", Name: "two"}); err != nil { t.Fatalf("Save g2: %v", err) } if got := s.List(); len(got) != 2 { t.Fatalf("List: want 2, got %d", len(got)) } // Reload from disk: a fresh Store over the same dir must see both graphs. s2, err := NewStore(dir) if err != nil { t.Fatalf("reopen: %v", err) } if got, err := s2.Get("g1"); err != nil || got.Name != "one" { t.Errorf("reloaded g1 = %+v, %v", got, err) } // Delete writes a trash backup then removes the item. if err := s.Delete("g1"); err != nil { t.Fatalf("Delete: %v", err) } if _, err := s.Get("g1"); err != ErrNotFound { t.Errorf("Get after delete: want ErrNotFound, got %v", err) } if err := s.Delete("g1"); err != ErrNotFound { t.Errorf("Delete missing: want ErrNotFound, got %v", err) } // A trash file should now exist for g1. trashDir := filepath.Join(dir, "trash", "controllogic") entries, err := os.ReadDir(trashDir) if err != nil || len(entries) == 0 { t.Errorf("trash dir = %v entries, err %v; want >=1", len(entries), err) } } // TestSplitCSV covers the comma-filter parser, including trimming and the // empty-input (nil) case. func TestSplitCSV(t *testing.T) { cases := []struct { in string want []string }{ {"", nil}, {" ", nil}, {"a", []string{"a"}}, {" a , b ,, c ", []string{"a", "b", "c"}}, } for _, tc := range cases { if got := splitCSV(tc.in); !reflect.DeepEqual(got, tc.want) { t.Errorf("splitCSV(%q) = %v, want %v", tc.in, got, tc.want) } } }