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  })