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 }