- Add .golangci.yml with v2 config (errcheck, govet, staticcheck, misspell, etc.) - Fix 32 errcheck issues across config, discord, ntfy, server packages - Fix misspelling: cancelled → canceled - Fix staticcheck: use append(slice...) instead of loop - Fix staticcheck: remove empty error branch - Use t.Setenv instead of os.Setenv/Unsetenv in tests - Update CI workflow: add lint job, release tagging, ntfy notifications
123 lines
3.0 KiB
Go
123 lines
3.0 KiB
Go
package discord
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"git.daviestechlabs.io/daviestechlabs/ntfy-discord/internal/ntfy"
|
|
)
|
|
|
|
// FuzzBuildEmbed tests that embed building doesn't panic on arbitrary input
|
|
func FuzzBuildEmbed(f *testing.F) {
|
|
// Seed with normal inputs
|
|
f.Add("Test Title", "Test message body", 3, "warning", "test-topic", "https://example.com")
|
|
f.Add("", "", 0, "", "", "")
|
|
f.Add("Alert!", "Critical issue detected", 5, "fire", "alerts", "")
|
|
|
|
// Edge cases
|
|
f.Add("x", "y", -1, "unknown", "t", "not-a-url")
|
|
f.Add("x", "y", 100, "", "", "")
|
|
f.Add("🔥 Fire Alert", "💀 Something broke", 5, "skull", "test", "")
|
|
|
|
// Long strings
|
|
longStr := ""
|
|
for i := 0; i < 10000; i++ {
|
|
longStr += "x"
|
|
}
|
|
f.Add(longStr, longStr, 3, "tag", "topic", "https://example.com")
|
|
|
|
// Special characters
|
|
f.Add("Title\x00with\x00nulls", "Message\nwith\nnewlines", 3, "tag", "topic", "")
|
|
f.Add("<script>alert('xss')</script>", "```code```", 3, "", "", "")
|
|
f.Add("Title\t\r\n", "Body\t\r\n", 3, "", "", "")
|
|
|
|
f.Fuzz(func(t *testing.T, title, message string, priority int, tag, topic, click string) {
|
|
msg := ntfy.Message{
|
|
Title: title,
|
|
Message: message,
|
|
Priority: priority,
|
|
Tags: []string{tag},
|
|
Topic: topic,
|
|
Click: click,
|
|
Time: 1706803200,
|
|
}
|
|
|
|
client := NewClient()
|
|
|
|
// Should never panic
|
|
embed := client.buildEmbed(msg)
|
|
|
|
// Resulting embed should be valid
|
|
if embed.Footer == nil {
|
|
t.Error("Footer should never be nil")
|
|
}
|
|
|
|
// Color should always be set to a valid value
|
|
if embed.Color == 0 {
|
|
t.Error("Color should never be 0")
|
|
}
|
|
})
|
|
}
|
|
|
|
// FuzzExtractEmoji tests emoji extraction doesn't panic
|
|
func FuzzExtractEmoji(f *testing.F) {
|
|
// Valid tags
|
|
f.Add("warning")
|
|
f.Add("fire")
|
|
f.Add("check")
|
|
f.Add("rocket")
|
|
|
|
// Edge cases
|
|
f.Add("")
|
|
f.Add("unknown_tag")
|
|
f.Add("WARNING") // uppercase
|
|
f.Add("WaRnInG") // mixed case
|
|
f.Add("\x00")
|
|
f.Add("tag with spaces")
|
|
f.Add("émoji")
|
|
f.Add("🔥") // emoji as tag
|
|
f.Add("a]b[c{d}") // special chars
|
|
|
|
f.Fuzz(func(t *testing.T, tag string) {
|
|
client := NewClient()
|
|
|
|
// Should never panic
|
|
tags := []string{tag}
|
|
_ = client.extractEmoji(tags)
|
|
|
|
// Multiple tags
|
|
_ = client.extractEmoji([]string{tag, tag, tag})
|
|
|
|
// Empty slice
|
|
_ = client.extractEmoji([]string{})
|
|
|
|
// Nil slice
|
|
_ = client.extractEmoji(nil)
|
|
})
|
|
}
|
|
|
|
// FuzzWebhookPayloadJSON tests JSON marshaling of payloads
|
|
func FuzzWebhookPayloadJSON(f *testing.F) {
|
|
f.Add("Title", "Description", 3066993, "Topic", "value", "footer")
|
|
|
|
f.Fuzz(func(t *testing.T, title, desc string, color int, fieldName, fieldValue, footer string) {
|
|
payload := WebhookPayload{
|
|
Embeds: []Embed{
|
|
{
|
|
Title: title,
|
|
Description: desc,
|
|
Color: color,
|
|
Fields: []Field{
|
|
{Name: fieldName, Value: fieldValue, Inline: true},
|
|
},
|
|
Footer: &Footer{Text: footer},
|
|
},
|
|
},
|
|
}
|
|
|
|
// Marshaling should not panic
|
|
// Marshaling should not panic; JSON encoding errors are acceptable for invalid UTF-8
|
|
_, _ = json.Marshal(payload)
|
|
})
|
|
}
|