Repository: favonia/cloudflare-ddns
Pull request #768 (2024-06-25 02:39:07)

feat(notifier): actually send messages (part 4 of shoutrrr support)

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) Report
Attention: Patch coverage is `29.41176%` with `12 lines` in your changes missing coverage. Please review.
> Project coverage is 90.52%. Comparing base [(`49cfd68`)](https://app.codecov.io/gh/favonia/cloudflare-ddns/commit/49cfd6845e4270c95330389ca7e0ed872f8f91fd?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) to head [(`1c7f2bc`)](https://app.codecov.io/gh/favonia/cloudflare-ddns/commit/1c7f2bcd86bec23d9addf474614b326bba6e0164?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia).

| [Files](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) | Patch % | Lines |
|---|---|---|
| [internal/notifier/composite.go](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768?src=pr&el=tree&filepath=internal%2Fnotifier%2Fcomposite.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia#diff-aW50ZXJuYWwvbm90aWZpZXIvY29tcG9zaXRlLmdv) | 14.28% | [6 Missing :warning: ](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) |
| [cmd/ddns/ddns.go](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768?src=pr&el=tree&filepath=cmd%2Fddns%2Fddns.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia#diff-Y21kL2RkbnMvZGRucy5nbw==) | 0.00% | [4 Missing :warning: ](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) |
| [internal/notifier/base.go](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768?src=pr&el=tree&filepath=internal%2Fnotifier%2Fbase.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia#diff-aW50ZXJuYWwvbm90aWZpZXIvYmFzZS5nbw==) | 0.00% | [2 Missing :warning: ](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #768      +/-   ##
==========================================
- Coverage   90.95%   90.52%   -0.43%     
==========================================
  Files          51       52       +1     
  Lines        2112     2122      +10     
==========================================
  Hits         1921     1921              
- Misses        180      190      +10     
  Partials       11       11              
```

| [Flag](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) | Coverage Δ | |
|---|---|---|
| [unittests](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia) | `90.52% <29.41%> (-0.43%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/favonia/cloudflare-ddns/pull/768?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=favonia).


Patch:
diff --git a/cmd/ddns/ddns.go b/cmd/ddns/ddns.go
index f86d13d..aca8f6b 100644
--- a/cmd/ddns/ddns.go
+++ b/cmd/ddns/ddns.go
@@ -10,6 +10,7 @@ import (
 	"github.com/favonia/cloudflare-ddns/internal/cron"
 	"github.com/favonia/cloudflare-ddns/internal/droproot"
 	"github.com/favonia/cloudflare-ddns/internal/monitor"
+	"github.com/favonia/cloudflare-ddns/internal/notifier"
 	"github.com/favonia/cloudflare-ddns/internal/pp"
 	"github.com/favonia/cloudflare-ddns/internal/setter"
 	"github.com/favonia/cloudflare-ddns/internal/signal"
@@ -56,7 +57,8 @@ func initConfig(ctx context.Context, ppfmt pp.PP) (*config.Config, setter.Setter
 func stopUpdating(ctx context.Context, ppfmt pp.PP, c *config.Config, s setter.Setter) {
 	if c.DeleteOnStop {
 		resp := updater.DeleteIPs(ctx, ppfmt, c, s)
-		monitor.SendAll(ctx, ppfmt, c.Monitors, resp)
+		monitor.SendResponseAll(ctx, ppfmt, c.Monitors, resp)
+		notifier.SendResponseAll(ctx, ppfmt, c.Notifiers, resp)
 	}
 }
 
@@ -121,7 +123,8 @@ func realMain() int { //nolint:funlen
 			monitor.SuccessAll(ctx, ppfmt, c.Monitors, "Started (no action)")
 		} else {
 			resp := updater.UpdateIPs(ctxWithSignals, ppfmt, c, s)
-			monitor.SendAll(ctx, ppfmt, c.Monitors, resp)
+			monitor.SendResponseAll(ctx, ppfmt, c.Monitors, resp)
+			notifier.SendResponseAll(ctx, ppfmt, c.Notifiers, resp)
 		}
 
 		// Check if cron was disabled
diff --git a/internal/monitor/base.go b/internal/monitor/base.go
index 613e143..d18b3ba 100644
--- a/internal/monitor/base.go
+++ b/internal/monitor/base.go
@@ -36,7 +36,7 @@ type Monitor interface {
 	ExitStatus(ctx context.Context, ppfmt pp.PP, code int, message string) bool
 }
 
-func Send(ctx context.Context, ppfmt pp.PP, m Monitor, r response.Response) bool {
+func SendResponse(ctx context.Context, ppfmt pp.PP, m Monitor, r response.Response) bool {
 	msg := strings.Join(r.MonitorMessages, "\n")
 	if r.Ok {
 		return m.Log(ctx, ppfmt, msg)
diff --git a/internal/monitor/composite.go b/internal/monitor/composite.go
index 76ef212..382ee5c 100644
--- a/internal/monitor/composite.go
+++ b/internal/monitor/composite.go
@@ -69,11 +69,11 @@ func ExitStatusAll(ctx context.Context, ppfmt pp.PP, ms []Monitor, code int, mes
 	return ok
 }
 
-// SendAll calls [Send] for each monitor in ms.
-func SendAll(ctx context.Context, ppfmt pp.PP, ms []Monitor, resp response.Response) bool {
+// SendResponseAll calls [SendResponse] for each monitor in ms.
+func SendResponseAll(ctx context.Context, ppfmt pp.PP, ms []Monitor, resp response.Response) bool {
 	ok := true
 	for _, m := range ms {
-		if !Send(ctx, ppfmt, m, resp) {
+		if !SendResponse(ctx, ppfmt, m, resp) {
 			ok = false
 		}
 	}
diff --git a/internal/notifier/base.go b/internal/notifier/base.go
index abc4d3b..401560a 100644
--- a/internal/notifier/base.go
+++ b/internal/notifier/base.go
@@ -3,8 +3,10 @@ package notifier
 
 import (
 	"context"
+	"strings"
 
 	"github.com/favonia/cloudflare-ddns/internal/pp"
+	"github.com/favonia/cloudflare-ddns/internal/response"
 )
 
 //go:generate mockgen -typed -destination=../mocks/mock_notifier.go -package=mocks . Notifier
@@ -17,3 +19,7 @@ type Notifier interface {
 	// Send out a message.
 	Send(ctx context.Context, ppfmt pp.PP, msg string) bool
 }
+
+func SendResponse(ctx context.Context, ppfmt pp.PP, n Notifier, r response.Response) bool {
+	return n.Send(ctx, ppfmt, strings.Join(r.NotifierMessages, " "))
+}
diff --git a/internal/notifier/composite.go b/internal/notifier/composite.go
index 0eb7f6f..8e71d20 100644
--- a/internal/notifier/composite.go
+++ b/internal/notifier/composite.go
@@ -4,6 +4,7 @@ import (
 	"context"
 
 	"github.com/favonia/cloudflare-ddns/internal/pp"
+	"github.com/favonia/cloudflare-ddns/internal/response"
 )
 
 // DescribeAll calls [Notifier.Describe] for each monitor in the group with the callback.
@@ -13,8 +14,8 @@ func DescribeAll(callback func(service, params string), ns []Notifier) {
 	}
 }
 
-// SendAll calls [Notifier.Success] for each monitor in the group.
-func SendAll(ctx context.Context, ppfmt pp.PP, message string, ns []Notifier) bool {
+// SendAll calls [Notifier.Send] for each monitor in the group.
+func SendAll(ctx context.Context, ppfmt pp.PP, ns []Notifier, message string) bool {
 	ok := true
 	for _, n := range ns {
 		if !n.Send(ctx, ppfmt, message) {
@@ -23,3 +24,14 @@ func SendAll(ctx context.Context, ppfmt pp.PP, message string, ns []Notifier) bo
 	}
 	return ok
 }
+
+// SendResponseAll calls [SendResponse] for each monitor in the group.
+func SendResponseAll(ctx context.Context, ppfmt pp.PP, ns []Notifier, r response.Response) bool {
+	ok := true
+	for _, n := range ns {
+		if !SendResponse(ctx, ppfmt, n, r) {
+			ok = false
+		}
+	}
+	return ok
+}
diff --git a/internal/updater/updater.go b/internal/updater/updater.go
index 4398702..6ab7103 100644
--- a/internal/updater/updater.go
+++ b/internal/updater/updater.go
@@ -64,7 +64,7 @@ func setIP(ctx context.Context, ppfmt pp.PP,
 		if resp == setter.ResponseFailed {
 			if ShouldDisplayHints["update-timeout"] && errors.Is(context.Cause(ctx), errSettingTimeout) {
 				ppfmt.Infof(pp.EmojiHint,
-					"If your network is working but with high latency, consider increasing the value of UPDATE_TIMEOUT",
+					"If your network is experiencing high latency, consider increasing the value of UPDATE_TIMEOUT",
 				)
 				ShouldDisplayHints["update-timeout"] = false
 			}


Test patch:
diff --git a/internal/monitor/composite_test.go b/internal/monitor/composite_test.go
index 50bd690..a71a850 100644
--- a/internal/monitor/composite_test.go
+++ b/internal/monitor/composite_test.go
@@ -124,7 +124,7 @@ func TestExitStatusAll(t *testing.T) {
 	monitor.ExitStatusAll(context.Background(), mockPP, ms, 42, message)
 }
 
-func TestSendAll(t *testing.T) {
+func TestSendResponseAll(t *testing.T) {
 	t.Parallel()
 
 	monitorMessages := []string{"forest", "grass"}
@@ -159,7 +159,7 @@ func TestSendAll(t *testing.T) {
 				MonitorMessages:  monitorMessages,
 				NotifierMessages: notifierMessages,
 			}
-			monitor.SendAll(context.Background(), mockPP, ms, resp)
+			monitor.SendResponseAll(context.Background(), mockPP, ms, resp)
 		})
 	}
 }
diff --git a/internal/notifier/composite_test.go b/internal/notifier/composite_test.go
index 7bbf662..3b6fb07 100644
--- a/internal/notifier/composite_test.go
+++ b/internal/notifier/composite_test.go
@@ -2,12 +2,14 @@ package notifier_test
 
 import (
 	"context"
+	"strings"
 	"testing"
 
 	"go.uber.org/mock/gomock"
 
 	"github.com/favonia/cloudflare-ddns/internal/mocks"
 	"github.com/favonia/cloudflare-ddns/internal/notifier"
+	"github.com/favonia/cloudflare-ddns/internal/response"
 )
 
 func TestDescribeAll(t *testing.T) {
@@ -43,5 +45,41 @@ func TestSendAll(t *testing.T) {
 		ms = append(ms, m)
 	}
 
-	notifier.SendAll(context.Background(), mockPP, message, ms)
+	notifier.SendAll(context.Background(), mockPP, ms, message)
+}
+
+func TestSendResponseAll(t *testing.T) {
+	t.Parallel()
+
+	monitorMessages := []string{"forest", "grass"}
+	notifierMessages := []string{"ocean", "moon"}
+	notifierMessage := strings.Join(notifierMessages, " ")
+
+	for name, tc := range map[string]struct {
+		ok bool
+	}{
+		"ok":    {true},
+		"notok": {false},
+	} {
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			ns := make([]notifier.Notifier, 0, 5)
+			mockCtrl := gomock.NewController(t)
+			mockPP := mocks.NewMockPP(mockCtrl)
+
+			for range 5 {
+				n := mocks.NewMockNotifier(mockCtrl)
+				n.EXPECT().Send(context.Background(), mockPP, notifierMessage)
+				ns = append(ns, n)
+			}
+
+			resp := response.Response{
+				Ok:               tc.ok,
+				MonitorMessages:  monitorMessages,
+				NotifierMessages: notifierMessages,
+			}
+			notifier.SendResponseAll(context.Background(), mockPP, ns, resp)
+		})
+	}
 }
diff --git a/internal/updater/updater_test.go b/internal/updater/updater_test.go
index 3b4ca9d..c3377d6 100644
--- a/internal/updater/updater_test.go
+++ b/internal/updater/updater_test.go
@@ -598,7 +598,7 @@ func TestUpdateIPs(t *testing.T) {
 			func(m *mocks.MockPP) {
 				gomock.InOrder(
 					m.EXPECT().Infof(pp.EmojiInternet, "Detected the %s address: %v", "IPv4", ip4),
-					m.EXPECT().Infof(pp.EmojiHint, "If your network is working but with high latency, consider increasing the value of UPDATE_TIMEOUT"), //nolint:lll
+					m.EXPECT().Infof(pp.EmojiHint, "If your network is experiencing high latency, consider increasing the value of UPDATE_TIMEOUT"), //nolint:lll
 				)
 			},
 			mockproviders{