From 44cfe72bbcc442f93e50f6f1f66733c58b1319bf Mon Sep 17 00:00:00 2001 From: clawbot <35+clawbot@noreply.example.org> Date: Fri, 2 Oct 2026 20:47:06 +0000 Subject: [PATCH] Show a slack target's retry setting in the target list (closes #395) The target list showed only the masked webhook URL for a slack target, though its edit page saves a retry setting and delivery honours it. It now shows the same retry fields, with the same labels and wording, as an http target. Model: opus-5-5 --- internal/delivery/target_config_view.go | 15 +++++---- internal/delivery/target_config_view_test.go | 32 ++++++++++++++++++-- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/internal/delivery/target_config_view.go b/internal/delivery/target_config_view.go index fc09a40..f8e3aa1 100644 --- a/internal/delivery/target_config_view.go +++ b/internal/delivery/target_config_view.go @@ -97,7 +97,7 @@ func targetConfigFields( ) []ConfigField { switch t.Type { case database.TargetTypeSlack: - return slackConfigFields(t.Config) + return slackConfigFields(t) case database.TargetTypeHTTP: return httpConfigFields(t) case database.TargetTypeDatabase: @@ -119,18 +119,21 @@ func unavailableConfigFields() []ConfigField { }} } -// slackConfigFields describes a Slack target. Only the masked -// webhook URL is shown; the full URL is the credential. -func slackConfigFields(configJSON string) []ConfigField { - cfg, err := parseSlackConfig(configJSON) +// slackConfigFields describes a Slack target: its masked +// webhook URL and its retry settings. Only the masked URL is +// shown; the full URL is the credential. +func slackConfigFields(t *database.Target) []ConfigField { + cfg, err := parseSlackConfig(t.Config) if err != nil { return unavailableConfigFields() } - return []ConfigField{{ + fields := []ConfigField{{ Label: "Webhook URL", Value: cfg.MaskedWebhookURL(), }} + + return append(fields, retryFields(t)...) } // httpConfigFields describes an HTTP target: its destination diff --git a/internal/delivery/target_config_view_test.go b/internal/delivery/target_config_view_test.go index 41211fa..0c22950 100644 --- a/internal/delivery/target_config_view_test.go +++ b/internal/delivery/target_config_view_test.go @@ -158,7 +158,10 @@ func TestNewTargetViews_DeletedTarget(t *testing.T) { ) assert.Equal( t, - map[string]string{"Webhook URL": slackMaskedURL}, + map[string]string{ + "Webhook URL": slackMaskedURL, + "Max Retries": "0 (fire-and-forget)", + }, fieldMap(view.Config), ) } @@ -189,7 +192,32 @@ func TestNewTargetViews_Slack(t *testing.T) { assert.Equal( t, - map[string]string{"Webhook URL": slackMaskedURL}, + map[string]string{ + "Webhook URL": slackMaskedURL, + "Max Retries": "0 (fire-and-forget)", + }, + fieldMap(view.Config), + ) +} + +// TestNewTargetViews_SlackRetries proves a Slack target shows +// its retry settings the same way an HTTP target does. +func TestNewTargetViews_SlackRetries(t *testing.T) { + t.Parallel() + + target := slackTarget() + target.MaxRetries = 2 + target.MaxQueueSize = 100 + + view := viewFor(t, target) + + assert.Equal( + t, + map[string]string{ + "Webhook URL": slackMaskedURL, + "Max Retries": "2", + "Max Queue Size": "100", + }, fieldMap(view.Config), ) }