package matrix import ( "strings" "testing" ) func TestFormatPost_Basic(t *testing.T) { story := &PostableStory{ Headline: "GPU prices drop 30% amid oversupply", ArticleURL: "https://example.com/gpu-prices", Lede: "Graphics card prices have fallen sharply across all tiers.", Source: "Ars Technica", Channel: "tech", } plain, html := formatPost(story) // Plain text checks if !strings.Contains(plain, "**GPU prices drop 30% amid oversupply**") { t.Errorf("plain missing bold headline: %s", plain) } if !strings.Contains(plain, "→ https://example.com/gpu-prices") { t.Errorf("plain missing article URL: %s", plain) } if !strings.Contains(plain, "Graphics card prices") { t.Errorf("plain missing lede: %s", plain) } if !strings.Contains(plain, "`ars technica`") { t.Errorf("plain missing source tag (lowercase): %s", plain) } // HTML checks if !strings.Contains(html, `GPU prices drop 30% amid oversupply`) { t.Errorf("html missing linked headline: %s", html) } if !strings.Contains(html, "ars technica") { t.Errorf("html missing source code tag: %s", html) } } func TestFormatPost_WithPlatforms(t *testing.T) { story := &PostableStory{ Headline: "Switch 2 launch lineup revealed", ArticleURL: "https://example.com/switch2", Lede: "Nintendo confirms 20 titles for day one.", Source: "Eurogamer", Channel: "gaming", Platforms: []string{"nintendo-switch"}, } plain, html := formatPost(story) if !strings.Contains(plain, "`eurogamer` · `nintendo-switch`") { t.Errorf("plain missing platform tag: %s", plain) } if !strings.Contains(html, "eurogamer · nintendo-switch") { t.Errorf("html missing platform tag: %s", html) } } func TestFormatPost_MultiplePlatforms(t *testing.T) { story := &PostableStory{ Headline: "Elden Ring Nightreign launches", ArticleURL: "https://example.com/er", Lede: "Available on all major platforms.", Source: "Ars Technica", Channel: "gaming", Platforms: []string{"pc", "playstation", "xbox"}, } plain, _ := formatPost(story) if !strings.Contains(plain, "`ars technica` · `pc` · `playstation` · `xbox`") { t.Errorf("plain tags wrong: %s", plain) } } func TestFormatPost_EmptyLede(t *testing.T) { story := &PostableStory{ Headline: "Breaking news", ArticleURL: "https://example.com/breaking", Source: "Guardian", Channel: "politics", } plain, html := formatPost(story) // Should have headline and source but no empty line for lede lines := strings.Split(plain, "\n") if len(lines) != 2 { t.Errorf("expected 2 lines (headline + source), got %d: %v", len(lines), lines) } parts := strings.Split(html, "
") if len(parts) != 2 { t.Errorf("expected 2 html parts, got %d: %v", len(parts), parts) } } func TestFormatPost_HTMLEscaping(t *testing.T) { story := &PostableStory{ Headline: `Apple's "M5" chip: & better`, ArticleURL: "https://example.com/m5", Lede: `Performance gains of >50% in "real-world" tests.`, Source: "Test & Source", Channel: "tech", } _, html := formatPost(story) if strings.Contains(html, "") { t.Error("html contains unescaped angle brackets in headline") } if !strings.Contains(html, "&") { t.Error("html missing escaped ampersand") } if !strings.Contains(html, ">50%") { t.Error("html missing escaped > in lede") } }