github.com/LukasHeimann/cloudfoundrycli/v8@v8.4.4/command/v7/update_service_command_test.go (about)

     1  package v7_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/LukasHeimann/cloudfoundrycli/v8/actor/actionerror"
     8  	"github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7action"
     9  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/commandfakes"
    10  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/flag"
    11  	. "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7"
    12  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/v7/v7fakes"
    13  	"github.com/LukasHeimann/cloudfoundrycli/v8/types"
    14  	"github.com/LukasHeimann/cloudfoundrycli/v8/util/configv3"
    15  	"github.com/LukasHeimann/cloudfoundrycli/v8/util/ui"
    16  	. "github.com/onsi/ginkgo"
    17  	. "github.com/onsi/gomega"
    18  	. "github.com/onsi/gomega/gbytes"
    19  )
    20  
    21  var _ = Describe("update-service command", func() {
    22  	const (
    23  		serviceInstanceName = "fake-service-instance-name"
    24  		spaceName           = "fake-space-name"
    25  		spaceGUID           = "fake-space-guid"
    26  		orgName             = "fake-org-name"
    27  		username            = "fake-username"
    28  	)
    29  
    30  	var (
    31  		input           *Buffer
    32  		testUI          *ui.UI
    33  		fakeConfig      *commandfakes.FakeConfig
    34  		fakeSharedActor *commandfakes.FakeSharedActor
    35  		fakeActor       *v7fakes.FakeActor
    36  		cmd             UpdateServiceCommand
    37  		executeErr      error
    38  	)
    39  
    40  	BeforeEach(func() {
    41  		input = NewBuffer()
    42  		testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer())
    43  		fakeConfig = new(commandfakes.FakeConfig)
    44  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    45  		fakeActor = new(v7fakes.FakeActor)
    46  
    47  		cmd = UpdateServiceCommand{
    48  			BaseCommand: BaseCommand{
    49  				UI:          testUI,
    50  				Config:      fakeConfig,
    51  				SharedActor: fakeSharedActor,
    52  				Actor:       fakeActor,
    53  			},
    54  		}
    55  
    56  		setPositionalFlags(&cmd, flag.TrimmedString(serviceInstanceName))
    57  
    58  		fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: orgName})
    59  		fakeConfig.TargetedSpaceReturns(configv3.Space{
    60  			Name: spaceName,
    61  			GUID: spaceGUID,
    62  		})
    63  		fakeActor.GetCurrentUserReturns(configv3.User{Name: username}, nil)
    64  
    65  		fakeStream := make(chan v7action.PollJobEvent)
    66  		close(fakeStream)
    67  		fakeActor.UpdateManagedServiceInstanceReturns(
    68  			fakeStream,
    69  			v7action.Warnings{"actor warning"},
    70  			nil,
    71  		)
    72  	})
    73  
    74  	JustBeforeEach(func() {
    75  		executeErr = cmd.Execute(nil)
    76  	})
    77  
    78  	It("checks the user is logged in, and targeting an org and space", func() {
    79  		Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
    80  		orgChecked, spaceChecked := fakeSharedActor.CheckTargetArgsForCall(0)
    81  		Expect(orgChecked).To(BeTrue())
    82  		Expect(spaceChecked).To(BeTrue())
    83  	})
    84  
    85  	When("upgrade flag specified", func() {
    86  		BeforeEach(func() {
    87  			setFlag(&cmd, "--upgrade")
    88  		})
    89  
    90  		It("prints a message and returns an error", func() {
    91  			Expect(executeErr).To(MatchError(
    92  				fmt.Sprintf(
    93  					`Upgrading is no longer supported via updates, please run "cf upgrade-service %s" instead.`,
    94  					serviceInstanceName,
    95  				),
    96  			))
    97  		})
    98  	})
    99  
   100  	When("no parameters specified", func() {
   101  		It("prints a message and exits 0", func() {
   102  			Expect(executeErr).NotTo(HaveOccurred())
   103  			Expect(testUI.Out).To(Say("No flags specified. No changes were made"))
   104  		})
   105  	})
   106  
   107  	Describe("updates", func() {
   108  		BeforeEach(func() {
   109  			setFlag(&cmd, "-t", `foo,bar`)
   110  			setFlag(&cmd, "-c", `{"baz": "quz"}`)
   111  			setFlag(&cmd, "-p", "some-plan")
   112  		})
   113  
   114  		It("does not return an error", func() {
   115  			Expect(executeErr).NotTo(HaveOccurred())
   116  		})
   117  
   118  		It("prints messages and warnings", func() {
   119  			Expect(testUI.Out).To(SatisfyAll(
   120  				Say(`Updating service instance %s in org %s / space %s as %s...\n`, serviceInstanceName, orgName, spaceName, username),
   121  				Say(`\n`),
   122  				Say(`Update of service instance %s complete\.`, serviceInstanceName),
   123  				Say(`OK\n`),
   124  			))
   125  
   126  			Expect(testUI.Err).To(Say("actor warning"))
   127  		})
   128  
   129  		It("delegates to the actor", func() {
   130  			Expect(fakeActor.UpdateManagedServiceInstanceCallCount()).To(Equal(1))
   131  			actualUpdates := fakeActor.UpdateManagedServiceInstanceArgsForCall(0)
   132  			Expect(actualUpdates).To(Equal(v7action.UpdateManagedServiceInstanceParams{
   133  				ServiceInstanceName: serviceInstanceName,
   134  				SpaceGUID:           spaceGUID,
   135  				Tags:                types.NewOptionalStringSlice("foo", "bar"),
   136  				Parameters:          types.NewOptionalObject(map[string]interface{}{"baz": "quz"}),
   137  				ServicePlanName:     "some-plan",
   138  			}))
   139  		})
   140  
   141  		When("stream goes to polling", func() {
   142  			BeforeEach(func() {
   143  				fakeStream := make(chan v7action.PollJobEvent)
   144  				fakeActor.UpdateManagedServiceInstanceReturns(
   145  					fakeStream,
   146  					v7action.Warnings{"actor warning"},
   147  					nil,
   148  				)
   149  
   150  				go func() {
   151  					fakeStream <- v7action.PollJobEvent{
   152  						State:    v7action.JobPolling,
   153  						Warnings: v7action.Warnings{"poll warning"},
   154  					}
   155  				}()
   156  			})
   157  
   158  			It("prints messages and warnings", func() {
   159  				Expect(testUI.Out).To(SatisfyAll(
   160  					Say(`Updating service instance %s in org %s / space %s as %s...\n`, serviceInstanceName, orgName, spaceName, username),
   161  					Say(`\n`),
   162  					Say(`Update in progress. Use 'cf services' or 'cf service %s' to check operation status\.`, serviceInstanceName),
   163  					Say(`OK\n`),
   164  				))
   165  
   166  				Expect(testUI.Err).To(SatisfyAll(
   167  					Say("actor warning"),
   168  					Say("poll warning"),
   169  				))
   170  			})
   171  		})
   172  
   173  		When("error in event stream", func() {
   174  			BeforeEach(func() {
   175  				setFlag(&cmd, "--wait")
   176  
   177  				fakeStream := make(chan v7action.PollJobEvent)
   178  				fakeActor.UpdateManagedServiceInstanceReturns(
   179  					fakeStream,
   180  					v7action.Warnings{"a warning"},
   181  					nil,
   182  				)
   183  
   184  				go func() {
   185  					fakeStream <- v7action.PollJobEvent{
   186  						State:    v7action.JobPolling,
   187  						Warnings: v7action.Warnings{"poll warning"},
   188  					}
   189  					fakeStream <- v7action.PollJobEvent{
   190  						State:    v7action.JobFailed,
   191  						Warnings: v7action.Warnings{"failed warning"},
   192  						Err:      errors.New("boom"),
   193  					}
   194  				}()
   195  			})
   196  
   197  			It("returns the error and prints warnings", func() {
   198  				Expect(executeErr).To(MatchError("boom"))
   199  				Expect(testUI.Err).To(SatisfyAll(
   200  					Say("poll warning"),
   201  					Say("failed warning"),
   202  				))
   203  			})
   204  		})
   205  
   206  		When("--wait flag specified", func() {
   207  			BeforeEach(func() {
   208  				setFlag(&cmd, "--wait")
   209  
   210  				fakeStream := make(chan v7action.PollJobEvent)
   211  				fakeActor.UpdateManagedServiceInstanceReturns(
   212  					fakeStream,
   213  					v7action.Warnings{"a warning"},
   214  					nil,
   215  				)
   216  
   217  				go func() {
   218  					fakeStream <- v7action.PollJobEvent{
   219  						State:    v7action.JobPolling,
   220  						Warnings: v7action.Warnings{"poll warning"},
   221  					}
   222  					fakeStream <- v7action.PollJobEvent{
   223  						State:    v7action.JobComplete,
   224  						Warnings: v7action.Warnings{"failed warning"},
   225  					}
   226  					close(fakeStream)
   227  				}()
   228  			})
   229  
   230  			It("prints messages and warnings", func() {
   231  				Expect(testUI.Out).To(SatisfyAll(
   232  					Say(`Updating service instance %s in org %s / space %s as %s...\n`, serviceInstanceName, orgName, spaceName, username),
   233  					Say(`\n`),
   234  					Say(`Waiting for the operation to complete\.\.\n`),
   235  					Say(`\n`),
   236  					Say(`Update of service instance %s complete\.\n`, serviceInstanceName),
   237  					Say(`OK\n`),
   238  				))
   239  
   240  				Expect(testUI.Err).To(SatisfyAll(
   241  					Say("a warning"),
   242  					Say("poll warning"),
   243  					Say("failed warning"),
   244  				))
   245  			})
   246  		})
   247  
   248  		When("plan is current plan", func() {
   249  			const currentPlan = "current-plan"
   250  
   251  			BeforeEach(func() {
   252  				setFlag(&cmd, "-p", currentPlan)
   253  				fakeActor.UpdateManagedServiceInstanceReturns(
   254  					nil,
   255  					v7action.Warnings{"actor warning"},
   256  					actionerror.ServiceInstanceUpdateIsNoop{},
   257  				)
   258  			})
   259  
   260  			It("prints warnings and a message", func() {
   261  				Expect(executeErr).NotTo(HaveOccurred())
   262  				Expect(testUI.Err).To(Say("actor warning"))
   263  				Expect(testUI.Out).To(Say("No changes were made"))
   264  			})
   265  		})
   266  
   267  		When("getting the user fails", func() {
   268  			BeforeEach(func() {
   269  				fakeActor.GetCurrentUserReturns(configv3.User{}, errors.New("bang"))
   270  			})
   271  
   272  			It("returns the error", func() {
   273  				Expect(executeErr).To(MatchError("bang"))
   274  			})
   275  		})
   276  
   277  		When("the actor reports the service instance was not found", func() {
   278  			BeforeEach(func() {
   279  				fakeActor.UpdateManagedServiceInstanceReturns(
   280  					nil,
   281  					v7action.Warnings{"actor warning"},
   282  					actionerror.ServiceInstanceNotFoundError{Name: serviceInstanceName},
   283  				)
   284  			})
   285  
   286  			It("prints warnings and returns an error", func() {
   287  				Expect(testUI.Err).To(Say("actor warning"))
   288  				Expect(executeErr).To(MatchError(actionerror.ServiceInstanceNotFoundError{
   289  					Name: serviceInstanceName,
   290  				}))
   291  			})
   292  		})
   293  
   294  		When("plan not found", func() {
   295  			const (
   296  				invalidPlan = "invalid-plan"
   297  			)
   298  
   299  			BeforeEach(func() {
   300  				setFlag(&cmd, "-p", invalidPlan)
   301  				fakeActor.UpdateManagedServiceInstanceReturns(
   302  					nil,
   303  					v7action.Warnings{"actor warning"},
   304  					actionerror.ServicePlanNotFoundError{PlanName: invalidPlan, ServiceBrokerName: "the-broker", OfferingName: "the-offering"},
   305  				)
   306  			})
   307  
   308  			It("prints warnings and returns a translatable error", func() {
   309  				Expect(testUI.Err).To(Say("actor warning"))
   310  				Expect(executeErr).To(MatchError(actionerror.ServicePlanNotFoundError{
   311  					PlanName:          invalidPlan,
   312  					OfferingName:      "the-offering",
   313  					ServiceBrokerName: "the-broker",
   314  				}))
   315  			})
   316  		})
   317  
   318  		When("the actor fails with an unexpected error", func() {
   319  			BeforeEach(func() {
   320  				fakeActor.UpdateManagedServiceInstanceReturns(
   321  					nil,
   322  					v7action.Warnings{"actor warning"},
   323  					errors.New("boof"),
   324  				)
   325  			})
   326  
   327  			It("prints warnings and returns an error", func() {
   328  				Expect(testUI.Err).To(Say("actor warning"))
   329  				Expect(executeErr).To(MatchError("boof"))
   330  			})
   331  		})
   332  	})
   333  
   334  	When("checking the target returns an error", func() {
   335  		BeforeEach(func() {
   336  			fakeSharedActor.CheckTargetReturns(errors.New("explode"))
   337  		})
   338  
   339  		It("returns the error", func() {
   340  			Expect(executeErr).To(MatchError("explode"))
   341  		})
   342  	})
   343  })