github.com/clerkinc/clerk-sdk-go@v1.49.1/clerk/users_test.go (about) 1 package clerk 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "net/url" 8 "reflect" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestUsersService_Create_happyPath(t *testing.T) { 15 token := "token" 16 var payload CreateUserParams 17 _ = json.Unmarshal([]byte(dummyCreateUserRequestJson), &payload) 18 19 client, mux, _, teardown := setup(token) 20 defer teardown() 21 22 mux.HandleFunc("/users", func(w http.ResponseWriter, req *http.Request) { 23 testHttpMethod(t, req, http.MethodPost) 24 testHeader(t, req, "Authorization", "Bearer "+token) 25 fmt.Fprint(w, dummyUserJson) 26 }) 27 28 got, err := client.Users().Create(payload) 29 30 var want User 31 _ = json.Unmarshal([]byte(dummyUserJson), &want) 32 33 assert.Nil(t, err) 34 assert.Equal(t, want, *got) 35 } 36 37 func TestUsersService_Create_invalidServer(t *testing.T) { 38 client, _ := NewClient("token") 39 40 _, err := client.Users().Create(CreateUserParams{}) 41 if err == nil { 42 t.Errorf("Expected error to be returned") 43 } 44 } 45 46 func TestUsersService_ListAll_happyPath(t *testing.T) { 47 client, mux, _, teardown := setup("token") 48 defer teardown() 49 50 expectedResponse := "[" + dummyUserJson + "]" 51 52 mux.HandleFunc("/users", func(w http.ResponseWriter, req *http.Request) { 53 testHttpMethod(t, req, "GET") 54 testHeader(t, req, "Authorization", "Bearer token") 55 fmt.Fprint(w, expectedResponse) 56 }) 57 58 var want []User 59 _ = json.Unmarshal([]byte(expectedResponse), &want) 60 61 got, _ := client.Users().ListAll(ListAllUsersParams{}) 62 if len(got) != len(want) { 63 t.Errorf("Was expecting %d user to be returned, instead got %d", len(want), len(got)) 64 } 65 66 if !reflect.DeepEqual(got, want) { 67 t.Errorf("Response = %v, want %v", got, want) 68 } 69 } 70 71 func TestUsersService_ListAll_happyPathWithParameters(t *testing.T) { 72 client, mux, _, teardown := setup("token") 73 defer teardown() 74 75 expectedResponse := "[" + dummyUserJson + "]" 76 77 mux.HandleFunc("/users", func(w http.ResponseWriter, req *http.Request) { 78 testHttpMethod(t, req, "GET") 79 testHeader(t, req, "Authorization", "Bearer token") 80 81 actualQuery := req.URL.Query() 82 expectedQuery := url.Values(map[string][]string{ 83 "limit": {"5"}, 84 "offset": {"6"}, 85 "email_address": {"email1", "email2"}, 86 "phone_number": {"phone1", "phone2"}, 87 "web3_wallet": {"wallet1", "wallet2"}, 88 "username": {"username1", "username2"}, 89 "user_id": {"userid1", "userid2"}, 90 "query": {"my-query"}, 91 "last_active_at_since": {"1700690400000"}, 92 "order_by": {"created_at"}, 93 }) 94 assert.Equal(t, expectedQuery, actualQuery) 95 fmt.Fprint(w, expectedResponse) 96 }) 97 98 var want []User 99 _ = json.Unmarshal([]byte(expectedResponse), &want) 100 101 got, _ := client.Users().ListAll(ListAllUsersParams{ 102 Limit: intToPtr(5), 103 Offset: intToPtr(6), 104 EmailAddresses: []string{"email1", "email2"}, 105 PhoneNumbers: []string{"phone1", "phone2"}, 106 Web3Wallets: []string{"wallet1", "wallet2"}, 107 Usernames: []string{"username1", "username2"}, 108 UserIDs: []string{"userid1", "userid2"}, 109 Query: stringToPtr("my-query"), 110 LastActiveAtSince: int64ToPtr(int64(1700690400000)), 111 OrderBy: stringToPtr("created_at"), 112 }) 113 if len(got) != len(want) { 114 t.Errorf("Was expecting %d user to be returned, instead got %d", len(want), len(got)) 115 } 116 117 if !reflect.DeepEqual(got, want) { 118 t.Errorf("Response = %v, want %v", got, want) 119 } 120 } 121 122 func TestUsersService_ListAll_invalidServer(t *testing.T) { 123 client, _ := NewClient("token") 124 125 users, err := client.Users().ListAll(ListAllUsersParams{}) 126 if err == nil { 127 t.Errorf("Expected error to be returned") 128 } 129 if users != nil { 130 t.Errorf("Was not expecting any users to be returned, instead got %v", users) 131 } 132 } 133 134 func TestUsersService_Count_happyPath(t *testing.T) { 135 client, mux, _, teardown := setup("token") 136 defer teardown() 137 138 expectedResponse := dummyUserCountJson 139 140 mux.HandleFunc("/users/count", func(w http.ResponseWriter, req *http.Request) { 141 testHttpMethod(t, req, "GET") 142 testHeader(t, req, "Authorization", "Bearer token") 143 fmt.Fprint(w, expectedResponse) 144 }) 145 146 var want UserCount 147 _ = json.Unmarshal([]byte(expectedResponse), &want) 148 149 got, _ := client.Users().Count(ListAllUsersParams{}) 150 if !reflect.DeepEqual(*got, want) { 151 t.Errorf("Response = %v, want %v", *got, want) 152 } 153 } 154 155 func TestUsersService_Count_happyPathWithParameters(t *testing.T) { 156 client, mux, _, teardown := setup("token") 157 defer teardown() 158 159 expectedResponse := dummyUserCountJson 160 161 mux.HandleFunc("/users/count", func(w http.ResponseWriter, req *http.Request) { 162 testHttpMethod(t, req, "GET") 163 testHeader(t, req, "Authorization", "Bearer token") 164 165 actualQuery := req.URL.Query() 166 expectedQuery := url.Values(map[string][]string{ 167 "email_address": {"email1", "email2"}, 168 "phone_number": {"phone1", "phone2"}, 169 "web3_wallet": {"wallet1", "wallet2"}, 170 "username": {"username1", "username2"}, 171 "user_id": {"userid1", "userid2"}, 172 "query": {"my-query"}, 173 }) 174 assert.Equal(t, expectedQuery, actualQuery) 175 fmt.Fprint(w, expectedResponse) 176 }) 177 178 var want UserCount 179 _ = json.Unmarshal([]byte(expectedResponse), &want) 180 181 got, _ := client.Users().Count(ListAllUsersParams{ 182 EmailAddresses: []string{"email1", "email2"}, 183 PhoneNumbers: []string{"phone1", "phone2"}, 184 Web3Wallets: []string{"wallet1", "wallet2"}, 185 Usernames: []string{"username1", "username2"}, 186 UserIDs: []string{"userid1", "userid2"}, 187 Query: stringToPtr("my-query"), 188 }) 189 if !reflect.DeepEqual(*got, want) { 190 t.Errorf("Response = %v, want %v", got, want) 191 } 192 } 193 194 func TestUsersService_Count_invalidServer(t *testing.T) { 195 client, _ := NewClient("token") 196 197 users, err := client.Users().Count(ListAllUsersParams{}) 198 if err == nil { 199 t.Errorf("Expected error to be returned") 200 } 201 if users != nil { 202 t.Errorf("Was not expecting any users to be returned, instead got %v", users) 203 } 204 } 205 206 func TestUsersService_Read_happyPath(t *testing.T) { 207 token := "token" 208 userId := "someUserId" 209 expectedResponse := dummyUserJson 210 211 client, mux, _, teardown := setup(token) 212 defer teardown() 213 214 mux.HandleFunc("/users/"+userId, func(w http.ResponseWriter, req *http.Request) { 215 testHttpMethod(t, req, "GET") 216 testHeader(t, req, "Authorization", "Bearer "+token) 217 fmt.Fprint(w, expectedResponse) 218 }) 219 220 var want User 221 _ = json.Unmarshal([]byte(expectedResponse), &want) 222 223 got, _ := client.Users().Read(userId) 224 if !reflect.DeepEqual(*got, want) { 225 t.Errorf("Response = %v, want %v", *got, want) 226 } 227 } 228 229 func TestUsersService_Read_invalidServer(t *testing.T) { 230 client, _ := NewClient("token") 231 232 user, err := client.Users().Read("someUserId") 233 if err == nil { 234 t.Errorf("Expected error to be returned") 235 } 236 if user != nil { 237 t.Errorf("Was not expecting any user to be returned, instead got %v", user) 238 } 239 } 240 241 func TestUsersService_Delete_happyPath(t *testing.T) { 242 token := "token" 243 userId := "someUserId" 244 245 client, mux, _, teardown := setup(token) 246 defer teardown() 247 248 mux.HandleFunc("/users/"+userId, func(w http.ResponseWriter, req *http.Request) { 249 testHttpMethod(t, req, "DELETE") 250 testHeader(t, req, "Authorization", "Bearer "+token) 251 response := fmt.Sprintf(`{ "deleted": true, "id": "%v", "object": "user" }`, userId) 252 fmt.Fprint(w, response) 253 }) 254 255 want := DeleteResponse{ID: userId, Object: "user", Deleted: true} 256 257 got, _ := client.Users().Delete(userId) 258 if !reflect.DeepEqual(*got, want) { 259 t.Errorf("Response = %v, want %v", *got, want) 260 } 261 } 262 263 func TestUsersService_Delete_invalidServer(t *testing.T) { 264 client, _ := NewClient("token") 265 266 delResponse, err := client.Users().Delete("someUserId") 267 if err == nil { 268 t.Errorf("Expected error to be returned") 269 } 270 if delResponse != nil { 271 t.Errorf("Was not expecting any reponse to be returned, instead got %v", delResponse) 272 } 273 } 274 275 func TestUsersService_Update_happyPath(t *testing.T) { 276 token := "token" 277 userId := "someUserId" 278 var payload UpdateUser 279 _ = json.Unmarshal([]byte(dummyUpdateRequestJson), &payload) 280 281 client, mux, _, teardown := setup(token) 282 defer teardown() 283 284 mux.HandleFunc("/users/"+userId, func(w http.ResponseWriter, req *http.Request) { 285 testHttpMethod(t, req, "PATCH") 286 testHeader(t, req, "Authorization", "Bearer "+token) 287 fmt.Fprint(w, dummyUserJson) 288 }) 289 290 got, _ := client.Users().Update(userId, &payload) 291 292 var want User 293 _ = json.Unmarshal([]byte(dummyUserJson), &want) 294 295 if !reflect.DeepEqual(*got, want) { 296 t.Errorf("Response = %v, want %v", *got, payload) 297 } 298 } 299 300 func TestUsersService_Update_invalidServer(t *testing.T) { 301 client, _ := NewClient("token") 302 303 _, err := client.Users().Update("someUserId", nil) 304 if err == nil { 305 t.Errorf("Expected error to be returned") 306 } 307 } 308 309 func TestUsersService_UpdateMetadata_happyPath(t *testing.T) { 310 token := "token" 311 userId := "someUserId" 312 var payload UpdateUserMetadata 313 _ = json.Unmarshal([]byte(dummyUpdateMetadataRequestJson), &payload) 314 315 client, mux, _, teardown := setup(token) 316 defer teardown() 317 318 mux.HandleFunc("/users/"+userId+"/metadata", func(w http.ResponseWriter, req *http.Request) { 319 testHttpMethod(t, req, http.MethodPatch) 320 testHeader(t, req, "Authorization", "Bearer "+token) 321 fmt.Fprint(w, dummyUserJson) 322 }) 323 324 got, _ := client.Users().UpdateMetadata(userId, &payload) 325 326 var want User 327 _ = json.Unmarshal([]byte(dummyUserJson), &want) 328 329 if !reflect.DeepEqual(*got, want) { 330 t.Errorf("Response = %v, want %v", *got, payload) 331 } 332 } 333 334 func TestUsersService_UpdateMetadata_invalidServer(t *testing.T) { 335 client, _ := NewClient("token") 336 337 _, err := client.Users().UpdateMetadata("someUserId", nil) 338 if err == nil { 339 t.Errorf("Expected error to be returned") 340 } 341 } 342 343 func TestUsersService_ListOAuthAccessTokens_happyPath(t *testing.T) { 344 token := "token" 345 userId := "someUserId" 346 provider := "testProvider" 347 348 client, mux, _, teardown := setup(token) 349 defer teardown() 350 351 mux.HandleFunc(fmt.Sprintf("/users/%s/oauth_access_tokens/%s", userId, provider), func(w http.ResponseWriter, req *http.Request) { 352 testHttpMethod(t, req, "GET") 353 testHeader(t, req, "Authorization", "Bearer "+token) 354 fmt.Fprint(w, dummyUserOAuthAccessTokensJson) 355 }) 356 357 got, _ := client.Users().ListOAuthAccessTokens(userId, provider) 358 359 want := make([]*UserOAuthAccessToken, 0) 360 _ = json.Unmarshal([]byte(dummyUserOAuthAccessTokensJson), &want) 361 362 if !reflect.DeepEqual(got, want) { 363 t.Errorf("Response = %v, want %v", got, want) 364 } 365 } 366 367 func TestUsersService_ListOAuthAccessTokens_invalidServer(t *testing.T) { 368 client, _ := NewClient("token") 369 370 _, err := client.Users().ListOAuthAccessTokens("someUserId", "testProvider") 371 if err == nil { 372 t.Errorf("Expected error to be returned") 373 } 374 } 375 376 func TestUsersService_DisableMFA_happyPath(t *testing.T) { 377 token := "token" 378 userID := "test-user-id" 379 var payload UpdateUserMetadata 380 _ = json.Unmarshal([]byte(dummyUpdateMetadataRequestJson), &payload) 381 382 client, mux, _, teardown := setup(token) 383 defer teardown() 384 385 mux.HandleFunc("/users/"+userID+"/mfa", func(w http.ResponseWriter, req *http.Request) { 386 testHttpMethod(t, req, http.MethodDelete) 387 testHeader(t, req, "Authorization", "Bearer "+token) 388 fmt.Fprint(w, `{"user_id":"`+userID+`"}`) 389 }) 390 391 got, err := client.Users().DisableMFA(userID) 392 assert.NoError(t, err) 393 assert.Equal(t, userID, got.UserID) 394 } 395 396 func TestUsersService_Ban_happyPath(t *testing.T) { 397 token := "token" 398 userID := "test-user-id" 399 400 client, mux, _, teardown := setup(token) 401 defer teardown() 402 403 mux.HandleFunc("/users/"+userID+"/ban", func(w http.ResponseWriter, req *http.Request) { 404 testHttpMethod(t, req, http.MethodPost) 405 testHeader(t, req, "Authorization", "Bearer "+token) 406 fmt.Fprint(w, dummyUserJson) 407 }) 408 409 _, err := client.Users().Ban(userID) 410 assert.NoError(t, err) 411 } 412 413 func TestUsersService_Unban_happyPath(t *testing.T) { 414 token := "token" 415 userID := "test-user-id" 416 417 client, mux, _, teardown := setup(token) 418 defer teardown() 419 420 mux.HandleFunc("/users/"+userID+"/unban", func(w http.ResponseWriter, req *http.Request) { 421 testHttpMethod(t, req, http.MethodPost) 422 testHeader(t, req, "Authorization", "Bearer "+token) 423 fmt.Fprint(w, dummyUserJson) 424 }) 425 426 _, err := client.Users().Unban(userID) 427 assert.NoError(t, err) 428 } 429 430 func TestUsersService_Lock_happyPath(t *testing.T) { 431 token := "token" 432 userID := "test-user-id" 433 434 client, mux, _, teardown := setup(token) 435 defer teardown() 436 437 mux.HandleFunc("/users/"+userID+"/lock", func(w http.ResponseWriter, req *http.Request) { 438 testHttpMethod(t, req, http.MethodPost) 439 testHeader(t, req, "Authorization", "Bearer "+token) 440 fmt.Fprint(w, dummyUserJson) 441 }) 442 443 _, err := client.Users().Lock(userID) 444 assert.NoError(t, err) 445 } 446 447 func TestUsersService_Unlock_happyPath(t *testing.T) { 448 token := "token" 449 userID := "test-user-id" 450 451 client, mux, _, teardown := setup(token) 452 defer teardown() 453 454 mux.HandleFunc("/users/"+userID+"/unlock", func(w http.ResponseWriter, req *http.Request) { 455 testHttpMethod(t, req, http.MethodPost) 456 testHeader(t, req, "Authorization", "Bearer "+token) 457 fmt.Fprint(w, dummyUserJson) 458 }) 459 460 _, err := client.Users().Unlock(userID) 461 assert.NoError(t, err) 462 } 463 464 const dummyUserJson = `{ 465 "birthday": "", 466 "created_at": 1610783813, 467 "email_addresses": [ 468 { 469 "email_address": "iron_man@avengers.com", 470 "id": "idn_1mebQ9KkZWrhbQGF8Yj", 471 "linked_to": [ 472 { 473 "id": "idn_1n8tzrjmoKzHtQkaFe1pvK1OqLr", 474 "type": "oauth_google" 475 } 476 ], 477 "object": "email_address", 478 "verification": { 479 "status": "verified", 480 "strategy": "from_oauth_google" 481 } 482 } 483 ], 484 "external_accounts": [ 485 { 486 "approved_scopes": "email https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid profile", 487 "email_address": "iron_man@avengers.com", 488 "family_name": "Stark", 489 "given_name": "Tony", 490 "google_id": "11031040442607", 491 "id": "idn_1mebQ8sPZOtb7UQgptk", 492 "object": "google_account", 493 "picture": "https://lh3.googleusercontent.com/a-/AOh14Gg-UlYe7Pzd8vngVKdFlNCuGTn7cqxx=s96-c" 494 } 495 ], 496 "first_name": "Anthony", 497 "gender": "", 498 "id": "user_1mebQggrD3xO5JfuHk7clQ94ysA", 499 "last_name": "Stark", 500 "object": "user", 501 "password_enabled": false, 502 "phone_numbers": [], 503 "primary_email_address_id": "idn_1n8tzqi8K5ydvb1K7RJEKjT7Wb8", 504 "primary_phone_number_id": null, 505 "profile_image_url": "https://lh3.googleusercontent.com/a-/AOh14Gg-UlYe7PzddYKJRu2r8vGTn7cqxx=s96-c", 506 "two_factor_enabled": false, 507 "updated_at": 1610783813, 508 "username": null, 509 "public_metadata": { 510 "address": { 511 "street": "Pennsylvania Avenue", 512 "number": "1600" 513 } 514 }, 515 "private_metadata": { 516 "app_id": 5 517 }, 518 "last_sign_in_at": 1610783813000, 519 "banned": false, 520 "locked": false, 521 "lockout_expires_in_seconds": null, 522 "verification_attempts_remaining": null, 523 "last_active_at": 1700690400000 524 }` 525 526 const dummyUserOAuthAccessTokensJson = `[ 527 { 528 "external_account_id": "eac_2dYS7stz9bgxQsSRvNqEAHhuxvW", 529 "object": "oauth_access_token", 530 "token": "test_token", 531 "provider": "oauth_testProvider", 532 "public_metadata": {}, 533 "label": null, 534 "scopes": [ 535 "user:read", 536 "user:write" 537 ] 538 } 539 ]` 540 541 const dummyCreateUserRequestJson = `{ 542 "first_name": "Tony", 543 "last_name": "Stark", 544 "email_address": ["email@example.com"], 545 "phone_number": ["+30123456789"], 546 "password": "new_password", 547 "public_metadata": { 548 "address": { 549 "street": "Pennsylvania Avenue", 550 "number": "1600" 551 } 552 }, 553 "private_metadata": { 554 app_id: 5 555 }, 556 "unsafe_metadata": { 557 viewed_profile: true 558 }, 559 "totp_secret": "AICJ3HCXKO4KOY6NDH6RII4E3ZYL5ZBH", 560 }` 561 562 const dummyUpdateRequestJson = `{ 563 "first_name": "Tony", 564 "last_name": "Stark", 565 "primary_email_address_id": "some_image_id", 566 "primary_phone_number_id": "some_phone_id", 567 "profile_image": "some_profile_image", 568 "password": "new_password", 569 "public_metadata": { 570 "address": { 571 "street": "Pennsylvania Avenue", 572 "number": "1600" 573 } 574 }, 575 "private_metadata": { 576 app_id: 5 577 }, 578 "unsafe_metadata": { 579 viewed_profile: true 580 }, 581 }` 582 583 const dummyUpdateMetadataRequestJson = `{ 584 "public_metadata": { 585 "value": "public_value", 586 }, 587 "private_metadata": { 588 "contact_id": "some_contact_id", 589 }, 590 "unsafe_metadata": { 591 viewed_profile: true 592 }, 593 }` 594 595 const dummyUserCountJson = `{ 596 "object": "total_count", 597 "total_count": 2 598 }`