github.com/google/go-github/v49@v49.1.0/github/scim_test.go (about) 1 // Copyright 2021 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "net/http" 11 "testing" 12 "time" 13 14 "github.com/google/go-cmp/cmp" 15 ) 16 17 func TestSCIMService_ListSCIMProvisionedIdentities(t *testing.T) { 18 client, mux, _, teardown := setup() 19 defer teardown() 20 21 mux.HandleFunc("/scim/v2/organizations/o/Users", func(w http.ResponseWriter, r *http.Request) { 22 testMethod(t, r, "GET") 23 w.WriteHeader(http.StatusOK) 24 _, _ = w.Write([]byte(`{ 25 "schemas": [ 26 "urn:ietf:params:scim:api:messages:2.0:ListResponse" 27 ], 28 "totalResults": 1, 29 "itemsPerPage": 1, 30 "startIndex": 1, 31 "Resources": [ 32 { 33 "schemas": [ 34 "urn:ietf:params:scim:schemas:core:2.0:User" 35 ], 36 "id": "5fc0c238-1112-11e8-8e45-920c87bdbd75", 37 "externalId": "00u1dhhb1fkIGP7RL1d8", 38 "userName": "octocat@github.com", 39 "displayName": "Mona Octocat", 40 "name": { 41 "givenName": "Mona", 42 "familyName": "Octocat", 43 "formatted": "Mona Octocat" 44 }, 45 "emails": [ 46 { 47 "value": "octocat@github.com", 48 "primary": true 49 } 50 ], 51 "active": true, 52 "meta": { 53 "resourceType": "User", 54 "created": "2018-02-13T15:05:24.000-00:00", 55 "lastModified": "2018-02-13T15:05:24.000-00:00", 56 "location": "https://api.github.com/scim/v2/organizations/octo-org/Users/5fc0c238-1112-11e8-8e45-920c87bdbd75" 57 } 58 } 59 ] 60 }`)) 61 }) 62 63 ctx := context.Background() 64 opts := &ListSCIMProvisionedIdentitiesOptions{} 65 identities, _, err := client.SCIM.ListSCIMProvisionedIdentities(ctx, "o", opts) 66 if err != nil { 67 t.Errorf("SCIM.ListSCIMProvisionedIdentities returned error: %v", err) 68 } 69 70 date := Timestamp{time.Date(2018, time.February, 13, 15, 5, 24, 0, time.UTC)} 71 want := SCIMProvisionedIdentities{ 72 Schemas: []string{"urn:ietf:params:scim:api:messages:2.0:ListResponse"}, 73 TotalResults: Int(1), 74 ItemsPerPage: Int(1), 75 StartIndex: Int(1), 76 Resources: []*SCIMUserAttributes{ 77 { 78 ID: String("5fc0c238-1112-11e8-8e45-920c87bdbd75"), 79 Meta: &SCIMMeta{ 80 ResourceType: String("User"), 81 Created: &date, 82 LastModified: &date, 83 Location: String("https://api.github.com/scim/v2/organizations/octo-org/Users/5fc0c238-1112-11e8-8e45-920c87bdbd75"), 84 }, 85 UserName: "octocat@github.com", 86 Name: SCIMUserName{ 87 GivenName: "Mona", 88 FamilyName: "Octocat", 89 Formatted: String("Mona Octocat"), 90 }, 91 DisplayName: String("Mona Octocat"), 92 Emails: []*SCIMUserEmail{ 93 { 94 Value: "octocat@github.com", 95 Primary: Bool(true), 96 }, 97 }, 98 Schemas: []string{"urn:ietf:params:scim:schemas:core:2.0:User"}, 99 ExternalID: String("00u1dhhb1fkIGP7RL1d8"), 100 Groups: nil, 101 Active: Bool(true), 102 }, 103 }, 104 } 105 106 if !cmp.Equal(identities, &want) { 107 diff := cmp.Diff(identities, want) 108 t.Errorf("SCIM.ListSCIMProvisionedIdentities returned %+v, want %+v: diff %+v", identities, want, diff) 109 } 110 111 const methodName = "ListSCIMProvisionedIdentities" 112 testBadOptions(t, methodName, func() (err error) { 113 _, _, err = client.SCIM.ListSCIMProvisionedIdentities(ctx, "\n", opts) 114 return err 115 }) 116 117 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 118 _, r, err := client.SCIM.ListSCIMProvisionedIdentities(ctx, "o", opts) 119 return r, err 120 }) 121 } 122 123 func TestSCIMService_ProvisionAndInviteSCIMUser(t *testing.T) { 124 client, mux, _, teardown := setup() 125 defer teardown() 126 127 mux.HandleFunc("/scim/v2/organizations/o/Users", func(w http.ResponseWriter, r *http.Request) { 128 testMethod(t, r, "POST") 129 w.WriteHeader(http.StatusOK) 130 }) 131 132 ctx := context.Background() 133 opts := &SCIMUserAttributes{ 134 UserName: "userName", 135 Name: SCIMUserName{ 136 GivenName: "givenName", 137 FamilyName: "familyName", 138 }, 139 Emails: []*SCIMUserEmail{ 140 { 141 Value: "octocat@github.com", 142 }, 143 }, 144 } 145 _, err := client.SCIM.ProvisionAndInviteSCIMUser(ctx, "o", opts) 146 if err != nil { 147 t.Errorf("SCIM.ListSCIMProvisionedIdentities returned error: %v", err) 148 } 149 150 const methodName = "ProvisionAndInviteSCIMUser" 151 testBadOptions(t, methodName, func() (err error) { 152 _, err = client.SCIM.ProvisionAndInviteSCIMUser(ctx, "\n", opts) 153 return err 154 }) 155 156 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 157 return client.SCIM.ProvisionAndInviteSCIMUser(ctx, "o", opts) 158 }) 159 } 160 161 func TestSCIMService_GetSCIMProvisioningInfoForUser(t *testing.T) { 162 client, mux, _, teardown := setup() 163 defer teardown() 164 165 mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) { 166 testMethod(t, r, "GET") 167 w.WriteHeader(http.StatusOK) 168 _, _ = w.Write([]byte(`{ 169 "schemas": [ 170 "urn:ietf:params:scim:schemas:core:2.0:User" 171 ], 172 "id": "edefdfedf-050c-11e7-8d32", 173 "externalId": "a7d0f98382", 174 "userName": "mona.octocat@okta.example.com", 175 "displayName": "Mona Octocat", 176 "name": { 177 "givenName": "Mona", 178 "familyName": "Octocat", 179 "formatted": "Mona Octocat" 180 }, 181 "emails": [ 182 { 183 "value": "mona.octocat@okta.example.com", 184 "primary": true 185 }, 186 { 187 "value": "mona@octocat.github.com" 188 } 189 ], 190 "active": true, 191 "meta": { 192 "resourceType": "User", 193 "created": "2017-03-09T16:11:13-00:00", 194 "lastModified": "2017-03-09T16:11:13-00:00", 195 "location": "https://api.github.com/scim/v2/organizations/octo-org/Users/edefdfedf-050c-11e7-8d32" 196 } 197 }`)) 198 }) 199 200 ctx := context.Background() 201 user, _, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "o", "123") 202 if err != nil { 203 t.Errorf("SCIM.GetSCIMProvisioningInfoForUser returned error: %v", err) 204 } 205 206 date := Timestamp{time.Date(2017, time.March, 9, 16, 11, 13, 0, time.UTC)} 207 want := SCIMUserAttributes{ 208 ID: String("edefdfedf-050c-11e7-8d32"), 209 Meta: &SCIMMeta{ 210 ResourceType: String("User"), 211 Created: &date, 212 LastModified: &date, 213 Location: String("https://api.github.com/scim/v2/organizations/octo-org/Users/edefdfedf-050c-11e7-8d32"), 214 }, 215 UserName: "mona.octocat@okta.example.com", 216 Name: SCIMUserName{ 217 GivenName: "Mona", 218 FamilyName: "Octocat", 219 Formatted: String("Mona Octocat"), 220 }, 221 DisplayName: String("Mona Octocat"), 222 Emails: []*SCIMUserEmail{ 223 { 224 Value: "mona.octocat@okta.example.com", 225 Primary: Bool(true), 226 }, 227 { 228 Value: "mona@octocat.github.com", 229 }, 230 }, 231 Schemas: []string{"urn:ietf:params:scim:schemas:core:2.0:User"}, 232 ExternalID: String("a7d0f98382"), 233 Groups: nil, 234 Active: Bool(true), 235 } 236 237 if !cmp.Equal(user, &want) { 238 diff := cmp.Diff(user, want) 239 t.Errorf("SCIM.ListSCIMProvisionedIdentities returned %+v, want %+v: diff %+v", user, want, diff) 240 } 241 242 const methodName = "GetSCIMProvisioningInfoForUser" 243 testBadOptions(t, methodName, func() error { 244 _, _, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "\n", "123") 245 return err 246 }) 247 248 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 249 _, r, err := client.SCIM.GetSCIMProvisioningInfoForUser(ctx, "o", "123") 250 return r, err 251 }) 252 } 253 254 func TestSCIMService_UpdateProvisionedOrgMembership(t *testing.T) { 255 client, mux, _, teardown := setup() 256 defer teardown() 257 258 mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) { 259 testMethod(t, r, "PUT") 260 w.WriteHeader(http.StatusOK) 261 }) 262 263 ctx := context.Background() 264 opts := &SCIMUserAttributes{ 265 UserName: "userName", 266 Name: SCIMUserName{ 267 GivenName: "givenName", 268 FamilyName: "familyName", 269 }, 270 Emails: []*SCIMUserEmail{ 271 { 272 Value: "octocat@github.com", 273 }, 274 }, 275 } 276 _, err := client.SCIM.UpdateProvisionedOrgMembership(ctx, "o", "123", opts) 277 if err != nil { 278 t.Errorf("SCIM.UpdateProvisionedOrgMembership returned error: %v", err) 279 } 280 281 const methodName = "UpdateProvisionedOrgMembership" 282 testBadOptions(t, methodName, func() error { 283 _, err := client.SCIM.UpdateProvisionedOrgMembership(ctx, "\n", "123", opts) 284 return err 285 }) 286 287 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 288 return client.SCIM.UpdateProvisionedOrgMembership(ctx, "o", "123", opts) 289 }) 290 } 291 292 func TestSCIMService_UpdateAttributeForSCIMUser(t *testing.T) { 293 client, mux, _, teardown := setup() 294 defer teardown() 295 296 mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) { 297 testMethod(t, r, "PATCH") 298 w.WriteHeader(http.StatusNoContent) 299 }) 300 301 ctx := context.Background() 302 opts := &UpdateAttributeForSCIMUserOptions{} 303 _, err := client.SCIM.UpdateAttributeForSCIMUser(ctx, "o", "123", opts) 304 if err != nil { 305 t.Errorf("SCIM.UpdateAttributeForSCIMUser returned error: %v", err) 306 } 307 308 const methodName = "UpdateAttributeForSCIMUser" 309 testBadOptions(t, methodName, func() error { 310 _, err := client.SCIM.UpdateAttributeForSCIMUser(ctx, "\n", "123", opts) 311 return err 312 }) 313 314 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 315 return client.SCIM.UpdateAttributeForSCIMUser(ctx, "o", "123", opts) 316 }) 317 } 318 319 func TestSCIMService_DeleteSCIMUserFromOrg(t *testing.T) { 320 client, mux, _, teardown := setup() 321 defer teardown() 322 323 mux.HandleFunc("/scim/v2/organizations/o/Users/123", func(w http.ResponseWriter, r *http.Request) { 324 testMethod(t, r, "DELETE") 325 w.WriteHeader(http.StatusNoContent) 326 }) 327 328 ctx := context.Background() 329 _, err := client.SCIM.DeleteSCIMUserFromOrg(ctx, "o", "123") 330 if err != nil { 331 t.Errorf("SCIM.DeleteSCIMUserFromOrg returned error: %v", err) 332 } 333 334 const methodName = "DeleteSCIMUserFromOrg" 335 testBadOptions(t, methodName, func() error { 336 _, err := client.SCIM.DeleteSCIMUserFromOrg(ctx, "\n", "") 337 return err 338 }) 339 340 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 341 return client.SCIM.DeleteSCIMUserFromOrg(ctx, "o", "123") 342 }) 343 } 344 345 func TestSCIMUserAttributes_Marshal(t *testing.T) { 346 testJSONMarshal(t, &SCIMUserAttributes{}, `{ 347 "userName":"","name":{"givenName":"","familyName":""},"emails":null 348 }`) 349 350 u := &SCIMUserAttributes{ 351 UserName: "userName1", 352 Name: SCIMUserName{ 353 GivenName: "Name1", 354 FamilyName: "Fname", 355 Formatted: String("formatted name"), 356 }, 357 DisplayName: String("Name"), 358 Emails: []*SCIMUserEmail{ 359 { 360 Value: "value", 361 Primary: Bool(false), 362 Type: String("type"), 363 }, 364 }, 365 Schemas: []string{"schema1"}, 366 ExternalID: String("id"), 367 Groups: []string{"group1"}, 368 Active: Bool(true), 369 } 370 371 want := `{ 372 "userName": "userName1", 373 "name": { 374 "givenName": "Name1", 375 "familyName": "Fname", 376 "formatted": "formatted name" 377 }, 378 "displayName": "Name", 379 "emails": [{ 380 "value": "value", 381 "primary": false, 382 "type": "type" 383 }], 384 "schemas": ["schema1"], 385 "externalId": "id", 386 "groups": ["group1"], 387 "active": true 388 }` 389 390 testJSONMarshal(t, u, want) 391 } 392 393 func TestUpdateAttributeForSCIMUserOperations_Marshal(t *testing.T) { 394 testJSONMarshal(t, &UpdateAttributeForSCIMUserOperations{}, `{}`) 395 396 u := &UpdateAttributeForSCIMUserOperations{ 397 Op: "TestOp", 398 Path: String("path"), 399 } 400 401 want := `{ 402 "op": "TestOp", 403 "path": "path" 404 }` 405 406 testJSONMarshal(t, u, want) 407 } 408 409 func TestUpdateAttributeForSCIMUserOptions_Marshal(t *testing.T) { 410 testJSONMarshal(t, &UpdateAttributeForSCIMUserOptions{}, `{}`) 411 412 u := &UpdateAttributeForSCIMUserOptions{ 413 Schemas: []string{"test", "schema"}, 414 Operations: UpdateAttributeForSCIMUserOperations{ 415 Op: "TestOp", 416 Path: String("path"), 417 }, 418 } 419 420 want := `{ 421 "schemas": ["test", "schema"], 422 "operations": { 423 "op": "TestOp", 424 "path": "path" 425 } 426 }` 427 428 testJSONMarshal(t, u, want) 429 } 430 431 func TestListSCIMProvisionedIdentitiesOptions_Marshal(t *testing.T) { 432 testJSONMarshal(t, &ListSCIMProvisionedIdentitiesOptions{}, `{}`) 433 434 u := &ListSCIMProvisionedIdentitiesOptions{ 435 StartIndex: Int(1), 436 Count: Int(10), 437 Filter: String("test"), 438 } 439 440 want := `{ 441 "startIndex": 1, 442 "count": 10, 443 "filter": "test" 444 }` 445 446 testJSONMarshal(t, u, want) 447 } 448 449 func TestSCIMUserName_Marshal(t *testing.T) { 450 testJSONMarshal(t, &SCIMUserName{}, `{ 451 "givenName":"","familyName":"" 452 }`) 453 454 u := &SCIMUserName{ 455 GivenName: "Name1", 456 FamilyName: "Fname", 457 Formatted: String("formatted name"), 458 } 459 460 want := `{ 461 "givenName": "Name1", 462 "familyName": "Fname", 463 "formatted": "formatted name" 464 }` 465 testJSONMarshal(t, u, want) 466 } 467 468 func TestSCIMMeta_Marshal(t *testing.T) { 469 testJSONMarshal(t, &SCIMMeta{}, `{}`) 470 471 u := &SCIMMeta{ 472 ResourceType: String("test"), 473 Location: String("test"), 474 } 475 476 want := `{ 477 "resourceType": "test", 478 "location": "test" 479 }` 480 481 testJSONMarshal(t, u, want) 482 } 483 484 func TestSCIMProvisionedIdentities_Marshal(t *testing.T) { 485 testJSONMarshal(t, &SCIMProvisionedIdentities{}, `{}`) 486 487 u := &SCIMProvisionedIdentities{ 488 Schemas: []string{"test", "schema"}, 489 TotalResults: Int(1), 490 ItemsPerPage: Int(2), 491 StartIndex: Int(1), 492 Resources: []*SCIMUserAttributes{ 493 { 494 UserName: "SCIM", 495 Name: SCIMUserName{ 496 GivenName: "scim", 497 FamilyName: "test", 498 Formatted: String("SCIM"), 499 }, 500 DisplayName: String("Test SCIM"), 501 Emails: []*SCIMUserEmail{ 502 { 503 Value: "test", 504 Primary: Bool(true), 505 Type: String("test"), 506 }, 507 }, 508 Schemas: []string{"schema1"}, 509 ExternalID: String("id"), 510 Groups: []string{"group1"}, 511 Active: Bool(true), 512 }, 513 }, 514 } 515 516 want := `{ 517 "schemas": ["test", "schema"], 518 "totalResults": 1, 519 "itemsPerPage": 2, 520 "startIndex": 1, 521 "Resources": [{ 522 "userName": "SCIM", 523 "name": { 524 "givenName": "scim", 525 "familyName": "test", 526 "formatted": "SCIM" 527 }, 528 "displayName": "Test SCIM", 529 "emails": [{ 530 "value": "test", 531 "primary": true, 532 "type": "test" 533 }], 534 "schemas": ["schema1"], 535 "externalId": "id", 536 "groups": ["group1"], 537 "active": true 538 }] 539 }` 540 541 testJSONMarshal(t, u, want) 542 }