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 |
| 974 | 974 | it posts your reply as a comment on the thread, as you. Off by |
| 975 | 975 | default; the account page has the switch when the instance reads |
| 976 | 976 | replies, 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 |
| 978 | as =reply_available=. A reply is posted only when it comes from one |
| 978 | 979 | of your verified addresses, you can still comment on the thread, and |
| 979 | 980 | the mail it answers is less than thirty days old. Quoted text (lines |
| 980 | 981 | starting 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 { |
| 268 | 268 | if err != nil { |
| 269 | 269 | return c.fail(protocol.ExitFailure, "%v", err) |
| 270 | 270 | } |
| 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) { |
| 272 | 275 | onOff := func(on bool) string { |
| 273 | 276 | if on { |
| 274 | 277 | return "on" |
internal/control/stage3notify_test.go
+27
| @@ -1,9 +1,13 @@ |
| 1 | 1 | package control |
| 2 | 2 | |
| 3 | 3 | import ( |
| 4 | "bytes" |
| 5 | "encoding/json" |
| 6 | "io" |
| 4 | 7 | "strings" |
| 5 | 8 | "testing" |
| 6 | 9 | |
| 10 | "gitbay.org/gitbay/internal/protocol" |
| 7 | 11 | "gitbay.org/gitbay/internal/store" |
| 8 | 12 | ) |
| 9 | 13 | |
| @@ -72,3 +76,26 @@ func TestNotifyScreens(t *testing.T) { |
| 72 | 76 | checkLegend(t, out) |
| 73 | 77 | } |
| 74 | 78 | } |
| 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. |
| 82 | func 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 | } |