diff --git a/internal/web/posts.go b/internal/web/posts.go index b448853..35d2f2e 100644 --- a/internal/web/posts.go +++ b/internal/web/posts.go @@ -93,7 +93,8 @@ func (s *Server) handleCreatePost(w http.ResponseWriter, r *http.Request) { ) } -// notifyPostReply asynchronously emails the direct parent post's author. +// notifyPostReply emails the root homeowner for admin replies and the direct +// parent author for homeowner replies. func (s *Server) notifyPostReply( parent *store.Post, root *store.Post, @@ -104,13 +105,19 @@ func (s *Server) notifyPostReply( root == nil || reply == nil || replyAuthor == nil || - s.cfg.Mail == nil || - parent.AuthorID == replyAuthor.ID { + s.cfg.Mail == nil { return } if _, disabled := s.cfg.Mail.(mail.Nop); disabled { return } + recipientID := parent.AuthorID + if replyAuthor.Admin() { + recipientID = root.AuthorID + } + if recipientID == replyAuthor.ID { + return + } msg := mail.PostReply{ RootID: root.ID, RootTitle: root.Title, @@ -118,7 +125,6 @@ func (s *Server) notifyPostReply( ReplyBody: reply.Body, ReplyAuthorName: replyAuthor.Name, } - recipientID := parent.AuthorID go func() { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() diff --git a/internal/web/posts_test.go b/internal/web/posts_test.go index 0ea4829..8e798a1 100644 --- a/internal/web/posts_test.go +++ b/internal/web/posts_test.go @@ -334,6 +334,22 @@ func TestPostReplyNotifications(t *testing.T) { t.Fatalf("homeowner reply notification = %+v", msg) } + rec = postForm(handler, "/posts", url.Values{ + "_csrf": {adminCSRF}, + "parent_id": {adminReply.ID}, + "body": {"One more plumber detail."}, + }, adminCookies) + if rec.Code != http.StatusSeeOther { + t.Fatalf("nested admin reply status = %d: %s", rec.Code, rec.Body.String()) + } + msgs = waitForMail(t, recording, 3) + if msg := msgs[2]; msg.ToEmail != homeowner.Email || + msg.RootID != root.ID || + msg.ReplyBody != "One more plumber detail." || + msg.ReplyAuthorName != admin.Name { + t.Fatalf("nested admin reply notification = %+v", msg) + } + rec = postForm(handler, "/posts", url.Values{ "_csrf": {homeownerCSRF}, "parent_id": {root.ID}, @@ -376,7 +392,7 @@ func TestPostReplyNotifications(t *testing.T) { t.Fatalf("no-email reply status = %d: %s", rec.Code, rec.Body.String()) } time.Sleep(50 * time.Millisecond) - if recording.Len() != 2 { + if recording.Len() != 3 { t.Fatalf("self, edit, or no-email action sent a notification: %+v", recording.Snapshot()) } }