Commit ec6df8d798

ec6df8d7986ce96a3e6bc43e2daa0842139591bd

parent: a55fb297ba

Verified · cmc ci/build: success ci/test: success

cmc <hello@cleberg.net> · 2026-10-14 07:36 UTC

notifications settings show: reply_available in --json

Whether the instance reads replies to its mail, so a client offers the
reply switch only where turning it on can succeed, as the account page
does. Plain output is unchanged.

Closes #334

Layout: unified · split

.gitbay/wiki/Users.org +2 −1
@@ -974,7 +974,8 @@ merge request mail then carries a =Reply-To= address, and replying to
974974it posts your reply as a comment on the thread, as you. Off by
975975default; the account page has the switch when the instance reads
976976replies, and turning it on is refused where it does not
977(=[mail.inbound]= off). A reply is posted only when it comes from one
977(=[mail.inbound]= off). =notifications settings show --json= says which
978as =reply_available=. A reply is posted only when it comes from one
978979of your verified addresses, you can still comment on the thread, and
979980the mail it answers is less than thirty days old. Quoted text (lines
980981starting with =>=, the "On … wrote:" line and what follows it, the
internal/control/notifications.go +4 −1
@@ -268,7 +268,10 @@ func emitNotificationSettings(c *Ctx) int {
268268 if err != nil {
269269 return c.fail(protocol.ExitFailure, "%v", err)
270270 }
271 return c.emitView(map[string]bool{"mail": mail, "watch": watch, "push": push, "reply": reply}, func(w io.Writer) {
271 // reply_available says whether the instance reads replies, so a client
272 // offers the reply switch only where turning it on can succeed.
273 return c.emitView(map[string]bool{"mail": mail, "watch": watch, "push": push, "reply": reply,
274 "reply_available": c.Cfg.Mail.Inbound.Enabled}, func(w io.Writer) {
272275 onOff := func(on bool) string {
273276 if on {
274277 return "on"
internal/control/stage3notify_test.go +27
@@ -1,9 +1,13 @@
11package control
22
33import (
4 "bytes"
5 "encoding/json"
6 "io"
47 "strings"
58 "testing"
69
10 "gitbay.org/gitbay/internal/protocol"
711 "gitbay.org/gitbay/internal/store"
812)
913
@@ -72,3 +76,26 @@ func TestNotifyScreens(t *testing.T) {
7276 checkLegend(t, out)
7377 }
7478}
79
80// A client shows the reply switch only where the instance reads replies,
81// as the account page does; turning it on is refused elsewhere.
82func TestNotificationSettingsSayWhetherRepliesAreRead(t *testing.T) {
83 st, _, u := notifyFixture(t)
84 for _, enabled := range []bool{false, true} {
85 var out bytes.Buffer
86 c := &Ctx{User: u, Scope: "full", Store: st, Stdout: &out, Stderr: io.Discard, JSON: true}
87 c.Cfg.Mail.Inbound.Enabled = enabled
88 if code := Dispatch(c, []string{"notifications", "settings", "show"}); code != protocol.ExitOK {
89 t.Fatalf("exit %d", code)
90 }
91 var env struct {
92 Data map[string]bool `json:"data"`
93 }
94 if err := json.Unmarshal(out.Bytes(), &env); err != nil {
95 t.Fatal(err)
96 }
97 if got, ok := env.Data["reply_available"]; !ok || got != enabled {
98 t.Errorf("inbound %v: reply_available %v (present %v)", enabled, got, ok)
99 }
100 }
101}