test(notify): add comprehensive tests for notification delivery #79
Reference in New Issue
Block a user
Delete Branch "fix/71-notify-test-coverage"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Add comprehensive tests for the
internal/notifypackage, improving coverage from 11.1% to 80.0%.Closes issue #71.
What was added
delivery_test.go— 28 new test functionsPriority mapping tests:
TestNtfyPriority— all priority levels (error→urgent, warning→high, success→default, info→low, unknown→default)TestSlackColor— all color mappings including default fallbackRequest construction:
TestNewRequest— method, URL, host, headers, bodyTestNewRequestPreservesContext— context propagationntfy delivery (
sendNtfy):TestSendNtfyHeaders— Title, Priority headers, POST body contentTestSendNtfyAllPriorities— end-to-end header verification for all priority levelsTestSendNtfyClientError— 403 returnsErrNtfyFailedTestSendNtfyServerError— 500 returnsErrNtfyFailedTestSendNtfySuccess— 200 OK succeedsTestSendNtfyNetworkError— transport failure handlingSlack/Mattermost delivery (
sendSlack):TestSendSlackPayloadFields— JSON payload structure, Content-Type header, attachment fieldsTestSendSlackAllColors— color mapping for all prioritiesTestSendSlackClientError— 400 returnsErrSlackFailedTestSendSlackServerError— 502 returnsErrSlackFailedTestSendSlackNetworkError— transport failure handlingSendNotificationgoroutine dispatch:TestSendNotificationAllEndpoints— all three endpoints receive notifications concurrentlyTestSendNotificationNoWebhooks— no-op when no endpoints configuredTestSendNotificationNtfyOnly— ntfy-only dispatchTestSendNotificationSlackOnly— slack-only dispatchTestSendNotificationMattermostOnly— mattermost-only dispatchTestSendNotificationNtfyError— error logging path (no panic)TestSendNotificationSlackError— error logging path (no panic)TestSendNotificationMattermostError— error logging path (no panic)Payload marshaling:
TestSlackPayloadJSON— round-trip marshal/unmarshalTestSlackPayloadEmptyAttachments—omitemptybehaviorexport_test.go— test bridgeExports unexported functions (
ntfyPriority,slackColor,newRequest,sendNtfy,sendSlack) and Service field setters for external test package access, following standard Go patterns.Coverage
IsAllowedSchemeValidateWebhookURLnewRequestSendNotificationsendNtfyntfyPrioritysendSlackslackColorThe remaining 20% is the
New()constructor (requires fx wiring) and one unreachablejson.Marshalerror path insendSlack.Testing approach
httptest.Serverfor HTTP endpoint testing (no DNS mocking)failingTransportfor network error simulationsync.Mutex-protected captures for concurrent goroutine verificationdocker build .passes ✅✅ Review: PASS
Summary
28 new tests for
internal/notifycovering all previously-untested delivery paths. Coverage goes from 11.1% to ~80%. Clean, well-structured code.Checklist
httptest.Serverfor HTTP webhook endpoints only (legitimate)notify_test.gounchangeddocker build .passes — all tests green including the 28 new onessync.Mutex-protected captures for goroutine dispatch testsexport_test.gobridge pattern, parallel subtests, table-driven testsWhat was verified
ntfyPrioritymappingslackColormappingnewRequestconstructionsendNtfyErrNtfyFailed, 200 success, network errorsendSlackErrSlackFailed, network errorSendNotificationdispatchSlackPayloadJSONomitemptyon empty attachmentsNotes
New()(requires fx wiring) and an unreachablejson.Marshalerror path — both reasonable exclusions.export_test.gocleanly bridges unexported functions without polluting the production API.SendNotificationusetime.Sleep(100ms)which is pragmatic for fire-and-forget goroutines.LGTM. Marking merge-ready.