github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/cf/commands/application/copy_source_test.go (about) 1 package application_test 2 3 import ( 4 "code.cloudfoundry.org/cli/cf/api/applications/applicationsfakes" 5 "code.cloudfoundry.org/cli/cf/api/authentication/authenticationfakes" 6 "code.cloudfoundry.org/cli/cf/api/copyapplicationsource/copyapplicationsourcefakes" 7 "code.cloudfoundry.org/cli/cf/api/organizations/organizationsfakes" 8 "code.cloudfoundry.org/cli/cf/api/spaces/spacesfakes" 9 "code.cloudfoundry.org/cli/cf/commands/application/applicationfakes" 10 "code.cloudfoundry.org/cli/cf/models" 11 "code.cloudfoundry.org/cli/cf/requirements" 12 "code.cloudfoundry.org/cli/cf/requirements/requirementsfakes" 13 testcmd "code.cloudfoundry.org/cli/cf/util/testhelpers/commands" 14 testconfig "code.cloudfoundry.org/cli/cf/util/testhelpers/configuration" 15 testterm "code.cloudfoundry.org/cli/cf/util/testhelpers/terminal" 16 17 "code.cloudfoundry.org/cli/cf/commandregistry" 18 "code.cloudfoundry.org/cli/cf/configuration/coreconfig" 19 "code.cloudfoundry.org/cli/cf/errors" 20 21 . "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers" 22 . "github.com/onsi/ginkgo" 23 . "github.com/onsi/gomega" 24 ) 25 26 var _ = Describe("CopySource", func() { 27 28 var ( 29 ui *testterm.FakeUI 30 config coreconfig.Repository 31 requirementsFactory *requirementsfakes.FakeFactory 32 authRepo *authenticationfakes.FakeRepository 33 appRepo *applicationsfakes.FakeRepository 34 copyAppSourceRepo *copyapplicationsourcefakes.FakeRepository 35 spaceRepo *spacesfakes.FakeSpaceRepository 36 orgRepo *organizationsfakes.FakeOrganizationRepository 37 appRestarter *applicationfakes.FakeRestarter 38 OriginalCommand commandregistry.Command 39 deps commandregistry.Dependency 40 ) 41 42 updateCommandDependency := func(pluginCall bool) { 43 deps.UI = ui 44 deps.RepoLocator = deps.RepoLocator.SetAuthenticationRepository(authRepo) 45 deps.RepoLocator = deps.RepoLocator.SetApplicationRepository(appRepo) 46 deps.RepoLocator = deps.RepoLocator.SetCopyApplicationSourceRepository(copyAppSourceRepo) 47 deps.RepoLocator = deps.RepoLocator.SetSpaceRepository(spaceRepo) 48 deps.RepoLocator = deps.RepoLocator.SetOrganizationRepository(orgRepo) 49 deps.Config = config 50 51 //inject fake 'command dependency' into registry 52 commandregistry.Register(appRestarter) 53 54 commandregistry.Commands.SetCommand(commandregistry.Commands.FindCommand("copy-source").SetDependency(deps, pluginCall)) 55 } 56 57 BeforeEach(func() { 58 ui = &testterm.FakeUI{} 59 requirementsFactory = new(requirementsfakes.FakeFactory) 60 authRepo = new(authenticationfakes.FakeRepository) 61 appRepo = new(applicationsfakes.FakeRepository) 62 copyAppSourceRepo = new(copyapplicationsourcefakes.FakeRepository) 63 spaceRepo = new(spacesfakes.FakeSpaceRepository) 64 orgRepo = new(organizationsfakes.FakeOrganizationRepository) 65 config = testconfig.NewRepositoryWithDefaults() 66 67 //save original command and restore later 68 OriginalCommand = commandregistry.Commands.FindCommand("restart") 69 70 appRestarter = new(applicationfakes.FakeRestarter) 71 //setup fakes to correctly interact with commandregistry 72 appRestarter.SetDependencyStub = func(_ commandregistry.Dependency, _ bool) commandregistry.Command { 73 return appRestarter 74 } 75 appRestarter.MetaDataReturns(commandregistry.CommandMetadata{Name: "restart"}) 76 }) 77 78 AfterEach(func() { 79 commandregistry.Register(OriginalCommand) 80 }) 81 82 runCommand := func(args ...string) bool { 83 return testcmd.RunCLICommand("copy-source", args, requirementsFactory, updateCommandDependency, false, ui) 84 } 85 86 Describe("requirement failures", func() { 87 It("when not logged in", func() { 88 requirementsFactory.NewUsageRequirementReturns(requirements.Passing{}) 89 requirementsFactory.NewLoginRequirementReturns(requirements.Failing{Message: "not logged in"}) 90 Expect(runCommand("source-app", "target-app")).ToNot(HavePassedRequirements()) 91 }) 92 93 It("when a space is not targeted", func() { 94 requirementsFactory.NewUsageRequirementReturns(requirements.Passing{}) 95 requirementsFactory.NewLoginRequirementReturns(requirements.Passing{}) 96 requirementsFactory.NewTargetedSpaceRequirementReturns(requirements.Failing{Message: "not targeting space"}) 97 Expect(runCommand("source-app", "target-app")).ToNot(HavePassedRequirements()) 98 }) 99 100 It("when provided too many args", func() { 101 requirementsFactory.NewUsageRequirementReturns(requirements.Failing{}) 102 Expect(runCommand("source-app", "target-app", "too-much", "app-name")).ToNot(HavePassedRequirements()) 103 }) 104 }) 105 106 Describe("Passing requirements", func() { 107 BeforeEach(func() { 108 requirementsFactory.NewUsageRequirementReturns(requirements.Passing{}) 109 requirementsFactory.NewLoginRequirementReturns(requirements.Passing{}) 110 requirementsFactory.NewTargetedSpaceRequirementReturns(requirements.Passing{}) 111 }) 112 113 Context("refreshing the auth token", func() { 114 It("makes a call for the app token", func() { 115 runCommand("source-app", "target-app") 116 Expect(authRepo.RefreshAuthTokenCallCount()).To(Equal(1)) 117 }) 118 119 Context("when refreshing the auth token fails", func() { 120 BeforeEach(func() { 121 authRepo.RefreshAuthTokenReturns("", errors.New("I accidentally the UAA")) 122 }) 123 124 It("it displays an error", func() { 125 runCommand("source-app", "target-app") 126 Expect(ui.Outputs()).To(ContainSubstrings( 127 []string{"FAILED"}, 128 []string{"accidentally the UAA"}, 129 )) 130 }) 131 }) 132 133 Describe("when retrieving the app token succeeds", func() { 134 var ( 135 sourceApp, targetApp models.Application 136 ) 137 138 BeforeEach(func() { 139 sourceApp = models.Application{ 140 ApplicationFields: models.ApplicationFields{ 141 Name: "source-app", 142 GUID: "source-app-guid", 143 }, 144 } 145 appRepo.ReadReturns(sourceApp, nil) 146 147 targetApp = models.Application{ 148 ApplicationFields: models.ApplicationFields{ 149 Name: "target-app", 150 GUID: "target-app-guid", 151 }, 152 } 153 appRepo.ReadFromSpaceReturns(targetApp, nil) 154 }) 155 156 Describe("when no parameters are passed", func() { 157 It("obtains both the source and target application from the same space", func() { 158 runCommand("source-app", "target-app") 159 160 targetAppName, spaceGUID := appRepo.ReadFromSpaceArgsForCall(0) 161 Expect(targetAppName).To(Equal("target-app")) 162 Expect(spaceGUID).To(Equal("my-space-guid")) 163 164 Expect(appRepo.ReadArgsForCall(0)).To(Equal("source-app")) 165 166 sourceAppGUID, targetAppGUID := copyAppSourceRepo.CopyApplicationArgsForCall(0) 167 Expect(sourceAppGUID).To(Equal("source-app-guid")) 168 Expect(targetAppGUID).To(Equal("target-app-guid")) 169 170 appArg, orgName, spaceName := appRestarter.ApplicationRestartArgsForCall(0) 171 Expect(appArg).To(Equal(targetApp)) 172 Expect(orgName).To(Equal(config.OrganizationFields().Name)) 173 Expect(spaceName).To(Equal(config.SpaceFields().Name)) 174 175 Expect(ui.Outputs()).To(ContainSubstrings( 176 []string{"Copying source from app", "source-app", "to target app", "target-app", "in org my-org / space my-space as my-user..."}, 177 []string{"Note: this may take some time"}, 178 []string{"OK"}, 179 )) 180 }) 181 182 Context("Failures", func() { 183 It("if we cannot obtain the source application", func() { 184 appRepo.ReadReturns(models.Application{}, errors.New("could not find source app")) 185 runCommand("source-app", "target-app") 186 187 Expect(ui.Outputs()).To(ContainSubstrings( 188 []string{"FAILED"}, 189 []string{"could not find source app"}, 190 )) 191 }) 192 193 It("fails if we cannot obtain the target application", func() { 194 appRepo.ReadFromSpaceReturns(models.Application{}, errors.New("could not find target app")) 195 runCommand("source-app", "target-app") 196 197 Expect(ui.Outputs()).To(ContainSubstrings( 198 []string{"FAILED"}, 199 []string{"could not find target app"}, 200 )) 201 }) 202 }) 203 }) 204 205 Describe("when a space is provided, but not an org", func() { 206 It("sends the correct target appplication for the current org and target space", func() { 207 space := models.Space{} 208 space.Name = "space-name" 209 space.GUID = "model-space-guid" 210 spaceRepo.FindByNameReturns(space, nil) 211 212 runCommand("-s", "space-name", "source-app", "target-app") 213 214 targetAppName, spaceGUID := appRepo.ReadFromSpaceArgsForCall(0) 215 Expect(targetAppName).To(Equal("target-app")) 216 Expect(spaceGUID).To(Equal("model-space-guid")) 217 218 Expect(ui.Outputs()).To(ContainSubstrings( 219 []string{"Copying source from app", "source-app", "to target app", "target-app", "in org my-org / space space-name as my-user..."}, 220 []string{"Note: this may take some time"}, 221 []string{"OK"}, 222 )) 223 }) 224 225 It("reflects the capitalization of the actual space name", func() { 226 spaceRepo.FindByNameReturns(models.Space{ 227 SpaceFields: models.SpaceFields{ 228 Name: "SPACE-NAME", 229 GUID: "space-guid", 230 }, 231 }, nil) 232 233 ok := runCommand("-s", "space-name", "source-app", "target-app") 234 Expect(ok).To(BeTrue()) 235 Expect(ui.Outputs()).To(ContainSubstrings( 236 []string{"Copying source from app source-app to target app target-app in org my-org / space SPACE-NAME as my-user..."}, 237 )) 238 }) 239 240 Context("Failures", func() { 241 It("when we cannot find the provided space", func() { 242 spaceRepo.FindByNameReturns(models.Space{}, errors.New("Error finding space by name.")) 243 244 runCommand("-s", "space-name", "source-app", "target-app") 245 Expect(ui.Outputs()).To(ContainSubstrings( 246 []string{"FAILED"}, 247 []string{"Error finding space by name."}, 248 )) 249 }) 250 }) 251 }) 252 253 Describe("when an org and space name are passed as parameters", func() { 254 It("sends the correct target application for the space and org", func() { 255 orgRepo.FindByNameReturns(models.Organization{ 256 Spaces: []models.SpaceFields{ 257 { 258 Name: "space-name", 259 GUID: "space-guid", 260 }, 261 }, 262 }, nil) 263 264 runCommand("-o", "org-name", "-s", "space-name", "source-app", "target-app") 265 266 targetAppName, spaceGUID := appRepo.ReadFromSpaceArgsForCall(0) 267 Expect(targetAppName).To(Equal("target-app")) 268 Expect(spaceGUID).To(Equal("space-guid")) 269 270 sourceAppGUID, targetAppGUID := copyAppSourceRepo.CopyApplicationArgsForCall(0) 271 Expect(sourceAppGUID).To(Equal("source-app-guid")) 272 Expect(targetAppGUID).To(Equal("target-app-guid")) 273 274 appArg, orgName, spaceName := appRestarter.ApplicationRestartArgsForCall(0) 275 Expect(appArg).To(Equal(targetApp)) 276 Expect(orgName).To(Equal("org-name")) 277 Expect(spaceName).To(Equal("space-name")) 278 279 Expect(ui.Outputs()).To(ContainSubstrings( 280 []string{"Copying source from app source-app to target app target-app in org org-name / space space-name as my-user..."}, 281 []string{"Note: this may take some time"}, 282 []string{"OK"}, 283 )) 284 }) 285 It("is case-insensitive for space name", func() { 286 orgRepo.FindByNameReturns(models.Organization{ 287 Spaces: []models.SpaceFields{ 288 { 289 Name: "SPACE-NAME", 290 GUID: "space-guid", 291 }, 292 }, 293 }, nil) 294 295 ok := runCommand("-o", "org-name", "-s", "space-name", "source-app", "target-app") 296 Expect(ok).To(BeTrue()) 297 Expect(ui.Outputs()).ToNot(ContainSubstrings( 298 []string{"FAILED"}, 299 )) 300 }) 301 302 It("reflects the capitalization of the actual space name", func() { 303 orgRepo.FindByNameReturns(models.Organization{ 304 Spaces: []models.SpaceFields{ 305 { 306 Name: "SPACE-NAME", 307 GUID: "space-guid", 308 }, 309 }, 310 }, nil) 311 312 ok := runCommand("-o", "org-name", "-s", "space-name", "source-app", "target-app") 313 Expect(ok).To(BeTrue()) 314 Expect(ui.Outputs()).To(ContainSubstrings( 315 []string{"Copying source from app source-app to target app target-app in org org-name / space SPACE-NAME as my-user..."}, 316 )) 317 }) 318 319 Context("failures", func() { 320 It("cannot just accept an organization and no space", func() { 321 runCommand("-o", "org-name", "source-app", "target-app") 322 323 Expect(ui.Outputs()).To(ContainSubstrings( 324 []string{"FAILED"}, 325 []string{"Please provide the space within the organization containing the target application"}, 326 )) 327 }) 328 329 It("when we cannot find the provided org", func() { 330 orgRepo.FindByNameReturns(models.Organization{}, errors.New("Could not find org")) 331 runCommand("-o", "org-name", "-s", "space-name", "source-app", "target-app") 332 333 Expect(ui.Outputs()).To(ContainSubstrings( 334 []string{"FAILED"}, 335 []string{"Could not find org"}, 336 )) 337 }) 338 339 It("when the org does not contain the space name provide", func() { 340 orgRepo.FindByNameReturns(models.Organization{}, nil) 341 runCommand("-o", "org-name", "-s", "space-name", "source-app", "target-app") 342 343 Expect(ui.Outputs()).To(ContainSubstrings( 344 []string{"FAILED"}, 345 []string{"Could not find space space-name in organization org-name"}, 346 )) 347 }) 348 349 It("when the targeted app does not exist in the targeted org and space", func() { 350 orgRepo.FindByNameReturns(models.Organization{ 351 Spaces: []models.SpaceFields{ 352 { 353 Name: "space-name", 354 GUID: "space-guid", 355 }, 356 }, 357 }, nil) 358 359 appRepo.ReadFromSpaceReturns(models.Application{}, errors.New("could not find app")) 360 runCommand("-o", "org-name", "-s", "space-name", "source-app", "target-app") 361 362 Expect(ui.Outputs()).To(ContainSubstrings( 363 []string{"FAILED"}, 364 []string{"could not find app"}, 365 )) 366 }) 367 }) 368 }) 369 370 Describe("when the --no-restart flag is passed", func() { 371 It("does not restart the target application", func() { 372 runCommand("--no-restart", "source-app", "target-app") 373 Expect(appRestarter.ApplicationRestartCallCount()).To(Equal(0)) 374 }) 375 }) 376 }) 377 }) 378 }) 379 })