github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/actor/v7action/label_test.go (about)

     1  package v7action_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/actor/v7action/v7actionfakes"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    10  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    11  	"code.cloudfoundry.org/cli/resources"
    12  	"code.cloudfoundry.org/cli/types"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  )
    16  
    17  var _ = Describe("labels", func() {
    18  	var (
    19  		actor                     *Actor
    20  		fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
    21  		fakeSharedActor           *v7actionfakes.FakeSharedActor
    22  		fakeConfig                *v7actionfakes.FakeConfig
    23  		warnings                  Warnings
    24  		executeErr                error
    25  		resourceName              string
    26  		spaceGUID                 string
    27  		orgGUID                   string
    28  		labels                    map[string]types.NullString
    29  	)
    30  
    31  	BeforeEach(func() {
    32  		fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient)
    33  		fakeSharedActor = new(v7actionfakes.FakeSharedActor)
    34  		fakeConfig = new(v7actionfakes.FakeConfig)
    35  		actor = NewActor(fakeCloudControllerClient, fakeConfig, fakeSharedActor, nil, nil, nil)
    36  		resourceName = "some-resource"
    37  		orgGUID = "some-org-guid"
    38  		spaceGUID = "some-space-guid"
    39  	})
    40  
    41  	Describe("UpdateApplicationLabelsByApplicationName", func() {
    42  		JustBeforeEach(func() {
    43  			warnings, executeErr = actor.UpdateApplicationLabelsByApplicationName(resourceName, spaceGUID, labels)
    44  		})
    45  
    46  		When("there are no client errors", func() {
    47  			BeforeEach(func() {
    48  				fakeCloudControllerClient.GetApplicationsReturns(
    49  					[]resources.Application{{GUID: "some-guid"}},
    50  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
    51  					nil,
    52  				)
    53  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
    54  					"",
    55  					ccv3.Warnings{"set-app-labels-warnings"},
    56  					nil,
    57  				)
    58  			})
    59  
    60  			It("gets the application", func() {
    61  				Expect(fakeCloudControllerClient.GetApplicationsCallCount()).To(Equal(1))
    62  				Expect(fakeCloudControllerClient.GetApplicationsArgsForCall(0)).To(ConsistOf(
    63  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{resourceName}},
    64  					ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}},
    65  				))
    66  			})
    67  
    68  			It("sets the app labels", func() {
    69  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
    70  				resourceType, appGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
    71  				Expect(executeErr).ToNot(HaveOccurred())
    72  				Expect(resourceType).To(BeEquivalentTo("app"))
    73  				Expect(appGUID).To(BeEquivalentTo("some-guid"))
    74  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
    75  			})
    76  
    77  			It("aggregates warnings", func() {
    78  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-app-labels-warnings"))
    79  			})
    80  		})
    81  
    82  		When("there are client errors", func() {
    83  			When("GetApplications fails", func() {
    84  				BeforeEach(func() {
    85  					fakeCloudControllerClient.GetApplicationsReturns(
    86  						[]resources.Application{{GUID: "some-guid"}},
    87  						ccv3.Warnings([]string{"warning-failure-1", "warning-failure-2"}),
    88  						errors.New("get-apps-error"),
    89  					)
    90  				})
    91  
    92  				It("returns the error and all warnings", func() {
    93  					Expect(executeErr).To(HaveOccurred())
    94  					Expect(warnings).To(ConsistOf("warning-failure-1", "warning-failure-2"))
    95  					Expect(executeErr).To(MatchError("get-apps-error"))
    96  				})
    97  			})
    98  
    99  			When("UpdateApplication fails", func() {
   100  				BeforeEach(func() {
   101  					fakeCloudControllerClient.GetApplicationsReturns(
   102  						[]resources.Application{{GUID: "some-guid"}},
   103  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
   104  						nil,
   105  					)
   106  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   107  						"",
   108  						ccv3.Warnings{"set-app-labels-warnings"},
   109  						errors.New("update-application-error"),
   110  					)
   111  				})
   112  
   113  				It("returns the error and all warnings", func() {
   114  					Expect(executeErr).To(HaveOccurred())
   115  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-app-labels-warnings"))
   116  					Expect(executeErr).To(MatchError("update-application-error"))
   117  				})
   118  			})
   119  		})
   120  	})
   121  
   122  	Describe("UpdateDomainLabelsByDomainName", func() {
   123  		JustBeforeEach(func() {
   124  			warnings, executeErr = actor.UpdateDomainLabelsByDomainName(resourceName, labels)
   125  		})
   126  
   127  		When("there are no client errors", func() {
   128  			BeforeEach(func() {
   129  				fakeCloudControllerClient.GetDomainsReturns(
   130  					[]resources.Domain{{GUID: "some-guid"}},
   131  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
   132  					nil,
   133  				)
   134  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
   135  					"",
   136  					ccv3.Warnings{"warning-updating-metadata"},
   137  					nil,
   138  				)
   139  			})
   140  
   141  			It("gets the domain", func() {
   142  				Expect(fakeCloudControllerClient.GetDomainsCallCount()).To(Equal(1))
   143  				Expect(fakeCloudControllerClient.GetDomainsArgsForCall(0)).To(ConsistOf(
   144  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{resourceName}},
   145  				))
   146  			})
   147  
   148  			It("sets the domain labels", func() {
   149  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
   150  				resourceType, domainGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
   151  				Expect(executeErr).ToNot(HaveOccurred())
   152  				Expect(resourceType).To(BeEquivalentTo("domain"))
   153  				Expect(domainGUID).To(BeEquivalentTo("some-guid"))
   154  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
   155  			})
   156  
   157  			It("aggregates warnings", func() {
   158  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "warning-updating-metadata"))
   159  			})
   160  		})
   161  
   162  		When("there are client errors", func() {
   163  			When("fetching the domain fails", func() {
   164  				BeforeEach(func() {
   165  					fakeCloudControllerClient.GetDomainsReturns(
   166  						[]resources.Domain{{GUID: "some-guid"}},
   167  						ccv3.Warnings([]string{"warning-failure-1", "warning-failure-2"}),
   168  						errors.New("get-domains-error"),
   169  					)
   170  				})
   171  
   172  				It("returns the error and all warnings", func() {
   173  					Expect(executeErr).To(HaveOccurred())
   174  					Expect(warnings).To(ConsistOf("warning-failure-1", "warning-failure-2"))
   175  					Expect(executeErr).To(MatchError("get-domains-error"))
   176  				})
   177  			})
   178  
   179  			When("updating the domain fails", func() {
   180  				BeforeEach(func() {
   181  					fakeCloudControllerClient.GetDomainsReturns(
   182  						[]resources.Domain{{GUID: "some-guid"}},
   183  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
   184  						nil,
   185  					)
   186  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   187  						"",
   188  						ccv3.Warnings{"warning-updating-metadata"},
   189  						errors.New("update-domain-error"),
   190  					)
   191  				})
   192  				It("returns the error and all warnings", func() {
   193  					Expect(executeErr).To(HaveOccurred())
   194  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "warning-updating-metadata"))
   195  					Expect(executeErr).To(MatchError("update-domain-error"))
   196  				})
   197  			})
   198  		})
   199  	})
   200  
   201  	Describe("UpdateOrganizationLabelsByOrganizationName", func() {
   202  		JustBeforeEach(func() {
   203  			warnings, executeErr = actor.UpdateOrganizationLabelsByOrganizationName(resourceName, labels)
   204  		})
   205  
   206  		When("there are no client errors", func() {
   207  			BeforeEach(func() {
   208  				fakeCloudControllerClient.GetOrganizationsReturns(
   209  					[]resources.Organization{{GUID: "some-guid"}},
   210  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
   211  					nil,
   212  				)
   213  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
   214  					"",
   215  					ccv3.Warnings{"set-org"},
   216  					nil,
   217  				)
   218  			})
   219  
   220  			It("gets the organization", func() {
   221  				Expect(fakeCloudControllerClient.GetOrganizationsCallCount()).To(Equal(1))
   222  				Expect(fakeCloudControllerClient.GetOrganizationsArgsForCall(0)).To(ConsistOf(
   223  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{resourceName}},
   224  				))
   225  			})
   226  
   227  			It("sets the org labels", func() {
   228  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
   229  				resourceType, orgGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
   230  				Expect(executeErr).ToNot(HaveOccurred())
   231  				Expect(resourceType).To(BeEquivalentTo("org"))
   232  				Expect(orgGUID).To(BeEquivalentTo("some-guid"))
   233  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
   234  			})
   235  
   236  			It("aggregates warnings", func() {
   237  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-org"))
   238  			})
   239  		})
   240  
   241  		When("there are client errors", func() {
   242  			When("fetching the organization fails", func() {
   243  				BeforeEach(func() {
   244  					fakeCloudControllerClient.GetOrganizationsReturns(
   245  						[]resources.Organization{{GUID: "some-guid"}},
   246  						ccv3.Warnings([]string{"warning-failure-1", "warning-failure-2"}),
   247  						errors.New("get-orgs-error"),
   248  					)
   249  				})
   250  
   251  				It("returns the error and all warnings", func() {
   252  					Expect(executeErr).To(HaveOccurred())
   253  					Expect(warnings).To(ConsistOf("warning-failure-1", "warning-failure-2"))
   254  					Expect(executeErr).To(MatchError("get-orgs-error"))
   255  				})
   256  			})
   257  
   258  			When("updating the organization fails", func() {
   259  				BeforeEach(func() {
   260  					fakeCloudControllerClient.GetOrganizationsReturns(
   261  						[]resources.Organization{{GUID: "some-guid"}},
   262  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
   263  						nil,
   264  					)
   265  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   266  						"",
   267  						ccv3.Warnings{"set-org"},
   268  						errors.New("update-orgs-error"),
   269  					)
   270  				})
   271  				It("returns the error and all warnings", func() {
   272  					Expect(executeErr).To(HaveOccurred())
   273  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-org"))
   274  					Expect(executeErr).To(MatchError("update-orgs-error"))
   275  				})
   276  			})
   277  		})
   278  	})
   279  
   280  	Describe("UpdateRouteLabels", func() {
   281  		JustBeforeEach(func() {
   282  			warnings, executeErr = actor.UpdateRouteLabels("sub.example.com/my-route/path", "space-guid", labels)
   283  		})
   284  
   285  		When("there are no client errors", func() {
   286  			BeforeEach(func() {
   287  				fakeCloudControllerClient.GetDomainsReturns(
   288  					[]resources.Domain{
   289  						{Name: "domain-name", GUID: "domain-guid"},
   290  					},
   291  					ccv3.Warnings{"get-domains-warning"},
   292  					nil,
   293  				)
   294  
   295  				fakeCloudControllerClient.GetRoutesReturns(
   296  					[]resources.Route{
   297  						{GUID: "route-guid", SpaceGUID: "space-guid", DomainGUID: "domain-guid", Host: "hostname", URL: "hostname.domain-name", Path: "/the-path"},
   298  					},
   299  					ccv3.Warnings{"get-route-warning-1", "get-route-warning-2"},
   300  					nil,
   301  				)
   302  
   303  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
   304  					"",
   305  					ccv3.Warnings{"set-route-warning"},
   306  					nil,
   307  				)
   308  			})
   309  
   310  			It("gets the domain", func() {
   311  				Expect(fakeCloudControllerClient.GetDomainsCallCount()).To(Equal(1))
   312  				Expect(fakeCloudControllerClient.GetDomainsArgsForCall(0)).To(ConsistOf(
   313  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{"sub.example.com"}},
   314  				))
   315  			})
   316  
   317  			It("gets the route", func() {
   318  				Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
   319  				Expect(fakeCloudControllerClient.GetRoutesArgsForCall(0)).To(ConsistOf(
   320  					ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{"space-guid"}},
   321  					ccv3.Query{Key: ccv3.DomainGUIDFilter, Values: []string{"domain-guid"}},
   322  					ccv3.Query{Key: ccv3.HostsFilter, Values: []string{""}},
   323  					ccv3.Query{Key: ccv3.PathsFilter, Values: []string{"/my-route/path"}},
   324  				))
   325  			})
   326  
   327  			It("sets the route labels", func() {
   328  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
   329  				resourceType, routeGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
   330  				Expect(executeErr).ToNot(HaveOccurred())
   331  				Expect(resourceType).To(BeEquivalentTo("route"))
   332  				Expect(routeGUID).To(BeEquivalentTo("route-guid"))
   333  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
   334  			})
   335  
   336  			It("aggregates warnings", func() {
   337  				Expect(warnings).To(ConsistOf("get-domains-warning", "get-route-warning-1", "get-route-warning-2", "set-route-warning"))
   338  			})
   339  		})
   340  
   341  		When("there are client errors", func() {
   342  			When("fetching the route fails", func() {
   343  				BeforeEach(func() {
   344  					fakeCloudControllerClient.GetDomainsReturns(
   345  						nil,
   346  						ccv3.Warnings{"get-domains-warning"},
   347  						errors.New("get-domain-error"),
   348  					)
   349  				})
   350  
   351  				It("returns the error and all warnings", func() {
   352  					Expect(executeErr).To(HaveOccurred())
   353  					Expect(warnings).To(ConsistOf("get-domains-warning"))
   354  					Expect(executeErr).To(MatchError("get-domain-error"))
   355  				})
   356  			})
   357  
   358  			When("updating the route fails", func() {
   359  				BeforeEach(func() {
   360  					fakeCloudControllerClient.GetDomainsReturns(
   361  						[]resources.Domain{
   362  							{Name: "domain-name", GUID: "domain-guid"},
   363  						},
   364  						ccv3.Warnings{"get-domains-warning"},
   365  						nil,
   366  					)
   367  
   368  					fakeCloudControllerClient.GetRoutesReturns(
   369  						[]resources.Route{
   370  							{GUID: "route-guid", SpaceGUID: "space-guid", DomainGUID: "domain-guid", Host: "hostname", URL: "hostname.domain-name", Path: "/the-path"},
   371  						},
   372  						ccv3.Warnings{"get-route-warning-1", "get-route-warning-2"},
   373  						nil,
   374  					)
   375  
   376  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   377  						"",
   378  						ccv3.Warnings{"set-route-warning"},
   379  						errors.New("update-route-error"),
   380  					)
   381  				})
   382  
   383  				It("returns the error and all warnings", func() {
   384  					Expect(executeErr).To(HaveOccurred())
   385  					Expect(warnings).To(ConsistOf("get-domains-warning", "get-route-warning-1", "get-route-warning-2", "set-route-warning"))
   386  				})
   387  			})
   388  		})
   389  	})
   390  
   391  	Describe("UpdateSpaceLabelsBySpaceName", func() {
   392  		JustBeforeEach(func() {
   393  			warnings, executeErr = actor.UpdateSpaceLabelsBySpaceName(resourceName, orgGUID, labels)
   394  		})
   395  
   396  		When("there are no client errors", func() {
   397  			BeforeEach(func() {
   398  				fakeCloudControllerClient.GetSpacesReturns(
   399  					[]resources.Space{resources.Space{GUID: "some-guid"}},
   400  					ccv3.IncludedResources{},
   401  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
   402  					nil,
   403  				)
   404  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
   405  					"",
   406  					ccv3.Warnings{"set-space-metadata"},
   407  					nil,
   408  				)
   409  			})
   410  
   411  			It("gets the space", func() {
   412  				Expect(fakeCloudControllerClient.GetSpacesCallCount()).To(Equal(1))
   413  				Expect(fakeCloudControllerClient.GetSpacesArgsForCall(0)).To(ConsistOf(
   414  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{resourceName}},
   415  					ccv3.Query{Key: ccv3.OrganizationGUIDFilter, Values: []string{orgGUID}},
   416  				))
   417  			})
   418  
   419  			It("sets the space labels", func() {
   420  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
   421  				resourceType, spaceGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
   422  				Expect(executeErr).ToNot(HaveOccurred())
   423  				Expect(resourceType).To(BeEquivalentTo("space"))
   424  				Expect(spaceGUID).To(BeEquivalentTo("some-guid"))
   425  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
   426  			})
   427  
   428  			It("aggregates warnings", func() {
   429  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-space-metadata"))
   430  			})
   431  		})
   432  
   433  		When("there are client errors", func() {
   434  			When("fetching the space fails", func() {
   435  				BeforeEach(func() {
   436  					fakeCloudControllerClient.GetSpacesReturns(
   437  						[]resources.Space{resources.Space{GUID: "some-guid"}},
   438  						ccv3.IncludedResources{},
   439  						ccv3.Warnings([]string{"warning-failure-1", "warning-failure-2"}),
   440  						errors.New("get-spaces-error"),
   441  					)
   442  				})
   443  
   444  				It("returns the error and all warnings", func() {
   445  					Expect(executeErr).To(HaveOccurred())
   446  					Expect(warnings).To(ConsistOf("warning-failure-1", "warning-failure-2"))
   447  					Expect(executeErr).To(MatchError("get-spaces-error"))
   448  				})
   449  			})
   450  
   451  			When("updating the space fails", func() {
   452  				BeforeEach(func() {
   453  					fakeCloudControllerClient.GetSpacesReturns(
   454  						[]resources.Space{resources.Space{GUID: "some-guid"}},
   455  						ccv3.IncludedResources{},
   456  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
   457  						nil,
   458  					)
   459  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   460  						"",
   461  						ccv3.Warnings{"set-space"},
   462  						errors.New("update-space-error"),
   463  					)
   464  				})
   465  				It("returns the error and all warnings", func() {
   466  					Expect(executeErr).To(HaveOccurred())
   467  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-space"))
   468  					Expect(executeErr).To(MatchError("update-space-error"))
   469  				})
   470  			})
   471  		})
   472  	})
   473  
   474  	Describe("UpdateStackLabelsByStackName", func() {
   475  		JustBeforeEach(func() {
   476  			warnings, executeErr = actor.UpdateStackLabelsByStackName(resourceName, labels)
   477  		})
   478  
   479  		When("there are no client errors", func() {
   480  			BeforeEach(func() {
   481  				fakeCloudControllerClient.GetStacksReturns(
   482  					[]resources.Stack{resources.Stack{GUID: "some-guid"}},
   483  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
   484  					nil,
   485  				)
   486  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
   487  					"",
   488  					ccv3.Warnings{"set-stack-metadata"},
   489  					nil,
   490  				)
   491  			})
   492  
   493  			It("gets the stack", func() {
   494  				Expect(fakeCloudControllerClient.GetStacksCallCount()).To(Equal(1))
   495  				Expect(fakeCloudControllerClient.GetStacksArgsForCall(0)).To(ConsistOf(
   496  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{resourceName}},
   497  				))
   498  			})
   499  
   500  			It("sets the stack labels", func() {
   501  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
   502  				resourceType, stackGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
   503  				Expect(executeErr).ToNot(HaveOccurred())
   504  				Expect(resourceType).To(BeEquivalentTo("stack"))
   505  				Expect(stackGUID).To(BeEquivalentTo("some-guid"))
   506  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
   507  			})
   508  
   509  			It("aggregates warnings", func() {
   510  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-stack-metadata"))
   511  			})
   512  		})
   513  
   514  		When("there are client errors", func() {
   515  			When("fetching the stack fails", func() {
   516  				BeforeEach(func() {
   517  					fakeCloudControllerClient.GetStacksReturns(
   518  						[]resources.Stack{resources.Stack{GUID: "some-guid"}},
   519  						ccv3.Warnings([]string{"warning-failure-1", "warning-failure-2"}),
   520  						errors.New("get-stacks-error"),
   521  					)
   522  				})
   523  
   524  				It("returns the error and all warnings", func() {
   525  					Expect(executeErr).To(HaveOccurred())
   526  					Expect(warnings).To(ConsistOf("warning-failure-1", "warning-failure-2"))
   527  					Expect(executeErr).To(MatchError("get-stacks-error"))
   528  				})
   529  			})
   530  
   531  			When("updating the stack fails", func() {
   532  				BeforeEach(func() {
   533  					fakeCloudControllerClient.GetStacksReturns(
   534  						[]resources.Stack{resources.Stack{GUID: "some-guid"}},
   535  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
   536  						nil,
   537  					)
   538  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   539  						"",
   540  						ccv3.Warnings{"set-stack"},
   541  						errors.New("update-stack-error"),
   542  					)
   543  				})
   544  				It("returns the error and all warnings", func() {
   545  					Expect(executeErr).To(HaveOccurred())
   546  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-stack"))
   547  					Expect(executeErr).To(MatchError("update-stack-error"))
   548  				})
   549  			})
   550  		})
   551  	})
   552  
   553  	Describe("UpdateServiceBrokerLabelsByServiceBrokerName", func() {
   554  		JustBeforeEach(func() {
   555  			warnings, executeErr = actor.UpdateServiceBrokerLabelsByServiceBrokerName(resourceName, labels)
   556  		})
   557  
   558  		When("there are no client errors", func() {
   559  			BeforeEach(func() {
   560  				fakeCloudControllerClient.GetServiceBrokersReturns(
   561  					[]resources.ServiceBroker{{GUID: "some-broker-guid", Name: resourceName}},
   562  					[]string{"warning-1", "warning-2"},
   563  					nil,
   564  				)
   565  
   566  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
   567  					ccv3.JobURL("fake-job-url"),
   568  					ccv3.Warnings{"set-service-broker-metadata"},
   569  					nil,
   570  				)
   571  
   572  				fakeCloudControllerClient.PollJobReturns(ccv3.Warnings{"poll-job-warning"}, nil)
   573  			})
   574  
   575  			It("gets the service broker", func() {
   576  				Expect(executeErr).ToNot(HaveOccurred())
   577  				Expect(fakeCloudControllerClient.GetServiceBrokersCallCount()).To(Equal(1))
   578  			})
   579  
   580  			It("sets the service-broker labels", func() {
   581  				Expect(executeErr).ToNot(HaveOccurred())
   582  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
   583  				resourceType, serviceBrokerGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
   584  				Expect(resourceType).To(BeEquivalentTo("service-broker"))
   585  				Expect(serviceBrokerGUID).To(BeEquivalentTo("some-broker-guid"))
   586  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
   587  			})
   588  
   589  			It("polls the job", func() {
   590  				Expect(executeErr).ToNot(HaveOccurred())
   591  				Expect(fakeCloudControllerClient.PollJobCallCount()).To(Equal(1))
   592  				Expect(fakeCloudControllerClient.PollJobArgsForCall(0)).To(BeEquivalentTo("fake-job-url"))
   593  			})
   594  
   595  			It("aggregates warnings", func() {
   596  				Expect(executeErr).ToNot(HaveOccurred())
   597  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-service-broker-metadata", "poll-job-warning"))
   598  			})
   599  		})
   600  
   601  		When("there are client errors", func() {
   602  			When("fetching the service-broker fails", func() {
   603  				BeforeEach(func() {
   604  					fakeCloudControllerClient.GetServiceBrokersReturns(
   605  						[]resources.ServiceBroker{},
   606  						ccv3.Warnings([]string{"warning-failure-1", "warning-failure-2"}),
   607  						errors.New("get-service-broker-error"),
   608  					)
   609  				})
   610  
   611  				It("returns the error and all warnings", func() {
   612  					Expect(warnings).To(ConsistOf("warning-failure-1", "warning-failure-2"))
   613  					Expect(executeErr).To(MatchError("get-service-broker-error"))
   614  				})
   615  			})
   616  
   617  			When("updating the service-broker fails", func() {
   618  				BeforeEach(func() {
   619  					fakeCloudControllerClient.GetServiceBrokersReturns(
   620  						[]resources.ServiceBroker{{GUID: "some-guid", Name: resourceName}},
   621  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
   622  						nil,
   623  					)
   624  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   625  						ccv3.JobURL(""),
   626  						ccv3.Warnings{"set-service-broker"},
   627  						errors.New("update-service-broker-error"),
   628  					)
   629  				})
   630  
   631  				It("returns the error and all warnings", func() {
   632  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-service-broker"))
   633  					Expect(executeErr).To(MatchError("update-service-broker-error"))
   634  				})
   635  			})
   636  
   637  			When("polling the job fails", func() {
   638  				BeforeEach(func() {
   639  					fakeCloudControllerClient.GetServiceBrokersReturns(
   640  						[]resources.ServiceBroker{{GUID: "some-guid", Name: resourceName}},
   641  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
   642  						nil,
   643  					)
   644  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   645  						ccv3.JobURL("fake-job-url"),
   646  						ccv3.Warnings{"set-service-broker-metadata"},
   647  						nil,
   648  					)
   649  
   650  					fakeCloudControllerClient.PollJobReturns(
   651  						ccv3.Warnings{"another-poll-job-warning"},
   652  						errors.New("polling-error"),
   653  					)
   654  				})
   655  
   656  				It("returns the error and all warnings", func() {
   657  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-service-broker-metadata", "another-poll-job-warning"))
   658  					Expect(executeErr).To(MatchError("polling-error"))
   659  				})
   660  			})
   661  		})
   662  	})
   663  
   664  	Describe("UpdateServiceInstanceLabels", func() {
   665  		JustBeforeEach(func() {
   666  			warnings, executeErr = actor.UpdateServiceInstanceLabels(resourceName, spaceGUID, labels)
   667  		})
   668  
   669  		When("there are no client errors", func() {
   670  			BeforeEach(func() {
   671  				fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
   672  					resources.ServiceInstance{
   673  						GUID: "fake-si-guid",
   674  						Name: resourceName,
   675  					},
   676  					ccv3.IncludedResources{},
   677  					[]string{"warning-1", "warning-2"},
   678  					nil,
   679  				)
   680  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
   681  					"",
   682  					ccv3.Warnings{"set-si-labels-warnings"},
   683  					nil,
   684  				)
   685  			})
   686  
   687  			It("gets the service instance", func() {
   688  				Expect(fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceCallCount()).To(Equal(1))
   689  				actualName, actualSpaceGUID, actualQuery := fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceArgsForCall(0)
   690  				Expect(actualName).To(Equal(resourceName))
   691  				Expect(actualSpaceGUID).To(Equal(spaceGUID))
   692  				Expect(actualQuery).To(BeEmpty())
   693  			})
   694  
   695  			It("sets the service instance labels", func() {
   696  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
   697  				resourceType, siGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
   698  				Expect(executeErr).ToNot(HaveOccurred())
   699  				Expect(resourceType).To(BeEquivalentTo("service-instance"))
   700  				Expect(siGUID).To(BeEquivalentTo("fake-si-guid"))
   701  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
   702  			})
   703  
   704  			It("aggregates warnings", func() {
   705  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-si-labels-warnings"))
   706  			})
   707  		})
   708  
   709  		When("there are client errors", func() {
   710  			When("GetServiceInstanceByNameAndSpace fails", func() {
   711  				BeforeEach(func() {
   712  					fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
   713  						resources.ServiceInstance{},
   714  						ccv3.IncludedResources{},
   715  						[]string{"warning-failure-1", "warning-failure-2"},
   716  						errors.New("get-si-error"),
   717  					)
   718  				})
   719  
   720  				It("returns the error and all warnings", func() {
   721  					Expect(executeErr).To(HaveOccurred())
   722  					Expect(warnings).To(ConsistOf("warning-failure-1", "warning-failure-2"))
   723  					Expect(executeErr).To(MatchError("get-si-error"))
   724  				})
   725  			})
   726  
   727  			When("UpdateResourceMetadata fails", func() {
   728  				BeforeEach(func() {
   729  					fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
   730  						resources.ServiceInstance{
   731  							GUID: "fake-si-guid",
   732  							Name: resourceName,
   733  						},
   734  						ccv3.IncludedResources{},
   735  						[]string{"warning-1", "warning-2"},
   736  						nil,
   737  					)
   738  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   739  						"",
   740  						ccv3.Warnings{"set-app-labels-warnings"},
   741  						errors.New("update-si-error"),
   742  					)
   743  				})
   744  
   745  				It("returns the error and all warnings", func() {
   746  					Expect(executeErr).To(HaveOccurred())
   747  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-app-labels-warnings"))
   748  					Expect(executeErr).To(MatchError("update-si-error"))
   749  				})
   750  			})
   751  		})
   752  	})
   753  
   754  	Describe("UpdateServiceOfferingLabels", func() {
   755  		const serviceBrokerName = "fake-service-broker"
   756  
   757  		JustBeforeEach(func() {
   758  			warnings, executeErr = actor.UpdateServiceOfferingLabels(resourceName, serviceBrokerName, labels)
   759  		})
   760  
   761  		When("there are no client errors", func() {
   762  			BeforeEach(func() {
   763  				fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerReturns(
   764  					resources.ServiceOffering{GUID: "some-service-offering-guid", Name: resourceName},
   765  					[]string{"warning-1", "warning-2"},
   766  					nil,
   767  				)
   768  
   769  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
   770  					"",
   771  					ccv3.Warnings{"set-service-offering-metadata"},
   772  					nil,
   773  				)
   774  			})
   775  
   776  			It("gets the service offering", func() {
   777  				Expect(executeErr).ToNot(HaveOccurred())
   778  				Expect(fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerCallCount()).To(Equal(1))
   779  				requestedServiceName, requestedBrokerName := fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerArgsForCall(0)
   780  				Expect(requestedServiceName).To(Equal(resourceName))
   781  				Expect(requestedBrokerName).To(Equal(serviceBrokerName))
   782  			})
   783  
   784  			It("sets the service offering labels", func() {
   785  				Expect(executeErr).ToNot(HaveOccurred())
   786  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
   787  				resourceType, serviceBrokerGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
   788  				Expect(resourceType).To(BeEquivalentTo("service-offering"))
   789  				Expect(serviceBrokerGUID).To(BeEquivalentTo("some-service-offering-guid"))
   790  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
   791  			})
   792  
   793  			It("aggregates warnings", func() {
   794  				Expect(executeErr).ToNot(HaveOccurred())
   795  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-service-offering-metadata"))
   796  			})
   797  		})
   798  
   799  		When("there are client errors", func() {
   800  			When("fetching the service offering fails", func() {
   801  				BeforeEach(func() {
   802  					fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerReturns(
   803  						resources.ServiceOffering{},
   804  						ccv3.Warnings([]string{"warning-failure-1", "warning-failure-2"}),
   805  						errors.New("get-service-offerings-error"),
   806  					)
   807  				})
   808  
   809  				It("returns the error and all warnings", func() {
   810  					Expect(warnings).To(ConsistOf("warning-failure-1", "warning-failure-2"))
   811  					Expect(executeErr).To(MatchError("get-service-offerings-error"))
   812  				})
   813  			})
   814  
   815  			When("updating the service offering fails", func() {
   816  				BeforeEach(func() {
   817  					fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerReturns(
   818  						resources.ServiceOffering{GUID: "some-guid"},
   819  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
   820  						nil,
   821  					)
   822  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   823  						"",
   824  						ccv3.Warnings{"set-service-offering"},
   825  						errors.New("update-service-offering-error"),
   826  					)
   827  				})
   828  
   829  				It("returns the error and all warnings", func() {
   830  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-service-offering"))
   831  					Expect(executeErr).To(MatchError("update-service-offering-error"))
   832  				})
   833  			})
   834  		})
   835  	})
   836  
   837  	Describe("UpdateServicePlanLabels", func() {
   838  		const serviceBrokerName = "fake-service-broker"
   839  		const serviceOfferingName = "fake-service-offering"
   840  
   841  		JustBeforeEach(func() {
   842  			warnings, executeErr = actor.UpdateServicePlanLabels(resourceName, serviceOfferingName, serviceBrokerName, labels)
   843  		})
   844  
   845  		When("there are no client errors", func() {
   846  			BeforeEach(func() {
   847  				fakeCloudControllerClient.GetServicePlansReturns(
   848  					[]resources.ServicePlan{{GUID: "some-service-plan-guid", Name: resourceName}},
   849  					[]string{"warning-1", "warning-2"},
   850  					nil,
   851  				)
   852  
   853  				fakeCloudControllerClient.UpdateResourceMetadataReturns(
   854  					"",
   855  					ccv3.Warnings{"set-service-plan-metadata"},
   856  					nil,
   857  				)
   858  			})
   859  
   860  			It("gets the service plan", func() {
   861  				Expect(executeErr).ToNot(HaveOccurred())
   862  				Expect(fakeCloudControllerClient.GetServicePlansCallCount()).To(Equal(1))
   863  				Expect(fakeCloudControllerClient.GetServicePlansArgsForCall(0)).To(ConsistOf(
   864  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{resourceName}},
   865  					ccv3.Query{Key: ccv3.ServiceBrokerNamesFilter, Values: []string{serviceBrokerName}},
   866  					ccv3.Query{Key: ccv3.ServiceOfferingNamesFilter, Values: []string{serviceOfferingName}},
   867  				))
   868  			})
   869  
   870  			It("sets the service plan labels", func() {
   871  				Expect(executeErr).ToNot(HaveOccurred())
   872  				Expect(fakeCloudControllerClient.UpdateResourceMetadataCallCount()).To(Equal(1))
   873  				resourceType, servicePlanGUID, sentMetadata := fakeCloudControllerClient.UpdateResourceMetadataArgsForCall(0)
   874  				Expect(resourceType).To(BeEquivalentTo("service-plan"))
   875  				Expect(servicePlanGUID).To(BeEquivalentTo("some-service-plan-guid"))
   876  				Expect(sentMetadata.Labels).To(BeEquivalentTo(labels))
   877  			})
   878  
   879  			It("aggregates warnings", func() {
   880  				Expect(executeErr).ToNot(HaveOccurred())
   881  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-service-plan-metadata"))
   882  			})
   883  		})
   884  
   885  		When("there are client errors", func() {
   886  			When("fetching the service plan fails", func() {
   887  				BeforeEach(func() {
   888  					fakeCloudControllerClient.GetServicePlansReturns(
   889  						[]resources.ServicePlan{},
   890  						ccv3.Warnings([]string{"warning-failure-1", "warning-failure-2"}),
   891  						errors.New("get-service-plan-error"),
   892  					)
   893  				})
   894  
   895  				It("returns the error and all warnings", func() {
   896  					Expect(warnings).To(ConsistOf("warning-failure-1", "warning-failure-2"))
   897  					Expect(executeErr).To(MatchError("get-service-plan-error"))
   898  				})
   899  			})
   900  
   901  			When("updating the service plan fails", func() {
   902  				BeforeEach(func() {
   903  					fakeCloudControllerClient.GetServicePlansReturns(
   904  						[]resources.ServicePlan{{GUID: "some-guid"}},
   905  						[]string{"warning-1", "warning-2"},
   906  						nil,
   907  					)
   908  					fakeCloudControllerClient.UpdateResourceMetadataReturns(
   909  						"",
   910  						ccv3.Warnings{"set-service-plan"},
   911  						errors.New("update-service-plan-error"),
   912  					)
   913  				})
   914  
   915  				It("returns the error and all warnings", func() {
   916  					Expect(warnings).To(ConsistOf("warning-1", "warning-2", "set-service-plan"))
   917  					Expect(executeErr).To(MatchError("update-service-plan-error"))
   918  				})
   919  			})
   920  		})
   921  	})
   922  
   923  	Describe("GetDomainLabels", func() {
   924  		JustBeforeEach(func() {
   925  			labels, warnings, executeErr = actor.GetDomainLabels(resourceName)
   926  		})
   927  
   928  		When("there are no client errors", func() {
   929  			BeforeEach(func() {
   930  				fakeCloudControllerClient.GetDomainsReturns(
   931  					[]resources.Domain{{GUID: "some-guid"}},
   932  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
   933  					nil,
   934  				)
   935  			})
   936  
   937  			It("gets the domain", func() {
   938  				Expect(fakeCloudControllerClient.GetDomainsCallCount()).To(Equal(1))
   939  				Expect(fakeCloudControllerClient.GetDomainsArgsForCall(0)).To(ConsistOf(
   940  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{resourceName}},
   941  				))
   942  			})
   943  
   944  			When("there are no labels on a domain", func() {
   945  				It("returns an empty map", func() {
   946  					Expect(executeErr).NotTo(HaveOccurred())
   947  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
   948  					Expect(labels).To(BeEmpty())
   949  				})
   950  			})
   951  
   952  			When("there are labels", func() {
   953  				var expectedLabels map[string]types.NullString
   954  
   955  				BeforeEach(func() {
   956  					expectedLabels = map[string]types.NullString{"key1": types.NewNullString("value1"), "key2": types.NewNullString("value2")}
   957  					fakeCloudControllerClient.GetDomainsReturns(
   958  						[]resources.Domain{{
   959  							GUID: "some-guid",
   960  							Metadata: &resources.Metadata{
   961  								Labels: expectedLabels,
   962  							},
   963  						}},
   964  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
   965  						nil,
   966  					)
   967  				})
   968  				It("returns the labels", func() {
   969  					Expect(executeErr).NotTo(HaveOccurred())
   970  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
   971  					Expect(labels).To(Equal(expectedLabels))
   972  				})
   973  			})
   974  		})
   975  
   976  		When("there is a client error", func() {
   977  			BeforeEach(func() {
   978  				fakeCloudControllerClient.GetDomainsReturns(
   979  					[]resources.Domain{{GUID: "some-guid"}},
   980  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
   981  					errors.New("get-domains-error"),
   982  				)
   983  			})
   984  			When("GetDomainByName fails", func() {
   985  				It("returns the error and all warnings", func() {
   986  					Expect(executeErr).To(HaveOccurred())
   987  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
   988  					Expect(executeErr).To(MatchError("get-domains-error"))
   989  				})
   990  			})
   991  		})
   992  	})
   993  
   994  	Describe("GetRouteLabels", func() {
   995  		JustBeforeEach(func() {
   996  			labels, warnings, executeErr = actor.GetRouteLabels("sub.example.com/my-route/path", spaceGUID)
   997  		})
   998  
   999  		When("there are no client errors", func() {
  1000  			BeforeEach(func() {
  1001  				fakeCloudControllerClient.GetDomainsReturns(
  1002  					[]resources.Domain{
  1003  						{Name: "domain-name", GUID: "domain-guid"},
  1004  					},
  1005  					ccv3.Warnings{"get-domains-warning"},
  1006  					nil,
  1007  				)
  1008  
  1009  				fakeCloudControllerClient.GetRoutesReturns(
  1010  					[]resources.Route{
  1011  						{GUID: "route-guid", SpaceGUID: "some-space-guid", DomainGUID: "domain-guid", Host: "hostname", URL: "hostname.domain-name", Path: "/the-path"},
  1012  					},
  1013  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
  1014  					nil,
  1015  				)
  1016  			})
  1017  
  1018  			It("gets the route", func() {
  1019  				Expect(fakeCloudControllerClient.GetRoutesCallCount()).To(Equal(1))
  1020  				Expect(fakeCloudControllerClient.GetRoutesArgsForCall(0)).To(ConsistOf(
  1021  					ccv3.Query{Key: ccv3.SpaceGUIDFilter, Values: []string{spaceGUID}},
  1022  					ccv3.Query{Key: ccv3.DomainGUIDFilter, Values: []string{"domain-guid"}},
  1023  					ccv3.Query{Key: ccv3.HostsFilter, Values: []string{""}},
  1024  					ccv3.Query{Key: ccv3.PathsFilter, Values: []string{"/my-route/path"}},
  1025  				))
  1026  			})
  1027  
  1028  			When("there are no labels on a route", func() {
  1029  				It("returns an empty map", func() {
  1030  					Expect(executeErr).NotTo(HaveOccurred())
  1031  					Expect(warnings).To(ConsistOf("get-domains-warning", "warning-1", "warning-2"))
  1032  					Expect(labels).To(BeEmpty())
  1033  				})
  1034  			})
  1035  
  1036  			When("there are labels", func() {
  1037  				var expectedLabels map[string]types.NullString
  1038  
  1039  				BeforeEach(func() {
  1040  					expectedLabels = map[string]types.NullString{"key1": types.NewNullString("value1"), "key2": types.NewNullString("value2")}
  1041  					fakeCloudControllerClient.GetRoutesReturns(
  1042  						[]resources.Route{
  1043  							{
  1044  								GUID: "some-guid",
  1045  								Metadata: &resources.Metadata{
  1046  									Labels: expectedLabels,
  1047  								},
  1048  							},
  1049  						},
  1050  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
  1051  						nil,
  1052  					)
  1053  				})
  1054  				It("returns the labels", func() {
  1055  					Expect(executeErr).NotTo(HaveOccurred())
  1056  					Expect(warnings).To(ConsistOf("get-domains-warning", "warning-1", "warning-2"))
  1057  					Expect(labels).To(Equal(expectedLabels))
  1058  				})
  1059  			})
  1060  		})
  1061  
  1062  		When("there is a client error", func() {
  1063  			BeforeEach(func() {
  1064  				fakeCloudControllerClient.GetDomainsReturns(
  1065  					[]resources.Domain{
  1066  						{Name: "domain-name", GUID: "domain-guid"},
  1067  					},
  1068  					ccv3.Warnings{"get-domains-warning"},
  1069  					nil,
  1070  				)
  1071  
  1072  				fakeCloudControllerClient.GetRoutesReturns(
  1073  					[]resources.Route{{GUID: "some-guid"}},
  1074  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
  1075  					errors.New("get-routes-error"),
  1076  				)
  1077  			})
  1078  
  1079  			It("returns the error and all warnings", func() {
  1080  				Expect(executeErr).To(HaveOccurred())
  1081  				Expect(warnings).To(ConsistOf("get-domains-warning", "warning-1", "warning-2"))
  1082  				Expect(executeErr).To(MatchError("get-routes-error"))
  1083  			})
  1084  		})
  1085  	})
  1086  
  1087  	Describe("GetStackLabels", func() {
  1088  		JustBeforeEach(func() {
  1089  			labels, warnings, executeErr = actor.GetStackLabels(resourceName)
  1090  		})
  1091  
  1092  		When("there are no client errors", func() {
  1093  			BeforeEach(func() {
  1094  				fakeCloudControllerClient.GetStacksReturns(
  1095  					[]resources.Stack{resources.Stack{GUID: "some-guid"}},
  1096  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
  1097  					nil,
  1098  				)
  1099  			})
  1100  
  1101  			It("gets the stack", func() {
  1102  				Expect(fakeCloudControllerClient.GetStacksCallCount()).To(Equal(1))
  1103  				Expect(fakeCloudControllerClient.GetStacksArgsForCall(0)).To(ConsistOf(
  1104  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{resourceName}},
  1105  				))
  1106  			})
  1107  
  1108  			When("there are no labels on a stack", func() {
  1109  				It("returns an empty map", func() {
  1110  					Expect(executeErr).NotTo(HaveOccurred())
  1111  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1112  					Expect(labels).To(BeEmpty())
  1113  				})
  1114  			})
  1115  
  1116  			When("there are labels", func() {
  1117  				var expectedLabels map[string]types.NullString
  1118  
  1119  				BeforeEach(func() {
  1120  					expectedLabels = map[string]types.NullString{"key1": types.NewNullString("value1"), "key2": types.NewNullString("value2")}
  1121  					fakeCloudControllerClient.GetStacksReturns(
  1122  						[]resources.Stack{resources.Stack{
  1123  							GUID: "some-guid",
  1124  							Metadata: &resources.Metadata{
  1125  								Labels: expectedLabels,
  1126  							},
  1127  						}},
  1128  						ccv3.Warnings([]string{"warning-1", "warning-2"}),
  1129  						nil,
  1130  					)
  1131  				})
  1132  				It("returns the labels", func() {
  1133  					Expect(executeErr).NotTo(HaveOccurred())
  1134  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1135  					Expect(labels).To(Equal(expectedLabels))
  1136  				})
  1137  			})
  1138  		})
  1139  
  1140  		When("there is a client error", func() {
  1141  			BeforeEach(func() {
  1142  				fakeCloudControllerClient.GetStacksReturns(
  1143  					[]resources.Stack{resources.Stack{GUID: "some-guid"}},
  1144  					ccv3.Warnings([]string{"warning-1", "warning-2"}),
  1145  					errors.New("get-stacks-error"),
  1146  				)
  1147  			})
  1148  			When("GetStackByName fails", func() {
  1149  				It("returns the error and all warnings", func() {
  1150  					Expect(executeErr).To(HaveOccurred())
  1151  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1152  					Expect(executeErr).To(MatchError("get-stacks-error"))
  1153  				})
  1154  			})
  1155  		})
  1156  	})
  1157  
  1158  	Describe("GetServiceBrokerLabels", func() {
  1159  		When("service broker does not exist", func() {
  1160  			BeforeEach(func() {
  1161  				fakeCloudControllerClient.GetServiceBrokersReturns(
  1162  					[]resources.ServiceBroker{},
  1163  					[]string{"warning-1", "warning-2"},
  1164  					nil,
  1165  				)
  1166  			})
  1167  
  1168  			JustBeforeEach(func() {
  1169  				labels, warnings, executeErr = actor.GetServiceBrokerLabels(resourceName)
  1170  			})
  1171  
  1172  			It("returns a service broker not found error and warnings", func() {
  1173  				Expect(executeErr).To(HaveOccurred())
  1174  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1175  				Expect(executeErr.Error()).To(ContainSubstring("Service broker 'some-resource' not found"))
  1176  			})
  1177  		})
  1178  
  1179  		When("client returns an error", func() {
  1180  			BeforeEach(func() {
  1181  				fakeCloudControllerClient.GetServiceBrokersReturns(
  1182  					[]resources.ServiceBroker{},
  1183  					[]string{"warning"},
  1184  					errors.New("some random error"),
  1185  				)
  1186  			})
  1187  
  1188  			JustBeforeEach(func() {
  1189  				labels, warnings, executeErr = actor.GetServiceBrokerLabels(resourceName)
  1190  			})
  1191  
  1192  			It("returns error and prints warnings", func() {
  1193  				Expect(executeErr).To(HaveOccurred())
  1194  				Expect(warnings).To(ConsistOf("warning"))
  1195  				Expect(executeErr).To(MatchError("some random error"))
  1196  			})
  1197  		})
  1198  		When("service broker has labels", func() {
  1199  			var expectedLabels map[string]types.NullString
  1200  
  1201  			BeforeEach(func() {
  1202  				expectedLabels = map[string]types.NullString{"key1": types.NewNullString("value1"), "key2": types.NewNullString("value2")}
  1203  				fakeCloudControllerClient.GetServiceBrokersReturns(
  1204  					[]resources.ServiceBroker{resources.ServiceBroker{
  1205  						GUID: "some-guid",
  1206  						Name: resourceName,
  1207  						Metadata: &resources.Metadata{
  1208  							Labels: expectedLabels,
  1209  						},
  1210  					}},
  1211  					[]string{"warning-1", "warning-2"},
  1212  					nil,
  1213  				)
  1214  			})
  1215  
  1216  			JustBeforeEach(func() {
  1217  				labels, warnings, executeErr = actor.GetServiceBrokerLabels(resourceName)
  1218  			})
  1219  
  1220  			It("returns labels associated with the service broker as well as warnings", func() {
  1221  				Expect(executeErr).ToNot(HaveOccurred())
  1222  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1223  				Expect(labels).To(Equal(expectedLabels))
  1224  			})
  1225  		})
  1226  
  1227  	})
  1228  
  1229  	Describe("GetServiceInstanceLabels", func() {
  1230  		JustBeforeEach(func() {
  1231  			labels, warnings, executeErr = actor.GetServiceInstanceLabels(resourceName, spaceGUID)
  1232  		})
  1233  
  1234  		When("does not exist", func() {
  1235  			BeforeEach(func() {
  1236  				fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
  1237  					resources.ServiceInstance{},
  1238  					ccv3.IncludedResources{},
  1239  					[]string{"warning-1", "warning-2"},
  1240  					ccerror.ServiceInstanceNotFoundError{},
  1241  				)
  1242  			})
  1243  
  1244  			It("returns a service instance not found error and warnings", func() {
  1245  				Expect(executeErr).To(MatchError(actionerror.ServiceInstanceNotFoundError{}))
  1246  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1247  			})
  1248  		})
  1249  
  1250  		When("client returns an error", func() {
  1251  			BeforeEach(func() {
  1252  				fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
  1253  					resources.ServiceInstance{},
  1254  					ccv3.IncludedResources{},
  1255  					[]string{"warning"},
  1256  					errors.New("some random error"),
  1257  				)
  1258  			})
  1259  
  1260  			It("returns error and warnings", func() {
  1261  				Expect(executeErr).To(MatchError("some random error"))
  1262  				Expect(warnings).To(ConsistOf("warning"))
  1263  			})
  1264  		})
  1265  
  1266  		When("service instance has labels", func() {
  1267  			var expectedLabels map[string]types.NullString
  1268  
  1269  			BeforeEach(func() {
  1270  				expectedLabels = map[string]types.NullString{"key1": types.NewNullString("value1"), "key2": types.NewNullString("value2")}
  1271  				fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
  1272  					resources.ServiceInstance{
  1273  						GUID: "some-guid",
  1274  						Name: resourceName,
  1275  						Metadata: &resources.Metadata{
  1276  							Labels: expectedLabels,
  1277  						},
  1278  					},
  1279  					ccv3.IncludedResources{},
  1280  					[]string{"warning-1", "warning-2"},
  1281  					nil,
  1282  				)
  1283  			})
  1284  
  1285  			It("returns labels associated with the service broker as well as warnings", func() {
  1286  				Expect(executeErr).ToNot(HaveOccurred())
  1287  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1288  				Expect(labels).To(Equal(expectedLabels))
  1289  			})
  1290  		})
  1291  	})
  1292  
  1293  	Describe("GetServiceOfferingLabels", func() {
  1294  		const serviceBrokerName = "my-service-broker"
  1295  
  1296  		When("service offering does not exist", func() {
  1297  			BeforeEach(func() {
  1298  				fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerReturns(
  1299  					resources.ServiceOffering{},
  1300  					[]string{"warning-1", "warning-2"},
  1301  					ccerror.ServiceOfferingNotFoundError{
  1302  						ServiceOfferingName: resourceName,
  1303  						ServiceBrokerName:   serviceBrokerName,
  1304  					},
  1305  				)
  1306  			})
  1307  
  1308  			JustBeforeEach(func() {
  1309  				labels, warnings, executeErr = actor.GetServiceOfferingLabels(resourceName, serviceBrokerName)
  1310  			})
  1311  
  1312  			It("returns a service offering not found error and warnings", func() {
  1313  				Expect(executeErr).To(HaveOccurred())
  1314  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1315  				Expect(executeErr.Error()).To(ContainSubstring("Service offering '%s' for service broker '%s' not found", resourceName, serviceBrokerName))
  1316  			})
  1317  		})
  1318  
  1319  		When("client returns an error", func() {
  1320  			BeforeEach(func() {
  1321  				fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerReturns(
  1322  					resources.ServiceOffering{},
  1323  					[]string{"warning"},
  1324  					errors.New("some random error"),
  1325  				)
  1326  			})
  1327  
  1328  			JustBeforeEach(func() {
  1329  				labels, warnings, executeErr = actor.GetServiceOfferingLabels(resourceName, serviceBrokerName)
  1330  			})
  1331  
  1332  			It("returns error and prints warnings", func() {
  1333  				Expect(executeErr).To(HaveOccurred())
  1334  				Expect(warnings).To(ConsistOf("warning"))
  1335  				Expect(executeErr).To(MatchError("some random error"))
  1336  			})
  1337  		})
  1338  
  1339  		When("service offering has labels", func() {
  1340  			var expectedLabels map[string]types.NullString
  1341  
  1342  			BeforeEach(func() {
  1343  				expectedLabels = map[string]types.NullString{"key1": types.NewNullString("value1"), "key2": types.NewNullString("value2")}
  1344  				fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerReturns(
  1345  					resources.ServiceOffering{
  1346  						GUID: "some-guid",
  1347  						Name: resourceName,
  1348  						Metadata: &resources.Metadata{
  1349  							Labels: expectedLabels,
  1350  						},
  1351  					},
  1352  					[]string{"warning-1", "warning-2"},
  1353  					nil,
  1354  				)
  1355  			})
  1356  
  1357  			JustBeforeEach(func() {
  1358  				labels, warnings, executeErr = actor.GetServiceOfferingLabels(resourceName, serviceBrokerName)
  1359  			})
  1360  
  1361  			It("queries the right names", func() {
  1362  				Expect(fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerCallCount()).To(Equal(1))
  1363  				requestedServiceOffering, requestedServiceBroker := fakeCloudControllerClient.GetServiceOfferingByNameAndBrokerArgsForCall(0)
  1364  				Expect(requestedServiceOffering).To(Equal(resourceName))
  1365  				Expect(requestedServiceBroker).To(Equal(serviceBrokerName))
  1366  			})
  1367  
  1368  			It("returns labels associated with the service offering as well as warnings", func() {
  1369  				Expect(executeErr).ToNot(HaveOccurred())
  1370  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1371  				Expect(labels).To(Equal(expectedLabels))
  1372  			})
  1373  		})
  1374  	})
  1375  
  1376  	Describe("GetServicePlanLabels", func() {
  1377  		When("service plan does not exist", func() {
  1378  			BeforeEach(func() {
  1379  				fakeCloudControllerClient.GetServicePlansReturns(
  1380  					[]resources.ServicePlan{},
  1381  					[]string{"warning-1", "warning-2"},
  1382  					nil,
  1383  				)
  1384  			})
  1385  
  1386  			JustBeforeEach(func() {
  1387  				labels, warnings, executeErr = actor.GetServicePlanLabels(resourceName, "", "")
  1388  			})
  1389  
  1390  			It("returns a service plan not found error and warnings", func() {
  1391  				Expect(executeErr).To(HaveOccurred())
  1392  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1393  				Expect(executeErr.Error()).To(ContainSubstring("Service plan '%s' not found", resourceName))
  1394  			})
  1395  		})
  1396  
  1397  		When("client returns an error", func() {
  1398  			BeforeEach(func() {
  1399  				fakeCloudControllerClient.GetServicePlansReturns(
  1400  					[]resources.ServicePlan{},
  1401  					[]string{"warning"},
  1402  					errors.New("some random error"),
  1403  				)
  1404  			})
  1405  
  1406  			JustBeforeEach(func() {
  1407  				labels, warnings, executeErr = actor.GetServicePlanLabels(resourceName, "", "")
  1408  			})
  1409  
  1410  			It("returns error and prints warnings", func() {
  1411  				Expect(executeErr).To(HaveOccurred())
  1412  				Expect(warnings).To(ConsistOf("warning"))
  1413  				Expect(executeErr).To(MatchError("some random error"))
  1414  			})
  1415  		})
  1416  
  1417  		When("service plan has labels", func() {
  1418  			var expectedLabels map[string]types.NullString
  1419  
  1420  			BeforeEach(func() {
  1421  				expectedLabels = map[string]types.NullString{"key1": types.NewNullString("value1"), "key2": types.NewNullString("value2")}
  1422  				fakeCloudControllerClient.GetServicePlansReturns(
  1423  					[]resources.ServicePlan{{
  1424  						GUID: "some-guid",
  1425  						Name: resourceName,
  1426  						Metadata: &resources.Metadata{
  1427  							Labels: expectedLabels,
  1428  						},
  1429  					}},
  1430  					[]string{"warning-1", "warning-2"},
  1431  					nil,
  1432  				)
  1433  			})
  1434  
  1435  			JustBeforeEach(func() {
  1436  				labels, warnings, executeErr = actor.GetServicePlanLabels(resourceName, "serviceOfferingName", "serviceBrokerName")
  1437  			})
  1438  
  1439  			It("queries the right names", func() {
  1440  				Expect(fakeCloudControllerClient.GetServicePlansCallCount()).To(Equal(1))
  1441  				Expect(fakeCloudControllerClient.GetServicePlansArgsForCall(0)).To(ConsistOf(
  1442  					ccv3.Query{Key: ccv3.NameFilter, Values: []string{resourceName}},
  1443  					ccv3.Query{Key: ccv3.ServiceOfferingNamesFilter, Values: []string{"serviceOfferingName"}},
  1444  					ccv3.Query{Key: ccv3.ServiceBrokerNamesFilter, Values: []string{"serviceBrokerName"}},
  1445  				))
  1446  			})
  1447  
  1448  			It("returns labels associated with the service plan as well as warnings", func() {
  1449  				Expect(executeErr).ToNot(HaveOccurred())
  1450  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1451  				Expect(labels).To(Equal(expectedLabels))
  1452  			})
  1453  		})
  1454  	})
  1455  })