github.com/Thanhphan1147/cloudfoundry-cli@v7.1.0+incompatible/actor/pushaction/application_test.go (about)

     1  package pushaction_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	. "code.cloudfoundry.org/cli/actor/pushaction"
     8  	"code.cloudfoundry.org/cli/actor/pushaction/pushactionfakes"
     9  	"code.cloudfoundry.org/cli/actor/v2action"
    10  	"code.cloudfoundry.org/cli/actor/v3action"
    11  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    12  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    13  	"code.cloudfoundry.org/cli/types"
    14  
    15  	. "github.com/onsi/ginkgo"
    16  	. "github.com/onsi/ginkgo/extensions/table"
    17  	. "github.com/onsi/gomega"
    18  	. "github.com/onsi/gomega/gstruct"
    19  )
    20  
    21  var _ = Describe("Applications", func() {
    22  	var (
    23  		actor       *Actor
    24  		fakeV2Actor *pushactionfakes.FakeV2Actor
    25  		fakeV3Actor *pushactionfakes.FakeV3Actor
    26  	)
    27  
    28  	BeforeEach(func() {
    29  		actor, fakeV2Actor, fakeV3Actor, _ = getTestPushActor()
    30  	})
    31  
    32  	Describe("Application", func() {
    33  		DescribeTable("CalculatedBuildpacks",
    34  			func(v2Buildpack string, v3Buildpacks []string, expected []string) {
    35  				var buildpack types.FilteredString
    36  				if len(v2Buildpack) > 0 {
    37  					buildpack = types.FilteredString{
    38  						Value: v2Buildpack,
    39  						IsSet: true,
    40  					}
    41  				}
    42  				Expect(Application{
    43  					Application: v2action.Application{
    44  						Buildpack: buildpack,
    45  					},
    46  					Buildpacks: v3Buildpacks,
    47  				}.CalculatedBuildpacks()).To(Equal(expected))
    48  			},
    49  
    50  			Entry("returns buildpacks when it contains values",
    51  				"some-buildpack", []string{"some-buildpack", "some-other-buildpack"},
    52  				[]string{"some-buildpack", "some-other-buildpack"}),
    53  
    54  			Entry("always returns buildpacks when it is set",
    55  				"some-buildpack", []string{},
    56  				[]string{}),
    57  
    58  			Entry("returns v2 buildpack when buildpacks is not set",
    59  				"some-buildpack", nil,
    60  				[]string{"some-buildpack"}),
    61  
    62  			Entry("returns empty when nothing is set", "", nil, nil),
    63  		)
    64  	})
    65  
    66  	Describe("UpdateApplication", func() {
    67  		var (
    68  			config ApplicationConfig
    69  
    70  			returnedConfig ApplicationConfig
    71  			event          Event
    72  			warnings       Warnings
    73  			executeErr     error
    74  
    75  			updatedApplication v2action.Application
    76  		)
    77  
    78  		BeforeEach(func() {
    79  			config = ApplicationConfig{
    80  				DesiredApplication: Application{
    81  					Application: v2action.Application{
    82  						Name:      "some-app-name",
    83  						GUID:      "some-app-guid",
    84  						SpaceGUID: "some-space-guid",
    85  					},
    86  					Stack: v2action.Stack{
    87  						Name:        "some-stack-name",
    88  						GUID:        "some-stack-guid",
    89  						Description: "some-stack-description",
    90  					},
    91  				},
    92  				CurrentApplication: Application{
    93  					Application: v2action.Application{
    94  						Name:      "some-app-name",
    95  						GUID:      "some-app-guid",
    96  						SpaceGUID: "some-space-guid",
    97  					},
    98  				},
    99  				Path: "some-path",
   100  			}
   101  		})
   102  
   103  		JustBeforeEach(func() {
   104  			returnedConfig, event, warnings, executeErr = actor.UpdateApplication(config)
   105  		})
   106  
   107  		When("the update is successful", func() {
   108  			BeforeEach(func() {
   109  				updatedApplication = v2action.Application{
   110  					Name:      "some-app-name",
   111  					GUID:      "some-app-guid",
   112  					SpaceGUID: "some-space-guid",
   113  					Buildpack: types.FilteredString{Value: "ruby", IsSet: true},
   114  				}
   115  				fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil)
   116  			})
   117  
   118  			It("updates the application", func() {
   119  				Expect(executeErr).ToNot(HaveOccurred())
   120  				Expect(warnings).To(ConsistOf("update-warning"))
   121  				Expect(event).To(Equal(UpdatedApplication))
   122  
   123  				Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication))
   124  				Expect(returnedConfig.CurrentApplication).To(Equal(returnedConfig.DesiredApplication))
   125  
   126  				Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1))
   127  				submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0)
   128  				Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   129  					"Name":      Equal("some-app-name"),
   130  					"GUID":      Equal("some-app-guid"),
   131  					"SpaceGUID": Equal("some-space-guid"),
   132  				}))
   133  			})
   134  		})
   135  
   136  		When("the update errors", func() {
   137  			var expectedErr error
   138  			BeforeEach(func() {
   139  				expectedErr = errors.New("oh my")
   140  				fakeV2Actor.UpdateApplicationReturns(v2action.Application{}, v2action.Warnings{"update-warning"}, expectedErr)
   141  			})
   142  
   143  			It("returns warnings and error and stops", func() {
   144  				Expect(executeErr).To(MatchError(expectedErr))
   145  				Expect(warnings).To(ConsistOf("update-warning"))
   146  			})
   147  		})
   148  
   149  		Context("State", func() {
   150  			When("the state is not being updated", func() {
   151  				BeforeEach(func() {
   152  					config.CurrentApplication.State = "some-state"
   153  					config.DesiredApplication.State = "some-state"
   154  				})
   155  
   156  				It("does not send the state on update", func() {
   157  					Expect(executeErr).ToNot(HaveOccurred())
   158  
   159  					Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1))
   160  					Expect(fakeV2Actor.UpdateApplicationArgsForCall(0)).To(MatchFields(IgnoreExtras, Fields{
   161  						"Name":      Equal("some-app-name"),
   162  						"GUID":      Equal("some-app-guid"),
   163  						"SpaceGUID": Equal("some-space-guid"),
   164  					}))
   165  				})
   166  			})
   167  		})
   168  
   169  		Context("StackGUID", func() {
   170  			When("the stack guid is not being updated", func() {
   171  				BeforeEach(func() {
   172  					config.CurrentApplication.StackGUID = "some-stack-guid"
   173  					config.DesiredApplication.StackGUID = "some-stack-guid"
   174  				})
   175  
   176  				It("does not send the stack guid on update", func() {
   177  					Expect(executeErr).ToNot(HaveOccurred())
   178  
   179  					Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1))
   180  					Expect(fakeV2Actor.UpdateApplicationArgsForCall(0)).To(MatchFields(IgnoreExtras, Fields{
   181  						"Name":      Equal("some-app-name"),
   182  						"GUID":      Equal("some-app-guid"),
   183  						"SpaceGUID": Equal("some-space-guid"),
   184  					}))
   185  				})
   186  			})
   187  		})
   188  
   189  		Context("Buildpack(s)", func() {
   190  			var (
   191  				buildpack  types.FilteredString
   192  				buildpacks []string
   193  			)
   194  
   195  			BeforeEach(func() {
   196  				buildpack = types.FilteredString{}
   197  				buildpacks = nil
   198  			})
   199  
   200  			When("buildpack is set", func() {
   201  				BeforeEach(func() {
   202  					buildpack = types.FilteredString{Value: "ruby", IsSet: true}
   203  					config.DesiredApplication.Buildpack = buildpack
   204  
   205  					updatedApplication = v2action.Application{Buildpack: buildpack}
   206  					fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil)
   207  				})
   208  
   209  				It("keeps buildpack in the desired application", func() {
   210  					Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1))
   211  					submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0)
   212  					Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   213  						"Buildpack": Equal(buildpack),
   214  					}))
   215  
   216  					Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0))
   217  					Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication))
   218  				})
   219  			})
   220  
   221  			When("buildpacks is set as an empty array (autodetect)", func() {
   222  				BeforeEach(func() {
   223  					buildpacks = []string{}
   224  					config.DesiredApplication.Buildpacks = buildpacks
   225  
   226  					updatedApplication = v2action.Application{Buildpack: types.FilteredString{
   227  						Value: "",
   228  						IsSet: true,
   229  					}}
   230  					fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil)
   231  				})
   232  
   233  				It("sets buildpack to the only provided buildpack in buildpacks", func() {
   234  					Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1))
   235  					submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0)
   236  					Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   237  						"Buildpack": Equal(types.FilteredString{Value: "", IsSet: true}),
   238  					}))
   239  
   240  					Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0))
   241  					Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication))
   242  				})
   243  			})
   244  
   245  			When("buildpacks is set with one buildpack", func() {
   246  				BeforeEach(func() {
   247  					buildpacks = []string{"ruby"}
   248  					config.DesiredApplication.Buildpacks = buildpacks
   249  
   250  					updatedApplication = v2action.Application{Buildpack: types.FilteredString{
   251  						Value: buildpacks[0],
   252  						IsSet: true,
   253  					}}
   254  					fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil)
   255  				})
   256  
   257  				It("sets buildpack to the only provided buildpack in buildpacks", func() {
   258  					Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1))
   259  					submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0)
   260  					Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   261  						"Buildpack": Equal(types.FilteredString{Value: buildpacks[0], IsSet: true}),
   262  					}))
   263  
   264  					Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0))
   265  					Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication))
   266  				})
   267  
   268  				When("that buildpack is default/null", func() {
   269  					BeforeEach(func() {
   270  						buildpacks = []string{"default"}
   271  						config.DesiredApplication.Buildpacks = buildpacks
   272  
   273  						updatedApplication = v2action.Application{Buildpack: types.FilteredString{
   274  							Value: buildpacks[0],
   275  							IsSet: true,
   276  						}}
   277  						fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil)
   278  					})
   279  
   280  					It("sets buildpack with the empty string", func() {
   281  						Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1))
   282  						submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0)
   283  						Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   284  							"Buildpack": Equal(types.FilteredString{IsSet: true}),
   285  						}))
   286  					})
   287  				})
   288  			})
   289  
   290  			When("buildpacks is set with more than one buildpack", func() {
   291  				BeforeEach(func() {
   292  					buildpacks = []string{"ruby", "java"}
   293  					config.DesiredApplication.Buildpacks = buildpacks
   294  
   295  					updatedApplication = v2action.Application{}
   296  					fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"update-warning"}, nil)
   297  				})
   298  
   299  				It("sets the first provided buildpack", func() {
   300  					Expect(fakeV2Actor.UpdateApplicationCallCount()).To(Equal(1))
   301  					submitApp := fakeV2Actor.UpdateApplicationArgsForCall(0)
   302  					Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   303  						"Buildpack": Equal(types.FilteredString{IsSet: true, Value: "ruby"}),
   304  					}))
   305  
   306  					Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication))
   307  				})
   308  
   309  				When("the v3 update is successful", func() {
   310  					var submitApp v3action.Application
   311  
   312  					BeforeEach(func() {
   313  						updatedApplication = config.DesiredApplication.Application
   314  						updatedApplication.GUID = "yay-im-a-guid"
   315  						submitApp = v3action.Application{
   316  							Name:                updatedApplication.Name,
   317  							GUID:                updatedApplication.GUID,
   318  							StackName:           config.DesiredApplication.Stack.Name,
   319  							LifecycleBuildpacks: []string{"ruby", "java"},
   320  							LifecycleType:       constant.AppLifecycleTypeBuildpack,
   321  						}
   322  
   323  						fakeV2Actor.UpdateApplicationReturns(updatedApplication, v2action.Warnings{"v2-create-application-warnings"}, nil)
   324  						fakeV3Actor.UpdateApplicationReturns(v3action.Application{}, v3action.Warnings{"v3-update-application-warnings"}, nil)
   325  					})
   326  
   327  					It("updates only the buildpacks in ccv3", func() {
   328  						Expect(executeErr).ToNot(HaveOccurred())
   329  						Expect(warnings).To(ConsistOf("v2-create-application-warnings", "v3-update-application-warnings"))
   330  
   331  						Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(1))
   332  						Expect(fakeV3Actor.UpdateApplicationArgsForCall(0)).To(Equal(submitApp))
   333  
   334  						Expect(returnedConfig.DesiredApplication.Application).To(Equal(updatedApplication))
   335  					})
   336  				})
   337  
   338  				When("the v3 update fails", func() {
   339  					BeforeEach(func() {
   340  						fakeV2Actor.UpdateApplicationReturns(v2action.Application{}, v2action.Warnings{"v2-create-application-warnings"}, nil)
   341  						fakeV3Actor.UpdateApplicationReturns(v3action.Application{}, v3action.Warnings{"v3-update-application-warnings"}, errors.New("boom"))
   342  					})
   343  
   344  					It("raises an error", func() {
   345  						Expect(executeErr).To(MatchError("boom"))
   346  						Expect(warnings).To(ConsistOf("v2-create-application-warnings", "v3-update-application-warnings"))
   347  
   348  						Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(1))
   349  					})
   350  				})
   351  			})
   352  		})
   353  	})
   354  
   355  	Describe("CreateApplication", func() {
   356  		var (
   357  			config ApplicationConfig
   358  
   359  			returnedConfig ApplicationConfig
   360  			event          Event
   361  			warnings       Warnings
   362  			executeErr     error
   363  
   364  			createdApplication v2action.Application
   365  		)
   366  
   367  		BeforeEach(func() {
   368  			config = ApplicationConfig{
   369  				DesiredApplication: Application{
   370  					Application: v2action.Application{
   371  						Name:      "some-app-name",
   372  						SpaceGUID: "some-space-guid",
   373  					},
   374  				},
   375  				Path: "some-path",
   376  			}
   377  		})
   378  
   379  		JustBeforeEach(func() {
   380  			returnedConfig, event, warnings, executeErr = actor.CreateApplication(config)
   381  		})
   382  
   383  		When("the creation is successful", func() {
   384  			BeforeEach(func() {
   385  				createdApplication = v2action.Application{
   386  					Name:      "some-app-name",
   387  					GUID:      "some-app-guid",
   388  					SpaceGUID: "some-space-guid",
   389  				}
   390  
   391  				fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"create-warning"}, nil)
   392  			})
   393  
   394  			It("creates the application", func() {
   395  				Expect(executeErr).ToNot(HaveOccurred())
   396  				Expect(warnings).To(ConsistOf("create-warning"))
   397  				Expect(event).To(Equal(CreatedApplication))
   398  
   399  				Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication))
   400  				Expect(returnedConfig.CurrentApplication).To(Equal(returnedConfig.DesiredApplication))
   401  
   402  				Expect(fakeV2Actor.CreateApplicationCallCount()).To(Equal(1))
   403  				submitApp := fakeV2Actor.CreateApplicationArgsForCall(0)
   404  				Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   405  					"Name":      Equal("some-app-name"),
   406  					"SpaceGUID": Equal("some-space-guid"),
   407  				}))
   408  			})
   409  		})
   410  
   411  		When("the creation errors", func() {
   412  			var expectedErr error
   413  
   414  			BeforeEach(func() {
   415  				expectedErr = errors.New("oh my")
   416  				fakeV2Actor.CreateApplicationReturns(v2action.Application{}, v2action.Warnings{"create-warning"}, expectedErr)
   417  			})
   418  
   419  			It("sends the warnings and errors and returns true", func() {
   420  				Expect(executeErr).To(MatchError(expectedErr))
   421  				Expect(warnings).To(ConsistOf("create-warning"))
   422  			})
   423  		})
   424  
   425  		Context("Buildpack(s)", func() {
   426  			var (
   427  				buildpack  types.FilteredString
   428  				buildpacks []string
   429  			)
   430  
   431  			When("buildpack is set", func() {
   432  				BeforeEach(func() {
   433  					buildpack = types.FilteredString{Value: "ruby", IsSet: true}
   434  					config.DesiredApplication.Buildpack = buildpack
   435  
   436  					createdApplication = v2action.Application{Buildpack: buildpack}
   437  					fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"create-warning"}, nil)
   438  				})
   439  
   440  				It("keeps buildpack in the desired application", func() {
   441  					Expect(fakeV2Actor.CreateApplicationCallCount()).To(Equal(1))
   442  					submitApp := fakeV2Actor.CreateApplicationArgsForCall(0)
   443  					Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   444  						"Buildpack": Equal(buildpack),
   445  					}))
   446  
   447  					Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0))
   448  					Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication))
   449  				})
   450  			})
   451  
   452  			When("buildpacks is set with one buildpack", func() {
   453  				BeforeEach(func() {
   454  					buildpacks = []string{"ruby"}
   455  					config.DesiredApplication.Buildpacks = buildpacks
   456  
   457  					createdApplication = v2action.Application{Buildpack: types.FilteredString{
   458  						Value: buildpacks[0],
   459  						IsSet: true,
   460  					}}
   461  					fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"create-warning"}, nil)
   462  				})
   463  
   464  				It("sets buildpack to the set buildpack in buildpacks", func() {
   465  					Expect(fakeV2Actor.CreateApplicationCallCount()).To(Equal(1))
   466  					submitApp := fakeV2Actor.CreateApplicationArgsForCall(0)
   467  					Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   468  						"Buildpack": Equal(types.FilteredString{Value: buildpacks[0], IsSet: true}),
   469  					}))
   470  
   471  					Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(0))
   472  					Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication))
   473  				})
   474  			})
   475  
   476  			When("buildpacks is set with more than one buildpack", func() {
   477  				BeforeEach(func() {
   478  					buildpacks = []string{"ruby", "java"}
   479  					config.DesiredApplication.Buildpacks = buildpacks
   480  
   481  					createdApplication = v2action.Application{}
   482  					fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"create-warning"}, nil)
   483  				})
   484  
   485  				It("sets the first provided buildpack", func() {
   486  					Expect(fakeV2Actor.CreateApplicationCallCount()).To(Equal(1))
   487  					submitApp := fakeV2Actor.CreateApplicationArgsForCall(0)
   488  					Expect(submitApp).To(MatchFields(IgnoreExtras, Fields{
   489  						"Buildpack": Equal(types.FilteredString{IsSet: true, Value: "ruby"}),
   490  					}))
   491  
   492  					Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication))
   493  				})
   494  
   495  				When("the v3 update is successful", func() {
   496  					var submitApp v3action.Application
   497  
   498  					BeforeEach(func() {
   499  						createdApplication = config.DesiredApplication.Application
   500  						createdApplication.GUID = "yay-im-a-guid"
   501  						submitApp = v3action.Application{
   502  							Name:                createdApplication.Name,
   503  							GUID:                createdApplication.GUID,
   504  							StackName:           config.DesiredApplication.Stack.Name,
   505  							LifecycleBuildpacks: []string{"ruby", "java"},
   506  							LifecycleType:       constant.AppLifecycleTypeBuildpack,
   507  						}
   508  
   509  						fakeV2Actor.CreateApplicationReturns(createdApplication, v2action.Warnings{"v2-create-application-warnings"}, nil)
   510  						fakeV3Actor.UpdateApplicationReturns(v3action.Application{}, v3action.Warnings{"v3-update-application-warnings"}, nil)
   511  					})
   512  
   513  					It("updates only the buildpacks in ccv3", func() {
   514  						Expect(executeErr).ToNot(HaveOccurred())
   515  						Expect(warnings).To(ConsistOf("v2-create-application-warnings", "v3-update-application-warnings"))
   516  
   517  						Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(1))
   518  						Expect(fakeV3Actor.UpdateApplicationArgsForCall(0)).To(Equal(submitApp))
   519  
   520  						Expect(returnedConfig.DesiredApplication.Application).To(Equal(createdApplication))
   521  					})
   522  				})
   523  
   524  				When("the v3 update fails", func() {
   525  					BeforeEach(func() {
   526  						fakeV2Actor.CreateApplicationReturns(v2action.Application{}, v2action.Warnings{"v2-create-application-warnings"}, nil)
   527  						fakeV3Actor.UpdateApplicationReturns(v3action.Application{}, v3action.Warnings{"v3-update-application-warnings"}, errors.New("boom"))
   528  					})
   529  
   530  					It("raises an error", func() {
   531  						Expect(executeErr).To(MatchError("boom"))
   532  						Expect(warnings).To(ConsistOf("v2-create-application-warnings", "v3-update-application-warnings"))
   533  
   534  						Expect(fakeV3Actor.UpdateApplicationCallCount()).To(Equal(1))
   535  					})
   536  				})
   537  			})
   538  		})
   539  	})
   540  
   541  	Describe("FindOrReturnPartialApp", func() {
   542  		var (
   543  			appName   string
   544  			spaceGUID string
   545  
   546  			found      bool
   547  			app        Application
   548  			warnings   v2action.Warnings
   549  			executeErr error
   550  
   551  			expectedStack v2action.Stack
   552  			expectedApp   v2action.Application
   553  		)
   554  
   555  		BeforeEach(func() {
   556  			appName = "some-app"
   557  			spaceGUID = "some-space-guid"
   558  		})
   559  
   560  		JustBeforeEach(func() {
   561  			found, app, warnings, executeErr = actor.FindOrReturnPartialApp(appName, spaceGUID)
   562  		})
   563  
   564  		When("the app exists", func() {
   565  			BeforeEach(func() {
   566  				expectedApp = v2action.Application{
   567  					GUID:      "some-app-guid",
   568  					Name:      "some-app",
   569  					StackGUID: expectedStack.GUID,
   570  				}
   571  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(expectedApp, v2action.Warnings{"app-warnings"}, nil)
   572  			})
   573  
   574  			Describe("buildpacks", func() {
   575  				When("getting the app returns an API not found error", func() {
   576  					BeforeEach(func() {
   577  						fakeV3Actor.GetApplicationByNameAndSpaceReturns(v3action.Application{}, v3action.Warnings{"some-v3-app-warning"}, ccerror.APINotFoundError{})
   578  					})
   579  
   580  					It("ignores the error and sets buildpacks to nil", func() {
   581  						Expect(found).To(BeTrue())
   582  						Expect(executeErr).ToNot(HaveOccurred())
   583  						Expect(warnings).To(ConsistOf("app-warnings", "some-v3-app-warning"))
   584  						Expect(app.Buildpacks).To(BeNil())
   585  					})
   586  				})
   587  
   588  				When("getting the app returns a generic error", func() {
   589  					BeforeEach(func() {
   590  						fakeV3Actor.GetApplicationByNameAndSpaceReturns(v3action.Application{}, v3action.Warnings{"some-v3-app-warning"}, errors.New("some-generic-error"))
   591  					})
   592  
   593  					It("returns the error and warnings", func() {
   594  						Expect(found).To(BeFalse())
   595  						Expect(executeErr).To(MatchError(errors.New("some-generic-error")))
   596  						Expect(warnings).To(ConsistOf("app-warnings", "some-v3-app-warning"))
   597  					})
   598  				})
   599  
   600  				When("getting the app is successful", func() {
   601  					BeforeEach(func() {
   602  						fakeV3Actor.GetApplicationByNameAndSpaceReturns(
   603  							v3action.Application{LifecycleBuildpacks: []string{"buildpack-1", "buildpack-2"}},
   604  							v3action.Warnings{"some-v3-app-warning"},
   605  							nil)
   606  					})
   607  
   608  					It("sets the buildpacks", func() {
   609  						Expect(found).To(BeTrue())
   610  						Expect(executeErr).ToNot(HaveOccurred())
   611  						Expect(warnings).To(ConsistOf("app-warnings", "some-v3-app-warning"))
   612  						Expect(app.Buildpacks).To(ConsistOf("buildpack-1", "buildpack-2"))
   613  					})
   614  				})
   615  			})
   616  
   617  			When("retrieving the stack is successful", func() {
   618  				BeforeEach(func() {
   619  					expectedStack = v2action.Stack{
   620  						Name: "some-stack",
   621  						GUID: "some-stack-guid",
   622  					}
   623  					fakeV2Actor.GetStackReturns(expectedStack, v2action.Warnings{"stack-warnings"}, nil)
   624  				})
   625  
   626  				It("fills in the stack", func() {
   627  					Expect(executeErr).ToNot(HaveOccurred())
   628  					Expect(warnings).To(ConsistOf("app-warnings", "stack-warnings"))
   629  					Expect(found).To(BeTrue())
   630  					Expect(app).To(Equal(Application{
   631  						Application: expectedApp,
   632  						Stack:       expectedStack,
   633  					}))
   634  				})
   635  			})
   636  
   637  			When("retrieving the stack errors", func() {
   638  				var expectedErr error
   639  
   640  				BeforeEach(func() {
   641  					expectedErr = errors.New("stack stack stack em up")
   642  					fakeV2Actor.GetStackReturns(v2action.Stack{}, v2action.Warnings{"stack-warnings"}, expectedErr)
   643  
   644  					expectedApp = v2action.Application{
   645  						GUID:      "some-app-guid",
   646  						Name:      "some-app",
   647  						StackGUID: "some-stack-guid",
   648  					}
   649  					fakeV2Actor.GetApplicationByNameAndSpaceReturns(expectedApp, v2action.Warnings{"app-warnings"}, nil)
   650  				})
   651  
   652  				It("returns error and warnings", func() {
   653  					Expect(executeErr).To(MatchError(expectedErr))
   654  					Expect(warnings).To(ConsistOf("app-warnings", "stack-warnings"))
   655  					Expect(found).To(BeFalse())
   656  				})
   657  			})
   658  		})
   659  
   660  		When("the app does not exist", func() {
   661  			BeforeEach(func() {
   662  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, actionerror.ApplicationNotFoundError{})
   663  			})
   664  
   665  			It("returns a partial app and warnings", func() {
   666  				Expect(executeErr).ToNot(HaveOccurred())
   667  				Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2"))
   668  				Expect(found).To(BeFalse())
   669  				Expect(app).To(Equal(Application{
   670  					Application: v2action.Application{
   671  						Name:      "some-app",
   672  						SpaceGUID: "some-space-guid",
   673  					},
   674  				}))
   675  			})
   676  		})
   677  
   678  		When("retrieving the app errors", func() {
   679  			var expectedErr error
   680  			BeforeEach(func() {
   681  				expectedErr = errors.New("dios mio")
   682  				fakeV2Actor.GetApplicationByNameAndSpaceReturns(v2action.Application{}, v2action.Warnings{"some-app-warning-1", "some-app-warning-2"}, expectedErr)
   683  			})
   684  
   685  			It("returns a errors and warnings", func() {
   686  				Expect(executeErr).To(MatchError(expectedErr))
   687  				Expect(warnings).To(ConsistOf("some-app-warning-1", "some-app-warning-2"))
   688  				Expect(found).To(BeFalse())
   689  			})
   690  		})
   691  	})
   692  })