github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/github/ghmetrics/ghpath_test.go (about)

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package ghmetrics
    18  
    19  import "testing"
    20  
    21  func Test_GetSimplifiedPath(t *testing.T) {
    22  	type args struct {
    23  		path string
    24  	}
    25  	tests := []struct {
    26  		name string
    27  		args args
    28  		want string
    29  	}{
    30  		{name: "path not in tree", args: args{path: "/this/path/is/not/in/the/tree"}, want: "unmatched"},
    31  		{name: "path not in tree #2", args: args{path: "/repos/hello/world/its/a/party"}, want: "unmatched"},
    32  		{name: "path not in tree #3", args: args{path: "/path-not-handled"}, want: "unmatched"},
    33  
    34  		{name: "repo branches protection (restrictions for users) by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection/restrictions/users"}, want: "/repos/:owner/:repo/branches/:branch/protection/restrictions/users"},
    35  		{name: "repositories", args: args{path: "/repositories"}, want: "/repositories"},
    36  
    37  		{name: "user", args: args{path: "/user"}, want: "/user"},
    38  		{name: "user", args: args{path: "/user/33322735/repos"}, want: "/user/:id/repos"},
    39  		{name: "users", args: args{path: "/users"}, want: "/users"},
    40  		{name: "user by username", args: args{path: "/users/testUser"}, want: "/users/:username"},
    41  
    42  		{name: "orgs", args: args{path: "/orgs"}, want: "/orgs"},
    43  		{name: "org by orgname", args: args{path: "/orgs/testOrg"}, want: "/orgs/:orgname"},
    44  
    45  		{name: "issues", args: args{path: "/issues"}, want: "/issues"},
    46  		{name: "issues by id", args: args{path: "/issues/testId"}, want: "/issues/:issueId"},
    47  
    48  		{name: "search", args: args{path: "/search"}, want: "/search"},
    49  		{name: "search repositories", args: args{path: "/search/repositories"}, want: "/search/repositories"},
    50  		{name: "search commits", args: args{path: "/search/commits"}, want: "/search/commits"},
    51  		{name: "search code", args: args{path: "/search/code"}, want: "/search/code"},
    52  		{name: "search issues", args: args{path: "/search/issues"}, want: "/search/issues"},
    53  		{name: "search users", args: args{path: "/search/users"}, want: "/search/users"},
    54  		{name: "search topics", args: args{path: "/search/topics"}, want: "/search/topics"},
    55  		{name: "search labels", args: args{path: "/search/labels"}, want: "/search/labels"},
    56  
    57  		{name: "gists", args: args{path: "/gists"}, want: "/gists"},
    58  		{name: "gists public", args: args{path: "/gists/public"}, want: "/gists/public"},
    59  		{name: "gists starred", args: args{path: "/gists/starred"}, want: "/gists/starred"},
    60  
    61  		{name: "notifications", args: args{path: "/notifications"}, want: "/notifications"},
    62  
    63  		{name: "graphql", args: args{path: "/graphql"}, want: "/graphql"},
    64  	}
    65  	for _, tt := range tests {
    66  		t.Run(tt.name, func(t *testing.T) {
    67  			if got := simplifier.Simplify(tt.args.path); got != tt.want {
    68  				t.Errorf("GetSimplifiedPath(%s) = %v, want %v", tt.args.path, got, tt.want)
    69  			}
    70  		})
    71  	}
    72  }
    73  
    74  func Test_GetSimplifiedPathRepos(t *testing.T) {
    75  	type args struct {
    76  		path string
    77  	}
    78  	tests := []struct {
    79  		name string
    80  		args args
    81  		want string
    82  	}{
    83  		{name: "access repos/ path should not fail, is not explicitly handled", args: args{path: "/repos"}, want: "/repos"},
    84  		{name: "access repos/ path should not fail, is not explicitly handled", args: args{path: "/repos/testOwner/testRepo/"}, want: "unmatched"},
    85  
    86  		{name: "repo issues", args: args{path: "/repos/testOwner/testRepo/issues"}, want: "/repos/:owner/:repo/issues"},
    87  		{name: "repo issue by number", args: args{path: "/repos/testOwner/testRepo/issues/21342"}, want: "/repos/:owner/:repo/issues/:issueId"},
    88  		{name: "repo issue by number lock", args: args{path: "/repos/testOwner/testRepo/issues/21321/lock"}, want: "/repos/:owner/:repo/issues/:issueId/lock"},
    89  		{name: "repo issues comments", args: args{path: "/repos/testOwner/testRepo/issues/comments"}, want: "/repos/:owner/:repo/issues/comments"},
    90  		{name: "repo issues comment by number", args: args{path: "/repos/testOwner/testRepo/issues/comments/321"}, want: "/repos/:owner/:repo/issues/comments/:commentId"},
    91  		{name: "repo issues events", args: args{path: "/repos/testOwner/testRepo/issues/events"}, want: "/repos/:owner/:repo/issues/events"},
    92  		{name: "repo issues event by number", args: args{path: "/repos/testOwner/testRepo/issues/events/123"}, want: "/repos/:owner/:repo/issues/events/:eventId"},
    93  
    94  		{name: "repo keys", args: args{path: "/repos/testOwner/testRepo/keys"}, want: "/repos/:owner/:repo/keys"},
    95  		{name: "repo key by id", args: args{path: "/repos/testOwner/testRepo/keys/421"}, want: "/repos/:owner/:repo/keys/:keyId"},
    96  
    97  		{name: "repo labels", args: args{path: "/repos/testOwner/testRepo/labels"}, want: "/repos/:owner/:repo/labels"},
    98  		{name: "repo label by name", args: args{path: "/repos/testOwner/testRepo/labels/testLabel"}, want: "/repos/:owner/:repo/labels/:labelId"},
    99  
   100  		{name: "repo merges", args: args{path: "/repos/testOwner/testRepo/merges"}, want: "/repos/:owner/:repo/merges"},
   101  
   102  		{name: "repo milestones", args: args{path: "/repos/testOwner/testRepo/milestones"}, want: "/repos/:owner/:repo/milestones"},
   103  		{name: "repo milestones by number", args: args{path: "/repos/testOwner/testRepo/milestones/421"}, want: "/repos/:owner/:repo/milestones/:milestone"},
   104  
   105  		{name: "repo pulls", args: args{path: "/repos/testOwner/testRepo/pulls"}, want: "/repos/:owner/:repo/pulls"},
   106  		{name: "repo pulls by number", args: args{path: "/repos/testOwner/testRepo/pulls/421"}, want: "/repos/:owner/:repo/pulls/:pullId"},
   107  		{name: "repo pull commits", args: args{path: "/repos/testOwner/testRepo/pulls/421/commits"}, want: "/repos/:owner/:repo/pulls/:pullId/commits"},
   108  		{name: "repo pull files ", args: args{path: "/repos/testOwner/testRepo/pulls/421/files"}, want: "/repos/:owner/:repo/pulls/:pullId/files"},
   109  		{name: "repo pull comments", args: args{path: "/repos/testOwner/testRepo/pulls/421/comments"}, want: "/repos/:owner/:repo/pulls/:pullId/comments"},
   110  		{name: "repo pull reviews", args: args{path: "/repos/testOwner/testRepo/pulls/421/reviews"}, want: "/repos/:owner/:repo/pulls/:pullId/reviews"},
   111  		{name: "repo pull requested_reviewers", args: args{path: "/repos/testOwner/testRepo/pulls/421/requested_reviewers"}, want: "/repos/:owner/:repo/pulls/:pullId/requested_reviewers"},
   112  		{name: "repo pull merge", args: args{path: "/repos/testOwner/testRepo/pulls/421/merge"}, want: "/repos/:owner/:repo/pulls/:pullId/merge"},
   113  
   114  		{name: "repo releases", args: args{path: "/repos/testOwner/testRepo/releases"}, want: "/repos/:owner/:repo/releases"},
   115  		{name: "repo releases by number", args: args{path: "/repos/testOwner/testRepo/releases/421"}, want: "/repos/:owner/:repo/releases/:releaseId"},
   116  
   117  		{name: "repo stargazers", args: args{path: "/repos/testOwner/testRepo/stargazers"}, want: "/repos/:owner/:repo/stargazers"},
   118  
   119  		{name: "repo statuses", args: args{path: "/repos/testOwner/testRepo/statuses"}, want: "/repos/:owner/:repo/statuses"},
   120  		{name: "repo statuses by sha", args: args{path: "/repos/testOwner/testRepo/statuses/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repos/:owner/:repo/statuses/:statusId"},
   121  
   122  		{name: "repo subscribers", args: args{path: "/repos/testOwner/testRepo/subscribers"}, want: "/repos/:owner/:repo/subscribers"},
   123  
   124  		{name: "repo subscribers", args: args{path: "/repos/testOwner/testRepo/subscribers"}, want: "/repos/:owner/:repo/subscribers"},
   125  
   126  		{name: "repo notifications", args: args{path: "/repos/testOwner/testRepo/notifications"}, want: "/repos/:owner/:repo/notifications"},
   127  
   128  		{name: "repo branches", args: args{path: "/repos/testOwner/testRepo/branches"}, want: "/repos/:owner/:repo/branches"},
   129  		{name: "repo branches by name", args: args{path: "/repos/testOwner/testRepo/branches/testBranch"}, want: "/repos/:owner/:repo/branches/:branch"},
   130  		{name: "repo branches protection by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection"}, want: "/repos/:owner/:repo/branches/:branch/protection"},
   131  		{name: "repo branches protection (required status checks) by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection/required_status_checks"}, want: "/repos/:owner/:repo/branches/:branch/protection/required_status_checks"},
   132  		{name: "repo branches protection (required status checks, contexts) by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection/required_status_checks/contexts"}, want: "/repos/:owner/:repo/branches/:branch/protection/required_status_checks/contexts"},
   133  		{name: "repo branches protection (required pull request reviews) by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection/required_pull_request_reviews"}, want: "/repos/:owner/:repo/branches/:branch/protection/required_pull_request_reviews"},
   134  		{name: "repo branches protection (required signatures) by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection/required_signatures"}, want: "/repos/:owner/:repo/branches/:branch/protection/required_signatures"},
   135  		{name: "repo branches protection (enforce admins) by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection/enforce_admins"}, want: "/repos/:owner/:repo/branches/:branch/protection/enforce_admins"},
   136  		{name: "repo branches protection (restrictions) by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection/restrictions"}, want: "/repos/:owner/:repo/branches/:branch/protection/restrictions"},
   137  		{name: "repo branches protection (restrictions for teams) by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection/restrictions/teams"}, want: "/repos/:owner/:repo/branches/:branch/protection/restrictions/teams"},
   138  		{name: "repo branches protection (restrictions for users) by name ", args: args{path: "/repos/testOwner/testRepo/branches/testBranch/protection/restrictions/users"}, want: "/repos/:owner/:repo/branches/:branch/protection/restrictions/users"},
   139  
   140  		{name: "repo archive", args: args{path: "/repos/testOwner/testRepo/archive"}, want: "/repos/:owner/:repo/archive"},
   141  		{name: "repo archive ref", args: args{path: "/repos/testOwner/testRepo/archive/tar.gz"}, want: "/repos/:owner/:repo/archive/:zip"},
   142  
   143  		{name: "repo assignees", args: args{path: "/repos/testOwner/testRepo/assignees"}, want: "/repos/:owner/:repo/assignees"},
   144  		{name: "repo assignees by name", args: args{path: "/repos/testOwner/testRepo/assignees/testUser"}, want: "/repos/:owner/:repo/assignees/:assigneeId"},
   145  
   146  		{name: "repo git commits", args: args{path: "/repos/testOwner/testRepo/git/commits"}, want: "/repos/:owner/:repo/git/commits"},
   147  		{name: "repo git commit by sha", args: args{path: "/repos/testOwner/testRepo/git/commits/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repos/:owner/:repo/git/commits/:sha"},
   148  		{name: "repo git refs", args: args{path: "/repos/testOwner/testRepo/git/ref"}, want: "/repos/:owner/:repo/git/ref"},
   149  		{name: "repo git ref by sha", args: args{path: "/repos/testOwner/testRepo/git/ref/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repos/:owner/:repo/git/ref/:refId"},
   150  		{name: "repo git tags", args: args{path: "/repos/testOwner/testRepo/git/tags"}, want: "/repos/:owner/:repo/git/tags"},
   151  		{name: "repo git tag by sha", args: args{path: "/repos/testOwner/testRepo/git/tags/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repos/:owner/:repo/git/tags/:tagId"},
   152  		{name: "repo git trees", args: args{path: "/repos/testOwner/testRepo/git/trees"}, want: "/repos/:owner/:repo/git/trees"},
   153  		{name: "repo git tree by sha", args: args{path: "/repos/testOwner/testRepo/git/trees/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repos/:owner/:repo/git/trees/:sha"},
   154  
   155  		{name: "repo git tags", args: args{path: "/repos/testOwner/testRepo/hooks"}, want: "/repos/:owner/:repo/hooks"},
   156  
   157  		{name: "repo collaborators", args: args{path: "/repos/testOwner/testRepo/collaborators"}, want: "/repos/:owner/:repo/collaborators"},
   158  		{name: "repo collaborators by name", args: args{path: "/repos/testOwner/testRepo/collaborators/testCollaborator"}, want: "/repos/:owner/:repo/collaborators/:collaboratorId"},
   159  
   160  		{name: "repo comments", args: args{path: "/repos/testOwner/testRepo/comments"}, want: "/repos/:owner/:repo/comments"},
   161  		{name: "repo comments by id", args: args{path: "/repos/testOwner/testRepo/comments/testComment"}, want: "/repos/:owner/:repo/comments/:commentId"},
   162  
   163  		{name: "repo commits", args: args{path: "/repos/testOwner/testRepo/commits"}, want: "/repos/:owner/:repo/commits"},
   164  		{name: "repo commits by sha", args: args{path: "/repos/testOwner/testRepo/commits/testCommitSha"}, want: "/repos/:owner/:repo/commits/:sha"},
   165  		{name: "repo commit status by sha", args: args{path: "/repos/testOwner/testRepo/commits/testCommitSha/status"}, want: "/repos/:owner/:repo/commits/:sha/status"},
   166  		{name: "repo commit check-runs by sha", args: args{path: "/repos/testOwner/testRepo/commits/testCommitSha/check-runs"}, want: "/repos/:owner/:repo/commits/:sha/check-runs"},
   167  		{name: "longer postfix is unmatched", args: args{path: "/repos/testOwner/testRepo/commits/testCommitSha/status/else"}, want: "unmatched"},
   168  
   169  		// /compare/base...head
   170  		{name: "repo compare", args: args{path: "/repos/testOwner/testRepo/compare/testBase...testHead"}, want: "/repos/:owner/:repo/compare/:sha"},
   171  
   172  		{name: "repo contents", args: args{path: "/repos/testOwner/testRepo/contents"}, want: "/repos/:owner/:repo/contents"},
   173  		{name: "repo contents by name", args: args{path: "/repos/testOwner/testRepo/contents/testContents"}, want: "/repos/:owner/:repo/contents/:contentId"},
   174  
   175  		{name: "repo deployments", args: args{path: "/repos/testOwner/testRepo/deployments"}, want: "/repos/:owner/:repo/deployments"},
   176  
   177  		{name: "repo downloads", args: args{path: "/repos/testOwner/testRepo/downloads"}, want: "/repos/:owner/:repo/downloads"},
   178  
   179  		{name: "repo events", args: args{path: "/repos/testOwner/testRepo/events"}, want: "/repos/:owner/:repo/events"},
   180  
   181  		{name: "repo forks", args: args{path: "/repos/testOwner/testRepo/forks"}, want: "/repos/:owner/:repo/forks"},
   182  
   183  		{name: "repo topics", args: args{path: "/repos/testOwner/testRepo/topics"}, want: "/repos/:owner/:repo/topics"},
   184  
   185  		{name: "repo vulnerability-alerts", args: args{path: "/repos/testOwner/testRepo/vulnerability-alerts"}, want: "/repos/:owner/:repo/vulnerability-alerts"},
   186  
   187  		{name: "repo automated-security-fixes", args: args{path: "/repos/testOwner/testRepo/automated-security-fixes"}, want: "/repos/:owner/:repo/automated-security-fixes"},
   188  
   189  		{name: "repo contributors", args: args{path: "/repos/testOwner/testRepo/contributors"}, want: "/repos/:owner/:repo/contributors"},
   190  
   191  		{name: "repo languages", args: args{path: "/repos/testOwner/testRepo/languages"}, want: "/repos/:owner/:repo/languages"},
   192  
   193  		{name: "repo teams", args: args{path: "/repos/testOwner/testRepo/teams"}, want: "/repos/:owner/:repo/teams"},
   194  
   195  		{name: "repo tags", args: args{path: "/repos/testOwner/testRepo/tags"}, want: "/repos/:owner/:repo/tags"},
   196  
   197  		{name: "repo transfer", args: args{path: "/repos/testOwner/testRepo/transfer"}, want: "/repos/:owner/:repo/transfer"},
   198  
   199  		{name: "master ref", args: args{path: "/repos/cri-o/cri-o/git/refs/heads/master"}, want: "/repos/:owner/:repo/git/refs/heads/:ref"},
   200  		{name: "issue comments", args: args{path: "/repos/openshift/aws-account-operator/issues/104/comments"}, want: "/repos/:owner/:repo/issues/:issueId/comments"},
   201  		{name: "issue labels", args: args{path: "/repos/openshift/aws-account-operator/issues/104/labels"}, want: "/repos/:owner/:repo/issues/:issueId/labels"},
   202  		{name: "issue label", args: args{path: "/repos/openshift/aws-account-operator/issues/104/labels/needs-rebase"}, want: "/repos/:owner/:repo/issues/:issueId/labels/:labelId"},
   203  		{name: "issue label with slash", args: args{path: "/repos/openshift/aws-account-operator/issues/104/labels/do-not-merge/hold"}, want: "/repos/:owner/:repo/issues/:issueId/labels/:labelId"},
   204  		{name: "issue events", args: args{path: "/repos/helm/charts/issues/15756/events"}, want: "/repos/:owner/:repo/issues/:issueId/events"},
   205  		{name: "issue assignees", args: args{path: "/repos/helm/charts/issues/15756/assignees"}, want: "/repos/:owner/:repo/issues/:issueId/assignees"},
   206  		{name: "issue reactions", args: args{path: "/repos/kubernetes-sigs/cluster-api-provider-aws/issues/958/reactions"}, want: "/repos/:owner/:repo/issues/:issueId/reactions"},
   207  	}
   208  	for _, tt := range tests {
   209  		t.Run(tt.name, func(t *testing.T) {
   210  			if got := simplifier.Simplify(tt.args.path); got != tt.want {
   211  				t.Errorf("GetSimplifiedPath(%s) = %v, want %v", tt.args.path, got, tt.want)
   212  			}
   213  		})
   214  	}
   215  }
   216  
   217  func Test_GetSimplifiedPathRepositories(t *testing.T) {
   218  	type args struct {
   219  		path string
   220  	}
   221  	tests := []struct {
   222  		name string
   223  		args args
   224  		want string
   225  	}{
   226  		{name: "access repositories/ path should not fail, is not explicitly handled", args: args{path: "/repositories"}, want: "/repositories"},
   227  
   228  		{name: "repo issues", args: args{path: "/repositories/testRepository/issues"}, want: "/repositories/:repoId/issues"},
   229  		{name: "repo issue by number", args: args{path: "/repositories/testRepository/issues/21342"}, want: "/repositories/:repoId/issues/:issueId"},
   230  		{name: "repo issue by number lock", args: args{path: "/repositories/testRepository/issues/21321/lock"}, want: "/repositories/:repoId/issues/:issueId/lock"},
   231  		{name: "repo issues comments", args: args{path: "/repositories/testRepository/issues/comments"}, want: "/repositories/:repoId/issues/comments"},
   232  		{name: "repo issues comment by number", args: args{path: "/repositories/testRepository/issues/comments/321"}, want: "/repositories/:repoId/issues/comments/:commentId"},
   233  		{name: "repo issues events", args: args{path: "/repositories/testRepository/issues/events"}, want: "/repositories/:repoId/issues/events"},
   234  		{name: "repo issues event by number", args: args{path: "/repositories/testRepository/issues/events/123"}, want: "/repositories/:repoId/issues/events/:eventId"},
   235  
   236  		{name: "repo keys", args: args{path: "/repositories/testRepository/keys"}, want: "/repositories/:repoId/keys"},
   237  		{name: "repo key by id", args: args{path: "/repositories/testRepository/keys/421"}, want: "/repositories/:repoId/keys/:keyId"},
   238  
   239  		{name: "repo labels", args: args{path: "/repositories/testRepository/labels"}, want: "/repositories/:repoId/labels"},
   240  		{name: "repo label by name", args: args{path: "/repositories/testRepository/labels/testLabel"}, want: "/repositories/:repoId/labels/:labelId"},
   241  
   242  		{name: "repo merges", args: args{path: "/repositories/testRepository/merges"}, want: "/repositories/:repoId/merges"},
   243  
   244  		{name: "repo milestones", args: args{path: "/repositories/testRepository/milestones"}, want: "/repositories/:repoId/milestones"},
   245  		{name: "repo milestones by number", args: args{path: "/repositories/testRepository/milestones/421"}, want: "/repositories/:repoId/milestones/:milestone"},
   246  
   247  		{name: "repo pulls", args: args{path: "/repositories/testRepository/pulls"}, want: "/repositories/:repoId/pulls"},
   248  		{name: "repo pulls by number", args: args{path: "/repositories/testRepository/pulls/421"}, want: "/repositories/:repoId/pulls/:pullId"},
   249  
   250  		{name: "repo releases", args: args{path: "/repositories/testRepository/releases"}, want: "/repositories/:repoId/releases"},
   251  		{name: "repo releases by number", args: args{path: "/repositories/testRepository/releases/421"}, want: "/repositories/:repoId/releases/:releaseId"},
   252  
   253  		{name: "repo stargazers", args: args{path: "/repositories/testRepository/stargazers"}, want: "/repositories/:repoId/stargazers"},
   254  
   255  		{name: "repo statuses", args: args{path: "/repositories/testRepository/statuses"}, want: "/repositories/:repoId/statuses"},
   256  		{name: "repo statuses by sha", args: args{path: "/repositories/testRepository/statuses/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repositories/:repoId/statuses/:statusId"},
   257  
   258  		{name: "repo subscribers", args: args{path: "/repositories/testRepository/subscribers"}, want: "/repositories/:repoId/subscribers"},
   259  
   260  		{name: "repo subscribers", args: args{path: "/repositories/testRepository/subscribers"}, want: "/repositories/:repoId/subscribers"},
   261  
   262  		{name: "repo notifications", args: args{path: "/repositories/testRepository/notifications"}, want: "/repositories/:repoId/notifications"},
   263  
   264  		{name: "repo branches", args: args{path: "/repositories/testRepository/branches"}, want: "/repositories/:repoId/branches"},
   265  		{name: "repo branches by name", args: args{path: "/repositories/testRepository/branches/testBranch"}, want: "/repositories/:repoId/branches/:branch"},
   266  		{name: "repo branches protection by name ", args: args{path: "/repositories/testRepository/branches/testBranch/protection"}, want: "/repositories/:repoId/branches/:branch/protection"},
   267  		{name: "repo branches protection (required status checks) by name ", args: args{path: "/repositories/testRepository/branches/testBranch/protection/required_status_checks"}, want: "/repositories/:repoId/branches/:branch/protection/required_status_checks"},
   268  		{name: "repo branches protection (required status checks, contexts) by name ", args: args{path: "/repositories/testRepository/branches/testBranch/protection/required_status_checks/contexts"}, want: "/repositories/:repoId/branches/:branch/protection/required_status_checks/contexts"},
   269  		{name: "repo branches protection (required pull request reviews) by name ", args: args{path: "/repositories/testRepository/branches/testBranch/protection/required_pull_request_reviews"}, want: "/repositories/:repoId/branches/:branch/protection/required_pull_request_reviews"},
   270  		{name: "repo branches protection (required signatures) by name ", args: args{path: "/repositories/testRepository/branches/testBranch/protection/required_signatures"}, want: "/repositories/:repoId/branches/:branch/protection/required_signatures"},
   271  		{name: "repo branches protection (enforce admins) by name ", args: args{path: "/repositories/testRepository/branches/testBranch/protection/enforce_admins"}, want: "/repositories/:repoId/branches/:branch/protection/enforce_admins"},
   272  		{name: "repo branches protection (restrictions) by name ", args: args{path: "/repositories/testRepository/branches/testBranch/protection/restrictions"}, want: "/repositories/:repoId/branches/:branch/protection/restrictions"},
   273  		{name: "repo branches protection (restrictions for teams) by name ", args: args{path: "/repositories/testRepository/branches/testBranch/protection/restrictions/teams"}, want: "/repositories/:repoId/branches/:branch/protection/restrictions/teams"},
   274  		{name: "repo branches protection (restrictions for users) by name ", args: args{path: "/repositories/testRepository/branches/testBranch/protection/restrictions/users"}, want: "/repositories/:repoId/branches/:branch/protection/restrictions/users"},
   275  
   276  		{name: "repo archive", args: args{path: "/repositories/testRepository/archive"}, want: "/repositories/:repoId/archive"},
   277  		{name: "repo archive ref", args: args{path: "/repositories/testRepository/archive/tar.gz"}, want: "/repositories/:repoId/archive/:zip"},
   278  
   279  		{name: "repo assignees", args: args{path: "/repositories/testRepository/assignees"}, want: "/repositories/:repoId/assignees"},
   280  		{name: "repo assignees by name", args: args{path: "/repositories/testRepository/assignees/testUser"}, want: "/repositories/:repoId/assignees/:assigneeId"},
   281  
   282  		{name: "repo git commits", args: args{path: "/repositories/testRepository/git/commits"}, want: "/repositories/:repoId/git/commits"},
   283  		{name: "repo git commit by sha", args: args{path: "/repositories/testRepository/git/commits/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repositories/:repoId/git/commits/:sha"},
   284  		{name: "repo git refs", args: args{path: "/repositories/testRepository/git/ref"}, want: "/repositories/:repoId/git/ref"},
   285  		{name: "repo git ref by sha", args: args{path: "/repositories/testRepository/git/ref/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repositories/:repoId/git/ref/:refId"},
   286  		{name: "repo git tags", args: args{path: "/repositories/testRepository/git/tags"}, want: "/repositories/:repoId/git/tags"},
   287  		{name: "repo git tag by sha", args: args{path: "/repositories/testRepository/git/tags/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repositories/:repoId/git/tags/:tagId"},
   288  		{name: "repo git trees", args: args{path: "/repositories/testRepository/git/trees"}, want: "/repositories/:repoId/git/trees"},
   289  		{name: "repo git tree by sha", args: args{path: "/repositories/testRepository/git/trees/4u8dsaag89ewfdjkt9fdajdsa"}, want: "/repositories/:repoId/git/trees/:sha"},
   290  
   291  		{name: "repo git tags", args: args{path: "/repositories/testRepository/hooks"}, want: "/repositories/:repoId/hooks"},
   292  
   293  		{name: "repo collaborators", args: args{path: "/repositories/testRepository/collaborators"}, want: "/repositories/:repoId/collaborators"},
   294  		{name: "repo collaborators by name", args: args{path: "/repositories/testRepository/collaborators/testCollaborator"}, want: "/repositories/:repoId/collaborators/:collaboratorId"},
   295  		{name: "repo collaborators by name permissions", args: args{path: "/repositories/testRepository/collaborators/testCollaborator/permission"}, want: "/repositories/:repoId/collaborators/:collaboratorId/permission"},
   296  
   297  		{name: "repo comments", args: args{path: "/repositories/testRepository/comments"}, want: "/repositories/:repoId/comments"},
   298  		{name: "repo comments by id", args: args{path: "/repositories/testRepository/comments/testComment"}, want: "/repositories/:repoId/comments/:commentId"},
   299  
   300  		{name: "repo commits", args: args{path: "/repositories/testRepository/commits"}, want: "/repositories/:repoId/commits"},
   301  		{name: "repo commits by sha", args: args{path: "/repositories/testRepository/commits/testCommitSha"}, want: "/repositories/:repoId/commits/:sha"},
   302  
   303  		// /compare/base...head
   304  		{name: "repo compare", args: args{path: "/repositories/testRepository/compare/testBase...testHead"}, want: "/repositories/:repoId/compare/:sha"},
   305  
   306  		{name: "repo contents", args: args{path: "/repositories/testRepository/contents"}, want: "/repositories/:repoId/contents"},
   307  		{name: "repo contents by name", args: args{path: "/repositories/testRepository/contents/testContents"}, want: "/repositories/:repoId/contents/:contentId"},
   308  
   309  		{name: "repo deployments", args: args{path: "/repositories/testRepository/deployments"}, want: "/repositories/:repoId/deployments"},
   310  
   311  		{name: "repo downloads", args: args{path: "/repositories/testRepository/downloads"}, want: "/repositories/:repoId/downloads"},
   312  
   313  		{name: "repo events", args: args{path: "/repositories/testRepository/events"}, want: "/repositories/:repoId/events"},
   314  
   315  		{name: "repo forks", args: args{path: "/repositories/testRepository/forks"}, want: "/repositories/:repoId/forks"},
   316  
   317  		{name: "repo topics", args: args{path: "/repositories/testRepository/topics"}, want: "/repositories/:repoId/topics"},
   318  
   319  		{name: "repo vulnerability-alerts", args: args{path: "/repositories/testRepository/vulnerability-alerts"}, want: "/repositories/:repoId/vulnerability-alerts"},
   320  
   321  		{name: "repo automated-security-fixes", args: args{path: "/repositories/testRepository/automated-security-fixes"}, want: "/repositories/:repoId/automated-security-fixes"},
   322  
   323  		{name: "repo contributors", args: args{path: "/repositories/testRepository/contributors"}, want: "/repositories/:repoId/contributors"},
   324  
   325  		{name: "repo languages", args: args{path: "/repositories/testRepository/languages"}, want: "/repositories/:repoId/languages"},
   326  
   327  		{name: "repo teams", args: args{path: "/repositories/testRepository/teams"}, want: "/repositories/:repoId/teams"},
   328  
   329  		{name: "repo tags", args: args{path: "/repositories/testRepository/tags"}, want: "/repositories/:repoId/tags"},
   330  
   331  		{name: "repo transfer", args: args{path: "/repositories/testRepository/transfer"}, want: "/repositories/:repoId/transfer"},
   332  
   333  		{name: "master ref", args: args{path: "/repositories/168397/git/refs/heads/master"}, want: "/repositories/:repoId/git/refs/heads/:ref"},
   334  		{name: "issue comments", args: args{path: "/repositories/168397/issues/104/comments"}, want: "/repositories/:repoId/issues/:issueId/comments"},
   335  		{name: "issue labels", args: args{path: "/repositories/168397/issues/104/labels"}, want: "/repositories/:repoId/issues/:issueId/labels"},
   336  		{name: "issue label", args: args{path: "/repositories/168397/issues/104/labels/needs-rebase"}, want: "/repositories/:repoId/issues/:issueId/labels/:labelId"},
   337  		{name: "issue events", args: args{path: "/repositories/168397/issues/15756/events"}, want: "/repositories/:repoId/issues/:issueId/events"},
   338  		{name: "issue assignees", args: args{path: "/repositories/168397/issues/15756/assignees"}, want: "/repositories/:repoId/issues/:issueId/assignees"},
   339  		{name: "issue reactions", args: args{path: "/repositories/168397/issues/958/reactions"}, want: "/repositories/:repoId/issues/:issueId/reactions"},
   340  	}
   341  	for _, tt := range tests {
   342  		t.Run(tt.name, func(t *testing.T) {
   343  			if got := simplifier.Simplify(tt.args.path); got != tt.want {
   344  				t.Errorf("GetSimplifiedPath(%s) = %v, want %v", tt.args.path, got, tt.want)
   345  			}
   346  		})
   347  	}
   348  }
   349  
   350  func Test_GetSimplifiedPathUser(t *testing.T) {
   351  	type args struct {
   352  		path string
   353  	}
   354  	tests := []struct {
   355  		name string
   356  		args args
   357  		want string
   358  	}{
   359  		{name: "user", args: args{path: "/user"}, want: "/user"},
   360  
   361  		{name: "user email", args: args{path: "/user/emails"}, want: "/user/emails"},
   362  		{name: "user email visibility", args: args{path: "/user/email/visibility"}, want: "/user/email/visibility"},
   363  
   364  		{name: "user public emails", args: args{path: "/user/public_emails"}, want: "/user/public_emails"},
   365  
   366  		{name: "user followers", args: args{path: "/user/followers"}, want: "/user/followers"},
   367  
   368  		{name: "user following", args: args{path: "/user/following"}, want: "/user/following"},
   369  		{name: "user following user", args: args{path: "/user/following/testUser"}, want: "/user/following/:userId"},
   370  
   371  		{name: "user starred", args: args{path: "/user/starred"}, want: "/user/starred"},
   372  
   373  		{name: "user issues", args: args{path: "/user/issues"}, want: "/user/issues"},
   374  
   375  		{name: "user keys", args: args{path: "/user/keys"}, want: "/user/keys"},
   376  		{name: "user keys by id", args: args{path: "/user/keys/testKey"}, want: "/user/keys/:keyId"},
   377  	}
   378  	for _, tt := range tests {
   379  		t.Run(tt.name, func(t *testing.T) {
   380  			if got := simplifier.Simplify(tt.args.path); got != tt.want {
   381  				t.Errorf("GetSimplifiedPath(%s) = %v, want %v", tt.args.path, got, tt.want)
   382  			}
   383  		})
   384  	}
   385  }
   386  
   387  func Test_GetSimplifiedPathUsers(t *testing.T) {
   388  	type args struct {
   389  		path string
   390  	}
   391  	tests := []struct {
   392  		name string
   393  		args args
   394  		want string
   395  	}{
   396  		{name: "users", args: args{path: "/users"}, want: "/users"},
   397  		{name: "users", args: args{path: "/users/testUser"}, want: "/users/:username"},
   398  
   399  		{name: "users username repos", args: args{path: "/users/testUser/repos"}, want: "/users/:username/repos"},
   400  
   401  		{name: "users username hovercard", args: args{path: "/users/testUser/hovercard"}, want: "/users/:username/hovercard"},
   402  
   403  		{name: "users username followers", args: args{path: "/users/testUser/followers"}, want: "/users/:username/followers"},
   404  		{name: "users username follows user", args: args{path: "/users/testUser/followers/testTargetUser"}, want: "/users/:username/followers/:username"},
   405  
   406  		{name: "users username following", args: args{path: "/users/testUser/following"}, want: "/users/:username/following"},
   407  	}
   408  	for _, tt := range tests {
   409  		t.Run(tt.name, func(t *testing.T) {
   410  			if got := simplifier.Simplify(tt.args.path); got != tt.want {
   411  				t.Errorf("GetSimplifiedPath() = %v, want %v", got, tt.want)
   412  			}
   413  		})
   414  	}
   415  }
   416  
   417  func Test_GetSimplifiedPathOrganizations(t *testing.T) {
   418  	type args struct {
   419  		path string
   420  	}
   421  	tests := []struct {
   422  		name string
   423  		args args
   424  		want string
   425  	}{
   426  		{name: "orgs", args: args{path: "/organizations"}, want: "/organizations"},
   427  		{name: "orgs", args: args{path: "/organizations/testOrg"}, want: "/organizations/:orgId"},
   428  
   429  		{name: "orgs orgname repos", args: args{path: "/organizations/testOrg/repos"}, want: "/organizations/:orgId/repos"},
   430  
   431  		{name: "orgs orgname issues", args: args{path: "/organizations/testOrg/issues"}, want: "/organizations/:orgId/issues"},
   432  
   433  		{name: "orgs orgname credential-authorizations", args: args{path: "/organizations/testOrg/credential-authorizations"}, want: "/organizations/:orgId/credential-authorizations"},
   434  		{name: "orgs orgname credential-authorizations by id", args: args{path: "/organizations/testOrg/credential-authorizations/testId"}, want: "/organizations/:orgId/credential-authorizations/:credentialId"},
   435  
   436  		{name: "org invitations", args: args{path: "/organizations/openshift/invitations"}, want: "/organizations/:orgId/invitations"},
   437  		{name: "org members", args: args{path: "/organizations/openshift/members"}, want: "/organizations/:orgId/members"},
   438  		{name: "org member", args: args{path: "/organizations/openshift/members/stevekuznetsov"}, want: "/organizations/:orgId/members/:login"},
   439  		{name: "org memberships", args: args{path: "/organizations/openshift/memberships/stevekuznetsov"}, want: "/organizations/:orgId/memberships/:login"},
   440  		{name: "org teams", args: args{path: "/organizations/openshift/teams"}, want: "/organizations/:orgId/teams"},
   441  
   442  		{name: "org members by ID", args: args{path: "/organizations/792337/members"}, want: "/organizations/:orgId/members"},
   443  		{name: "org teams by ID", args: args{path: "/organizations/792337/teams"}, want: "/organizations/:orgId/teams"},
   444  		{name: "org team members by ID", args: args{path: "/organizations/792337/team/792337/members"}, want: "/organizations/:orgId/team/:teamId/members"},
   445  		{name: "org team repos by ID", args: args{path: "/organizations/792337/team/792337/repos"}, want: "/organizations/:orgId/team/:teamId/repos"},
   446  		{name: "org repos by ID", args: args{path: "/organizations/792337/repos"}, want: "/organizations/:orgId/repos"},
   447  	}
   448  	for _, tt := range tests {
   449  		t.Run(tt.name, func(t *testing.T) {
   450  			if got := simplifier.Simplify(tt.args.path); got != tt.want {
   451  				t.Errorf("GetSimplifiedPath(%s) = %v, want %v", tt.args.path, got, tt.want)
   452  			}
   453  		})
   454  	}
   455  }
   456  
   457  func Test_GetSimplifiedPathOrgs(t *testing.T) {
   458  	type args struct {
   459  		path string
   460  	}
   461  	tests := []struct {
   462  		name string
   463  		args args
   464  		want string
   465  	}{
   466  		{name: "orgs", args: args{path: "/orgs"}, want: "/orgs"},
   467  		{name: "orgs", args: args{path: "/orgs/testOrg"}, want: "/orgs/:orgname"},
   468  
   469  		{name: "orgs orgname repos", args: args{path: "/orgs/testOrg/repos"}, want: "/orgs/:orgname/repos"},
   470  
   471  		{name: "orgs orgname issues", args: args{path: "/orgs/testOrg/issues"}, want: "/orgs/:orgname/issues"},
   472  
   473  		{name: "orgs orgname credential-authorizations", args: args{path: "/orgs/testOrg/credential-authorizations"}, want: "/orgs/:orgname/credential-authorizations"},
   474  		{name: "orgs orgname credential-authorizations by id", args: args{path: "/orgs/testOrg/credential-authorizations/testId"}, want: "/orgs/:orgname/credential-authorizations/:credentialId"},
   475  
   476  		{name: "org invitations", args: args{path: "/orgs/openshift/invitations"}, want: "/orgs/:orgname/invitations"},
   477  		{name: "org members", args: args{path: "/orgs/openshift/members"}, want: "/orgs/:orgname/members"},
   478  		{name: "org member", args: args{path: "/orgs/openshift/members/stevekuznetsov"}, want: "/orgs/:orgname/members/:login"},
   479  		{name: "org teams", args: args{path: "/orgs/openshift/teams"}, want: "/orgs/:orgname/teams"},
   480  	}
   481  	for _, tt := range tests {
   482  		t.Run(tt.name, func(t *testing.T) {
   483  			if got := simplifier.Simplify(tt.args.path); got != tt.want {
   484  				t.Errorf("GetSimplifiedPath(%s) = %v, want %v", tt.args.path, got, tt.want)
   485  			}
   486  		})
   487  	}
   488  }
   489  
   490  func Test_GetSimplifiedPathNotifications(t *testing.T) {
   491  	type args struct {
   492  		path string
   493  	}
   494  	tests := []struct {
   495  		name string
   496  		args args
   497  		want string
   498  	}{
   499  		{name: "notifications", args: args{path: "/notifications"}, want: "/notifications"},
   500  		{name: "notifications threads", args: args{path: "/notifications/threads"}, want: "/notifications/threads"},
   501  		{name: "notifications thread by id", args: args{path: "/notifications/threads/testThreadId"}, want: "/notifications/threads/:threadId"},
   502  		{name: "notifications thread by id", args: args{path: "/notifications/threads/testThreadId/subscription"}, want: "/notifications/threads/:threadId/subscription"},
   503  	}
   504  	for _, tt := range tests {
   505  		t.Run(tt.name, func(t *testing.T) {
   506  			if got := simplifier.Simplify(tt.args.path); got != tt.want {
   507  				t.Errorf("GetSimplifiedPath(%s) = %v, want %v", tt.args.path, got, tt.want)
   508  			}
   509  		})
   510  	}
   511  }
   512  
   513  func Test_GetSimplifiedPathTeams(t *testing.T) {
   514  	type args struct {
   515  		path string
   516  	}
   517  	tests := []struct {
   518  		name string
   519  		args args
   520  		want string
   521  	}{
   522  		{name: "the team itself", args: args{path: "/teams/3673574"}, want: "/teams/:id"},
   523  		{name: "members", args: args{path: "/teams/3005744/members"}, want: "/teams/:id/members"},
   524  		{name: "all repos", args: args{path: "/teams/1020908/repos"}, want: "/teams/:id/repos"},
   525  		{name: "inviations", args: args{path: "/teams/1135236/invitations"}, want: "/teams/:id/invitations"},
   526  		{name: "a repo", args: args{path: "/teams/2984756/repos/openshift/gcp-project-operator"}, want: "/teams/:id/repos/:org/:repo"},
   527  		{name: "a member", args: args{path: "/teams/3224926/memberships/deads2k"}, want: "/teams/:id/memberships/:user"},
   528  	}
   529  	for _, tt := range tests {
   530  		t.Run(tt.name, func(t *testing.T) {
   531  			if got := simplifier.Simplify(tt.args.path); got != tt.want {
   532  				t.Errorf("GetSimplifiedPath() = %v, want %v", got, tt.want)
   533  			}
   534  		})
   535  	}
   536  }
   537  
   538  func TestUserAgentWithoutVersion(t *testing.T) {
   539  	tests := []struct {
   540  		name, in, out string
   541  	}{
   542  		{
   543  			name: "normal user agent gets split",
   544  			in:   "hook.config-updater/v20200314-12f848798",
   545  			out:  "hook.config-updater",
   546  		},
   547  		{
   548  			name: "user agent without version does not split",
   549  			in:   "some-custom-thing",
   550  			out:  "some-custom-thing",
   551  		},
   552  		{
   553  			name: "malformed user agent returns something sensible",
   554  			in:   "some/custom/thing",
   555  			out:  "some",
   556  		},
   557  	}
   558  
   559  	for _, test := range tests {
   560  		t.Run(test.name, func(t *testing.T) {
   561  			if actual, expected := userAgentWithoutVersion(test.in), test.out; actual != expected {
   562  				t.Errorf("%s: expected %s, got %s", test.name, expected, actual)
   563  			}
   564  		})
   565  	}
   566  }