github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/api/cloudcontroller/ccv3/user_test.go (about)

     1  package ccv3_test
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  
     7  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     8  	. "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
     9  	"code.cloudfoundry.org/cli/resources"
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  	. "github.com/onsi/gomega/ghttp"
    13  )
    14  
    15  var _ = Describe("User", func() {
    16  	var client *Client
    17  
    18  	BeforeEach(func() {
    19  		client, _ = NewTestClient()
    20  	})
    21  
    22  	Describe("CreateUser", func() {
    23  		var (
    24  			warnings   Warnings
    25  			executeErr error
    26  			user       resources.User
    27  		)
    28  
    29  		JustBeforeEach(func() {
    30  			user, warnings, executeErr = client.CreateUser("some-uaa-guid")
    31  		})
    32  
    33  		When("no error occurs", func() {
    34  			BeforeEach(func() {
    35  				response := `{
    36                      "guid": "some-uaa-guid",
    37                      "username": "some-user-name",
    38                      "presentation_name": "some-user-name",
    39                      "origin": "ldap",
    40                      "created_at": "2016-12-07T18:18:30Z",
    41                      "updated_at": null
    42  
    43                  }`
    44  				expectedBody := `{"guid":"some-uaa-guid"}`
    45  				server.AppendHandlers(
    46  					CombineHandlers(
    47  						VerifyRequest(http.MethodPost, "/v3/users"),
    48  						VerifyJSON(expectedBody),
    49  						RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"warning-1, warning-2"}}),
    50  					),
    51  				)
    52  			})
    53  
    54  			It("creates and returns the user and all warnings", func() {
    55  				Expect(executeErr).ToNot(HaveOccurred())
    56  
    57  				Expect(user).To(Equal(resources.User{GUID: "some-uaa-guid", Username: "some-user-name", PresentationName: "some-user-name", Origin: "ldap"}))
    58  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
    59  			})
    60  		})
    61  
    62  		When("the cloud controller returns errors and warnings", func() {
    63  			BeforeEach(func() {
    64  				response := `{
    65    "errors": [
    66      {
    67        "code": 10008,
    68        "detail": "The request is semantically invalid: command presence",
    69        "title": "CF-UnprocessableEntity"
    70      },
    71  		{
    72        "code": 10010,
    73        "detail": "Isolation segment not found",
    74        "title": "CF-ResourceNotFound"
    75      }
    76    ]
    77  }`
    78  				server.AppendHandlers(
    79  					CombineHandlers(
    80  						VerifyRequest(http.MethodPost, "/v3/users"),
    81  						RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
    82  					),
    83  				)
    84  			})
    85  
    86  			It("returns the error and all warnings", func() {
    87  				Expect(executeErr).To(MatchError(ccerror.MultiError{
    88  					ResponseCode: http.StatusTeapot,
    89  					Errors: []ccerror.V3Error{
    90  						{
    91  							Code:   10008,
    92  							Detail: "The request is semantically invalid: command presence",
    93  							Title:  "CF-UnprocessableEntity",
    94  						},
    95  						{
    96  							Code:   10010,
    97  							Detail: "Isolation segment not found",
    98  							Title:  "CF-ResourceNotFound",
    99  						},
   100  					},
   101  				}))
   102  				Expect(warnings).To(ConsistOf("this is a warning"))
   103  			})
   104  		})
   105  	})
   106  
   107  	Describe("DeleteUser", func() {
   108  		var (
   109  			jobUrl     JobURL
   110  			warnings   Warnings
   111  			executeErr error
   112  		)
   113  
   114  		JustBeforeEach(func() {
   115  			jobUrl, warnings, executeErr = client.DeleteUser("some-uaa-guid")
   116  		})
   117  
   118  		When("no error occurs", func() {
   119  			BeforeEach(func() {
   120  				response := `{}`
   121  				server.AppendHandlers(
   122  					CombineHandlers(
   123  						VerifyRequest(http.MethodDelete, "/v3/users/some-uaa-guid"),
   124  						RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"warning-1, warning-2"}, "Location": []string{"job-url"}}),
   125  					),
   126  				)
   127  			})
   128  
   129  			It("deletes and returns all warnings", func() {
   130  				Expect(executeErr).ToNot(HaveOccurred())
   131  
   132  				Expect(jobUrl).To(Equal(JobURL("job-url")))
   133  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
   134  			})
   135  		})
   136  
   137  		When("the cloud controller returns errors and warnings", func() {
   138  			When("the error should be raise", func() {
   139  
   140  				BeforeEach(func() {
   141  					response := `{
   142    "errors": [
   143      {
   144        "code": 10008,
   145        "detail": "The request is semantically invalid: command presence",
   146        "title": "CF-UnprocessableEntity"
   147      },
   148  		{
   149        "code": 10010,
   150        "detail": "Isolation segment not found",
   151        "title": "CF-ResourceNotFound"
   152      }
   153    ]
   154  }`
   155  					server.AppendHandlers(
   156  						CombineHandlers(
   157  							VerifyRequest(http.MethodDelete, "/v3/users/some-uaa-guid"),
   158  							RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a delete warning"}}),
   159  						),
   160  					)
   161  				})
   162  
   163  				It("returns the error and all warnings", func() {
   164  					Expect(executeErr).To(MatchError(ccerror.MultiError{
   165  						ResponseCode: http.StatusTeapot,
   166  						Errors: []ccerror.V3Error{
   167  							{
   168  								Code:   10008,
   169  								Detail: "The request is semantically invalid: command presence",
   170  								Title:  "CF-UnprocessableEntity",
   171  							},
   172  							{
   173  								Code:   10010,
   174  								Detail: "Isolation segment not found",
   175  								Title:  "CF-ResourceNotFound",
   176  							},
   177  						},
   178  					}))
   179  					Expect(warnings).To(ConsistOf("this is a delete warning"))
   180  				})
   181  			})
   182  		})
   183  	})
   184  
   185  	Describe("GetUsers", func() {
   186  		var (
   187  			users      []resources.User
   188  			warnings   Warnings
   189  			executeErr error
   190  			query      []Query
   191  		)
   192  
   193  		BeforeEach(func() {
   194  			query = []Query{
   195  				{
   196  					Key:    UsernamesFilter,
   197  					Values: []string{"some-user-name"},
   198  				},
   199  				{
   200  					Key:    OriginsFilter,
   201  					Values: []string{"uaa"},
   202  				},
   203  			}
   204  		})
   205  		JustBeforeEach(func() {
   206  			users, warnings, executeErr = client.GetUsers(query...)
   207  		})
   208  
   209  		Describe("listing users", func() {
   210  			When("the request succeeds", func() {
   211  				BeforeEach(func() {
   212  					response1 := fmt.Sprintf(`{
   213  	"pagination": {
   214  		"next": {
   215  			"href": null
   216  		}
   217  	},
   218    "resources": [
   219      {
   220        "guid": "user-guid-1",
   221        "username": "some-user-name",
   222        "origin": "uaa"
   223      }
   224    ]
   225  }`)
   226  
   227  					server.AppendHandlers(
   228  						CombineHandlers(
   229  							VerifyRequest(http.MethodGet, "/v3/users", "usernames=some-user-name&origins=uaa"),
   230  							RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"warning-1"}}),
   231  						),
   232  					)
   233  				})
   234  
   235  				It("returns the given user and all warnings", func() {
   236  					Expect(executeErr).ToNot(HaveOccurred())
   237  					Expect(warnings).To(ConsistOf("warning-1"))
   238  
   239  					Expect(users).To(Equal([]resources.User{{
   240  						GUID:     "user-guid-1",
   241  						Username: "some-user-name",
   242  						Origin:   "uaa",
   243  					},
   244  					}))
   245  				})
   246  			})
   247  
   248  			When("the cloud controller returns errors and warnings", func() {
   249  				BeforeEach(func() {
   250  					response := `{
   251    "errors": [
   252      {
   253        "code": 10008,
   254        "detail": "The request is semantically invalid: command presence",
   255        "title": "CF-UnprocessableEntity"
   256      },
   257      {
   258        "code": 10010,
   259        "detail": "Org not found",
   260        "title": "CF-ResourceNotFound"
   261      }
   262    ]
   263  }`
   264  					server.AppendHandlers(
   265  						CombineHandlers(
   266  							VerifyRequest(http.MethodGet, "/v3/users"),
   267  							RespondWith(http.StatusTeapot, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   268  						),
   269  					)
   270  				})
   271  
   272  				It("returns the error and all warnings", func() {
   273  					Expect(executeErr).To(MatchError(ccerror.MultiError{
   274  						ResponseCode: http.StatusTeapot,
   275  						Errors: []ccerror.V3Error{
   276  							{
   277  								Code:   10008,
   278  								Detail: "The request is semantically invalid: command presence",
   279  								Title:  "CF-UnprocessableEntity",
   280  							},
   281  							{
   282  								Code:   10010,
   283  								Detail: "Org not found",
   284  								Title:  "CF-ResourceNotFound",
   285  							},
   286  						},
   287  					}))
   288  					Expect(warnings).To(ConsistOf("this is a warning"))
   289  				})
   290  			})
   291  		})
   292  	})
   293  
   294  	Describe("GetUser", func() {
   295  		var (
   296  			user       resources.User
   297  			warnings   Warnings
   298  			executeErr error
   299  		)
   300  
   301  		JustBeforeEach(func() {
   302  			user, warnings, executeErr = client.GetUser("some-guid")
   303  		})
   304  
   305  		When("the request succeeds", func() {
   306  			BeforeEach(func() {
   307  				response := `{
   308  					"guid": "some-guid",
   309  					"username": "some-user-name",
   310  					"origin": "some-origin"
   311  				}`
   312  				server.AppendHandlers(
   313  					CombineHandlers(
   314  						VerifyRequest(http.MethodGet, "/v3/users/some-guid"),
   315  						RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
   316  					),
   317  				)
   318  			})
   319  
   320  			It("returns the given user and all warnings", func() {
   321  				Expect(executeErr).ToNot(HaveOccurred())
   322  
   323  				Expect(user).To(Equal(resources.User{
   324  					GUID:     "some-guid",
   325  					Username: "some-user-name",
   326  					Origin:   "some-origin",
   327  				}))
   328  				Expect(warnings).To(ConsistOf("warning-1"))
   329  			})
   330  		})
   331  
   332  		When("cloud controller returns an error", func() {
   333  			BeforeEach(func() {
   334  				response := `{
   335  					"errors": [
   336  						{
   337  							"code": 10010,
   338  							"detail": "User not found",
   339  							"title": "CF-ResourceNotFound"
   340  						}
   341  					]
   342  				}`
   343  				server.AppendHandlers(
   344  					CombineHandlers(
   345  						VerifyRequest(http.MethodGet, "/v3/users/some-guid"),
   346  						RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
   347  					),
   348  				)
   349  			})
   350  
   351  			It("returns the error", func() {
   352  				Expect(executeErr).To(MatchError(ccerror.UserNotFoundError{}))
   353  				Expect(warnings).To(ConsistOf("warning-1"))
   354  			})
   355  		})
   356  	})
   357  
   358  	Describe("Who am I", func() {
   359  		var (
   360  			k8sUser    resources.K8sUser
   361  			warnings   Warnings
   362  			executeErr error
   363  		)
   364  
   365  		JustBeforeEach(func() {
   366  			k8sUser, warnings, executeErr = client.WhoAmI()
   367  		})
   368  
   369  		When("the request succeeds", func() {
   370  			BeforeEach(func() {
   371  				response := `{
   372                      "name": "bob",
   373                      "kind": "User"
   374                  }`
   375  				server.AppendHandlers(
   376  					CombineHandlers(
   377  						VerifyRequest(http.MethodGet, "/whoami"),
   378  						RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
   379  					),
   380  				)
   381  			})
   382  
   383  			It("returns the expected user and all warnings", func() {
   384  				Expect(executeErr).ToNot(HaveOccurred())
   385  				Expect(k8sUser.Name).To(Equal("bob"))
   386  				Expect(k8sUser.Kind).To(Equal("User"))
   387  				Expect(warnings).To(ConsistOf("warning-1"))
   388  			})
   389  		})
   390  
   391  		When("cloud controller returns an error", func() {
   392  			BeforeEach(func() {
   393  				response := `{
   394                      "errors": [
   395                          {
   396                              "code": 1000,
   397                              "detail": "Not authenticated",
   398                              "title": "CF-InvalidAuthToken"
   399                          }
   400                      ]
   401                  }`
   402  				server.AppendHandlers(
   403  					CombineHandlers(
   404  						VerifyRequest(http.MethodGet, "/whoami"),
   405  						RespondWith(http.StatusUnauthorized, response, http.Header{"X-Cf-Warnings": {"warning-1"}}),
   406  					),
   407  				)
   408  			})
   409  
   410  			It("returns the error", func() {
   411  				Expect(executeErr).To(MatchError(ccerror.InvalidAuthTokenError{Message: "Not authenticated"}))
   412  				Expect(warnings).To(ConsistOf("warning-1"))
   413  			})
   414  		})
   415  	})
   416  })