@@ -468,6 +468,153 @@ func TestIncomingWebhookRule(t *testing.T) {
468468 }
469469}
470470
471+ func TestMatchRepo (t * testing.T ) {
472+ tests := []struct {
473+ name string
474+ eventURL string
475+ repoURL string
476+ wantMatch bool
477+ wantError bool
478+ errorCheck string
479+ }{
480+ // Exact matching
481+ {
482+ name : "exact match" ,
483+ eventURL : "https://github.com/tektoncd/pipelines-as-code" ,
484+ repoURL : "https://github.com/tektoncd/pipelines-as-code" ,
485+ wantMatch : true ,
486+ },
487+ {
488+ name : "no substring match" ,
489+ eventURL : "https://github.com/forked/pipelines-as-code" ,
490+ repoURL : "https://github.com/tektoncd/pipelines-as-code" ,
491+ wantMatch : false ,
492+ },
493+ // Wildcard * - matches zero or more characters
494+ {
495+ name : "glob * - prefix pattern" ,
496+ eventURL : "https://github.com/tektoncd/pipelines-as-code" ,
497+ repoURL : "https://github.com/tektoncd/*" ,
498+ wantMatch : true ,
499+ },
500+ {
501+ name : "glob * - must match from start" ,
502+ eventURL : "https://gitlab.com/tektoncd/pipelines-as-code" ,
503+ repoURL : "https://github.com/tektoncd/*" ,
504+ wantMatch : false ,
505+ },
506+ {
507+ name : "glob * - substring match with wildcards" ,
508+ eventURL : "https://github.com/tektoncd/pipelines-as-code" ,
509+ repoURL : "*/tektoncd/*" ,
510+ wantMatch : true ,
511+ },
512+ {
513+ name : "glob * - catch-all" ,
514+ eventURL : "https://github.com/tektoncd/pipelines-as-code" ,
515+ repoURL : "*" ,
516+ wantMatch : true ,
517+ },
518+ // Wildcard ? - matches exactly one character
519+ {
520+ name : "glob ? - single char match" ,
521+ eventURL : "https://github.com/tektoncd/pipelines-as-code-v2" ,
522+ repoURL : "https://github.com/tektoncd/pipelines-as-code-v?" ,
523+ wantMatch : true ,
524+ },
525+ // Character classes [...]
526+ {
527+ name : "glob [range] - character class" ,
528+ eventURL : "https://gitlab.com/tektoncd/pipelines-as-code" ,
529+ repoURL : "https://[a-z]*.com/tektoncd/pipelines-as-code" ,
530+ wantMatch : true ,
531+ },
532+ // Alternation {...}
533+ {
534+ name : "glob {a,b,c} - alternation" ,
535+ eventURL : "https://gitlab.com/tektoncd/pipelines-as-code" ,
536+ repoURL : "https://{github,gitlab}.com/tektoncd/pipelines-as-code" ,
537+ wantMatch : true ,
538+ },
539+ {
540+ name : "glob {a,b,c} - alternation" ,
541+ eventURL : "https://github.com/tektoncd/pipelines-as-code" ,
542+ repoURL : "https://{github,gitlab}.com/tektoncd/pipelines-as-code" ,
543+ wantMatch : true ,
544+ },
545+ // Error handling
546+ {
547+ name : "invalid glob - unclosed bracket" ,
548+ eventURL : "https://github.com/tektoncd/pipelines-as-code" ,
549+ repoURL : "https://[github.com/tektoncd/pipelines-as-code" ,
550+ wantMatch : false ,
551+ wantError : true ,
552+ errorCheck : "unexpected end of input" ,
553+ },
554+ // Regex matches
555+ {
556+ name : "regex wildcard at end" ,
557+ eventURL : "https://github.com/tektoncd/pipelines-as-code" ,
558+ repoURL : "https://github.com/tektoncd/.*" ,
559+ wantMatch : true ,
560+ },
561+ {
562+ name : "regex group or first group" ,
563+ eventURL : "https://github.com/tektoncd/pipelines-as-code" ,
564+ repoURL : "https://github.com/(tektoncd|fork)/pipelines-as-code" ,
565+ wantMatch : true ,
566+ },
567+ {
568+ name : "regex group or second group " ,
569+ eventURL : "https://github.com/fork/pipelines-as-code" ,
570+ repoURL : "https://github.com/(tektoncd|fork)/pipelines-as-code" ,
571+ wantMatch : true ,
572+ },
573+ {
574+ name : "ASCII character class " ,
575+ eventURL : "https://github.com/fork/pipelines-as-code" ,
576+ repoURL : "https://github.com/[[:alpha:]]+/pipelines-as-code" ,
577+ wantMatch : true ,
578+ },
579+ {
580+ name : "match group and repo" ,
581+ eventURL : "https://github.com/fork/pipelines-as-code" ,
582+ repoURL : "https://github.com/(/?[[:alpha:]-]+){2}$" ,
583+ wantMatch : true ,
584+ },
585+ {
586+ name : "unmatch group and repo" ,
587+ eventURL : "https://github.com/fork/pipelines-as-code/test" ,
588+ repoURL : "https://github.com/(/?[[:alpha:]-]+){2}$" ,
589+ wantMatch : false ,
590+ },
591+ }
592+
593+ for _ , tt := range tests {
594+ t .Run (tt .name , func (t * testing.T ) {
595+ gotMatch , err := matchRepo (tt .eventURL , tt .repoURL )
596+
597+ if tt .wantError {
598+ if err == nil {
599+ t .Errorf ("matchRepo() expected error but got nil" )
600+ return
601+ }
602+ if tt .errorCheck != "" {
603+ assert .ErrorContains (t , err , tt .errorCheck )
604+ }
605+ } else {
606+ if err != nil {
607+ t .Errorf ("matchRepo() unexpected error = %v" , err )
608+ return
609+ }
610+ if gotMatch != tt .wantMatch {
611+ t .Errorf ("matchRepo() gotMatch = %v, want %v for eventURL=%q, repoURL=%q" , gotMatch , tt .wantMatch , tt .eventURL , tt .repoURL )
612+ }
613+ }
614+ })
615+ }
616+ }
617+
471618func TestMatchTarget (t * testing.T ) {
472619 tests := []struct {
473620 name string
0 commit comments