github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/identity/v3/tokens/testing/requests_test.go (about) 1 package testing 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "testing" 8 "time" 9 10 "github.com/vnpaycloud-console/gophercloud/v2" 11 "github.com/vnpaycloud-console/gophercloud/v2/openstack/identity/v3/tokens" 12 th "github.com/vnpaycloud-console/gophercloud/v2/testhelper" 13 "github.com/vnpaycloud-console/gophercloud/v2/testhelper/client" 14 ) 15 16 // authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure. 17 func authTokenPost(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, requestJSON string) { 18 th.SetupHTTP() 19 defer th.TeardownHTTP() 20 21 client := gophercloud.ServiceClient{ 22 ProviderClient: &gophercloud.ProviderClient{}, 23 Endpoint: th.Endpoint(), 24 } 25 26 th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { 27 th.TestMethod(t, r, "POST") 28 th.TestHeader(t, r, "Content-Type", "application/json") 29 th.TestHeader(t, r, "Accept", "application/json") 30 th.TestJSONRequest(t, r, requestJSON) 31 32 w.WriteHeader(http.StatusCreated) 33 fmt.Fprint(w, `{ 34 "token": { 35 "expires_at": "2014-10-02T13:45:00.000000Z" 36 } 37 }`) 38 }) 39 40 if scope != nil { 41 options.Scope = *scope 42 } 43 44 expected := &tokens.Token{ 45 ExpiresAt: time.Date(2014, 10, 2, 13, 45, 0, 0, time.UTC), 46 } 47 actual, err := tokens.Create(context.TODO(), &client, &options).Extract() 48 th.AssertNoErr(t, err) 49 th.CheckDeepEquals(t, expected, actual) 50 } 51 52 func authTokenPostErr(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, includeToken bool, expectedErr error) { 53 th.SetupHTTP() 54 defer th.TeardownHTTP() 55 56 client := gophercloud.ServiceClient{ 57 ProviderClient: &gophercloud.ProviderClient{}, 58 Endpoint: th.Endpoint(), 59 } 60 if includeToken { 61 client.TokenID = "abcdef123456" 62 } 63 64 if scope != nil { 65 options.Scope = *scope 66 } 67 68 _, err := tokens.Create(context.TODO(), &client, &options).Extract() 69 if err == nil { 70 t.Errorf("Create did NOT return an error") 71 } 72 if err != expectedErr { 73 t.Errorf("Create returned an unexpected error: wanted %v, got %v", expectedErr, err) 74 } 75 } 76 77 func TestCreateUserIDAndPassword(t *testing.T) { 78 authTokenPost(t, tokens.AuthOptions{UserID: "me", Password: "squirrel!"}, nil, ` 79 { 80 "auth": { 81 "identity": { 82 "methods": ["password"], 83 "password": { 84 "user": { "id": "me", "password": "squirrel!" } 85 } 86 } 87 } 88 } 89 `) 90 } 91 92 func TestCreateUsernameDomainIDPassword(t *testing.T) { 93 authTokenPost(t, tokens.AuthOptions{Username: "fakey", Password: "notpassword", DomainID: "abc123"}, nil, ` 94 { 95 "auth": { 96 "identity": { 97 "methods": ["password"], 98 "password": { 99 "user": { 100 "domain": { 101 "id": "abc123" 102 }, 103 "name": "fakey", 104 "password": "notpassword" 105 } 106 } 107 } 108 } 109 } 110 `) 111 } 112 113 func TestCreateUsernameDomainNamePassword(t *testing.T) { 114 authTokenPost(t, tokens.AuthOptions{Username: "frank", Password: "swordfish", DomainName: "spork.net"}, nil, ` 115 { 116 "auth": { 117 "identity": { 118 "methods": ["password"], 119 "password": { 120 "user": { 121 "domain": { 122 "name": "spork.net" 123 }, 124 "name": "frank", 125 "password": "swordfish" 126 } 127 } 128 } 129 } 130 } 131 `) 132 } 133 134 func TestCreateTokenID(t *testing.T) { 135 authTokenPost(t, tokens.AuthOptions{TokenID: "12345abcdef"}, nil, ` 136 { 137 "auth": { 138 "identity": { 139 "methods": ["token"], 140 "token": { 141 "id": "12345abcdef" 142 } 143 } 144 } 145 } 146 `) 147 } 148 149 func TestCreateProjectIDScope(t *testing.T) { 150 options := tokens.AuthOptions{UserID: "someuser", Password: "somepassword"} 151 scope := &tokens.Scope{ProjectID: "123456"} 152 authTokenPost(t, options, scope, ` 153 { 154 "auth": { 155 "identity": { 156 "methods": ["password"], 157 "password": { 158 "user": { 159 "id": "someuser", 160 "password": "somepassword" 161 } 162 } 163 }, 164 "scope": { 165 "project": { 166 "id": "123456" 167 } 168 } 169 } 170 } 171 `) 172 } 173 174 func TestCreateDomainIDScope(t *testing.T) { 175 options := tokens.AuthOptions{UserID: "someuser", Password: "somepassword"} 176 scope := &tokens.Scope{DomainID: "1000"} 177 authTokenPost(t, options, scope, ` 178 { 179 "auth": { 180 "identity": { 181 "methods": ["password"], 182 "password": { 183 "user": { 184 "id": "someuser", 185 "password": "somepassword" 186 } 187 } 188 }, 189 "scope": { 190 "domain": { 191 "id": "1000" 192 } 193 } 194 } 195 } 196 `) 197 } 198 199 func TestCreateDomainNameScope(t *testing.T) { 200 options := tokens.AuthOptions{UserID: "someuser", Password: "somepassword"} 201 scope := &tokens.Scope{DomainName: "evil-plans"} 202 authTokenPost(t, options, scope, ` 203 { 204 "auth": { 205 "identity": { 206 "methods": ["password"], 207 "password": { 208 "user": { 209 "id": "someuser", 210 "password": "somepassword" 211 } 212 } 213 }, 214 "scope": { 215 "domain": { 216 "name": "evil-plans" 217 } 218 } 219 } 220 } 221 `) 222 } 223 224 func TestCreateProjectNameAndDomainIDScope(t *testing.T) { 225 options := tokens.AuthOptions{UserID: "someuser", Password: "somepassword"} 226 scope := &tokens.Scope{ProjectName: "world-domination", DomainID: "1000"} 227 authTokenPost(t, options, scope, ` 228 { 229 "auth": { 230 "identity": { 231 "methods": ["password"], 232 "password": { 233 "user": { 234 "id": "someuser", 235 "password": "somepassword" 236 } 237 } 238 }, 239 "scope": { 240 "project": { 241 "domain": { 242 "id": "1000" 243 }, 244 "name": "world-domination" 245 } 246 } 247 } 248 } 249 `) 250 } 251 252 func TestCreateProjectNameAndDomainNameScope(t *testing.T) { 253 options := tokens.AuthOptions{UserID: "someuser", Password: "somepassword"} 254 scope := &tokens.Scope{ProjectName: "world-domination", DomainName: "evil-plans"} 255 authTokenPost(t, options, scope, ` 256 { 257 "auth": { 258 "identity": { 259 "methods": ["password"], 260 "password": { 261 "user": { 262 "id": "someuser", 263 "password": "somepassword" 264 } 265 } 266 }, 267 "scope": { 268 "project": { 269 "domain": { 270 "name": "evil-plans" 271 }, 272 "name": "world-domination" 273 } 274 } 275 } 276 } 277 `) 278 } 279 280 func TestCreateSystemScope(t *testing.T) { 281 options := tokens.AuthOptions{UserID: "someuser", Password: "somepassword"} 282 scope := &tokens.Scope{System: true} 283 authTokenPost(t, options, scope, ` 284 { 285 "auth": { 286 "identity": { 287 "methods": ["password"], 288 "password": { 289 "user": { 290 "id": "someuser", 291 "password": "somepassword" 292 } 293 } 294 }, 295 "scope": { 296 "system": { 297 "all": true 298 } 299 } 300 } 301 } 302 `) 303 } 304 305 func TestCreateUserIDPasswordTrustID(t *testing.T) { 306 th.SetupHTTP() 307 defer th.TeardownHTTP() 308 309 requestJSON := `{ 310 "auth": { 311 "identity": { 312 "methods": ["password"], 313 "password": { 314 "user": { "id": "demo", "password": "squirrel!" } 315 } 316 }, 317 "scope": { 318 "OS-TRUST:trust": { 319 "id": "95946f9eef864fdc993079d8fe3e5747" 320 } 321 } 322 } 323 }` 324 responseJSON := `{ 325 "token": { 326 "OS-TRUST:trust": { 327 "id": "95946f9eef864fdc993079d8fe3e5747", 328 "impersonation": false, 329 "trustee_user": { 330 "id": "64f9caa2872b442c98d42a986ee3b37a" 331 }, 332 "trustor_user": { 333 "id": "c88693b7c81c408e9084ac1e51082bfb" 334 } 335 }, 336 "audit_ids": [ 337 "wwcoUZGPR6mCIIl-COn8Kg" 338 ], 339 "catalog": [], 340 "expires_at": "2024-02-28T12:10:39.000000Z", 341 "issued_at": "2024-02-28T11:10:39.000000Z", 342 "methods": [ 343 "password" 344 ], 345 "project": { 346 "domain": { 347 "id": "default", 348 "name": "Default" 349 }, 350 "id": "1fd93a4455c74d2ea94b929fc5f0e488", 351 "name": "admin" 352 }, 353 "roles": [], 354 "user": { 355 "domain": { 356 "id": "default", 357 "name": "Default" 358 }, 359 "id": "64f9caa2872b442c98d42a986ee3b37a", 360 "name": "demo", 361 "password_expires_at": null 362 } 363 } 364 }` 365 th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { 366 th.TestMethod(t, r, "POST") 367 th.TestHeader(t, r, "Content-Type", "application/json") 368 th.TestHeader(t, r, "Accept", "application/json") 369 th.TestJSONRequest(t, r, requestJSON) 370 371 w.WriteHeader(http.StatusCreated) 372 fmt.Fprint(w, responseJSON) 373 }) 374 375 ao := gophercloud.AuthOptions{ 376 UserID: "demo", 377 Password: "squirrel!", 378 Scope: &gophercloud.AuthScope{ 379 TrustID: "95946f9eef864fdc993079d8fe3e5747", 380 }, 381 } 382 383 rsp := tokens.Create(context.TODO(), client.ServiceClient(), &ao) 384 385 token, err := rsp.Extract() 386 if err != nil { 387 t.Errorf("Create returned an error: %v", err) 388 } 389 expectedToken := &tokens.Token{ 390 ExpiresAt: time.Date(2024, 02, 28, 12, 10, 39, 0, time.UTC), 391 } 392 th.AssertDeepEquals(t, expectedToken, token) 393 394 trust, err := rsp.ExtractTrust() 395 if err != nil { 396 t.Errorf("ExtractTrust returned an error: %v", err) 397 } 398 expectedTrust := &tokens.Trust{ 399 ID: "95946f9eef864fdc993079d8fe3e5747", 400 Impersonation: false, 401 TrusteeUserID: tokens.TrustUser{ 402 ID: "64f9caa2872b442c98d42a986ee3b37a", 403 }, 404 TrustorUserID: tokens.TrustUser{ 405 ID: "c88693b7c81c408e9084ac1e51082bfb", 406 }, 407 } 408 th.AssertDeepEquals(t, expectedTrust, trust) 409 } 410 411 func TestCreateApplicationCredentialIDAndSecret(t *testing.T) { 412 authTokenPost(t, tokens.AuthOptions{ApplicationCredentialID: "12345abcdef", ApplicationCredentialSecret: "mysecret"}, nil, ` 413 { 414 "auth": { 415 "identity": { 416 "application_credential": { 417 "id": "12345abcdef", 418 "secret": "mysecret" 419 }, 420 "methods": [ 421 "application_credential" 422 ] 423 } 424 } 425 } 426 `) 427 } 428 429 func TestCreateApplicationCredentialNameAndSecret(t *testing.T) { 430 authTokenPost(t, tokens.AuthOptions{ApplicationCredentialName: "myappcred", ApplicationCredentialSecret: "mysecret", Username: "someuser", DomainName: "evil-plans"}, nil, ` 431 { 432 "auth": { 433 "identity": { 434 "application_credential": { 435 "name": "myappcred", 436 "secret": "mysecret", 437 "user": { 438 "name": "someuser", 439 "domain": { 440 "name": "evil-plans" 441 } 442 } 443 }, 444 "methods": [ 445 "application_credential" 446 ] 447 } 448 } 449 } 450 `) 451 } 452 453 func TestCreateTOTPProjectNameAndDomainNameScope(t *testing.T) { 454 options := tokens.AuthOptions{UserID: "someuser", Passcode: "12345678"} 455 scope := &tokens.Scope{ProjectName: "world-domination", DomainName: "evil-plans"} 456 authTokenPost(t, options, scope, ` 457 { 458 "auth": { 459 "identity": { 460 "methods": ["totp"], 461 "totp": { 462 "user": { 463 "id": "someuser", 464 "passcode": "12345678" 465 } 466 } 467 }, 468 "scope": { 469 "project": { 470 "domain": { 471 "name": "evil-plans" 472 }, 473 "name": "world-domination" 474 } 475 } 476 } 477 } 478 `) 479 } 480 481 func TestCreatePasswordTOTPProjectNameAndDomainNameScope(t *testing.T) { 482 options := tokens.AuthOptions{UserID: "someuser", Password: "somepassword", Passcode: "12345678"} 483 scope := &tokens.Scope{ProjectName: "world-domination", DomainName: "evil-plans"} 484 authTokenPost(t, options, scope, ` 485 { 486 "auth": { 487 "identity": { 488 "methods": ["password","totp"], 489 "password": { 490 "user": { 491 "id": "someuser", 492 "password": "somepassword" 493 } 494 }, 495 "totp": { 496 "user": { 497 "id": "someuser", 498 "passcode": "12345678" 499 } 500 } 501 }, 502 "scope": { 503 "project": { 504 "domain": { 505 "name": "evil-plans" 506 }, 507 "name": "world-domination" 508 } 509 } 510 } 511 } 512 `) 513 } 514 515 func TestCreateExtractsTokenFromResponse(t *testing.T) { 516 th.SetupHTTP() 517 defer th.TeardownHTTP() 518 519 client := gophercloud.ServiceClient{ 520 ProviderClient: &gophercloud.ProviderClient{}, 521 Endpoint: th.Endpoint(), 522 } 523 524 th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { 525 w.Header().Add("X-Subject-Token", "aaa111") 526 527 w.WriteHeader(http.StatusCreated) 528 fmt.Fprint(w, `{ 529 "token": { 530 "expires_at": "2014-10-02T13:45:00.000000Z" 531 } 532 }`) 533 }) 534 535 options := tokens.AuthOptions{UserID: "me", Password: "shhh"} 536 token, err := tokens.Create(context.TODO(), &client, &options).Extract() 537 if err != nil { 538 t.Fatalf("Create returned an error: %v", err) 539 } 540 541 if token.ID != "aaa111" { 542 t.Errorf("Expected token to be aaa111, but was %s", token.ID) 543 } 544 } 545 546 func TestCreateFailureEmptyAuth(t *testing.T) { 547 authTokenPostErr(t, tokens.AuthOptions{}, nil, false, gophercloud.ErrMissingPassword{}) 548 } 549 550 func TestCreateFailureTokenIDUsername(t *testing.T) { 551 authTokenPostErr(t, tokens.AuthOptions{Username: "something", TokenID: "12345"}, nil, true, gophercloud.ErrUsernameWithToken{}) 552 } 553 554 func TestCreateFailureTokenIDUserID(t *testing.T) { 555 authTokenPostErr(t, tokens.AuthOptions{UserID: "something", TokenID: "12345"}, nil, true, gophercloud.ErrUserIDWithToken{}) 556 } 557 558 func TestCreateFailureTokenIDDomainID(t *testing.T) { 559 authTokenPostErr(t, tokens.AuthOptions{DomainID: "something", TokenID: "12345"}, nil, true, gophercloud.ErrDomainIDWithToken{}) 560 } 561 562 func TestCreateFailureTokenIDDomainName(t *testing.T) { 563 authTokenPostErr(t, tokens.AuthOptions{DomainName: "something", TokenID: "12345"}, nil, true, gophercloud.ErrDomainNameWithToken{}) 564 } 565 566 func TestCreateFailureMissingUser(t *testing.T) { 567 options := tokens.AuthOptions{Password: "supersecure"} 568 authTokenPostErr(t, options, nil, false, gophercloud.ErrUsernameOrUserID{}) 569 } 570 571 func TestCreateFailureBothUser(t *testing.T) { 572 options := tokens.AuthOptions{ 573 Password: "supersecure", 574 Username: "oops", 575 UserID: "redundancy", 576 } 577 authTokenPostErr(t, options, nil, false, gophercloud.ErrUsernameOrUserID{}) 578 } 579 580 func TestCreateFailureMissingDomain(t *testing.T) { 581 options := tokens.AuthOptions{ 582 Password: "supersecure", 583 Username: "notuniqueenough", 584 } 585 authTokenPostErr(t, options, nil, false, gophercloud.ErrDomainIDOrDomainName{}) 586 } 587 588 func TestCreateFailureBothDomain(t *testing.T) { 589 options := tokens.AuthOptions{ 590 Password: "supersecure", 591 Username: "someone", 592 DomainID: "hurf", 593 DomainName: "durf", 594 } 595 authTokenPostErr(t, options, nil, false, gophercloud.ErrDomainIDOrDomainName{}) 596 } 597 598 func TestCreateFailureUserIDDomainID(t *testing.T) { 599 options := tokens.AuthOptions{ 600 UserID: "100", 601 Password: "stuff", 602 DomainID: "oops", 603 } 604 authTokenPostErr(t, options, nil, false, gophercloud.ErrDomainIDWithUserID{}) 605 } 606 607 func TestCreateFailureUserIDDomainName(t *testing.T) { 608 options := tokens.AuthOptions{ 609 UserID: "100", 610 Password: "sssh", 611 DomainName: "oops", 612 } 613 authTokenPostErr(t, options, nil, false, gophercloud.ErrDomainNameWithUserID{}) 614 } 615 616 func TestCreateFailureScopeProjectNameAlone(t *testing.T) { 617 options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"} 618 scope := &tokens.Scope{ProjectName: "notenough"} 619 authTokenPostErr(t, options, scope, false, gophercloud.ErrScopeDomainIDOrDomainName{}) 620 } 621 622 func TestCreateFailureScopeProjectNameAndID(t *testing.T) { 623 options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"} 624 scope := &tokens.Scope{ProjectName: "whoops", ProjectID: "toomuch", DomainID: "1234"} 625 authTokenPostErr(t, options, scope, false, gophercloud.ErrScopeProjectIDOrProjectName{}) 626 } 627 628 func TestCreateFailureScopeProjectIDAndDomainID(t *testing.T) { 629 options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"} 630 scope := &tokens.Scope{ProjectID: "toomuch", DomainID: "notneeded"} 631 authTokenPostErr(t, options, scope, false, gophercloud.ErrScopeProjectIDAlone{}) 632 } 633 634 func TestCreateFailureScopeProjectIDAndDomainNAme(t *testing.T) { 635 options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"} 636 scope := &tokens.Scope{ProjectID: "toomuch", DomainName: "notneeded"} 637 authTokenPostErr(t, options, scope, false, gophercloud.ErrScopeProjectIDAlone{}) 638 } 639 640 func TestCreateFailureScopeDomainIDAndDomainName(t *testing.T) { 641 options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"} 642 scope := &tokens.Scope{DomainID: "toomuch", DomainName: "notneeded"} 643 authTokenPostErr(t, options, scope, false, gophercloud.ErrScopeDomainIDOrDomainName{}) 644 } 645 646 /* 647 func TestCreateFailureEmptyScope(t *testing.T) { 648 options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"} 649 scope := &tokens.Scope{} 650 authTokenPostErr(t, options, scope, false, gophercloud.ErrScopeEmpty{}) 651 } 652 */ 653 654 func TestGetRequest(t *testing.T) { 655 th.SetupHTTP() 656 defer th.TeardownHTTP() 657 658 client := gophercloud.ServiceClient{ 659 ProviderClient: &gophercloud.ProviderClient{ 660 TokenID: "12345abcdef", 661 }, 662 Endpoint: th.Endpoint(), 663 } 664 665 th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { 666 th.TestMethod(t, r, "GET") 667 th.TestHeaderUnset(t, r, "Content-Type") 668 th.TestHeader(t, r, "Accept", "application/json") 669 th.TestHeader(t, r, "X-Auth-Token", "12345abcdef") 670 th.TestHeader(t, r, "X-Subject-Token", "abcdef12345") 671 672 w.WriteHeader(http.StatusOK) 673 fmt.Fprint(w, ` 674 { "token": { "expires_at": "2014-08-29T13:10:01.000000Z" } } 675 `) 676 }) 677 678 token, err := tokens.Get(context.TODO(), &client, "abcdef12345").Extract() 679 if err != nil { 680 t.Errorf("Info returned an error: %v", err) 681 } 682 683 expected, _ := time.Parse(time.UnixDate, "Fri Aug 29 13:10:01 UTC 2014") 684 if token.ExpiresAt != expected { 685 t.Errorf("Expected expiration time %s, but was %s", expected.Format(time.UnixDate), time.Time(token.ExpiresAt).Format(time.UnixDate)) 686 } 687 } 688 689 func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) gophercloud.ServiceClient { 690 client := gophercloud.ServiceClient{ 691 ProviderClient: &gophercloud.ProviderClient{ 692 TokenID: "12345abcdef", 693 }, 694 Endpoint: th.Endpoint(), 695 } 696 697 th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { 698 th.TestMethod(t, r, expectedMethod) 699 th.TestHeaderUnset(t, r, "Content-Type") 700 th.TestHeader(t, r, "Accept", "application/json") 701 th.TestHeader(t, r, "X-Auth-Token", "12345abcdef") 702 th.TestHeader(t, r, "X-Subject-Token", "abcdef12345") 703 704 w.WriteHeader(status) 705 }) 706 707 return client 708 } 709 710 func TestValidateRequestSuccessful(t *testing.T) { 711 th.SetupHTTP() 712 defer th.TeardownHTTP() 713 client := prepareAuthTokenHandler(t, "HEAD", http.StatusNoContent) 714 715 ok, err := tokens.Validate(context.TODO(), &client, "abcdef12345") 716 if err != nil { 717 t.Errorf("Unexpected error from Validate: %v", err) 718 } 719 720 if !ok { 721 t.Errorf("Validate returned false for a valid token") 722 } 723 } 724 725 func TestValidateRequestFailure(t *testing.T) { 726 th.SetupHTTP() 727 defer th.TeardownHTTP() 728 client := prepareAuthTokenHandler(t, "HEAD", http.StatusNotFound) 729 730 ok, err := tokens.Validate(context.TODO(), &client, "abcdef12345") 731 if err != nil { 732 t.Errorf("Unexpected error from Validate: %v", err) 733 } 734 735 if ok { 736 t.Errorf("Validate returned true for an invalid token") 737 } 738 } 739 740 func TestValidateRequestError(t *testing.T) { 741 th.SetupHTTP() 742 defer th.TeardownHTTP() 743 client := prepareAuthTokenHandler(t, "HEAD", http.StatusMethodNotAllowed) 744 745 _, err := tokens.Validate(context.TODO(), &client, "abcdef12345") 746 if err == nil { 747 t.Errorf("Missing expected error from Validate") 748 } 749 } 750 751 func TestRevokeRequestSuccessful(t *testing.T) { 752 th.SetupHTTP() 753 defer th.TeardownHTTP() 754 client := prepareAuthTokenHandler(t, "DELETE", http.StatusNoContent) 755 756 res := tokens.Revoke(context.TODO(), &client, "abcdef12345") 757 th.AssertNoErr(t, res.Err) 758 } 759 760 func TestRevokeRequestError(t *testing.T) { 761 th.SetupHTTP() 762 defer th.TeardownHTTP() 763 client := prepareAuthTokenHandler(t, "DELETE", http.StatusNotFound) 764 765 res := tokens.Revoke(context.TODO(), &client, "abcdef12345") 766 if res.Err == nil { 767 t.Errorf("Missing expected error from Revoke") 768 } 769 } 770 771 func TestNoTokenInResponse(t *testing.T) { 772 th.SetupHTTP() 773 defer th.TeardownHTTP() 774 775 client := gophercloud.ServiceClient{ 776 ProviderClient: &gophercloud.ProviderClient{}, 777 Endpoint: th.Endpoint(), 778 } 779 780 th.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) { 781 w.WriteHeader(http.StatusCreated) 782 fmt.Fprint(w, `{}`) 783 }) 784 785 options := tokens.AuthOptions{UserID: "me", Password: "squirrel!"} 786 _, err := tokens.Create(context.TODO(), &client, &options).Extract() 787 th.AssertNoErr(t, err) 788 }