Files
email_agent/internal/apprise/apprise_test.go
Sam Rolfe a349b42b1f Phase 7: daily summary and read-only Hub API (AUD-73)
- internal/hub: project side of the frozen ask-contract. GET /capabilities,
  read-only POST /ask answerer (no LLM, <3s), and the outbound POST /notify
  client.
- internal/apprise: daily-summary delivery through the house Apprise API.
- internal/summary: deterministic plain-text daily summary builder.
- internal/store: CountByCategory, MessagesByCategory, and summary CRUD.
- internal/server: /capabilities and /ask (bearer-token protected), plus the
  Reports screen (/reports, build, send, delete).
- main.go: -summary, -summary-send, and -notify CLI entry points for n8n.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-11 22:38:49 +11:00

92 lines
2.6 KiB
Go

package apprise
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
)
type captured struct {
path string
auth string
body notifyBody
}
func TestSendWithKey(t *testing.T) {
var got captured
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
got.path = r.URL.Path
got.auth = r.Header.Get("Authorization")
_ = json.NewDecoder(r.Body).Decode(&got.body)
w.WriteHeader(http.StatusOK)
}))
defer srv.Close()
c := New(srv.URL, "email-summary", nil, "apprise-token", time.Second)
if err := c.Send(context.Background(), "Subject", "Body text"); err != nil {
t.Fatalf("Send() error = %v", err)
}
if got.path != "/notify/email-summary" {
t.Errorf("path = %q, want /notify/email-summary", got.path)
}
if got.auth != "Bearer apprise-token" {
t.Errorf("auth = %q", got.auth)
}
if got.body.Title != "Subject" || got.body.Body != "Body text" {
t.Errorf("body = %+v", got.body)
}
if got.body.Type != "info" {
t.Errorf("type = %q, want info", got.body.Type)
}
if len(got.body.URLs) != 0 {
t.Errorf("urls = %v, want none in key mode", got.body.URLs)
}
}
func TestSendStatelessURLs(t *testing.T) {
var got captured
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
got.path = r.URL.Path
_ = json.NewDecoder(r.Body).Decode(&got.body)
w.WriteHeader(http.StatusOK)
}))
defer srv.Close()
c := New(srv.URL, "", []string{"mailto://user:pass@example.com"}, "", time.Second)
if err := c.Send(context.Background(), "T", "B"); err != nil {
t.Fatalf("Send() error = %v", err)
}
if got.path != "/notify" {
t.Errorf("path = %q, want /notify", got.path)
}
if len(got.body.URLs) != 1 || got.body.URLs[0] != "mailto://user:pass@example.com" {
t.Errorf("urls = %v", got.body.URLs)
}
}
func TestSendErrorStatus(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "bad", http.StatusUnauthorized)
}))
defer srv.Close()
c := New(srv.URL, "key", nil, "", time.Second)
if err := c.Send(context.Background(), "T", "B"); err == nil {
t.Fatal("expected an error for a 401 reply")
}
}
func TestConfigured(t *testing.T) {
if New("http://x", "", nil, "", time.Second).Configured() {
t.Error("keyless and urlless client reports configured")
}
if New("http://x", "k", nil, "", time.Second).Configured() != true {
t.Error("key client should report configured")
}
if New("http://x", "", []string{"mailto://a@b"}, "", time.Second).Configured() != true {
t.Error("url client should report configured")
}
}