package store import ( "strings" "testing" ) func mustCreateWorkload(t *testing.T, s *Store, name string) Workload { t.Helper() w, err := s.CreateWorkload(Workload{ Name: name, Kind: "plugin", RefID: name, SourceKind: "image", TriggerKind: "manual", }) if err != nil { t.Fatalf("CreateWorkload(%s): %v", name, err) } return w } func TestSetWorkloadEnvUpsertSameKey(t *testing.T) { s := newTestStore(t) w := mustCreateWorkload(t, s, "envwl") first, err := s.SetWorkloadEnv(WorkloadEnv{ WorkloadID: w.ID, Key: "DB_URL", Value: "v1", }) if err != nil { t.Fatalf("first set: %v", err) } second, err := s.SetWorkloadEnv(WorkloadEnv{ WorkloadID: w.ID, Key: "DB_URL", Value: "v2", Encrypted: true, }) if err != nil { t.Fatalf("second set: %v", err) } // Same row ID — UPSERT must preserve identity, not accumulate rows. if first.ID != second.ID { t.Errorf("upsert produced new row: first=%s second=%s", first.ID, second.ID) } all, err := s.ListWorkloadEnv(w.ID) if err != nil { t.Fatalf("ListWorkloadEnv: %v", err) } if len(all) != 1 { t.Fatalf("expected 1 row after upsert, got %d", len(all)) } if all[0].Value != "v2" || !all[0].Encrypted { t.Errorf("expected upserted value+encrypted, got value=%q encrypted=%v", all[0].Value, all[0].Encrypted) } } func TestSetWorkloadEnvValidation(t *testing.T) { s := newTestStore(t) w := mustCreateWorkload(t, s, "validate-wl") if _, err := s.SetWorkloadEnv(WorkloadEnv{Key: "X"}); err == nil { t.Fatal("expected error when WorkloadID missing") } if _, err := s.SetWorkloadEnv(WorkloadEnv{WorkloadID: w.ID}); err == nil { t.Fatal("expected error when Key missing") } } func TestDeleteWorkloadEnv(t *testing.T) { s := newTestStore(t) w := mustCreateWorkload(t, s, "delete-wl") row, _ := s.SetWorkloadEnv(WorkloadEnv{WorkloadID: w.ID, Key: "K", Value: "V"}) if err := s.DeleteWorkloadEnv(row.ID); err != nil { t.Fatalf("delete: %v", err) } if err := s.DeleteWorkloadEnv(row.ID); err == nil { t.Fatal("expected ErrNotFound on second delete") } else if !strings.Contains(err.Error(), "not found") { t.Errorf("expected not-found error, got %v", err) } } func TestListChildrenByParent(t *testing.T) { s := newTestStore(t) parent := mustCreateWorkload(t, s, "parent") other := mustCreateWorkload(t, s, "other-root") // Two children of parent, plus one root unrelated. for _, name := range []string{"child-a", "child-b"} { c, err := s.CreateWorkload(Workload{ Name: name, Kind: "plugin", RefID: name, SourceKind: "image", TriggerKind: "manual", ParentWorkloadID: parent.ID, }) if err != nil { t.Fatalf("create child %s: %v", name, err) } _ = c } got, err := s.ListChildrenByParent(parent.ID) if err != nil { t.Fatalf("ListChildrenByParent: %v", err) } if len(got) != 2 { t.Fatalf("expected 2 children, got %d", len(got)) } if got[0].Name >= got[1].Name { t.Errorf("expected name-ordered output, got %q then %q", got[0].Name, got[1].Name) } // The unrelated workload must not appear. for _, c := range got { if c.ID == other.ID { t.Errorf("ListChildrenByParent leaked unrelated workload %s", other.ID) } } // Empty parent returns empty slice, not error. empty, err := s.ListChildrenByParent("") if err != nil { t.Fatalf("empty parent should not error: %v", err) } if len(empty) != 0 { t.Errorf("empty parent should return 0 rows, got %d", len(empty)) } }