github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/tenantfetchersvc/resync/client_test.go (about) 1 package resync_test 2 3 import ( 4 "context" 5 "crypto/tls" 6 "fmt" 7 "io" 8 "net/http" 9 "net/http/httptest" 10 "testing" 11 "time" 12 13 "github.com/kyma-incubator/compass/components/director/internal/tenantfetchersvc/resync" 14 "golang.org/x/oauth2" 15 "golang.org/x/oauth2/clientcredentials" 16 17 "github.com/kyma-incubator/compass/components/director/pkg/oauth" 18 19 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 20 21 "github.com/stretchr/testify/assert" 22 "github.com/stretchr/testify/require" 23 ) 24 25 func TestClient_FetchTenantEventsPage(t *testing.T) { 26 // GIVEN 27 ctx := context.TODO() 28 mockClient, mockServerCloseFn, endpoint := fixHTTPClient(t) 29 defer mockServerCloseFn() 30 31 queryParams := resync.QueryParams{ 32 "pageSize": "1", 33 "pageNum": "1", 34 "timestamp": "1", 35 } 36 37 subaccountQueryParams := resync.QueryParams{ 38 "pageSize": "1", 39 "pageNum": "1", 40 "timestamp": "1", 41 "region": "test-region", 42 } 43 44 clientCfg := resync.ClientConfig{ 45 TenantProvider: "", 46 APIConfig: resync.APIEndpointsConfig{ 47 EndpointTenantCreated: endpoint + "/ga-created", 48 EndpointTenantDeleted: endpoint + "/ga-deleted", 49 EndpointTenantUpdated: endpoint + "/ga-updated", 50 EndpointSubaccountCreated: endpoint + "/sub-created", 51 EndpointSubaccountDeleted: endpoint + "/sub-deleted", 52 EndpointSubaccountUpdated: endpoint + "/sub-updated", 53 EndpointSubaccountMoved: endpoint + "/sub-moved", 54 }, 55 FieldMapping: resync.TenantFieldMapping{}, 56 MovedSAFieldMapping: resync.MovedSubaccountsFieldMapping{}, 57 } 58 59 client, err := resync.NewClient(resync.OAuth2Config{}, oauth.Standard, clientCfg, time.Second) 60 require.NoError(t, err) 61 62 client.SetHTTPClient(mockClient) 63 64 t.Run("Success fetching account creation events", func(t *testing.T) { 65 // WHEN 66 res, err := client.FetchTenantEventsPage(ctx, resync.CreatedAccountType, queryParams) 67 // THEN 68 require.NoError(t, err) 69 assert.NotEmpty(t, res) 70 }) 71 72 t.Run("Success fetching account update events", func(t *testing.T) { 73 // WHEN 74 res, err := client.FetchTenantEventsPage(ctx, resync.UpdatedAccountType, queryParams) 75 // THEN 76 require.NoError(t, err) 77 assert.NotEmpty(t, res) 78 }) 79 80 t.Run("Success fetching account deletion events", func(t *testing.T) { 81 // WHEN 82 res, err := client.FetchTenantEventsPage(ctx, resync.DeletedAccountType, queryParams) 83 // THEN 84 require.NoError(t, err) 85 assert.NotEmpty(t, res) 86 }) 87 88 t.Run("Success fetching subaccount creation events", func(t *testing.T) { 89 // WHEN 90 res, err := client.FetchTenantEventsPage(ctx, resync.CreatedSubaccountType, subaccountQueryParams) 91 // THEN 92 require.NoError(t, err) 93 assert.NotEmpty(t, res) 94 }) 95 96 t.Run("Success fetching subaccount update events", func(t *testing.T) { 97 // WHEN 98 res, err := client.FetchTenantEventsPage(ctx, resync.UpdatedSubaccountType, subaccountQueryParams) 99 // THEN 100 require.NoError(t, err) 101 assert.NotEmpty(t, res) 102 }) 103 104 t.Run("Success fetching subaccount deletion events", func(t *testing.T) { 105 // WHEN 106 res, err := client.FetchTenantEventsPage(ctx, resync.DeletedSubaccountType, subaccountQueryParams) 107 // THEN 108 require.NoError(t, err) 109 assert.NotEmpty(t, res) 110 }) 111 112 t.Run("Success fetching moved subaccount events", func(t *testing.T) { 113 // WHEN 114 res, err := client.FetchTenantEventsPage(ctx, resync.MovedSubaccountType, subaccountQueryParams) 115 // THEN 116 require.NoError(t, err) 117 assert.NotEmpty(t, res) 118 }) 119 120 t.Run("Error when unknown events type", func(t *testing.T) { 121 // WHEN 122 res, err := client.FetchTenantEventsPage(ctx, -1, queryParams) 123 // THEN 124 require.EqualError(t, err, apperrors.NewInternalError("unknown events type").Error()) 125 assert.Empty(t, res) 126 }) 127 128 // GIVEN 129 clientCfg = resync.ClientConfig{ 130 TenantProvider: "", 131 APIConfig: resync.APIEndpointsConfig{ 132 EndpointTenantCreated: "___ :// ___ ", 133 EndpointTenantDeleted: "http://127.0.0.1:8111/badpath", 134 EndpointTenantUpdated: endpoint + "/empty", 135 }, 136 FieldMapping: resync.TenantFieldMapping{}, 137 MovedSAFieldMapping: resync.MovedSubaccountsFieldMapping{}, 138 } 139 140 client, err = resync.NewClient(resync.OAuth2Config{}, oauth.Standard, clientCfg, time.Second) 141 require.NoError(t, err) 142 143 client.SetHTTPClient(mockClient) 144 145 t.Run("Success when no content", func(t *testing.T) { 146 // WHEN 147 res, err := client.FetchTenantEventsPage(ctx, resync.UpdatedAccountType, queryParams) 148 // THEN 149 require.NoError(t, err) 150 require.Empty(t, res) 151 }) 152 153 t.Run("Error when endpoint not parsable", func(t *testing.T) { 154 // WHEN 155 res, err := client.FetchTenantEventsPage(ctx, resync.CreatedAccountType, queryParams) 156 // THEN 157 require.EqualError(t, err, "parse \"___ :// ___ \": first path segment in URL cannot contain colon") 158 assert.Empty(t, res) 159 }) 160 161 t.Run("Error when bad path", func(t *testing.T) { 162 // WHEN 163 res, err := client.FetchTenantEventsPage(ctx, resync.DeletedAccountType, queryParams) 164 // THEN 165 require.EqualError(t, err, "while sending get request: Get \"http://127.0.0.1:8111/badpath?pageNum=1&pageSize=1×tamp=1\": dial tcp 127.0.0.1:8111: connect: connection refused") 166 assert.Empty(t, res) 167 }) 168 169 // GIVEN 170 clientCfg = resync.ClientConfig{ 171 TenantProvider: "", 172 APIConfig: resync.APIEndpointsConfig{ 173 EndpointTenantCreated: endpoint + "/created", 174 EndpointTenantDeleted: endpoint + "/deleted", 175 EndpointTenantUpdated: endpoint + "/badRequest", 176 }, 177 FieldMapping: resync.TenantFieldMapping{}, 178 MovedSAFieldMapping: resync.MovedSubaccountsFieldMapping{}, 179 } 180 client, err = resync.NewClient(resync.OAuth2Config{}, oauth.Standard, clientCfg, time.Second) 181 require.NoError(t, err) 182 183 client.SetHTTPClient(mockClient) 184 185 t.Run("Error when status code not equal to 200 OK and 204 No Content is returned", func(t *testing.T) { 186 // WHEN 187 res, err := client.FetchTenantEventsPage(ctx, resync.UpdatedAccountType, queryParams) 188 // THEN 189 require.EqualError(t, err, fmt.Sprintf("request to \"%s/badRequest?pageNum=1&pageSize=1×tamp=1\" returned status code 400 and body \"\"", endpoint)) 190 assert.Empty(t, res) 191 }) 192 193 // GIVEN 194 clientCfg = resync.ClientConfig{ 195 APIConfig: resync.APIEndpointsConfig{EndpointSubaccountMoved: ""}, 196 } 197 client, err = resync.NewClient(resync.OAuth2Config{}, oauth.Standard, clientCfg, time.Second) 198 require.NoError(t, err) 199 200 client.SetHTTPClient(mockClient) 201 202 t.Run("Skip fetching moved subaccount events when endpoint is not provided", func(t *testing.T) { 203 // WHEN 204 res, err := client.FetchTenantEventsPage(ctx, resync.MovedSubaccountType, queryParams) 205 // THEN 206 require.NoError(t, err) 207 require.Nil(t, res) 208 }) 209 } 210 211 func fixHTTPClient(t *testing.T) (*http.Client, func(), string) { 212 mux := http.NewServeMux() 213 214 mux.HandleFunc("/ga-created", func(w http.ResponseWriter, r *http.Request) { 215 w.Header().Set("Content-Type", "application/json") 216 w.WriteHeader(http.StatusOK) 217 _, err := io.WriteString(w, fixCreatedTenantsJSON()) 218 require.NoError(t, err) 219 }) 220 mux.HandleFunc("/ga-deleted", func(w http.ResponseWriter, r *http.Request) { 221 w.Header().Set("Content-Type", "application/json") 222 w.WriteHeader(http.StatusOK) 223 _, err := io.WriteString(w, fixDeletedAccountsJSON()) 224 require.NoError(t, err) 225 }) 226 mux.HandleFunc("/ga-updated", func(w http.ResponseWriter, r *http.Request) { 227 w.Header().Set("Content-Type", "application/json") 228 w.WriteHeader(http.StatusOK) 229 _, err := io.WriteString(w, fixUpdatedAccountsJSON()) 230 require.NoError(t, err) 231 }) 232 233 mux.HandleFunc("/sub-created", func(w http.ResponseWriter, r *http.Request) { 234 w.Header().Set("Content-Type", "application/json") 235 w.WriteHeader(http.StatusOK) 236 _, err := io.WriteString(w, fixCreatedSubaccountsJSON()) 237 require.NoError(t, err) 238 }) 239 mux.HandleFunc("/sub-deleted", func(w http.ResponseWriter, r *http.Request) { 240 w.Header().Set("Content-Type", "application/json") 241 w.WriteHeader(http.StatusOK) 242 _, err := io.WriteString(w, fixDeletedSubaccountsJSON()) 243 require.NoError(t, err) 244 }) 245 mux.HandleFunc("/sub-updated", func(w http.ResponseWriter, r *http.Request) { 246 w.Header().Set("Content-Type", "application/json") 247 w.WriteHeader(http.StatusOK) 248 _, err := io.WriteString(w, fixUpdatedSubaccountsJSON()) 249 require.NoError(t, err) 250 }) 251 mux.HandleFunc("/sub-moved", func(w http.ResponseWriter, r *http.Request) { 252 w.Header().Set("Content-Type", "application/json") 253 w.WriteHeader(http.StatusOK) 254 _, err := io.WriteString(w, fixMovedSubaccountsJSON()) 255 require.NoError(t, err) 256 }) 257 258 mux.HandleFunc("/empty", func(w http.ResponseWriter, r *http.Request) { 259 w.WriteHeader(http.StatusNoContent) 260 }) 261 mux.HandleFunc("/badRequest", func(w http.ResponseWriter, r *http.Request) { 262 w.WriteHeader(http.StatusBadRequest) 263 }) 264 265 ts := httptest.NewServer(mux) 266 267 return ts.Client(), ts.Close, ts.URL 268 } 269 270 func fixCreatedTenantsJSON() string { 271 return `{ 272 "events": [ 273 { 274 "id": 5, 275 "type": "GLOBALACCOUNT_CREATION", 276 "timestamp": "1579771215736", 277 "eventData": "{\"id\":\"55\",\"displayName\":\"TEN5\",\"model\":\"default\"}" 278 }, 279 { 280 "id": 4, 281 "type": "GLOBALACCOUNT_CREATION", 282 "timestamp": "1579771215636", 283 "eventData": "{\"id\":\"44\",\"displayName\":\"TEN4\",\"model\":\"default\"}" 284 }, 285 { 286 "id": 3, 287 "type": "GLOBALACCOUNT_CREATION", 288 "timestamp": "1579771215536", 289 "eventData": "{\"id\":\"33\",\"displayName\":\"TEN3\",\"model\":\"default\"}" 290 }, 291 { 292 "id": 2, 293 "type": "GLOBALACCOUNT_CREATION", 294 "timestamp": "1579771215436", 295 "eventData": "{\"id\":\"22\",\"displayName\":\"TEN2\",\"model\":\"default\"}" 296 }, 297 { 298 "id": 1, 299 "type": "GLOBALACCOUNT_CREATION", 300 "timestamp": "1579771215336", 301 "eventData": "{\"id\":\"11\",\"displayName\":\"TEN1\",\"model\":\"default\"}" 302 } 303 ], 304 "totalResults": 5, 305 "totalPages": 1 306 }` 307 } 308 309 func fixUpdatedAccountsJSON() string { 310 return `{ 311 "events": [ 312 { 313 "id": 2, 314 "type": "GLOBALACCOUNT_UPDATE", 315 "timestamp": "1579771215436", 316 "eventData": "{\"id\":\"22\",\"displayName\":\"TEN2\",\"model\":\"default\"}" 317 }, 318 { 319 "id": 1, 320 "type": "GLOBALACCOUNT_UPDATE", 321 "timestamp": "1579771215336", 322 "eventData": "{\"id\":\"11\",\"displayName\":\"TEN1\",\"model\":\"default\"}" 323 } 324 ], 325 "totalResults": 2, 326 "totalPages": 1 327 }` 328 } 329 330 func fixDeletedAccountsJSON() string { 331 return `{ 332 "events": [ 333 { 334 "id": 2, 335 "type": "GLOBALACCOUNT_DELETION", 336 "timestamp": "1579771215436", 337 "eventData": "{\"id\":\"22\",\"displayName\":\"TEN2\",\"model\":\"default\"}" 338 }, 339 { 340 "id": 1, 341 "type": "GLOBALACCOUNT_DELETION", 342 "timestamp": "1579771215336", 343 "eventData": "{\"id\":\"11\",\"displayName\":\"TEN1\",\"model\":\"default\"}" 344 } 345 ], 346 "totalResults": 2, 347 "totalPages": 1 348 }` 349 } 350 351 func fixCreatedSubaccountsJSON() string { 352 return `{ 353 "events": [ 354 { 355 "id": 5, 356 "type": "SUBACCOUNT_CREATION", 357 "region": "test-region", 358 "timestamp": "1579771215736", 359 "eventData": "{\"id\":\"55\",\"displayName\":\"TEN5\",\"model\":\"default\"}" 360 }, 361 { 362 "id": 4, 363 "type": "SUBACCOUNT_CREATION", 364 "region": "test-region", 365 "timestamp": "1579771215636", 366 "eventData": "{\"id\":\"44\",\"displayName\":\"TEN4\",\"model\":\"default\"}" 367 }, 368 { 369 "id": 3, 370 "type": "SUBACCOUNT_CREATION", 371 "region": "test-region", 372 "timestamp": "1579771215536", 373 "eventData": "{\"id\":\"33\",\"displayName\":\"TEN3\",\"model\":\"default\"}" 374 }, 375 { 376 "id": 2, 377 "type": "SUBACCOUNT_CREATION", 378 "region": "test-region", 379 "timestamp": "1579771215436", 380 "eventData": "{\"id\":\"22\",\"displayName\":\"TEN2\",\"model\":\"default\"}" 381 }, 382 { 383 "id": 1, 384 "type": "SUBACCOUNT_CREATION", 385 "region": "test-region", 386 "timestamp": "1579771215336", 387 "eventData": "{\"id\":\"11\",\"displayName\":\"TEN1\",\"model\":\"default\"}" 388 } 389 ], 390 "totalResults": 5, 391 "totalPages": 1 392 }` 393 } 394 395 func fixUpdatedSubaccountsJSON() string { 396 return `{ 397 "events": [ 398 { 399 "id": 2, 400 "type": "SUBACCOUNT_UPDATE", 401 "region": "test-region", 402 "timestamp": "1579771215436", 403 "eventData": "{\"id\":\"22\",\"displayName\":\"TEN2\",\"model\":\"default\"}" 404 }, 405 { 406 "id": 1, 407 "type": "SUBACCOUNT_UPDATE", 408 "region": "test-region", 409 "timestamp": "1579771215336", 410 "eventData": "{\"id\":\"11\",\"displayName\":\"TEN1\",\"model\":\"default\"}" 411 } 412 ], 413 "totalResults": 2, 414 "totalPages": 1 415 }` 416 } 417 418 func fixDeletedSubaccountsJSON() string { 419 return `{ 420 "events": [ 421 { 422 "id": 2, 423 "type": "SUBACCOUNT_DELETION", 424 "region": "test-region", 425 "timestamp": "1579771215436", 426 "eventData": "{\"id\":\"22\",\"displayName\":\"TEN2\",\"model\":\"default\"}" 427 }, 428 { 429 "id": 1, 430 "type": "SUBACCOUNT_DELETION", 431 "region": "test-region", 432 "timestamp": "1579771215336", 433 "eventData": "{\"id\":\"11\",\"displayName\":\"TEN1\",\"model\":\"default\"}" 434 } 435 ], 436 "totalResults": 2, 437 "totalPages": 1 438 }` 439 } 440 441 func fixMovedSubaccountsJSON() string { 442 return `{ 443 "events": [ 444 { 445 "id": 2, 446 "type": "SUBACCOUNT_MOVED", 447 "region": "test-region", 448 "timestamp": "1579771215436", 449 "eventData": "{\"id\":\"22\",\"source\":\"TEN1\",\"target\":\"TEN2\"}" 450 }, 451 { 452 "id": 1, 453 "type": "SUBACCOUNT_MOVED", 454 "region": "test-region", 455 "timestamp": "1579771215336", 456 "eventData": "{\"id\":\"11\",\"source\":\"TEN3\",\"target\":\"TEN4\"}" 457 } 458 ], 459 "totalResults": 2, 460 "totalPages": 1 461 }` 462 } 463 464 func TestNewClient(t *testing.T) { 465 const clientID = "client" 466 const clientSecret = "secret" 467 468 t.Run("expect error on invalid auth mode", func(t *testing.T) { 469 _, err := resync.NewClient(resync.OAuth2Config{}, "invalid-auth-mode", resync.ClientConfig{}, 1) 470 require.Error(t, err) 471 }) 472 473 t.Run("standard client-credentials mode", func(t *testing.T) { 474 client, err := resync.NewClient(resync.OAuth2Config{ 475 ClientID: clientID, 476 ClientSecret: clientSecret, 477 }, oauth.Standard, resync.ClientConfig{}, 1) 478 require.NoError(t, err) 479 480 httpClient := client.GetHTTPClient() 481 tr, ok := httpClient.Transport.(*oauth2.Transport) 482 require.True(t, ok, "expected *oauth2.Transport") 483 require.Equal(t, http.DefaultClient.Transport, tr.Base) 484 485 cfg := clientcredentials.Config{ 486 ClientID: clientID, 487 ClientSecret: clientSecret, 488 } 489 expectedTokenSrc := cfg.TokenSource(context.Background()) 490 require.Equal(t, expectedTokenSrc, tr.Source) 491 }) 492 493 t.Run("mtls+client-secret mode", func(t *testing.T) { 494 const certificate = "-----BEGIN CERTIFICATE-----\nMIIDbjCCAlYCCQDg7pmtw8dIVTANBgkqhkiG9w0BAQsFADB5MQswCQYDVQQGEwJC\nRzENMAsGA1UECAwEVGVzdDENMAsGA1UEBwwEVGVzdDENMAsGA1UECgwEVGVzdDEN\nMAsGA1UECwwEVGVzdDENMAsGA1UEAwwEVGVzdDEfMB0GCSqGSIb3DQEJARYQdGVz\ndEBleGFtcGxlLmNvbTAeFw0yMjAxMjQxMTM4MDFaFw0zMjAxMjIxMTM4MDFaMHkx\nCzAJBgNVBAYTAkJHMQ0wCwYDVQQIDARUZXN0MQ0wCwYDVQQHDARUZXN0MQ0wCwYD\nVQQKDARUZXN0MQ0wCwYDVQQLDARUZXN0MQ0wCwYDVQQDDARUZXN0MR8wHQYJKoZI\nhvcNAQkBFhB0ZXN0QGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAuiFt98GUVTDSCHsOlBcblvUB/02uEmsalsG+DKEufzIVrp4DCxsA\nEsIN85Ywkd1Fsl0vwg9+3ibQlf1XtyXqJ6/jwm2zFdJPM3u2JfGGiiQpscHYp5hS\nlVscBjxZh1CQMKeBXltDsD64EV+XgHGN1aaw9mWKb6iSKsHLhBz594jYMFCnP3wH\nw9/hm6zBAhoF4Xr6UMOp4ZzzY8nzLCGPQuQ9UGp4lyAethrBpsqI6zAxjPKlqhmx\nL3591wkQgTzuL9th54yLEmyEvPTE26ONJBKylH2BqbAFiZPrwet0+PRJSflAfMU8\nYHqqo2AkaY1lmMAZiKDhj1RxMe/jt3HmVQIDAQABMA0GCSqGSIb3DQEBCwUAA4IB\nAQBx8BRhJ59UA3JDL+FHNKwIpxFewxjJwIGWqJTsOh4+rjPK3QeSnF0vt4cnLrCY\n+FLuhhUdFxjeFqJtWN7tHDK3ywSn/yZQTD5Nwcy/F1RmLjl91hjudxO/VewznOlq\nHJlDoM7kW9kOG6xS2HbbSaC1CzU33E90QOwcyCoeVXJ8aMDe6v/kWC65RoI9evg5\n2OxoARA8fpjyUphMTXuVNVI1kd2Uskpo8PePbc1h3OJVzYPIQ4+qMGsu7n3ZdwzI\nqDs2kdBD77k6cBQS+n7g5ETwv5OAgl5q1O17ye/YFNA/T3FhL9to6Nmrkqt7rlnF\nL8uAkeTGuHEATjmosQWUmbYi\n-----END CERTIFICATE-----\n" 495 const key = "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAuiFt98GUVTDSCHsOlBcblvUB/02uEmsalsG+DKEufzIVrp4D\nCxsAEsIN85Ywkd1Fsl0vwg9+3ibQlf1XtyXqJ6/jwm2zFdJPM3u2JfGGiiQpscHY\np5hSlVscBjxZh1CQMKeBXltDsD64EV+XgHGN1aaw9mWKb6iSKsHLhBz594jYMFCn\nP3wHw9/hm6zBAhoF4Xr6UMOp4ZzzY8nzLCGPQuQ9UGp4lyAethrBpsqI6zAxjPKl\nqhmxL3591wkQgTzuL9th54yLEmyEvPTE26ONJBKylH2BqbAFiZPrwet0+PRJSflA\nfMU8YHqqo2AkaY1lmMAZiKDhj1RxMe/jt3HmVQIDAQABAoIBAH+9xa0N6/FzqhIr\n8ltsaID38cD33QnC++KPYRFl5XViOEM5KrmKdEhragvM/dR92gGJtucmn1lzph/q\nWTLXEJbgPh4ID6pgRf79Xos38bAJFZxrf3e2MKdUei1FaeRWRD9AFqddV100DjvO\nMTnztPX2iujv00zCkl5J1pT7FgrtcYgDPxXQK7dIcHrc9bV9fdTQUnpbVIs/9U7a\n7Qk/eJnEkezbjQCk7+Pgt3ymR29s4vJvyPen3jek0FKhQCxAg6iA5ZOtY+J5AS9e\n3ozZLUEa3b0eOABMw8QnKMtGTmIhLbf9JhISK2Ltsisc/yHHH3KfFE2nayqjvLZf\n5GR62hkCgYEA612EgoRHg4+BSfPfLNG3xsSnM+a98nZOmyxgZ3eNFWpSvi+7MemL\nCJHpwwje412OU1wCc2MtWYvGFY+heL62FxT8+JJLntykZcTQzQoHX3wvaMwopWRi\nJdrv3tEDtSJo9za54kfrNqnVyaxu82r7zgxVbcNiAVR+n7cRXuov288CgYEAynLm\nVI7cIKBOM6U44unkKyIS99Bh57FPjE1QAIsEOiNCWZay4qmzdEboOXjtC95Qyyxn\nTb+MONybwXKkGiLZQZQ2SlgjtEMBDQ+ofk2fK+yHWf4VeLtYWJdBESaAz85xGCCY\nYqlqbFEQd8cl86gTne+emLXp8KrDMuXhbbPvMJsCgYEAgBISAacS9t6GfoQqA0xW\nkNz/EnnTD/UaTst15bci2O1S+tQkK0OmeNJU/eB80AFfabKeTsU/rwMklSTjuz0i\n/ipYgLWyWk47UnknGPsFCgscDQ1SbLTTxz972KWpO83uid6IhT2XGtaNU0D12pRz\nUipZ7fEsCgc9I5FM7XXG9vcCgYBp6xN2ygeBSl2fx6GrlpM5veoOnYeboLjtvsVM\ng28Cu8/K731H+WFaRH7bEtlyjC3ZHrItiznhxgn3e/M/eVwRY2nEG7kSZrv2CWsu\nKY5NfMKT4st5Dwt5zijMwEhEcM3awbL4a4qygPcMs7S3dghNaUCgxQxQTgcyafM3\nYhySYQKBgF7pqQW7ESo1Mp9by+HzJBJsSju5zPBrCZrx8rFAMLCk1uDAIRcUuQtq\n+YwKU8ViemkOHWfN6bePap3/kdVHUxj2xJ6xTAUYHpVOQVMhTw1UmOikiV4FwUo+\nGb5Nk5evWBGhsl2LFqoOqhvFpjftv8+qgRHxmWtj4EoJYWng+hRz\n-----END RSA PRIVATE KEY-----\n" 496 497 certCfg := resync.X509Config{ 498 Cert: certificate, 499 Key: key, 500 } 501 502 tlsCert, err := certCfg.ParseCertificate() 503 require.NoError(t, err) 504 505 oauthCfg := resync.OAuth2Config{ 506 X509Config: certCfg, 507 ClientID: clientID, 508 } 509 client, err := resync.NewClient(oauthCfg, oauth.Mtls, resync.ClientConfig{}, 1) 510 require.NoError(t, err) 511 512 httpClient := client.GetHTTPClient() 513 tr, ok := httpClient.Transport.(*oauth2.Transport) 514 require.True(t, ok, "expected *oauth2.Transport") 515 516 expectedTransport := &http.Transport{ 517 TLSClientConfig: &tls.Config{ 518 Certificates: []tls.Certificate{*tlsCert}, 519 InsecureSkipVerify: oauthCfg.SkipSSLValidation, 520 }, 521 } 522 require.Equal(t, tr.Base, expectedTransport) 523 }) 524 }