github.com/argoproj/argo-cd/v2@v2.10.9/server/deeplinks/deeplinks_test.go (about)

     1  package deeplinks
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/argoproj/gitops-engine/pkg/utils/kube"
     9  	"github.com/stretchr/testify/assert"
    10  	v1 "k8s.io/api/core/v1"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    13  	"k8s.io/utils/pointer"
    14  
    15  	"github.com/argoproj/argo-cd/v2/pkg/apiclient/application"
    16  	"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
    17  	"github.com/argoproj/argo-cd/v2/util/settings"
    18  )
    19  
    20  type deepLinkTC struct {
    21  	appObj      *unstructured.Unstructured
    22  	clusterObj  *unstructured.Unstructured
    23  	resourceObj *unstructured.Unstructured
    24  	projectObj  *unstructured.Unstructured
    25  	inputLinks  []settings.DeepLink
    26  	outputLinks []*application.LinkInfo
    27  	error       []string
    28  }
    29  
    30  func TestDeepLinks(t *testing.T) {
    31  	appObj, err := kube.ToUnstructured(&v1alpha1.Application{
    32  		ObjectMeta: metav1.ObjectMeta{
    33  			Name:      "test",
    34  			Namespace: "test",
    35  		},
    36  		Spec: v1alpha1.ApplicationSpec{
    37  			Destination: v1alpha1.ApplicationDestination{
    38  				Server:    "test.example.com",
    39  				Namespace: "testns",
    40  			},
    41  		},
    42  	})
    43  	assert.NoError(t, err)
    44  	resourceObj, err := kube.ToUnstructured(&v1.ConfigMap{
    45  		ObjectMeta: metav1.ObjectMeta{
    46  			Name:      "test-cm",
    47  			Namespace: "test-cm",
    48  			Labels:    map[string]string{"test-label": "cm-value"},
    49  		},
    50  		Data: map[string]string{
    51  			"key": "value1",
    52  		},
    53  	})
    54  	assert.NoError(t, err)
    55  	clusterObj, err := kube.ToUnstructured(&ClusterLinksData{
    56  		Server: "test-svc.com",
    57  		Name:   "test-cluster",
    58  	})
    59  	assert.NoError(t, err)
    60  	projectObj, err := kube.ToUnstructured(&v1alpha1.AppProject{
    61  		ObjectMeta: metav1.ObjectMeta{
    62  			Name:      "test-project",
    63  			Namespace: "test-project",
    64  		},
    65  		Spec: v1alpha1.AppProjectSpec{
    66  			SourceRepos: []string{"test-repo.git"},
    67  		},
    68  	})
    69  	assert.NoError(t, err)
    70  	testTable := []deepLinkTC{
    71  		{
    72  			appObj:      appObj,
    73  			resourceObj: resourceObj,
    74  			projectObj:  projectObj,
    75  			clusterObj:  clusterObj,
    76  			inputLinks: []settings.DeepLink{{
    77  				Title:     "link",
    78  				URL:       "http://example.com/{{ .application.metadata.name }}&{{ .resource.data.key }}&{{ index .project.spec.sourceRepos 0}}&{{ .cluster.name }}",
    79  				Condition: pointer.String(`application.metadata.name == "test" && project.metadata.name == "test-project"`),
    80  			}},
    81  			outputLinks: []*application.LinkInfo{{
    82  				Title: pointer.String("link"),
    83  				Url:   pointer.String("http://example.com/test&value1&test-repo.git&test-cluster"),
    84  			}},
    85  			error: []string{},
    86  		},
    87  		{
    88  			appObj:      appObj,
    89  			resourceObj: resourceObj,
    90  			projectObj:  projectObj,
    91  			clusterObj:  clusterObj,
    92  			inputLinks: []settings.DeepLink{{
    93  				Title:     "link",
    94  				URL:       "http://example.com/{{ .app.metadata.name }}&{{ .resource.data.key }}&{{ index .project.spec.sourceRepos 0}}&{{ .cluster.name }}",
    95  				Condition: pointer.String(`app.metadata.name == "test" && project.metadata.name == "test-project"`),
    96  			}},
    97  			outputLinks: []*application.LinkInfo{{
    98  				Title: pointer.String("link"),
    99  				Url:   pointer.String("http://example.com/test&value1&test-repo.git&test-cluster"),
   100  			}},
   101  			error: []string{},
   102  		},
   103  		{
   104  			appObj:      appObj,
   105  			resourceObj: resourceObj,
   106  			projectObj:  projectObj,
   107  			inputLinks: []settings.DeepLink{
   108  				{
   109  					Title:     "link",
   110  					URL:       "http://example.com/{{ .application.metadata.name }}&{{ .application.spec.destination.namespace }}",
   111  					Condition: pointer.String(`application.metadata.name matches "test"`),
   112  				},
   113  				{
   114  					Title:     "link1",
   115  					URL:       "http://example.com/{{ .application.metadata.name }}&{{ .application.spec.destination.namespace }}",
   116  					Condition: pointer.String(`application.metadata.name matches "test1"`),
   117  				},
   118  				{
   119  					Title:     "link2",
   120  					URL:       "http://example.com/{{ .application.metadata.name }}&{{ .application.spec.destination.namespace }}",
   121  					Condition: pointer.String(`application.metadata.test matches "test"`),
   122  				}},
   123  			outputLinks: []*application.LinkInfo{{
   124  				Title: pointer.String("link"),
   125  				Url:   pointer.String("http://example.com/test&testns"),
   126  			}},
   127  			error: []string{"failed to evaluate link condition 'application.metadata.test matches \"test\"' with resource test, error=interface conversion: interface {} is nil, not string (1:27)\n | application.metadata.test matches \"test\"\n | ..........................^"},
   128  		},
   129  		{
   130  			appObj:      appObj,
   131  			resourceObj: resourceObj,
   132  			projectObj:  projectObj,
   133  			inputLinks: []settings.DeepLink{
   134  				{
   135  					Title:     "link",
   136  					URL:       "http://example.com/{{ .application.metadata.name }}&{{ .application.spec.destination.namespace }}",
   137  					Condition: pointer.String(`application.metadata.name matches "test"`),
   138  				},
   139  				{
   140  					Title:     "link1",
   141  					URL:       "http://example.com/{{ .application.metadata.name }}&{{ .application.spec.destination.namespace }}",
   142  					Condition: pointer.String(`1 + 1`),
   143  				}},
   144  			outputLinks: []*application.LinkInfo{{
   145  				Title: pointer.String("link"),
   146  				Url:   pointer.String("http://example.com/test&testns"),
   147  			}},
   148  			error: []string{"link condition '1 + 1' evaluated to non-boolean value for resource test"},
   149  		},
   150  		{
   151  			appObj:      appObj,
   152  			resourceObj: resourceObj,
   153  			projectObj:  projectObj,
   154  			clusterObj:  clusterObj,
   155  			inputLinks: []settings.DeepLink{{
   156  				Title:     "link",
   157  				URL:       "http://example.com/{{ .cluster.name | replace \"-\" \"_\" }}&{{ first .project.spec.sourceRepos }}",
   158  				Condition: pointer.String(`application.metadata.name == "test" && project.metadata.name == "test-project"`),
   159  			}},
   160  			outputLinks: []*application.LinkInfo{{
   161  				Title: pointer.String("link"),
   162  				Url:   pointer.String("http://example.com/test_cluster&test-repo.git"),
   163  			}},
   164  			error: []string{},
   165  		},
   166  	}
   167  
   168  	for _, tc := range testTable {
   169  		objs := CreateDeepLinksObject(tc.resourceObj, tc.appObj, tc.clusterObj, tc.projectObj)
   170  		output, err := EvaluateDeepLinksResponse(objs, tc.appObj.GetName(), tc.inputLinks)
   171  		assert.Equal(t, tc.error, err, strings.Join(err, ","))
   172  		assert.Equal(t, reflect.DeepEqual(output.Items, tc.outputLinks), true)
   173  	}
   174  }