github.com/sleungcy/cli@v7.1.0+incompatible/command/v7/copy_source_command_test.go (about)

     1  package v7_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	"code.cloudfoundry.org/cli/actor/v7action"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
     9  	"code.cloudfoundry.org/cli/command/commandfakes"
    10  	"code.cloudfoundry.org/cli/command/flag"
    11  	"code.cloudfoundry.org/cli/command/translatableerror"
    12  	v7 "code.cloudfoundry.org/cli/command/v7"
    13  	"code.cloudfoundry.org/cli/command/v7/shared/sharedfakes"
    14  	"code.cloudfoundry.org/cli/command/v7/v7fakes"
    15  	"code.cloudfoundry.org/cli/resources"
    16  	"code.cloudfoundry.org/cli/util/configv3"
    17  	"code.cloudfoundry.org/cli/util/ui"
    18  	. "github.com/onsi/ginkgo"
    19  	. "github.com/onsi/gomega"
    20  	. "github.com/onsi/gomega/gbytes"
    21  )
    22  
    23  var _ = Describe("copy-source Command", func() {
    24  	var (
    25  		cmd             v7.CopySourceCommand
    26  		testUI          *ui.UI
    27  		fakeConfig      *commandfakes.FakeConfig
    28  		fakeSharedActor *commandfakes.FakeSharedActor
    29  		fakeActor       *v7fakes.FakeActor
    30  		fakeAppStager   *sharedfakes.FakeAppStager
    31  
    32  		binaryName    string
    33  		userName      string
    34  		executeErr    error
    35  		sourceApp     resources.Application
    36  		targetApp     resources.Application
    37  		actorError    error
    38  		targetPackage v7action.Package
    39  	)
    40  
    41  	BeforeEach(func() {
    42  		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
    43  		fakeConfig = new(commandfakes.FakeConfig)
    44  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    45  		fakeActor = new(v7fakes.FakeActor)
    46  		fakeAppStager = new(sharedfakes.FakeAppStager)
    47  
    48  		binaryName = "faceman"
    49  		userName = "banana"
    50  		sourceApp = resources.Application{
    51  			Name: "source-app-name",
    52  			GUID: "source-app-guid",
    53  		}
    54  		targetApp = resources.Application{
    55  			Name: "target-app-name",
    56  			GUID: "target-app-guid",
    57  		}
    58  		targetPackage = v7action.Package{
    59  			GUID: "target-package-guid",
    60  		}
    61  
    62  		cmd = v7.CopySourceCommand{
    63  			BaseCommand: v7.BaseCommand{
    64  				UI:          testUI,
    65  				Config:      fakeConfig,
    66  				SharedActor: fakeSharedActor,
    67  				Actor:       fakeActor,
    68  			},
    69  			RequiredArgs: flag.CopySourceArgs{SourceAppName: sourceApp.Name, TargetAppName: targetApp.Name},
    70  			Stager:       fakeAppStager,
    71  		}
    72  
    73  		fakeConfig.BinaryNameReturns(binaryName)
    74  		fakeSharedActor.CheckTargetReturns(nil)
    75  		fakeConfig.CurrentUserReturns(configv3.User{Name: userName}, nil)
    76  
    77  		fakeConfig.TargetedSpaceReturns(configv3.Space{Name: "some-space", GUID: "some-space-guid"})
    78  		fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: "some-org"})
    79  
    80  		fakeActor.GetSpaceByNameAndOrganizationReturns(resources.Space{Name: "destination-space", GUID: "destination-space-guid"},
    81  			v7action.Warnings{"get-space-by-name-warning"},
    82  			nil,
    83  		)
    84  		fakeActor.GetOrganizationByNameReturns(resources.Organization{Name: "destination-org", GUID: "destination-org-guid"},
    85  			v7action.Warnings{"get-org-by-name-warning"},
    86  			nil,
    87  		)
    88  
    89  		fakeActor.GetApplicationByNameAndSpaceReturnsOnCall(0, sourceApp, v7action.Warnings{"get-source-app-warning"}, nil)
    90  		fakeActor.GetApplicationByNameAndSpaceReturnsOnCall(1, targetApp, v7action.Warnings{"get-target-app-warning"}, nil)
    91  		fakeActor.CopyPackageReturns(targetPackage, v7action.Warnings{"copy-package-warning"}, nil)
    92  
    93  	})
    94  
    95  	JustBeforeEach(func() {
    96  		executeErr = cmd.Execute(nil)
    97  	})
    98  
    99  	When("checking target fails", func() {
   100  		BeforeEach(func() {
   101  			fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName})
   102  		})
   103  
   104  		It("returns an error", func() {
   105  			Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: binaryName}))
   106  
   107  			Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
   108  			checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
   109  			Expect(checkTargetedOrg).To(BeTrue())
   110  			Expect(checkTargetedSpace).To(BeTrue())
   111  		})
   112  	})
   113  
   114  	It("retrieves the current user", func() {
   115  		Expect(fakeConfig.CurrentUserCallCount()).To(Equal(1))
   116  	})
   117  
   118  	When("retrieving the current user fails", func() {
   119  		BeforeEach(func() {
   120  			fakeConfig.CurrentUserReturns(configv3.User{}, errors.New("not-logged-in"))
   121  		})
   122  
   123  		It("returns an error", func() {
   124  			Expect(executeErr).To(MatchError("not-logged-in"))
   125  		})
   126  	})
   127  
   128  	When("the target organization is specified but the targeted space isn't", func() {
   129  		BeforeEach(func() {
   130  			cmd.Organization = "some-other-organization"
   131  		})
   132  
   133  		It("returns an error", func() {
   134  			Expect(executeErr).To(MatchError(translatableerror.RequiredFlagsError{
   135  				Arg1: "--organization, -o",
   136  				Arg2: "--space, -s",
   137  			}))
   138  		})
   139  	})
   140  
   141  	When("the no restart and strategy flags are both provided", func() {
   142  		BeforeEach(func() {
   143  			cmd.NoRestart = true
   144  			cmd.Strategy = flag.DeploymentStrategy{Name: constant.DeploymentStrategyRolling}
   145  		})
   146  
   147  		It("returns an error", func() {
   148  			Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{
   149  				Args: []string{
   150  					"--no-restart", "--strategy",
   151  				},
   152  			}))
   153  		})
   154  	})
   155  
   156  	When("the no restart and no wait flags are both provided", func() {
   157  		BeforeEach(func() {
   158  			cmd.NoRestart = true
   159  			cmd.NoWait = true
   160  		})
   161  
   162  		It("returns an error", func() {
   163  			Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{
   164  				Args: []string{
   165  					"--no-restart", "--no-wait",
   166  				},
   167  			}))
   168  		})
   169  	})
   170  
   171  	When("a target org and space is provided", func() {
   172  		BeforeEach(func() {
   173  			cmd.Organization = "destination-org"
   174  			cmd.Space = "destination-space"
   175  		})
   176  
   177  		It("retrieves the org by name and the space by name and organization", func() {
   178  			Expect(fakeActor.GetOrganizationByNameCallCount()).To(Equal(1))
   179  			org := fakeActor.GetOrganizationByNameArgsForCall(0)
   180  			Expect(org).To(Equal(cmd.Organization))
   181  
   182  			Expect(fakeActor.GetSpaceByNameAndOrganizationCallCount()).To(Equal(1))
   183  			space, orgGUID := fakeActor.GetSpaceByNameAndOrganizationArgsForCall(0)
   184  			Expect(space).To(Equal(cmd.Space))
   185  			Expect(orgGUID).To(Equal("destination-org-guid"))
   186  		})
   187  
   188  		It("displays the warnings", func() {
   189  			Expect(testUI.Err).To(Say("get-org-by-name-warning"))
   190  		})
   191  
   192  		When("retrieving the organization fails", func() {
   193  			BeforeEach(func() {
   194  				fakeActor.GetOrganizationByNameReturns(
   195  					resources.Organization{},
   196  					v7action.Warnings{},
   197  					errors.New("get-org-by-name-err"),
   198  				)
   199  			})
   200  			It("returns an error", func() {
   201  				Expect(executeErr).To(MatchError("get-org-by-name-err"))
   202  			})
   203  		})
   204  
   205  		When("retrieving the space fails", func() {
   206  			BeforeEach(func() {
   207  				fakeActor.GetSpaceByNameAndOrganizationReturns(
   208  					resources.Space{},
   209  					v7action.Warnings{},
   210  					errors.New("get-space-by-name-err"),
   211  				)
   212  			})
   213  			It("returns an error", func() {
   214  				Expect(executeErr).To(MatchError("get-space-by-name-err"))
   215  			})
   216  		})
   217  
   218  		It("uses the provided org and space", func() {
   219  			Expect(testUI.Out).To(Say(
   220  				"Copying source from app %s to target app %s in org %s / space %s as %s...",
   221  				sourceApp.Name,
   222  				targetApp.Name,
   223  				"destination-org",
   224  				"destination-space",
   225  				userName,
   226  			))
   227  		})
   228  	})
   229  
   230  	When("only a target space is provided", func() {
   231  		BeforeEach(func() {
   232  			cmd.Space = "destination-space"
   233  		})
   234  
   235  		It("retrieves the space by name and organization", func() {
   236  			Expect(fakeActor.GetSpaceByNameAndOrganizationCallCount()).To(Equal(1))
   237  			space, orgGUID := fakeActor.GetSpaceByNameAndOrganizationArgsForCall(0)
   238  			Expect(space).To(Equal(cmd.Space))
   239  			Expect(orgGUID).To(Equal(fakeConfig.TargetedOrganization().GUID))
   240  		})
   241  
   242  		It("displays the warnings", func() {
   243  			Expect(testUI.Err).To(Say("get-space-by-name-warning"))
   244  		})
   245  
   246  		It("uses the provided org and space", func() {
   247  			Expect(testUI.Out).To(Say(
   248  				"Copying source from app %s to target app %s in org %s / space %s as %s...",
   249  				sourceApp.Name,
   250  				targetApp.Name,
   251  				fakeConfig.TargetedOrganization().Name,
   252  				"destination-space",
   253  				userName,
   254  			))
   255  		})
   256  	})
   257  
   258  	It("displays a message about copying the source", func() {
   259  		Expect(testUI.Out).To(Say(
   260  			"Copying source from app %s to target app %s in org %s / space %s as %s...",
   261  			sourceApp.Name,
   262  			targetApp.Name,
   263  			fakeConfig.TargetedOrganization().Name,
   264  			fakeConfig.TargetedSpace().Name,
   265  			userName,
   266  		))
   267  	})
   268  
   269  	It("retrieves the source app", func() {
   270  		Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(2))
   271  		givenAppName, givenSpaceGUID := fakeActor.GetApplicationByNameAndSpaceArgsForCall(0)
   272  		Expect(givenAppName).To(Equal(sourceApp.Name))
   273  		Expect(givenSpaceGUID).To(Equal("some-space-guid"))
   274  
   275  		Expect(testUI.Err).To(Say("get-source-app-warning"))
   276  	})
   277  
   278  	When("retrieving the source app fails", func() {
   279  		BeforeEach(func() {
   280  			fakeActor.GetApplicationByNameAndSpaceReturnsOnCall(0, resources.Application{}, v7action.Warnings{"get-source-app-warning"}, errors.New("get-source-app-error"))
   281  		})
   282  
   283  		It("returns an error", func() {
   284  			Expect(executeErr).To(MatchError("get-source-app-error"))
   285  		})
   286  	})
   287  
   288  	It("retrieves the target app", func() {
   289  		Expect(fakeActor.GetApplicationByNameAndSpaceCallCount()).To(Equal(2))
   290  		givenAppName, givenSpaceGUID := fakeActor.GetApplicationByNameAndSpaceArgsForCall(1)
   291  		Expect(givenAppName).To(Equal(targetApp.Name))
   292  		Expect(givenSpaceGUID).To(Equal("some-space-guid"))
   293  
   294  		Expect(testUI.Err).To(Say("get-target-app-warning"))
   295  	})
   296  
   297  	When("retrieving the target app fails", func() {
   298  		BeforeEach(func() {
   299  			fakeActor.GetApplicationByNameAndSpaceReturnsOnCall(1, resources.Application{}, v7action.Warnings{"get-target-app-warning"}, errors.New("get-target-app-error"))
   300  		})
   301  
   302  		It("returns an error", func() {
   303  			Expect(executeErr).To(MatchError("get-target-app-error"))
   304  		})
   305  	})
   306  
   307  	It("copies the package", func() {
   308  		Expect(fakeActor.CopyPackageCallCount()).To(Equal(1))
   309  		srcApp, tgtApp := fakeActor.CopyPackageArgsForCall(0)
   310  		Expect(srcApp).To(Equal(sourceApp))
   311  		Expect(tgtApp).To(Equal(targetApp))
   312  
   313  		Expect(testUI.Err).To(Say("copy-package-warning"))
   314  	})
   315  
   316  	When("copying the package fails", func() {
   317  		BeforeEach(func() {
   318  			actorError = errors.New("copy-package-error")
   319  			fakeActor.CopyPackageReturns(v7action.Package{}, v7action.Warnings{}, actorError)
   320  		})
   321  
   322  		It("returns an error", func() {
   323  			Expect(executeErr).To(MatchError(actorError))
   324  		})
   325  	})
   326  
   327  	When("the strategy flag is set to rolling", func() {
   328  		BeforeEach(func() {
   329  			cmd.Strategy = flag.DeploymentStrategy{
   330  				Name: constant.DeploymentStrategyRolling,
   331  			}
   332  		})
   333  
   334  		It("stages and starts the app with the appropriate strategy", func() {
   335  			Expect(fakeAppStager.StageAndStartCallCount()).To(Equal(1))
   336  			returnedApp, spaceForApp, orgForApp, pkgGUID, strategy, noWait, appAction := fakeAppStager.StageAndStartArgsForCall(0)
   337  			Expect(returnedApp).To(Equal(targetApp))
   338  			Expect(spaceForApp).To(Equal(configv3.Space{Name: "some-space", GUID: "some-space-guid"}))
   339  			Expect(orgForApp).To(Equal(configv3.Organization{Name: "some-org"}))
   340  			Expect(pkgGUID).To(Equal("target-package-guid"))
   341  			Expect(strategy).To(Equal(constant.DeploymentStrategyRolling))
   342  			Expect(noWait).To(Equal(false))
   343  			Expect(appAction).To(Equal(constant.ApplicationRestarting))
   344  		})
   345  	})
   346  
   347  	When("the no-wait flag is set", func() {
   348  		BeforeEach(func() {
   349  			cmd.NoWait = true
   350  		})
   351  
   352  		It("stages and starts the app with the appropriate strategy", func() {
   353  			Expect(fakeAppStager.StageAndStartCallCount()).To(Equal(1))
   354  			returnedApp, spaceForApp, orgForApp, pkgGUID, strategy, noWait, appAction := fakeAppStager.StageAndStartArgsForCall(0)
   355  			Expect(returnedApp).To(Equal(targetApp))
   356  			Expect(spaceForApp).To(Equal(configv3.Space{Name: "some-space", GUID: "some-space-guid"}))
   357  			Expect(orgForApp).To(Equal(configv3.Organization{Name: "some-org"}))
   358  			Expect(pkgGUID).To(Equal("target-package-guid"))
   359  			Expect(strategy).To(Equal(constant.DeploymentStrategyDefault))
   360  			Expect(noWait).To(Equal(true))
   361  			Expect(appAction).To(Equal(constant.ApplicationRestarting))
   362  		})
   363  	})
   364  
   365  	It("stages and starts the target app", func() {
   366  		Expect(fakeAppStager.StageAndStartCallCount()).To(Equal(1))
   367  		returnedApp, spaceForApp, orgForApp, pkgGUID, strategy, noWait, appAction := fakeAppStager.StageAndStartArgsForCall(0)
   368  		Expect(returnedApp).To(Equal(targetApp))
   369  		Expect(spaceForApp).To(Equal(configv3.Space{Name: "some-space", GUID: "some-space-guid"}))
   370  		Expect(orgForApp).To(Equal(configv3.Organization{Name: "some-org"}))
   371  		Expect(pkgGUID).To(Equal("target-package-guid"))
   372  		Expect(strategy).To(Equal(constant.DeploymentStrategyDefault))
   373  		Expect(noWait).To(Equal(false))
   374  		Expect(appAction).To(Equal(constant.ApplicationRestarting))
   375  	})
   376  
   377  	When("staging and starting the app fails", func() {
   378  		BeforeEach(func() {
   379  			fakeAppStager.StageAndStartReturns(errors.New("stage-and-start-error"))
   380  		})
   381  
   382  		It("returns an error", func() {
   383  			Expect(executeErr).To(MatchError("stage-and-start-error"))
   384  		})
   385  	})
   386  
   387  	When("the no-restart flag is set", func() {
   388  		BeforeEach(func() {
   389  			cmd.NoRestart = true
   390  		})
   391  		It("succeeds but does not restart the app", func() {
   392  			Expect(executeErr).To(Not(HaveOccurred()))
   393  			Expect(fakeAppStager.StageAndStartCallCount()).To(Equal(0))
   394  		})
   395  	})
   396  
   397  	It("succeeds", func() {
   398  		Expect(executeErr).To(Not(HaveOccurred()))
   399  	})
   400  })