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

     1  package pull_request
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"testing"
     7  
     8  	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/core"
     9  	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/git"
    10  	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/webapi"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/mock"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	azureMock "github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider/azure_devops/git/mocks"
    16  )
    17  
    18  func createBoolPtr(x bool) *bool {
    19  	return &x
    20  }
    21  
    22  func createStringPtr(x string) *string {
    23  	return &x
    24  }
    25  
    26  func createIntPtr(x int) *int {
    27  	return &x
    28  }
    29  
    30  func createLabelsPtr(x []core.WebApiTagDefinition) *[]core.WebApiTagDefinition {
    31  	return &x
    32  }
    33  
    34  func createUniqueNamePtr(x string) *string {
    35  	return &x
    36  }
    37  
    38  type AzureClientFactoryMock struct {
    39  	mock *mock.Mock
    40  }
    41  
    42  func (m *AzureClientFactoryMock) GetClient(ctx context.Context) (git.Client, error) {
    43  	args := m.mock.Called(ctx)
    44  
    45  	var client git.Client
    46  	c := args.Get(0)
    47  	if c != nil {
    48  		client = c.(git.Client)
    49  	}
    50  
    51  	var err error
    52  	if len(args) > 1 {
    53  		if e, ok := args.Get(1).(error); ok {
    54  			err = e
    55  		}
    56  	}
    57  
    58  	return client, err
    59  }
    60  
    61  func TestListPullRequest(t *testing.T) {
    62  	teamProject := "myorg_project"
    63  	repoName := "myorg_project_repo"
    64  	prID := 123
    65  	prTitle := "feat(123)"
    66  	prHeadSha := "cd4973d9d14a08ffe6b641a89a68891d6aac8056"
    67  	ctx := t.Context()
    68  	uniqueName := "testName"
    69  
    70  	pullRequestMock := []git.GitPullRequest{
    71  		{
    72  			PullRequestId: createIntPtr(prID),
    73  			Title:         createStringPtr(prTitle),
    74  			SourceRefName: createStringPtr("refs/heads/feature-branch"),
    75  			TargetRefName: createStringPtr("refs/heads/main"),
    76  			LastMergeSourceCommit: &git.GitCommitRef{
    77  				CommitId: createStringPtr(prHeadSha),
    78  			},
    79  			Labels: &[]core.WebApiTagDefinition{},
    80  			Repository: &git.GitRepository{
    81  				Name: createStringPtr(repoName),
    82  			},
    83  			CreatedBy: &webapi.IdentityRef{
    84  				UniqueName: createUniqueNamePtr(uniqueName + "@example.com"),
    85  			},
    86  		},
    87  	}
    88  
    89  	args := git.GetPullRequestsByProjectArgs{
    90  		Project:        &teamProject,
    91  		SearchCriteria: &git.GitPullRequestSearchCriteria{},
    92  	}
    93  
    94  	gitClientMock := azureMock.Client{}
    95  	clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}}
    96  	clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, nil)
    97  	gitClientMock.On("GetPullRequestsByProject", ctx, args).Return(&pullRequestMock, nil)
    98  
    99  	provider := AzureDevOpsService{
   100  		clientFactory: clientFactoryMock,
   101  		project:       teamProject,
   102  		repo:          repoName,
   103  		labels:        nil,
   104  	}
   105  
   106  	list, err := provider.List(ctx)
   107  	require.NoError(t, err)
   108  	assert.Len(t, list, 1)
   109  	assert.Equal(t, "feature-branch", list[0].Branch)
   110  	assert.Equal(t, "main", list[0].TargetBranch)
   111  	assert.Equal(t, prHeadSha, list[0].HeadSHA)
   112  	assert.Equal(t, "feat(123)", list[0].Title)
   113  	assert.Equal(t, prID, list[0].Number)
   114  	assert.Equal(t, uniqueName, list[0].Author)
   115  }
   116  
   117  func TestConvertLabes(t *testing.T) {
   118  	testCases := []struct {
   119  		name           string
   120  		gotLabels      *[]core.WebApiTagDefinition
   121  		expectedLabels []string
   122  	}{
   123  		{
   124  			name:           "empty labels",
   125  			gotLabels:      createLabelsPtr([]core.WebApiTagDefinition{}),
   126  			expectedLabels: []string{},
   127  		},
   128  		{
   129  			name:           "nil labels",
   130  			gotLabels:      createLabelsPtr(nil),
   131  			expectedLabels: []string{},
   132  		},
   133  		{
   134  			name: "one label",
   135  			gotLabels: createLabelsPtr([]core.WebApiTagDefinition{
   136  				{Name: createStringPtr("label1"), Active: createBoolPtr(true)},
   137  			}),
   138  			expectedLabels: []string{"label1"},
   139  		},
   140  		{
   141  			name: "two label",
   142  			gotLabels: createLabelsPtr([]core.WebApiTagDefinition{
   143  				{Name: createStringPtr("label1"), Active: createBoolPtr(true)},
   144  				{Name: createStringPtr("label2"), Active: createBoolPtr(true)},
   145  			}),
   146  			expectedLabels: []string{"label1", "label2"},
   147  		},
   148  	}
   149  
   150  	for _, tc := range testCases {
   151  		t.Run(tc.name, func(t *testing.T) {
   152  			got := convertLabels(tc.gotLabels)
   153  			assert.Equal(t, tc.expectedLabels, got)
   154  		})
   155  	}
   156  }
   157  
   158  func TestContainAzureDevOpsLabels(t *testing.T) {
   159  	testCases := []struct {
   160  		name           string
   161  		expectedLabels []string
   162  		gotLabels      []string
   163  		expectedResult bool
   164  	}{
   165  		{
   166  			name:           "empty labels",
   167  			expectedLabels: []string{},
   168  			gotLabels:      []string{},
   169  			expectedResult: true,
   170  		},
   171  		{
   172  			name:           "no matching labels",
   173  			expectedLabels: []string{"label1", "label2"},
   174  			gotLabels:      []string{"label3", "label4"},
   175  			expectedResult: false,
   176  		},
   177  		{
   178  			name:           "some matching labels",
   179  			expectedLabels: []string{"label1", "label2"},
   180  			gotLabels:      []string{"label1", "label3"},
   181  			expectedResult: false,
   182  		},
   183  		{
   184  			name:           "all matching labels",
   185  			expectedLabels: []string{"label1", "label2"},
   186  			gotLabels:      []string{"label1", "label2"},
   187  			expectedResult: true,
   188  		},
   189  	}
   190  
   191  	for _, tc := range testCases {
   192  		t.Run(tc.name, func(t *testing.T) {
   193  			got := containAzureDevOpsLabels(tc.expectedLabels, tc.gotLabels)
   194  			assert.Equal(t, tc.expectedResult, got)
   195  		})
   196  	}
   197  }
   198  
   199  func TestBuildURL(t *testing.T) {
   200  	testCases := []struct {
   201  		name         string
   202  		url          string
   203  		organization string
   204  		expected     string
   205  	}{
   206  		{
   207  			name:         "Provided default URL and organization",
   208  			url:          "https://dev.azure.com/",
   209  			organization: "myorganization",
   210  			expected:     "https://dev.azure.com/myorganization",
   211  		},
   212  		{
   213  			name:         "Provided default URL and organization without trailing slash",
   214  			url:          "https://dev.azure.com",
   215  			organization: "myorganization",
   216  			expected:     "https://dev.azure.com/myorganization",
   217  		},
   218  		{
   219  			name:         "Provided no URL and organization",
   220  			url:          "",
   221  			organization: "myorganization",
   222  			expected:     "https://dev.azure.com/myorganization",
   223  		},
   224  		{
   225  			name:         "Provided custom URL and organization",
   226  			url:          "https://azuredevops.example.com/",
   227  			organization: "myorganization",
   228  			expected:     "https://azuredevops.example.com/myorganization",
   229  		},
   230  	}
   231  
   232  	for _, tc := range testCases {
   233  		t.Run(tc.name, func(t *testing.T) {
   234  			result := buildURL(tc.url, tc.organization)
   235  			assert.Equal(t, tc.expected, result)
   236  		})
   237  	}
   238  }
   239  
   240  func TestAzureDevOpsListReturnsRepositoryNotFoundError(t *testing.T) {
   241  	args := git.GetPullRequestsByProjectArgs{
   242  		Project:        createStringPtr("nonexistent"),
   243  		SearchCriteria: &git.GitPullRequestSearchCriteria{},
   244  	}
   245  
   246  	pullRequestMock := []git.GitPullRequest{}
   247  
   248  	gitClientMock := azureMock.Client{}
   249  	clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}}
   250  	clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, nil)
   251  
   252  	// Mock the GetPullRequestsByProject to return an error containing "404"
   253  	gitClientMock.On("GetPullRequestsByProject", t.Context(), args).Return(&pullRequestMock,
   254  		errors.New("The following project does not exist:"))
   255  
   256  	provider := AzureDevOpsService{
   257  		clientFactory: clientFactoryMock,
   258  		project:       "nonexistent",
   259  		repo:          "nonexistent",
   260  		labels:        nil,
   261  	}
   262  
   263  	prs, err := provider.List(t.Context())
   264  
   265  	// Should return empty pull requests list
   266  	assert.Empty(t, prs)
   267  
   268  	// Should return RepositoryNotFoundError
   269  	require.Error(t, err)
   270  	assert.True(t, IsRepositoryNotFoundError(err), "Expected RepositoryNotFoundError but got: %v", err)
   271  }