github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/commands/login_test.go (about)

     1  package commands_test
     2  
     3  import (
     4  	"strconv"
     5  
     6  	"github.com/cloudfoundry/cli/cf"
     7  	testapi "github.com/cloudfoundry/cli/cf/api/fakes"
     8  	fake_organizations "github.com/cloudfoundry/cli/cf/api/organizations/fakes"
     9  	"github.com/cloudfoundry/cli/cf/command_registry"
    10  	"github.com/cloudfoundry/cli/cf/configuration/core_config"
    11  	"github.com/cloudfoundry/cli/cf/errors"
    12  	"github.com/cloudfoundry/cli/cf/models"
    13  	testcmd "github.com/cloudfoundry/cli/testhelpers/commands"
    14  	testconfig "github.com/cloudfoundry/cli/testhelpers/configuration"
    15  	testterm "github.com/cloudfoundry/cli/testhelpers/terminal"
    16  	. "github.com/onsi/ginkgo"
    17  	. "github.com/onsi/gomega"
    18  
    19  	. "github.com/cloudfoundry/cli/testhelpers/matchers"
    20  )
    21  
    22  var _ = Describe("Login Command", func() {
    23  	var (
    24  		Flags        []string
    25  		Config       core_config.Repository
    26  		ui           *testterm.FakeUI
    27  		authRepo     *testapi.FakeAuthenticationRepository
    28  		endpointRepo *testapi.FakeEndpointRepo
    29  		orgRepo      *fake_organizations.FakeOrganizationRepository
    30  		spaceRepo    *testapi.FakeSpaceRepository
    31  
    32  		org  models.Organization
    33  		deps command_registry.Dependency
    34  	)
    35  
    36  	updateCommandDependency := func(pluginCall bool) {
    37  		deps.Ui = ui
    38  		deps.Config = Config
    39  		deps.RepoLocator = deps.RepoLocator.SetEndpointRepository(endpointRepo)
    40  		deps.RepoLocator = deps.RepoLocator.SetAuthenticationRepository(authRepo)
    41  		deps.RepoLocator = deps.RepoLocator.SetOrganizationRepository(orgRepo)
    42  		deps.RepoLocator = deps.RepoLocator.SetSpaceRepository(spaceRepo)
    43  		command_registry.Commands.SetCommand(command_registry.Commands.FindCommand("login").SetDependency(deps, pluginCall))
    44  	}
    45  
    46  	BeforeEach(func() {
    47  		Flags = []string{}
    48  		Config = testconfig.NewRepository()
    49  		ui = &testterm.FakeUI{}
    50  		authRepo = &testapi.FakeAuthenticationRepository{
    51  			AccessToken:  "my_access_token",
    52  			RefreshToken: "my_refresh_token",
    53  			Config:       Config,
    54  		}
    55  		endpointRepo = &testapi.FakeEndpointRepo{}
    56  
    57  		org = models.Organization{}
    58  		org.Name = "my-new-org"
    59  		org.Guid = "my-new-org-guid"
    60  
    61  		orgRepo = &fake_organizations.FakeOrganizationRepository{}
    62  		orgRepo.ListOrgsReturns([]models.Organization{org}, nil)
    63  
    64  		space := models.Space{}
    65  		space.Guid = "my-space-guid"
    66  		space.Name = "my-space"
    67  
    68  		spaceRepo = &testapi.FakeSpaceRepository{
    69  			Spaces: []models.Space{space},
    70  		}
    71  
    72  		authRepo.GetLoginPromptsReturns.Prompts = map[string]core_config.AuthPrompt{
    73  			"username": core_config.AuthPrompt{
    74  				DisplayName: "Username",
    75  				Type:        core_config.AuthPromptTypeText,
    76  			},
    77  			"password": core_config.AuthPrompt{
    78  				DisplayName: "Password",
    79  				Type:        core_config.AuthPromptTypePassword,
    80  			},
    81  		}
    82  	})
    83  
    84  	Context("interactive usage", func() {
    85  		Describe("when there are a small number of organizations and spaces", func() {
    86  			var org2 models.Organization
    87  			var space2 models.Space
    88  
    89  			BeforeEach(func() {
    90  				org1 := models.Organization{}
    91  				org1.Guid = "some-org-guid"
    92  				org1.Name = "some-org"
    93  
    94  				org2 = models.Organization{}
    95  				org2.Guid = "my-new-org-guid"
    96  				org2.Name = "my-new-org"
    97  
    98  				space1 := models.Space{}
    99  				space1.Guid = "my-space-guid"
   100  				space1.Name = "my-space"
   101  
   102  				space2 = models.Space{}
   103  				space2.Guid = "some-space-guid"
   104  				space2.Name = "some-space"
   105  
   106  				orgRepo.ListOrgsReturns([]models.Organization{org1, org2}, nil)
   107  				spaceRepo.Spaces = []models.Space{space1, space2}
   108  			})
   109  
   110  			It("lets the user select an org and space by number", func() {
   111  				orgRepo.FindByNameReturns(org2, nil)
   112  				OUT_OF_RANGE_CHOICE := "3"
   113  				ui.Inputs = []string{"api.example.com", "user@example.com", "password", OUT_OF_RANGE_CHOICE, "2", OUT_OF_RANGE_CHOICE, "1"}
   114  
   115  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   116  
   117  				Expect(ui.Outputs).To(ContainSubstrings(
   118  					[]string{"Select an org"},
   119  					[]string{"1. some-org"},
   120  					[]string{"2. my-new-org"},
   121  					[]string{"Select a space"},
   122  					[]string{"1. my-space"},
   123  					[]string{"2. some-space"},
   124  				))
   125  
   126  				Expect(Config.OrganizationFields().Guid).To(Equal("my-new-org-guid"))
   127  				Expect(Config.SpaceFields().Guid).To(Equal("my-space-guid"))
   128  				Expect(Config.AccessToken()).To(Equal("my_access_token"))
   129  				Expect(Config.RefreshToken()).To(Equal("my_refresh_token"))
   130  
   131  				Expect(endpointRepo.UpdateEndpointReceived).To(Equal("api.example.com"))
   132  
   133  				Expect(orgRepo.FindByNameArgsForCall(0)).To(Equal("my-new-org"))
   134  				Expect(spaceRepo.FindByNameName).To(Equal("my-space"))
   135  
   136  				Expect(ui.ShowConfigurationCalled).To(BeTrue())
   137  			})
   138  
   139  			It("lets the user select an org and space by name", func() {
   140  				ui.Inputs = []string{"api.example.com", "user@example.com", "password", "my-new-org", "my-space"}
   141  				orgRepo.FindByNameReturns(org2, nil)
   142  
   143  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   144  
   145  				Expect(ui.Outputs).To(ContainSubstrings(
   146  					[]string{"Select an org"},
   147  					[]string{"1. some-org"},
   148  					[]string{"2. my-new-org"},
   149  					[]string{"Select a space"},
   150  					[]string{"1. my-space"},
   151  					[]string{"2. some-space"},
   152  				))
   153  
   154  				Expect(Config.OrganizationFields().Guid).To(Equal("my-new-org-guid"))
   155  				Expect(Config.SpaceFields().Guid).To(Equal("my-space-guid"))
   156  				Expect(Config.AccessToken()).To(Equal("my_access_token"))
   157  				Expect(Config.RefreshToken()).To(Equal("my_refresh_token"))
   158  
   159  				Expect(endpointRepo.UpdateEndpointReceived).To(Equal("api.example.com"))
   160  
   161  				Expect(orgRepo.FindByNameArgsForCall(0)).To(Equal("my-new-org"))
   162  				Expect(spaceRepo.FindByNameName).To(Equal("my-space"))
   163  
   164  				Expect(ui.ShowConfigurationCalled).To(BeTrue())
   165  			})
   166  
   167  			It("lets the user specify an org and space using flags", func() {
   168  				Flags = []string{"-a", "api.example.com", "-u", "user@example.com", "-p", "password", "-o", "my-new-org", "-s", "my-space"}
   169  
   170  				orgRepo.FindByNameReturns(org2, nil)
   171  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   172  
   173  				Expect(Config.OrganizationFields().Guid).To(Equal("my-new-org-guid"))
   174  				Expect(Config.SpaceFields().Guid).To(Equal("my-space-guid"))
   175  				Expect(Config.AccessToken()).To(Equal("my_access_token"))
   176  				Expect(Config.RefreshToken()).To(Equal("my_refresh_token"))
   177  
   178  				Expect(endpointRepo.UpdateEndpointReceived).To(Equal("api.example.com"))
   179  				Expect(authRepo.AuthenticateArgs.Credentials).To(Equal([]map[string]string{
   180  					{
   181  						"username": "user@example.com",
   182  						"password": "password",
   183  					},
   184  				}))
   185  
   186  				Expect(ui.ShowConfigurationCalled).To(BeTrue())
   187  			})
   188  
   189  			It("doesn't ask the user for the API url if they have it in their config", func() {
   190  				orgRepo.FindByNameReturns(org, nil)
   191  				Config.SetApiEndpoint("http://api.example.com")
   192  
   193  				Flags = []string{"-o", "my-new-org", "-s", "my-space"}
   194  				ui.Inputs = []string{"user@example.com", "password"}
   195  
   196  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   197  
   198  				Expect(Config.ApiEndpoint()).To(Equal("http://api.example.com"))
   199  				Expect(Config.OrganizationFields().Guid).To(Equal("my-new-org-guid"))
   200  				Expect(Config.SpaceFields().Guid).To(Equal("my-space-guid"))
   201  				Expect(Config.AccessToken()).To(Equal("my_access_token"))
   202  				Expect(Config.RefreshToken()).To(Equal("my_refresh_token"))
   203  
   204  				Expect(endpointRepo.UpdateEndpointReceived).To(Equal("http://api.example.com"))
   205  				Expect(ui.ShowConfigurationCalled).To(BeTrue())
   206  			})
   207  		})
   208  		Describe("when the CLI version is below the minimum required", func() {
   209  			BeforeEach(func() {
   210  				Config.SetMinCliVersion("5.0.0")
   211  				Config.SetMinRecommendedCliVersion("5.5.0")
   212  			})
   213  
   214  			It("prompts users to upgrade if CLI version < min cli version requirement", func() {
   215  				ui.Inputs = []string{"http://api.example.com", "user@example.com", "password"}
   216  				cf.Version = "4.5.0"
   217  
   218  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   219  
   220  				Expect(ui.Outputs).To(ContainSubstrings(
   221  					[]string{"To upgrade your CLI"},
   222  					[]string{"5.0.0"},
   223  				))
   224  			})
   225  		})
   226  
   227  		Describe("when there are too many orgs to show", func() {
   228  			BeforeEach(func() {
   229  				organizations := []models.Organization{}
   230  				for i := 0; i < 60; i++ {
   231  					id := strconv.Itoa(i)
   232  					org := models.Organization{}
   233  					org.Guid = "my-org-guid-" + id
   234  					org.Name = "my-org-" + id
   235  					organizations = append(organizations, org)
   236  				}
   237  				orgRepo.ListOrgsReturns(organizations, nil)
   238  				orgRepo.FindByNameReturns(organizations[1], nil)
   239  
   240  				space1 := models.Space{}
   241  				space1.Guid = "my-space-guid"
   242  				space1.Name = "my-space"
   243  
   244  				space2 := models.Space{}
   245  				space2.Guid = "some-space-guid"
   246  				space2.Name = "some-space"
   247  
   248  				spaceRepo.Spaces = []models.Space{space1, space2}
   249  			})
   250  
   251  			It("doesn't display a list of orgs (the user must type the name)", func() {
   252  				ui.Inputs = []string{"api.example.com", "user@example.com", "password", "my-org-1", "my-space"}
   253  
   254  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   255  
   256  				Expect(ui.Outputs).ToNot(ContainSubstrings([]string{"my-org-2"}))
   257  				Expect(orgRepo.FindByNameArgsForCall(0)).To(Equal("my-org-1"))
   258  				Expect(Config.OrganizationFields().Guid).To(Equal("my-org-guid-1"))
   259  			})
   260  		})
   261  
   262  		Describe("when there is only a single org and space", func() {
   263  			It("does not ask the user to select an org/space", func() {
   264  				ui.Inputs = []string{"http://api.example.com", "user@example.com", "password"}
   265  
   266  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   267  
   268  				Expect(Config.OrganizationFields().Guid).To(Equal("my-new-org-guid"))
   269  				Expect(Config.SpaceFields().Guid).To(Equal("my-space-guid"))
   270  				Expect(Config.AccessToken()).To(Equal("my_access_token"))
   271  				Expect(Config.RefreshToken()).To(Equal("my_refresh_token"))
   272  
   273  				Expect(endpointRepo.UpdateEndpointReceived).To(Equal("http://api.example.com"))
   274  				Expect(authRepo.AuthenticateArgs.Credentials).To(Equal([]map[string]string{
   275  					{
   276  						"username": "user@example.com",
   277  						"password": "password",
   278  					},
   279  				}))
   280  				Expect(ui.ShowConfigurationCalled).To(BeTrue())
   281  			})
   282  		})
   283  
   284  		Describe("where there are no available orgs", func() {
   285  			BeforeEach(func() {
   286  				orgRepo.ListOrgsReturns([]models.Organization{}, nil)
   287  				spaceRepo.Spaces = []models.Space{}
   288  			})
   289  
   290  			It("does not as the user to select an org", func() {
   291  				ui.Inputs = []string{"http://api.example.com", "user@example.com", "password"}
   292  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   293  
   294  				Expect(Config.OrganizationFields().Guid).To(Equal(""))
   295  				Expect(Config.SpaceFields().Guid).To(Equal(""))
   296  				Expect(Config.AccessToken()).To(Equal("my_access_token"))
   297  				Expect(Config.RefreshToken()).To(Equal("my_refresh_token"))
   298  
   299  				Expect(endpointRepo.UpdateEndpointReceived).To(Equal("http://api.example.com"))
   300  				Expect(authRepo.AuthenticateArgs.Credentials).To(Equal([]map[string]string{
   301  					{
   302  						"username": "user@example.com",
   303  						"password": "password",
   304  					},
   305  				}))
   306  				Expect(ui.ShowConfigurationCalled).To(BeTrue())
   307  			})
   308  		})
   309  
   310  		Describe("when there is only a single org and no spaces", func() {
   311  			BeforeEach(func() {
   312  				orgRepo.ListOrgsReturns([]models.Organization{org}, nil)
   313  				spaceRepo.Spaces = []models.Space{}
   314  			})
   315  
   316  			It("does not ask the user to select a space", func() {
   317  				ui.Inputs = []string{"http://api.example.com", "user@example.com", "password"}
   318  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   319  
   320  				Expect(Config.OrganizationFields().Guid).To(Equal("my-new-org-guid"))
   321  				Expect(Config.SpaceFields().Guid).To(Equal(""))
   322  				Expect(Config.AccessToken()).To(Equal("my_access_token"))
   323  				Expect(Config.RefreshToken()).To(Equal("my_refresh_token"))
   324  
   325  				Expect(endpointRepo.UpdateEndpointReceived).To(Equal("http://api.example.com"))
   326  				Expect(authRepo.AuthenticateArgs.Credentials).To(Equal([]map[string]string{
   327  					{
   328  						"username": "user@example.com",
   329  						"password": "password",
   330  					},
   331  				}))
   332  				Expect(ui.ShowConfigurationCalled).To(BeTrue())
   333  			})
   334  		})
   335  
   336  		Describe("login prompts", func() {
   337  			BeforeEach(func() {
   338  				authRepo.GetLoginPromptsReturns.Prompts = map[string]core_config.AuthPrompt{
   339  					"account_number": core_config.AuthPrompt{
   340  						DisplayName: "Account Number",
   341  						Type:        core_config.AuthPromptTypeText,
   342  					},
   343  					"username": core_config.AuthPrompt{
   344  						DisplayName: "Username",
   345  						Type:        core_config.AuthPromptTypeText,
   346  					},
   347  					"passcode": core_config.AuthPrompt{
   348  						DisplayName: "It's a passcode, what you want it to be???",
   349  						Type:        core_config.AuthPromptTypePassword,
   350  					},
   351  					"password": core_config.AuthPrompt{
   352  						DisplayName: "Your Password",
   353  						Type:        core_config.AuthPromptTypePassword,
   354  					},
   355  				}
   356  			})
   357  
   358  			Context("when the user does not provide the --sso flag", func() {
   359  				It("prompts the user for 'password' prompt and any text type prompt", func() {
   360  					ui.Inputs = []string{"api.example.com", "the-username", "the-account-number", "the-password"}
   361  
   362  					testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   363  
   364  					Expect(ui.Prompts).To(ContainSubstrings(
   365  						[]string{"API endpoint"},
   366  						[]string{"Account Number"},
   367  						[]string{"Username"},
   368  					))
   369  					Expect(ui.PasswordPrompts).To(ContainSubstrings([]string{"Your Password"}))
   370  					Expect(ui.PasswordPrompts).ToNot(ContainSubstrings(
   371  						[]string{"passcode"},
   372  					))
   373  
   374  					Expect(authRepo.AuthenticateArgs.Credentials).To(Equal([]map[string]string{
   375  						{
   376  							"account_number": "the-account-number",
   377  							"username":       "the-username",
   378  							"password":       "the-password",
   379  						},
   380  					}))
   381  				})
   382  			})
   383  
   384  			Context("when the user does provide the --sso flag", func() {
   385  				It("only prompts the user for the passcode type prompts", func() {
   386  					Flags = []string{"--sso", "-a", "api.example.com"}
   387  					ui.Inputs = []string{"the-one-time-code"}
   388  
   389  					testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   390  
   391  					Expect(ui.Prompts).To(BeEmpty())
   392  					Expect(ui.PasswordPrompts).To(ContainSubstrings([]string{"passcode"}))
   393  					Expect(authRepo.AuthenticateArgs.Credentials).To(Equal([]map[string]string{
   394  						{
   395  							"passcode": "the-one-time-code",
   396  						},
   397  					}))
   398  				})
   399  			})
   400  
   401  			It("takes the password from the -p flag", func() {
   402  				Flags = []string{"-p", "the-password"}
   403  				ui.Inputs = []string{"api.example.com", "the-username", "the-account-number", "the-pin"}
   404  
   405  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   406  
   407  				Expect(ui.PasswordPrompts).ToNot(ContainSubstrings([]string{"Your Password"}))
   408  				Expect(authRepo.AuthenticateArgs.Credentials).To(Equal([]map[string]string{
   409  					{
   410  						"account_number": "the-account-number",
   411  						"username":       "the-username",
   412  						"password":       "the-password",
   413  					},
   414  				}))
   415  			})
   416  
   417  			It("tries 3 times for the password-type prompts", func() {
   418  				authRepo.AuthError = true
   419  				ui.Inputs = []string{"api.example.com", "the-username", "the-account-number",
   420  					"the-password-1", "the-password-2", "the-password-3"}
   421  
   422  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   423  
   424  				Expect(authRepo.AuthenticateArgs.Credentials).To(Equal([]map[string]string{
   425  					{
   426  						"username":       "the-username",
   427  						"account_number": "the-account-number",
   428  						"password":       "the-password-1",
   429  					},
   430  					{
   431  						"username":       "the-username",
   432  						"account_number": "the-account-number",
   433  						"password":       "the-password-2",
   434  					},
   435  					{
   436  						"username":       "the-username",
   437  						"account_number": "the-account-number",
   438  						"password":       "the-password-3",
   439  					},
   440  				}))
   441  
   442  				Expect(ui.Outputs).To(ContainSubstrings([]string{"FAILED"}))
   443  			})
   444  
   445  			It("prompts user for password again if password given on the cmd line fails", func() {
   446  				authRepo.AuthError = true
   447  
   448  				Flags = []string{"-p", "the-password-1"}
   449  
   450  				ui.Inputs = []string{"api.example.com", "the-username", "the-account-number",
   451  					"the-password-2", "the-password-3"}
   452  
   453  				testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   454  
   455  				Expect(authRepo.AuthenticateArgs.Credentials).To(Equal([]map[string]string{
   456  					{
   457  						"account_number": "the-account-number",
   458  						"username":       "the-username",
   459  						"password":       "the-password-1",
   460  					},
   461  					{
   462  						"account_number": "the-account-number",
   463  						"username":       "the-username",
   464  						"password":       "the-password-2",
   465  					},
   466  					{
   467  						"account_number": "the-account-number",
   468  						"username":       "the-username",
   469  						"password":       "the-password-3",
   470  					},
   471  				}))
   472  
   473  				Expect(ui.Outputs).To(ContainSubstrings([]string{"FAILED"}))
   474  			})
   475  		})
   476  	})
   477  
   478  	Describe("updates to the config", func() {
   479  		BeforeEach(func() {
   480  			Config.SetApiEndpoint("api.the-old-endpoint.com")
   481  			Config.SetAccessToken("the-old-access-token")
   482  			Config.SetRefreshToken("the-old-refresh-token")
   483  		})
   484  
   485  		JustBeforeEach(func() {
   486  			testcmd.RunCliCommand("login", Flags, nil, updateCommandDependency, false)
   487  		})
   488  
   489  		var ItShowsTheTarget = func() {
   490  			It("shows the target", func() {
   491  				Expect(ui.ShowConfigurationCalled).To(BeTrue())
   492  			})
   493  		}
   494  
   495  		var ItDoesntShowTheTarget = func() {
   496  			It("does not show the target info", func() {
   497  				Expect(ui.ShowConfigurationCalled).To(BeFalse())
   498  			})
   499  		}
   500  
   501  		var ItFails = func() {
   502  			It("fails", func() {
   503  				Expect(ui.Outputs).To(ContainSubstrings([]string{"FAILED"}))
   504  			})
   505  		}
   506  
   507  		var ItSucceeds = func() {
   508  			It("runs successfully", func() {
   509  				Expect(ui.Outputs).ToNot(ContainSubstrings([]string{"FAILED"}))
   510  				Expect(ui.Outputs).To(ContainSubstrings([]string{"OK"}))
   511  			})
   512  		}
   513  
   514  		Describe("when the user is setting an API", func() {
   515  			BeforeEach(func() {
   516  				Flags = []string{"-a", "https://api.the-server.com", "-u", "the-user-name", "-p", "the-password"}
   517  			})
   518  
   519  			Describe("when the --skip-ssl-validation flag is provided", func() {
   520  				BeforeEach(func() {
   521  					Flags = append(Flags, "--skip-ssl-validation")
   522  				})
   523  
   524  				Describe("setting api endpoint is successful", func() {
   525  					BeforeEach(func() {
   526  						Config.SetSSLDisabled(false)
   527  					})
   528  
   529  					ItSucceeds()
   530  					ItShowsTheTarget()
   531  
   532  					It("stores the API endpoint and the skip-ssl flag", func() {
   533  						Expect(endpointRepo.UpdateEndpointReceived).To(Equal("https://api.the-server.com"))
   534  						Expect(Config.IsSSLDisabled()).To(BeTrue())
   535  					})
   536  				})
   537  
   538  				Describe("setting api endpoint failed", func() {
   539  					BeforeEach(func() {
   540  						Config.SetSSLDisabled(true)
   541  						endpointRepo.UpdateEndpointError = errors.New("API endpoint not found")
   542  					})
   543  
   544  					ItFails()
   545  					ItDoesntShowTheTarget()
   546  
   547  					It("clears the entire config", func() {
   548  						Expect(Config.ApiEndpoint()).To(BeEmpty())
   549  						Expect(Config.IsSSLDisabled()).To(BeFalse())
   550  						Expect(Config.AccessToken()).To(BeEmpty())
   551  						Expect(Config.RefreshToken()).To(BeEmpty())
   552  						Expect(Config.OrganizationFields().Guid).To(BeEmpty())
   553  						Expect(Config.SpaceFields().Guid).To(BeEmpty())
   554  					})
   555  				})
   556  			})
   557  
   558  			Describe("when the --skip-ssl-validation flag is not provided", func() {
   559  				Describe("setting api endpoint is successful", func() {
   560  					BeforeEach(func() {
   561  						Config.SetSSLDisabled(true)
   562  					})
   563  
   564  					ItSucceeds()
   565  					ItShowsTheTarget()
   566  
   567  					It("updates the API endpoint and enables SSL validation", func() {
   568  						Expect(endpointRepo.UpdateEndpointReceived).To(Equal("https://api.the-server.com"))
   569  						Expect(Config.IsSSLDisabled()).To(BeFalse())
   570  					})
   571  				})
   572  
   573  				Describe("setting api endpoint failed", func() {
   574  					BeforeEach(func() {
   575  						Config.SetSSLDisabled(true)
   576  						endpointRepo.UpdateEndpointError = errors.New("API endpoint not found")
   577  					})
   578  
   579  					ItFails()
   580  					ItDoesntShowTheTarget()
   581  
   582  					It("clears the entire config", func() {
   583  						Expect(Config.ApiEndpoint()).To(BeEmpty())
   584  						Expect(Config.IsSSLDisabled()).To(BeFalse())
   585  						Expect(Config.AccessToken()).To(BeEmpty())
   586  						Expect(Config.RefreshToken()).To(BeEmpty())
   587  						Expect(Config.OrganizationFields().Guid).To(BeEmpty())
   588  						Expect(Config.SpaceFields().Guid).To(BeEmpty())
   589  					})
   590  				})
   591  			})
   592  
   593  			Describe("when there is an invalid SSL cert", func() {
   594  				BeforeEach(func() {
   595  					endpointRepo.UpdateEndpointError = errors.NewInvalidSSLCert("https://bobs-burgers.com", "SELF SIGNED SADNESS")
   596  					ui.Inputs = []string{"bobs-burgers.com"}
   597  				})
   598  
   599  				It("fails and suggests the user skip SSL validation", func() {
   600  					Expect(ui.Outputs).To(ContainSubstrings(
   601  						[]string{"FAILED"},
   602  						[]string{"SSL Cert", "https://bobs-burgers.com"},
   603  						[]string{"TIP", "login", "--skip-ssl-validation"},
   604  					))
   605  				})
   606  
   607  				ItDoesntShowTheTarget()
   608  			})
   609  		})
   610  
   611  		Describe("when user is logging in and not setting the api endpoint", func() {
   612  			BeforeEach(func() {
   613  				Flags = []string{"-u", "the-user-name", "-p", "the-password"}
   614  			})
   615  
   616  			Describe("when the --skip-ssl-validation flag is provided", func() {
   617  				BeforeEach(func() {
   618  					Flags = append(Flags, "--skip-ssl-validation")
   619  					Config.SetSSLDisabled(false)
   620  				})
   621  
   622  				It("disables SSL validation", func() {
   623  					Expect(Config.IsSSLDisabled()).To(BeTrue())
   624  				})
   625  			})
   626  
   627  			Describe("when the --skip-ssl-validation flag is not provided", func() {
   628  				BeforeEach(func() {
   629  					Config.SetSSLDisabled(true)
   630  				})
   631  
   632  				It("should not change config's SSLDisabled flag", func() {
   633  					Expect(Config.IsSSLDisabled()).To(BeTrue())
   634  				})
   635  			})
   636  
   637  			Describe("and the login fails authenticaton", func() {
   638  				BeforeEach(func() {
   639  					authRepo.AuthError = true
   640  
   641  					Config.SetSSLDisabled(true)
   642  
   643  					Flags = []string{"-u", "user@example.com"}
   644  					ui.Inputs = []string{"password", "password2", "password3", "password4"}
   645  				})
   646  
   647  				ItFails()
   648  				ItShowsTheTarget()
   649  
   650  				It("does not change the api endpoint or SSL setting in the config", func() {
   651  					Expect(Config.ApiEndpoint()).To(Equal("api.the-old-endpoint.com"))
   652  					Expect(Config.IsSSLDisabled()).To(BeTrue())
   653  				})
   654  
   655  				It("clears Access Token, Refresh Token, Org, and Space in the config", func() {
   656  					Expect(Config.AccessToken()).To(BeEmpty())
   657  					Expect(Config.RefreshToken()).To(BeEmpty())
   658  					Expect(Config.OrganizationFields().Guid).To(BeEmpty())
   659  					Expect(Config.SpaceFields().Guid).To(BeEmpty())
   660  				})
   661  			})
   662  		})
   663  
   664  		Describe("and the login fails to target an org", func() {
   665  			BeforeEach(func() {
   666  				Flags = []string{"-u", "user@example.com", "-p", "password", "-o", "nonexistentorg", "-s", "my-space"}
   667  				orgRepo.FindByNameReturns(models.Organization{}, errors.New("No org"))
   668  				Config.SetSSLDisabled(true)
   669  			})
   670  
   671  			ItFails()
   672  			ItShowsTheTarget()
   673  
   674  			It("does not update the api endpoint or ssl setting in the config", func() {
   675  				Expect(Config.ApiEndpoint()).To(Equal("api.the-old-endpoint.com"))
   676  				Expect(Config.IsSSLDisabled()).To(BeTrue())
   677  			})
   678  
   679  			It("clears Org, and Space in the config", func() {
   680  				Expect(Config.OrganizationFields().Guid).To(BeEmpty())
   681  				Expect(Config.SpaceFields().Guid).To(BeEmpty())
   682  			})
   683  		})
   684  
   685  		Describe("and the login fails to target a space", func() {
   686  			BeforeEach(func() {
   687  				Flags = []string{"-u", "user@example.com", "-p", "password", "-o", "my-new-org", "-s", "nonexistent"}
   688  				orgRepo.FindByNameReturns(org, nil)
   689  
   690  				Config.SetSSLDisabled(true)
   691  			})
   692  
   693  			ItFails()
   694  			ItShowsTheTarget()
   695  
   696  			It("does not update the api endpoint or ssl setting in the config", func() {
   697  				Expect(Config.ApiEndpoint()).To(Equal("api.the-old-endpoint.com"))
   698  				Expect(Config.IsSSLDisabled()).To(BeTrue())
   699  			})
   700  
   701  			It("updates the org in the config", func() {
   702  				Expect(Config.OrganizationFields().Guid).To(Equal("my-new-org-guid"))
   703  			})
   704  
   705  			It("clears the space in the config", func() {
   706  				Expect(Config.SpaceFields().Guid).To(BeEmpty())
   707  			})
   708  		})
   709  
   710  		Describe("and the login succeeds", func() {
   711  			BeforeEach(func() {
   712  				orgRepo.FindByNameReturns(models.Organization{
   713  					OrganizationFields: models.OrganizationFields{
   714  						Name: "new-org",
   715  						Guid: "new-org-guid",
   716  					},
   717  				}, nil)
   718  				spaceRepo.Spaces[0].Name = "new-space"
   719  				spaceRepo.Spaces[0].Guid = "new-space-guid"
   720  				authRepo.AccessToken = "new_access_token"
   721  				authRepo.RefreshToken = "new_refresh_token"
   722  
   723  				Flags = []string{"-u", "user@example.com", "-p", "password", "-o", "new-org", "-s", "new-space"}
   724  
   725  				Config.SetApiEndpoint("api.the-old-endpoint.com")
   726  				Config.SetSSLDisabled(true)
   727  			})
   728  
   729  			ItSucceeds()
   730  			ItShowsTheTarget()
   731  
   732  			It("does not update the api endpoint or SSL setting", func() {
   733  				Expect(Config.ApiEndpoint()).To(Equal("api.the-old-endpoint.com"))
   734  				Expect(Config.IsSSLDisabled()).To(BeTrue())
   735  			})
   736  
   737  			It("updates Access Token, Refresh Token, Org, and Space in the config", func() {
   738  				Expect(Config.AccessToken()).To(Equal("new_access_token"))
   739  				Expect(Config.RefreshToken()).To(Equal("new_refresh_token"))
   740  				Expect(Config.OrganizationFields().Guid).To(Equal("new-org-guid"))
   741  				Expect(Config.SpaceFields().Guid).To(Equal("new-space-guid"))
   742  			})
   743  		})
   744  	})
   745  })