@@ -301,6 +301,9 @@ func TestHandleWebhookWithContainer_MergedPR(t *testing.T) {
301301 Number : github .Int (123 ),
302302 Merged : github .Bool (true ),
303303 MergeCommitSHA : github .String ("abc123" ),
304+ Base : & github.PullRequestBranch {
305+ Ref : github .String ("main" ),
306+ },
304307 },
305308 Repo : & github.Repository {
306309 Name : github .String ("test-repo" ),
@@ -334,6 +337,186 @@ func TestHandleWebhookWithContainer_MergedPR(t *testing.T) {
334337 // when trying to access GitHub APIs. This is expected and doesn't affect the test result.
335338}
336339
340+ func TestHandleWebhookWithContainer_MergedPRToDevelopmentBranch (t * testing.T ) {
341+ // This test verifies that PRs merged to non-main branches (like development)
342+ // are accepted by the webhook handler but won't match any workflows
343+ // (assuming workflows are configured for main branch only)
344+
345+ // Set up environment variables
346+ os .Setenv (configs .AppId , "123456" )
347+ os .Setenv (configs .InstallationId , "789012" )
348+ os .Setenv (configs .ConfigRepoOwner , "test-owner" )
349+ os .Setenv (configs .ConfigRepoName , "test-repo" )
350+ os .Setenv ("SKIP_SECRET_MANAGER" , "true" )
351+
352+ // Generate a valid RSA private key for testing
353+ key , _ := rsa .GenerateKey (rand .Reader , 1024 )
354+ der := x509 .MarshalPKCS1PrivateKey (key )
355+ pemBytes := pem .EncodeToMemory (& pem.Block {Type : "RSA PRIVATE KEY" , Bytes : der })
356+ os .Setenv ("GITHUB_APP_PRIVATE_KEY" , string (pemBytes ))
357+ os .Setenv ("GITHUB_APP_PRIVATE_KEY_B64" , base64 .StdEncoding .EncodeToString (pemBytes ))
358+
359+ InstallationAccessToken = "test-token"
360+
361+ config := & configs.Config {
362+ ConfigRepoOwner : "test-owner" ,
363+ ConfigRepoName : "test-repo" ,
364+ ConfigFile : "nonexistent-config.yaml" ,
365+ AuditEnabled : false ,
366+ }
367+
368+ container , err := NewServiceContainer (config )
369+ if err != nil {
370+ t .Fatalf ("NewServiceContainer() error = %v" , err )
371+ }
372+
373+ // Create a merged PR event to development branch
374+ prEvent := & github.PullRequestEvent {
375+ Action : github .String ("closed" ),
376+ PullRequest : & github.PullRequest {
377+ Number : github .Int (456 ),
378+ Merged : github .Bool (true ),
379+ MergeCommitSHA : github .String ("def456" ),
380+ Base : & github.PullRequestBranch {
381+ Ref : github .String ("development" ),
382+ },
383+ },
384+ Repo : & github.Repository {
385+ Name : github .String ("test-repo" ),
386+ Owner : & github.User {
387+ Login : github .String ("test-owner" ),
388+ },
389+ },
390+ }
391+ payload , _ := json .Marshal (prEvent )
392+
393+ req := httptest .NewRequest ("POST" , "/webhook" , bytes .NewReader (payload ))
394+ req .Header .Set ("X-GitHub-Event" , "pull_request" )
395+
396+ w := httptest .NewRecorder ()
397+
398+ HandleWebhookWithContainer (w , req , config , container )
399+
400+ // Should still return 202 Accepted (webhook accepts the event)
401+ if w .Code != http .StatusAccepted {
402+ t .Errorf ("Status code = %d, want %d" , w .Code , http .StatusAccepted )
403+ }
404+
405+ // Check response body
406+ var response map [string ]string
407+ json .Unmarshal (w .Body .Bytes (), & response )
408+ if response ["status" ] != "accepted" {
409+ t .Errorf ("Response status = %v, want accepted" , response ["status" ])
410+ }
411+
412+ // Note: The background goroutine will fail to find matching workflows
413+ // because the workflow config specifies main branch, not development.
414+ // This is the expected behavior - the webhook accepts the event but
415+ // no workflows will be processed.
416+ }
417+
418+ func TestHandleWebhookWithContainer_MergedPRWithDifferentBranches (t * testing.T ) {
419+ // This test verifies that the base branch is correctly extracted
420+ // from different PR events
421+
422+ testCases := []struct {
423+ name string
424+ baseBranch string
425+ prNumber int
426+ }{
427+ {
428+ name : "main branch" ,
429+ baseBranch : "main" ,
430+ prNumber : 100 ,
431+ },
432+ {
433+ name : "development branch" ,
434+ baseBranch : "development" ,
435+ prNumber : 101 ,
436+ },
437+ {
438+ name : "feature branch" ,
439+ baseBranch : "feature/new-feature" ,
440+ prNumber : 102 ,
441+ },
442+ {
443+ name : "release branch" ,
444+ baseBranch : "release/v1.0" ,
445+ prNumber : 103 ,
446+ },
447+ }
448+
449+ // Set up environment variables
450+ os .Setenv (configs .AppId , "123456" )
451+ os .Setenv (configs .InstallationId , "789012" )
452+ os .Setenv (configs .ConfigRepoOwner , "test-owner" )
453+ os .Setenv (configs .ConfigRepoName , "test-repo" )
454+ os .Setenv ("SKIP_SECRET_MANAGER" , "true" )
455+
456+ key , _ := rsa .GenerateKey (rand .Reader , 1024 )
457+ der := x509 .MarshalPKCS1PrivateKey (key )
458+ pemBytes := pem .EncodeToMemory (& pem.Block {Type : "RSA PRIVATE KEY" , Bytes : der })
459+ os .Setenv ("GITHUB_APP_PRIVATE_KEY" , string (pemBytes ))
460+ os .Setenv ("GITHUB_APP_PRIVATE_KEY_B64" , base64 .StdEncoding .EncodeToString (pemBytes ))
461+
462+ InstallationAccessToken = "test-token"
463+
464+ for _ , tc := range testCases {
465+ t .Run (tc .name , func (t * testing.T ) {
466+ config := & configs.Config {
467+ ConfigRepoOwner : "test-owner" ,
468+ ConfigRepoName : "test-repo" ,
469+ ConfigFile : "nonexistent-config.yaml" ,
470+ AuditEnabled : false ,
471+ }
472+
473+ container , err := NewServiceContainer (config )
474+ if err != nil {
475+ t .Fatalf ("NewServiceContainer() error = %v" , err )
476+ }
477+
478+ // Create a merged PR event with specific base branch
479+ prEvent := & github.PullRequestEvent {
480+ Action : github .String ("closed" ),
481+ PullRequest : & github.PullRequest {
482+ Number : github .Int (tc .prNumber ),
483+ Merged : github .Bool (true ),
484+ MergeCommitSHA : github .String ("abc123" ),
485+ Base : & github.PullRequestBranch {
486+ Ref : github .String (tc .baseBranch ),
487+ },
488+ },
489+ Repo : & github.Repository {
490+ Name : github .String ("test-repo" ),
491+ Owner : & github.User {
492+ Login : github .String ("test-owner" ),
493+ },
494+ },
495+ }
496+ payload , _ := json .Marshal (prEvent )
497+
498+ req := httptest .NewRequest ("POST" , "/webhook" , bytes .NewReader (payload ))
499+ req .Header .Set ("X-GitHub-Event" , "pull_request" )
500+
501+ w := httptest .NewRecorder ()
502+
503+ HandleWebhookWithContainer (w , req , config , container )
504+
505+ // Should return 202 Accepted for all merged PRs
506+ if w .Code != http .StatusAccepted {
507+ t .Errorf ("Status code = %d, want %d" , w .Code , http .StatusAccepted )
508+ }
509+
510+ // Check response body
511+ var response map [string ]string
512+ json .Unmarshal (w .Body .Bytes (), & response )
513+ if response ["status" ] != "accepted" {
514+ t .Errorf ("Response status = %v, want accepted" , response ["status" ])
515+ }
516+ })
517+ }
518+ }
519+
337520func TestRetrieveFileContentsWithConfigAndBranch (t * testing.T ) {
338521 // This test would require mocking the GitHub client
339522 // For now, we document the expected behavior
0 commit comments