feat: настраиваемые каналы уведомлений (telegram/pachca/email) с маршрутизацией по пути
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
93
notifier_test.go
Normal file
93
notifier_test.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var errSend = errors.New("send failed")
|
||||
|
||||
func sampleData() RequestData {
|
||||
return RequestData{
|
||||
Time: time.Date(2026, 6, 14, 10, 0, 0, 0, time.UTC),
|
||||
Method: "POST",
|
||||
Host: "example.com",
|
||||
URL: "/telegram",
|
||||
RemoteAddr: "1.2.3.4",
|
||||
Header: http.Header{"X-Test": []string{"v"}},
|
||||
Body: "payload<>",
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatMarkdown(t *testing.T) {
|
||||
out := formatMarkdown(sampleData())
|
||||
if !strings.HasPrefix(out, "```") || !strings.HasSuffix(out, "```") {
|
||||
t.Fatalf("expected ``` wrapping, got: %q", out)
|
||||
}
|
||||
if !strings.Contains(out, "POST") || !strings.Contains(out, "1.2.3.4") {
|
||||
t.Errorf("missing fields: %q", out)
|
||||
}
|
||||
if !strings.Contains(out, "X-Test: v") {
|
||||
t.Errorf("missing header: %q", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatHTML(t *testing.T) {
|
||||
out := formatHTML(sampleData())
|
||||
if !strings.Contains(out, "<pre>") || !strings.Contains(out, "</pre>") {
|
||||
t.Fatalf("expected <pre> wrapping, got: %q", out)
|
||||
}
|
||||
if !strings.Contains(out, "payload<>") {
|
||||
t.Errorf("body not escaped: %q", out)
|
||||
}
|
||||
if strings.Contains(out, "payload<>") {
|
||||
t.Errorf("unescaped body present: %q", out)
|
||||
}
|
||||
}
|
||||
|
||||
type mockNotifier struct {
|
||||
called bool
|
||||
err error
|
||||
}
|
||||
|
||||
func (m *mockNotifier) Send(d RequestData) error {
|
||||
m.called = true
|
||||
return m.err
|
||||
}
|
||||
|
||||
func TestHandlerRouting(t *testing.T) {
|
||||
tg := &mockNotifier{}
|
||||
h := makeHandler(map[string]Notifier{"telegram": tg})
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
h(rec, httptest.NewRequest("POST", "/telegram", strings.NewReader("x")))
|
||||
if rec.Code != 200 || !tg.called {
|
||||
t.Fatalf("telegram: code=%d called=%v", rec.Code, tg.called)
|
||||
}
|
||||
|
||||
rec = httptest.NewRecorder()
|
||||
h(rec, httptest.NewRequest("POST", "/unknown", strings.NewReader("x")))
|
||||
if rec.Code != 404 {
|
||||
t.Fatalf("unknown: code=%d", rec.Code)
|
||||
}
|
||||
|
||||
rec = httptest.NewRecorder()
|
||||
h(rec, httptest.NewRequest("POST", "/", nil))
|
||||
if rec.Code != 404 {
|
||||
t.Fatalf("empty: code=%d", rec.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandlerSendError(t *testing.T) {
|
||||
failing := &mockNotifier{err: errSend}
|
||||
h := makeHandler(map[string]Notifier{"telegram": failing})
|
||||
rec := httptest.NewRecorder()
|
||||
h(rec, httptest.NewRequest("POST", "/telegram", strings.NewReader("x")))
|
||||
if rec.Code != 502 {
|
||||
t.Fatalf("expected 502, got %d", rec.Code)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user