@@ -318,6 +318,107 @@ func Test_getPostMessage(t *testing.T) {
318318 // This ensures the function executes and returns the expected slice structure
319319}
320320
321+ // fakeSlackAPI is a test double for the slackAPI interface.
322+ type fakeSlackAPI struct {
323+ capturedChannelID string
324+ capturedOptions []slack.MsgOption
325+ err error
326+ }
327+
328+ func (f * fakeSlackAPI ) PostMessage (channelID string , options ... slack.MsgOption ) (string , string , error ) {
329+ f .capturedChannelID = channelID
330+ f .capturedOptions = options
331+ return "" , "" , f .err
332+ }
333+
334+ func Test_productionSlackClientWorker_postChannelMessage (t * testing.T ) {
335+ t .Run ("calls PostMessage with correct channelID and non-empty options" , func (t * testing.T ) {
336+ fakeAPI := & fakeSlackAPI {}
337+ worker := & productionSlackClientWorker {
338+ apiFactory : func (token string ) slackAPI { return fakeAPI },
339+ }
340+ buildInfo := BuildInfo {
341+ JobName : "test-job" ,
342+ BuildURL : "https://example.com" ,
343+ BuildStatus : successKey ,
344+ OauthToken : "token" ,
345+ DestChannelId : "C12345" ,
346+ }
347+ err := worker .postChannelMessage (buildInfo )
348+ if err != nil {
349+ t .Errorf ("unexpected error: %v" , err )
350+ }
351+ if fakeAPI .capturedChannelID != "C12345" {
352+ t .Errorf ("expected channelID %q, got %q" , "C12345" , fakeAPI .capturedChannelID )
353+ }
354+ if len (fakeAPI .capturedOptions ) == 0 {
355+ t .Error ("expected non-empty message options" )
356+ }
357+ })
358+
359+ t .Run ("propagates error from PostMessage" , func (t * testing.T ) {
360+ fakeAPI := & fakeSlackAPI {err : fmt .Errorf ("api error" )}
361+ worker := & productionSlackClientWorker {
362+ apiFactory : func (token string ) slackAPI { return fakeAPI },
363+ }
364+ buildInfo := BuildInfo {
365+ OauthToken : "token" ,
366+ DestChannelId : "C12345" ,
367+ BuildStatus : successKey ,
368+ }
369+ err := worker .postChannelMessage (buildInfo )
370+ if err == nil || err .Error () != "api error" {
371+ t .Errorf ("expected 'api error', got %v" , err )
372+ }
373+ })
374+ }
375+
376+ func Test_productionSlackClientWorker_postWebhookMessage (t * testing.T ) {
377+ t .Run ("calls webhookPoster with correct URL and non-nil message" , func (t * testing.T ) {
378+ var capturedURL string
379+ var capturedMsg * slack.WebhookMessage
380+ worker := & productionSlackClientWorker {
381+ webhookPoster : func (url string , msg * slack.WebhookMessage ) error {
382+ capturedURL = url
383+ capturedMsg = msg
384+ return nil
385+ },
386+ }
387+ buildInfo := BuildInfo {
388+ JobName : "test-job" ,
389+ BuildURL : "https://example.com" ,
390+ BuildStatus : successKey ,
391+ HookURL : "https://hooks.slack.com/test" ,
392+ }
393+ err := worker .postWebhookMessage (buildInfo )
394+ if err != nil {
395+ t .Errorf ("unexpected error: %v" , err )
396+ }
397+ if capturedURL != "https://hooks.slack.com/test" {
398+ t .Errorf ("expected URL %q, got %q" , "https://hooks.slack.com/test" , capturedURL )
399+ }
400+ if capturedMsg == nil {
401+ t .Error ("expected non-nil webhook message" )
402+ }
403+ })
404+
405+ t .Run ("propagates error from webhookPoster" , func (t * testing.T ) {
406+ worker := & productionSlackClientWorker {
407+ webhookPoster : func (url string , msg * slack.WebhookMessage ) error {
408+ return fmt .Errorf ("webhook error" )
409+ },
410+ }
411+ buildInfo := BuildInfo {
412+ HookURL : "https://hooks.slack.com/test" ,
413+ BuildStatus : successKey ,
414+ }
415+ err := worker .postWebhookMessage (buildInfo )
416+ if err == nil || err .Error () != "webhook error" {
417+ t .Errorf ("expected 'webhook error', got %v" , err )
418+ }
419+ })
420+ }
421+
321422func Test_NewSlackClient (t * testing.T ) {
322423 client := NewSlackClient ()
323424 if client .slackClient == nil {
@@ -385,6 +486,31 @@ func Test_PostToSlack_EdgeCases(t *testing.T) {
385486 true ,
386487 PickRunModeErrorMessage ,
387488 },
489+ {
490+ "channel message client returns error - PostToSlack propagates it" ,
491+ BuildInfo {
492+ JobName : "job" ,
493+ BuildURL : "url" ,
494+ BuildStatus : "SUCCESS" ,
495+ OauthToken : "token" ,
496+ DestChannelId : "channel" ,
497+ },
498+ NewTestClient (true , false ),
499+ true ,
500+ ChannelMessageTestErr ,
501+ },
502+ {
503+ "webhook client returns error - PostToSlack propagates it" ,
504+ BuildInfo {
505+ JobName : "job" ,
506+ BuildURL : "url" ,
507+ BuildStatus : "SUCCESS" ,
508+ HookURL : "https://hooks.slack.com/test" ,
509+ },
510+ NewTestClient (false , true ),
511+ true ,
512+ WebhookMessageTestErr ,
513+ },
388514 }
389515 for _ , tt := range tests {
390516 t .Run (tt .name , func (t * testing.T ) {
0 commit comments