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

     1  package pull_request
     2  
     3  import (
     4  	"crypto/x509"
     5  	"encoding/pem"
     6  	"io"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"os"
    10  	"testing"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  func writeMRListResponse(t *testing.T, w io.Writer) {
    17  	t.Helper()
    18  	f, err := os.Open("fixtures/gitlab_mr_list_response.json")
    19  	require.NoErrorf(t, err, "error opening fixture file: %v", err)
    20  
    21  	_, err = io.Copy(w, f)
    22  	require.NoErrorf(t, err, "error writing response: %v", err)
    23  }
    24  
    25  func TestGitLabServiceCustomBaseURL(t *testing.T) {
    26  	mux := http.NewServeMux()
    27  	server := httptest.NewServer(mux)
    28  	defer server.Close()
    29  
    30  	path := "/api/v4/projects/278964/merge_requests"
    31  
    32  	mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
    33  		assert.Equal(t, path+"?per_page=100", r.URL.RequestURI())
    34  		writeMRListResponse(t, w)
    35  	})
    36  
    37  	svc, err := NewGitLabService("", server.URL, "278964", nil, "", "", false, nil)
    38  	require.NoError(t, err)
    39  
    40  	_, err = svc.List(t.Context())
    41  	require.NoError(t, err)
    42  }
    43  
    44  func TestGitLabServiceToken(t *testing.T) {
    45  	mux := http.NewServeMux()
    46  	server := httptest.NewServer(mux)
    47  	defer server.Close()
    48  
    49  	path := "/api/v4/projects/278964/merge_requests"
    50  
    51  	mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
    52  		assert.Equal(t, "token-123", r.Header.Get("Private-Token"))
    53  		writeMRListResponse(t, w)
    54  	})
    55  
    56  	svc, err := NewGitLabService("token-123", server.URL, "278964", nil, "", "", false, nil)
    57  	require.NoError(t, err)
    58  
    59  	_, err = svc.List(t.Context())
    60  	require.NoError(t, err)
    61  }
    62  
    63  func TestList(t *testing.T) {
    64  	mux := http.NewServeMux()
    65  	server := httptest.NewServer(mux)
    66  	defer server.Close()
    67  
    68  	path := "/api/v4/projects/278964/merge_requests"
    69  
    70  	mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
    71  		assert.Equal(t, path+"?per_page=100", r.URL.RequestURI())
    72  		writeMRListResponse(t, w)
    73  	})
    74  
    75  	svc, err := NewGitLabService("", server.URL, "278964", []string{}, "", "", false, nil)
    76  	require.NoError(t, err)
    77  
    78  	prs, err := svc.List(t.Context())
    79  	require.NoError(t, err)
    80  	assert.Len(t, prs, 1)
    81  	assert.Equal(t, 15442, prs[0].Number)
    82  	assert.Equal(t, "Draft: Use structured logging for DB load balancer", prs[0].Title)
    83  	assert.Equal(t, "use-structured-logging-for-db-load-balancer", prs[0].Branch)
    84  	assert.Equal(t, "master", prs[0].TargetBranch)
    85  	assert.Equal(t, "2fc4e8b972ff3208ec63b6143e34ad67ff343ad7", prs[0].HeadSHA)
    86  	assert.Equal(t, "hfyngvason", prs[0].Author)
    87  }
    88  
    89  func TestListWithLabels(t *testing.T) {
    90  	mux := http.NewServeMux()
    91  	server := httptest.NewServer(mux)
    92  	defer server.Close()
    93  
    94  	path := "/api/v4/projects/278964/merge_requests"
    95  
    96  	mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
    97  		assert.Equal(t, path+"?labels=feature%2Cready&per_page=100", r.URL.RequestURI())
    98  		writeMRListResponse(t, w)
    99  	})
   100  
   101  	svc, err := NewGitLabService("", server.URL, "278964", []string{"feature", "ready"}, "", "", false, nil)
   102  	require.NoError(t, err)
   103  
   104  	_, err = svc.List(t.Context())
   105  	require.NoError(t, err)
   106  }
   107  
   108  func TestListWithState(t *testing.T) {
   109  	mux := http.NewServeMux()
   110  	server := httptest.NewServer(mux)
   111  	defer server.Close()
   112  
   113  	path := "/api/v4/projects/278964/merge_requests"
   114  
   115  	mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
   116  		assert.Equal(t, path+"?per_page=100&state=opened", r.URL.RequestURI())
   117  		writeMRListResponse(t, w)
   118  	})
   119  
   120  	svc, err := NewGitLabService("", server.URL, "278964", []string{}, "opened", "", false, nil)
   121  	require.NoError(t, err)
   122  
   123  	_, err = svc.List(t.Context())
   124  	require.NoError(t, err)
   125  }
   126  
   127  func TestListWithStateTLS(t *testing.T) {
   128  	tests := []struct {
   129  		name        string
   130  		tlsInsecure bool
   131  		passCerts   bool
   132  		requireErr  bool
   133  	}{
   134  		{
   135  			name:        "TLS Insecure: true, No Certs",
   136  			tlsInsecure: true,
   137  			passCerts:   false,
   138  			requireErr:  false,
   139  		},
   140  		{
   141  			name:        "TLS Insecure: true, With Certs",
   142  			tlsInsecure: true,
   143  			passCerts:   true,
   144  			requireErr:  false,
   145  		},
   146  		{
   147  			name:        "TLS Insecure: false, With Certs",
   148  			tlsInsecure: false,
   149  			passCerts:   true,
   150  			requireErr:  false,
   151  		},
   152  		{
   153  			name:        "TLS Insecure: false, No Certs",
   154  			tlsInsecure: false,
   155  			passCerts:   false,
   156  			requireErr:  true,
   157  		},
   158  	}
   159  
   160  	for _, test := range tests {
   161  		test := test
   162  		t.Run(test.name, func(t *testing.T) {
   163  			ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
   164  				writeMRListResponse(t, w)
   165  			}))
   166  			defer ts.Close()
   167  
   168  			var certs []byte
   169  			if test.passCerts {
   170  				for _, cert := range ts.TLS.Certificates {
   171  					for _, c := range cert.Certificate {
   172  						parsedCert, err := x509.ParseCertificate(c)
   173  						require.NoError(t, err, "Failed to parse certificate")
   174  						certs = append(certs, pem.EncodeToMemory(&pem.Block{
   175  							Type:  "CERTIFICATE",
   176  							Bytes: parsedCert.Raw,
   177  						})...)
   178  					}
   179  				}
   180  			}
   181  
   182  			svc, err := NewGitLabService("", ts.URL, "278964", []string{}, "opened", "", test.tlsInsecure, certs)
   183  			require.NoError(t, err)
   184  
   185  			_, err = svc.List(t.Context())
   186  			if test.requireErr {
   187  				require.Error(t, err)
   188  			} else {
   189  				require.NoError(t, err)
   190  			}
   191  		})
   192  	}
   193  }
   194  
   195  func TestGitLabListReturnsRepositoryNotFoundError(t *testing.T) {
   196  	mux := http.NewServeMux()
   197  	server := httptest.NewServer(mux)
   198  	defer server.Close()
   199  
   200  	path := "/api/v4/projects/nonexistent/merge_requests"
   201  
   202  	mux.HandleFunc(path, func(w http.ResponseWriter, _ *http.Request) {
   203  		// Return 404 status to simulate repository not found
   204  		w.WriteHeader(http.StatusNotFound)
   205  		_, _ = w.Write([]byte(`{"message": "404 Project Not Found"}`))
   206  	})
   207  
   208  	svc, err := NewGitLabService("", server.URL, "nonexistent", []string{}, "", "", false, nil)
   209  	require.NoError(t, err)
   210  
   211  	prs, err := svc.List(t.Context())
   212  
   213  	// Should return empty pull requests list
   214  	assert.Empty(t, prs)
   215  
   216  	// Should return RepositoryNotFoundError
   217  	require.Error(t, err)
   218  	assert.True(t, IsRepositoryNotFoundError(err), "Expected RepositoryNotFoundError but got: %v", err)
   219  }