github.com/argoproj/argo-cd/v3@v3.2.1/applicationset/services/pull_request/gitea_test.go (about)

     1  package pull_request
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"testing"
     9  
    10  	"code.gitea.io/sdk/gitea"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func giteaMockHandler(t *testing.T) func(http.ResponseWriter, *http.Request) {
    16  	t.Helper()
    17  	return func(w http.ResponseWriter, r *http.Request) {
    18  		w.Header().Set("Content-Type", "application/json")
    19  		fmt.Println(r.RequestURI)
    20  		switch r.RequestURI {
    21  		case "/api/v1/version":
    22  			_, err := io.WriteString(w, `{"version":"1.17.0+dev-452-g1f0541780"}`)
    23  			if err != nil {
    24  				t.Fail()
    25  			}
    26  		case "/api/v1/repos/test-argocd/pr-test/pulls?limit=0&page=1&state=open":
    27  			_, err := io.WriteString(w, `[{
    28  				"id": 50721,
    29  				"url": "https://gitea.com/test-argocd/pr-test/pulls/1",
    30  				"number": 1,
    31  				"user": {
    32  					"id": 4476,
    33  					"login": "graytshirt",
    34  					"full_name": "Dan",
    35  					"email": "graytshirt@noreply.gitea.io",
    36  					"avatar_url": "https://secure.gravatar.com/avatar/2446c67bcd59d71f6ae3cf376ec2ae37?d=identicon",
    37  					"language": "",
    38  					"is_admin": false,
    39  					"last_login": "0001-01-01T00:00:00Z",
    40  					"created": "2020-04-07T01:14:36+08:00",
    41  					"restricted": false,
    42  					"active": false,
    43  					"prohibit_login": false,
    44  					"location": "",
    45  					"website": "",
    46  					"description": "",
    47  					"visibility": "public",
    48  					"followers_count": 0,
    49  					"following_count": 4,
    50  					"starred_repos_count": 1,
    51  					"username": "graytshirt"
    52  				},
    53  				"title": "add an empty file",
    54  				"body": "",
    55  				"labels": [{"id": 1, "name": "label1", "color": "00aabb", "description": "foo", "url": ""}],
    56  				"milestone": null,
    57  				"assignee": null,
    58  				"assignees": null,
    59  				"state": "open",
    60  				"is_locked": false,
    61  				"comments": 0,
    62  				"html_url": "https://gitea.com/test-argocd/pr-test/pulls/1",
    63  				"diff_url": "https://gitea.com/test-argocd/pr-test/pulls/1.diff",
    64  				"patch_url": "https://gitea.com/test-argocd/pr-test/pulls/1.patch",
    65  				"mergeable": true,
    66  				"merged": false,
    67  				"merged_at": null,
    68  				"merge_commit_sha": null,
    69  				"merged_by": null,
    70  				"base": {
    71  					"label": "main",
    72  					"ref": "main",
    73  					"sha": "72687815ccba81ef014a96201cc2e846a68789d8",
    74  					"repo_id": 21618,
    75  					"repo": {
    76  						"id": 21618,
    77  						"owner": {
    78  							"id": 31480,
    79  							"login": "test-argocd",
    80  							"full_name": "",
    81  							"email": "",
    82  							"avatar_url": "https://gitea.com/avatars/22d1b1d3f61abf95951c4a958731d848",
    83  							"language": "",
    84  							"is_admin": false,
    85  							"last_login": "0001-01-01T00:00:00Z",
    86  							"created": "2022-04-06T02:28:06+08:00",
    87  							"restricted": false,
    88  							"active": false,
    89  							"prohibit_login": false,
    90  							"location": "",
    91  							"website": "",
    92  							"description": "",
    93  							"visibility": "public",
    94  							"followers_count": 0,
    95  							"following_count": 0,
    96  							"starred_repos_count": 0,
    97  							"username": "test-argocd"
    98  						},
    99  						"name": "pr-test",
   100  						"full_name": "test-argocd/pr-test",
   101  						"description": "",
   102  						"empty": false,
   103  						"private": false,
   104  						"fork": false,
   105  						"template": false,
   106  						"parent": null,
   107  						"mirror": false,
   108  						"size": 28,
   109  						"language": "",
   110  						"languages_url": "https://gitea.com/api/v1/repos/test-argocd/pr-test/languages",
   111  						"html_url": "https://gitea.com/test-argocd/pr-test",
   112  						"ssh_url": "git@gitea.com:test-argocd/pr-test.git",
   113  						"clone_url": "https://gitea.com/test-argocd/pr-test.git",
   114  						"original_url": "",
   115  						"website": "",
   116  						"stars_count": 0,
   117  						"forks_count": 0,
   118  						"watchers_count": 1,
   119  						"open_issues_count": 0,
   120  						"open_pr_counter": 1,
   121  						"release_counter": 0,
   122  						"default_branch": "main",
   123  						"archived": false,
   124  						"created_at": "2022-04-06T02:32:09+08:00",
   125  						"updated_at": "2022-04-06T02:33:12+08:00",
   126  						"permissions": {
   127  							"admin": false,
   128  							"push": false,
   129  							"pull": true
   130  						},
   131  						"has_issues": true,
   132  						"internal_tracker": {
   133  							"enable_time_tracker": true,
   134  							"allow_only_contributors_to_track_time": true,
   135  							"enable_issue_dependencies": true
   136  						},
   137  						"has_wiki": true,
   138  						"has_pull_requests": true,
   139  						"has_projects": true,
   140  						"ignore_whitespace_conflicts": false,
   141  						"allow_merge_commits": true,
   142  						"allow_rebase": true,
   143  						"allow_rebase_explicit": true,
   144  						"allow_squash_merge": true,
   145  						"default_merge_style": "merge",
   146  						"avatar_url": "",
   147  						"internal": false,
   148  						"mirror_interval": "",
   149  						"mirror_updated": "0001-01-01T00:00:00Z",
   150  						"repo_transfer": null
   151  					}
   152  				},
   153  				"head": {
   154  					"label": "test",
   155  					"ref": "test",
   156  					"sha": "7bbaf62d92ddfafd9cc8b340c619abaec32bc09f",
   157  					"repo_id": 21618,
   158  					"repo": {
   159  						"id": 21618,
   160  						"owner": {
   161  							"id": 31480,
   162  							"login": "test-argocd",
   163  							"full_name": "",
   164  							"email": "",
   165  							"avatar_url": "https://gitea.com/avatars/22d1b1d3f61abf95951c4a958731d848",
   166  							"language": "",
   167  							"is_admin": false,
   168  							"last_login": "0001-01-01T00:00:00Z",
   169  							"created": "2022-04-06T02:28:06+08:00",
   170  							"restricted": false,
   171  							"active": false,
   172  							"prohibit_login": false,
   173  							"location": "",
   174  							"website": "",
   175  							"description": "",
   176  							"visibility": "public",
   177  							"followers_count": 0,
   178  							"following_count": 0,
   179  							"starred_repos_count": 0,
   180  							"username": "test-argocd"
   181  						},
   182  						"name": "pr-test",
   183  						"full_name": "test-argocd/pr-test",
   184  						"description": "",
   185  						"empty": false,
   186  						"private": false,
   187  						"fork": false,
   188  						"template": false,
   189  						"parent": null,
   190  						"mirror": false,
   191  						"size": 28,
   192  						"language": "",
   193  						"languages_url": "https://gitea.com/api/v1/repos/test-argocd/pr-test/languages",
   194  						"html_url": "https://gitea.com/test-argocd/pr-test",
   195  						"ssh_url": "git@gitea.com:test-argocd/pr-test.git",
   196  						"clone_url": "https://gitea.com/test-argocd/pr-test.git",
   197  						"original_url": "",
   198  						"website": "",
   199  						"stars_count": 0,
   200  						"forks_count": 0,
   201  						"watchers_count": 1,
   202  						"open_issues_count": 0,
   203  						"open_pr_counter": 1,
   204  						"release_counter": 0,
   205  						"default_branch": "main",
   206  						"archived": false,
   207  						"created_at": "2022-04-06T02:32:09+08:00",
   208  						"updated_at": "2022-04-06T02:33:12+08:00",
   209  						"permissions": {
   210  							"admin": false,
   211  							"push": false,
   212  							"pull": true
   213  						},
   214  						"has_issues": true,
   215  						"internal_tracker": {
   216  							"enable_time_tracker": true,
   217  							"allow_only_contributors_to_track_time": true,
   218  							"enable_issue_dependencies": true
   219  						},
   220  						"has_wiki": true,
   221  						"has_pull_requests": true,
   222  						"has_projects": true,
   223  						"ignore_whitespace_conflicts": false,
   224  						"allow_merge_commits": true,
   225  						"allow_rebase": true,
   226  						"allow_rebase_explicit": true,
   227  						"allow_squash_merge": true,
   228  						"default_merge_style": "merge",
   229  						"avatar_url": "",
   230  						"internal": false,
   231  						"mirror_interval": "",
   232  						"mirror_updated": "0001-01-01T00:00:00Z",
   233  						"repo_transfer": null
   234  					}
   235  				},
   236  				"merge_base": "72687815ccba81ef014a96201cc2e846a68789d8",
   237  				"due_date": null,
   238  				"created_at": "2022-04-06T02:34:24+08:00",
   239  				"updated_at": "2022-04-06T02:34:24+08:00",
   240  				"closed_at": null
   241  			}]`)
   242  			if err != nil {
   243  				t.Fail()
   244  			}
   245  		}
   246  	}
   247  }
   248  
   249  func TestGiteaContainLabels(t *testing.T) {
   250  	cases := []struct {
   251  		Name       string
   252  		Labels     []string
   253  		PullLabels []*gitea.Label
   254  		Expect     bool
   255  	}{
   256  		{
   257  			Name:   "Match labels",
   258  			Labels: []string{"label1", "label2"},
   259  			PullLabels: []*gitea.Label{
   260  				{Name: "label1"},
   261  				{Name: "label2"},
   262  				{Name: "label3"},
   263  			},
   264  			Expect: true,
   265  		},
   266  		{
   267  			Name:   "Not match labels",
   268  			Labels: []string{"label1", "label4"},
   269  			PullLabels: []*gitea.Label{
   270  				{Name: "label1"},
   271  				{Name: "label2"},
   272  				{Name: "label3"},
   273  			},
   274  			Expect: false,
   275  		},
   276  		{
   277  			Name:   "No specify",
   278  			Labels: []string{},
   279  			PullLabels: []*gitea.Label{
   280  				{Name: "label1"},
   281  				{Name: "label2"},
   282  				{Name: "label3"},
   283  			},
   284  			Expect: true,
   285  		},
   286  	}
   287  
   288  	for _, c := range cases {
   289  		t.Run(c.Name, func(t *testing.T) {
   290  			if got := giteaContainLabels(c.Labels, c.PullLabels); got != c.Expect {
   291  				t.Errorf("expect: %v, got: %v", c.Expect, got)
   292  			}
   293  		})
   294  	}
   295  }
   296  
   297  func TestGiteaList(t *testing.T) {
   298  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   299  		giteaMockHandler(t)(w, r)
   300  	}))
   301  	host, err := NewGiteaService("", ts.URL, "test-argocd", "pr-test", []string{"label1"}, false)
   302  	require.NoError(t, err)
   303  	prs, err := host.List(t.Context())
   304  	require.NoError(t, err)
   305  	assert.Len(t, prs, 1)
   306  	assert.Equal(t, 1, prs[0].Number)
   307  	assert.Equal(t, "add an empty file", prs[0].Title)
   308  	assert.Equal(t, "test", prs[0].Branch)
   309  	assert.Equal(t, "main", prs[0].TargetBranch)
   310  	assert.Equal(t, "7bbaf62d92ddfafd9cc8b340c619abaec32bc09f", prs[0].HeadSHA)
   311  	assert.Equal(t, "graytshirt", prs[0].Author)
   312  }
   313  
   314  func TestGetGiteaPRLabelNames(t *testing.T) {
   315  	Tests := []struct {
   316  		Name           string
   317  		PullLabels     []*gitea.Label
   318  		ExpectedResult []string
   319  	}{
   320  		{
   321  			Name: "PR has labels",
   322  			PullLabels: []*gitea.Label{
   323  				{Name: "label1"},
   324  				{Name: "label2"},
   325  				{Name: "label3"},
   326  			},
   327  			ExpectedResult: []string{"label1", "label2", "label3"},
   328  		},
   329  		{
   330  			Name:           "PR does not have labels",
   331  			PullLabels:     []*gitea.Label{},
   332  			ExpectedResult: nil,
   333  		},
   334  	}
   335  	for _, test := range Tests {
   336  		t.Run(test.Name, func(t *testing.T) {
   337  			labels := getGiteaPRLabelNames(test.PullLabels)
   338  			assert.Equal(t, test.ExpectedResult, labels)
   339  		})
   340  	}
   341  }
   342  
   343  func TestGiteaListReturnsRepositoryNotFoundError(t *testing.T) {
   344  	mux := http.NewServeMux()
   345  	server := httptest.NewServer(mux)
   346  	defer server.Close()
   347  
   348  	// Handle version endpoint that Gitea client calls first
   349  	mux.HandleFunc("/api/v1/version", func(w http.ResponseWriter, _ *http.Request) {
   350  		w.Header().Set("Content-Type", "application/json")
   351  		_, _ = w.Write([]byte(`{"version":"1.17.0+dev-452-g1f0541780"}`))
   352  	})
   353  
   354  	path := "/api/v1/repos/nonexistent/nonexistent/pulls?limit=0&page=1&state=open"
   355  
   356  	mux.HandleFunc(path, func(w http.ResponseWriter, _ *http.Request) {
   357  		// Return 404 status to simulate repository not found
   358  		w.WriteHeader(http.StatusNotFound)
   359  		_, _ = w.Write([]byte(`{"message": "404 Project Not Found"}`))
   360  	})
   361  
   362  	svc, err := NewGiteaService("", server.URL, "nonexistent", "nonexistent", []string{}, false)
   363  	require.NoError(t, err)
   364  
   365  	prs, err := svc.List(t.Context())
   366  
   367  	// Should return empty pull requests list
   368  	assert.Empty(t, prs)
   369  
   370  	// Should return RepositoryNotFoundError
   371  	require.Error(t, err)
   372  	assert.True(t, IsRepositoryNotFoundError(err), "Expected RepositoryNotFoundError but got: %v", err)
   373  }