Add polished answer notifications (#1)

Sends a branded Resend email when a question receives its first answer, records accepted and failed sends, and adds collapsed answer editing with cancel behavior.

Co-authored-by: codegirl-007 <s.raide@gmail.com>
This commit was merged in pull request #1.
This commit is contained in:
2026-08-27 06:55:24 +00:00
committed by codegirl007
parent 35c8c9f391
commit 418ef93da5
28 changed files with 827 additions and 74 deletions
+76
View File
@@ -0,0 +1,76 @@
package mail
import (
"bytes"
"strings"
"testing"
)
func TestEmbeddedMarkIsPNG(t *testing.T) {
t.Parallel()
if !bytes.HasPrefix(markPNG, []byte("\x89PNG\r\n\x1a\n")) {
t.Fatal("embedded mark is not PNG data")
}
}
func TestQuestionAnsweredContent(t *testing.T) {
t.Parallel()
text, htmlBody := questionAnsweredContent("https://plumber.example/", QuestionAnswered{
ToName: `<Sam & Pat>`,
QuestionID: "question-123",
QuestionTitle: `<b>Leaky sink</b>`,
AnswerBody: "Replace the cartridge.\nThen test the handle. <script>alert('x')</script>",
})
for _, want := range []string{
"Ask a Plumber First",
"Shop response",
"cid:answer-notification-mark",
"https://plumber.example/questions/question-123",
"white-space:pre-wrap",
"&lt;Sam &amp; Pat&gt;",
"&lt;b&gt;Leaky sink&lt;/b&gt;",
"&lt;script&gt;alert(&#39;x&#39;)&lt;/script&gt;",
} {
if !strings.Contains(htmlBody, want) {
t.Errorf("HTML missing %q", want)
}
}
for _, unsafe := range []string{
"<Sam & Pat>",
"<b>Leaky sink</b>",
"<script>alert('x')</script>",
} {
if strings.Contains(htmlBody, unsafe) {
t.Errorf("HTML contains unescaped content %q", unsafe)
}
}
if strings.Contains(htmlBody, "{{") {
t.Error("HTML contains an unresolved template token")
}
for _, want := range []string{
`Hi <Sam & Pat>,`,
`Your question "<b>Leaky sink</b>"`,
"Replace the cartridge.\nThen test the handle.",
"https://plumber.example/questions/question-123",
} {
if !strings.Contains(text, want) {
t.Errorf("text missing %q", want)
}
}
}
func TestQuestionAnsweredContentUsesFallbackTitle(t *testing.T) {
t.Parallel()
text, htmlBody := questionAnsweredContent("https://plumber.example", QuestionAnswered{})
if !strings.Contains(text, `"your question"`) {
t.Errorf("text missing fallback title")
}
if !strings.Contains(htmlBody, "a plumber replied to:</p>") ||
!strings.Contains(htmlBody, "“your question”") {
t.Errorf("HTML missing fallback title")
}
}