package cmd import ( "encoding/json" "testing" "github.com/lerko/nib/internal/db" ) func TestGenerateCardData_Snippet(t *testing.T) { data := generateCardData(db.CardSnippet, "some snippet") if data == nil || *data != "{}" { t.Errorf("snippet should produce {}, got %v", data) } } func TestGenerateCardData_Template(t *testing.T) { data := generateCardData(db.CardTemplate, "deploy ${host} to ${env}") if data == nil { t.Fatal("expected non-nil data") } var parsed struct { Slots []struct { Name string `json:"name"` Default string `json:"default"` } `json:"slots"` } if err := json.Unmarshal([]byte(*data), &parsed); err != nil { t.Fatal(err) } if len(parsed.Slots) != 2 { t.Fatalf("expected 2 slots, got %d", len(parsed.Slots)) } if parsed.Slots[0].Name != "host" { t.Errorf("first slot: %q", parsed.Slots[0].Name) } if parsed.Slots[1].Name != "env" { t.Errorf("second slot: %q", parsed.Slots[1].Name) } } func TestGenerateCardData_TemplateDedupe(t *testing.T) { data := generateCardData(db.CardTemplate, "${x} and ${x}") var parsed struct { Slots []struct { Name string `json:"name"` } `json:"slots"` } json.Unmarshal([]byte(*data), &parsed) if len(parsed.Slots) != 1 { t.Errorf("duplicate slots should be deduped, got %d", len(parsed.Slots)) } } func TestGenerateCardData_TemplateNoSlots(t *testing.T) { data := generateCardData(db.CardTemplate, "no placeholders here") var parsed struct { Slots []struct { Name string `json:"name"` } `json:"slots"` } json.Unmarshal([]byte(*data), &parsed) if len(parsed.Slots) != 0 { t.Errorf("expected empty slots, got %d", len(parsed.Slots)) } } func TestGenerateCardData_Checklist(t *testing.T) { body := "[ ] step one\n[x] step two\n[ ] step three" data := generateCardData(db.CardChecklist, body) if data == nil { t.Fatal("expected non-nil data") } var parsed struct { Steps []struct { Text string `json:"text"` Done bool `json:"done"` } `json:"steps"` } if err := json.Unmarshal([]byte(*data), &parsed); err != nil { t.Fatal(err) } if len(parsed.Steps) != 3 { t.Fatalf("expected 3 steps, got %d", len(parsed.Steps)) } if parsed.Steps[0].Text != "step one" || parsed.Steps[0].Done { t.Errorf("step 0: %+v", parsed.Steps[0]) } if parsed.Steps[1].Text != "step two" || !parsed.Steps[1].Done { t.Errorf("step 1: %+v", parsed.Steps[1]) } } func TestGenerateCardData_ChecklistFallback(t *testing.T) { data := generateCardData(db.CardChecklist, "no checkbox syntax") var parsed struct { Steps []struct { Text string `json:"text"` Done bool `json:"done"` } `json:"steps"` } json.Unmarshal([]byte(*data), &parsed) if len(parsed.Steps) != 1 { t.Fatalf("fallback should produce 1 step, got %d", len(parsed.Steps)) } if parsed.Steps[0].Text != "no checkbox syntax" { t.Errorf("fallback step text: %q", parsed.Steps[0].Text) } } func TestGenerateCardData_Decision(t *testing.T) { data := generateCardData(db.CardDecision, "which db?") var parsed struct { Chose string `json:"chose"` Why string `json:"why"` Rejected []string `json:"rejected"` } if err := json.Unmarshal([]byte(*data), &parsed); err != nil { t.Fatal(err) } if parsed.Chose != "" || parsed.Why != "" { t.Error("decision fields should start empty") } if len(parsed.Rejected) != 0 { t.Error("rejected should start empty") } } func TestGenerateCardData_Link(t *testing.T) { data := generateCardData(db.CardLink, "check https://example.com/path for details") var parsed struct { URL string `json:"url"` } json.Unmarshal([]byte(*data), &parsed) if parsed.URL != "https://example.com/path" { t.Errorf("url: %q", parsed.URL) } } func TestGenerateCardData_LinkNoURL(t *testing.T) { data := generateCardData(db.CardLink, "no url here") var parsed struct { URL string `json:"url"` } json.Unmarshal([]byte(*data), &parsed) if parsed.URL != "" { t.Errorf("expected empty url, got %q", parsed.URL) } }