- SSE subscription to ntfy with auto-reconnect - Discord webhook integration with embed formatting - Priority to color mapping, tag to emoji conversion - Native HashiCorp Vault support (Kubernetes + token auth) - Hot reload secrets via fsnotify or Vault polling - Prometheus metrics (/metrics endpoint) - Health/ready endpoints for Kubernetes probes - Comprehensive unit tests and fuzz tests - Multi-stage Docker build (~10MB scratch image) - CI/CD pipeline for Gitea Actions
59 lines
1.4 KiB
Go
59 lines
1.4 KiB
Go
package ntfy
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
// FuzzParseMessage tests that JSON unmarshaling doesn't panic on arbitrary input
|
|
func FuzzParseMessage(f *testing.F) {
|
|
// Seed corpus with valid messages
|
|
f.Add(`{"event":"message","topic":"test","title":"hello","message":"world"}`)
|
|
f.Add(`{"event":"message","topic":"alerts","priority":5,"tags":["warning"]}`)
|
|
f.Add(`{"event":"keepalive"}`)
|
|
f.Add(`{"event":"open"}`)
|
|
f.Add(`{}`)
|
|
f.Add(`{"id":"abc123","time":1706803200,"expires":1706889600}`)
|
|
f.Add(`{"click":"https://example.com","icon":"https://example.com/icon.png"}`)
|
|
|
|
// Edge cases
|
|
f.Add(``)
|
|
f.Add(`null`)
|
|
f.Add(`[]`)
|
|
f.Add(`"string"`)
|
|
f.Add(`123`)
|
|
f.Add(`{"priority":-1}`)
|
|
f.Add(`{"priority":999999999}`)
|
|
f.Add(`{"tags":[]}`)
|
|
f.Add(`{"tags":["","",""]}`)
|
|
|
|
f.Fuzz(func(t *testing.T, data string) {
|
|
var msg Message
|
|
// Should never panic regardless of input
|
|
_ = json.Unmarshal([]byte(data), &msg)
|
|
|
|
// If it parsed, accessing fields should not panic
|
|
_ = msg.ID
|
|
_ = msg.Event
|
|
_ = msg.Topic
|
|
_ = msg.Title
|
|
_ = msg.Message
|
|
_ = msg.Priority
|
|
_ = msg.Click
|
|
_ = len(msg.Tags)
|
|
})
|
|
}
|
|
|
|
// FuzzParseMessageBytes tests binary input doesn't cause panics
|
|
func FuzzParseMessageBytes(f *testing.F) {
|
|
f.Add([]byte(`{"event":"message"}`))
|
|
f.Add([]byte{0x00})
|
|
f.Add([]byte{0xff, 0xfe})
|
|
f.Add([]byte("\xef\xbb\xbf{}")) // BOM + JSON
|
|
|
|
f.Fuzz(func(t *testing.T, data []byte) {
|
|
var msg Message
|
|
_ = json.Unmarshal(data, &msg)
|
|
})
|
|
}
|