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

     1  package v7_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/LukasHeimann/cloudfoundrycli/v8/actor/actionerror"
     7  	"github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7action"
     8  	"github.com/LukasHeimann/cloudfoundrycli/v8/api/cloudcontroller/ccerror"
     9  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/commandfakes"
    10  	v7 "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7"
    11  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/v7/v7fakes"
    12  	"github.com/LukasHeimann/cloudfoundrycli/v8/types"
    13  	"github.com/LukasHeimann/cloudfoundrycli/v8/util/configv3"
    14  	"github.com/LukasHeimann/cloudfoundrycli/v8/util/ui"
    15  	. "github.com/onsi/ginkgo"
    16  	. "github.com/onsi/gomega"
    17  	. "github.com/onsi/gomega/gbytes"
    18  )
    19  
    20  var _ = Describe("create-service Command", func() {
    21  	var (
    22  		cmd             v7.CreateServiceCommand
    23  		testUI          *ui.UI
    24  		fakeConfig      *commandfakes.FakeConfig
    25  		fakeSharedActor *commandfakes.FakeSharedActor
    26  		executeErr      error
    27  		fakeActor       *v7fakes.FakeActor
    28  		expectedError   error
    29  	)
    30  
    31  	const (
    32  		fakeUserName                 = "fake-user-name"
    33  		requestedServiceInstanceName = "service-instance-name"
    34  		fakeOrgName                  = "fake-org-name"
    35  		fakeSpaceName                = "fake-space-name"
    36  		fakeSpaceGUID                = "fake-space-guid"
    37  		requestedPlanName            = "coolPlan"
    38  		requestedOfferingName        = "coolOffering"
    39  	)
    40  
    41  	BeforeEach(func() {
    42  		testUI = ui.NewTestUI(NewBuffer(), NewBuffer(), NewBuffer())
    43  		fakeConfig = new(commandfakes.FakeConfig)
    44  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    45  		fakeActor = new(v7fakes.FakeActor)
    46  
    47  		cmd = v7.CreateServiceCommand{
    48  			BaseCommand: v7.BaseCommand{
    49  				UI:          testUI,
    50  				Config:      fakeConfig,
    51  				SharedActor: fakeSharedActor,
    52  				Actor:       fakeActor,
    53  			},
    54  		}
    55  
    56  		setPositionalFlags(&cmd, requestedOfferingName, requestedPlanName, requestedServiceInstanceName)
    57  	})
    58  
    59  	JustBeforeEach(func() {
    60  		executeErr = cmd.Execute(nil)
    61  	})
    62  
    63  	It("checks the user is logged in, and targeting an org and space", func() {
    64  		Expect(executeErr).NotTo(HaveOccurred())
    65  
    66  		Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
    67  		org, space := fakeSharedActor.CheckTargetArgsForCall(0)
    68  		Expect(org).To(BeTrue())
    69  		Expect(space).To(BeTrue())
    70  	})
    71  
    72  	When("checking the target returns an error", func() {
    73  		BeforeEach(func() {
    74  			fakeSharedActor.CheckTargetReturns(errors.New("explode"))
    75  		})
    76  
    77  		It("returns the error", func() {
    78  			Expect(executeErr).To(MatchError("explode"))
    79  		})
    80  	})
    81  
    82  	When("logged in and targeting a space", func() {
    83  		BeforeEach(func() {
    84  			fakeConfig.TargetedSpaceReturns(configv3.Space{
    85  				Name: fakeSpaceName,
    86  				GUID: fakeSpaceGUID,
    87  			})
    88  
    89  			fakeConfig.TargetedOrganizationReturns(configv3.Organization{
    90  				Name: fakeOrgName,
    91  			})
    92  
    93  			fakeActor.GetCurrentUserReturns(configv3.User{Name: fakeUserName}, nil)
    94  		})
    95  
    96  		It("calls the actor with the right arguments", func() {
    97  			Expect(fakeActor.CreateManagedServiceInstanceCallCount()).To(Equal(1))
    98  			params := fakeActor.CreateManagedServiceInstanceArgsForCall(0)
    99  			Expect(params.ServicePlanName).To(Equal(requestedPlanName))
   100  			Expect(params.ServiceOfferingName).To(Equal(requestedOfferingName))
   101  			Expect(params.ServiceBrokerName).To(BeEmpty())
   102  			Expect(params.ServiceInstanceName).To(Equal(requestedServiceInstanceName))
   103  			Expect(params.SpaceGUID).To(Equal(fakeSpaceGUID))
   104  		})
   105  
   106  		When("requesting from a specific broker", func() {
   107  			var requestedBrokerName string
   108  
   109  			BeforeEach(func() {
   110  				requestedBrokerName = "aCoolBroker"
   111  				setFlag(&cmd, "-b", requestedBrokerName)
   112  			})
   113  
   114  			It("passes the right parameters to the actor", func() {
   115  				Expect(executeErr).To(Not(HaveOccurred()))
   116  
   117  				Expect(fakeActor.CreateManagedServiceInstanceCallCount()).To(Equal(1))
   118  				params := fakeActor.CreateManagedServiceInstanceArgsForCall(0)
   119  				Expect(params.ServicePlanName).To(Equal(requestedPlanName))
   120  				Expect(params.ServiceOfferingName).To(Equal(requestedOfferingName))
   121  				Expect(params.ServiceBrokerName).To(Equal(requestedBrokerName))
   122  				Expect(params.ServiceInstanceName).To(Equal(requestedServiceInstanceName))
   123  				Expect(params.SpaceGUID).To(Equal(fakeSpaceGUID))
   124  			})
   125  		})
   126  
   127  		When("there are user provided tags", func() {
   128  			var requestedTags types.OptionalStringSlice
   129  
   130  			BeforeEach(func() {
   131  				requestedTags = types.NewOptionalStringSlice("tag-1", "tag-2")
   132  				setFlag(&cmd, "-t", requestedTags)
   133  			})
   134  
   135  			It("passes the right parameters to the actor", func() {
   136  				Expect(executeErr).To(Not(HaveOccurred()))
   137  
   138  				Expect(fakeActor.CreateManagedServiceInstanceCallCount()).To(Equal(1))
   139  				params := fakeActor.CreateManagedServiceInstanceArgsForCall(0)
   140  				Expect(params.ServicePlanName).To(Equal(requestedPlanName))
   141  				Expect(params.ServiceOfferingName).To(Equal(requestedOfferingName))
   142  				Expect(params.ServiceInstanceName).To(Equal(requestedServiceInstanceName))
   143  				Expect(params.SpaceGUID).To(Equal(fakeSpaceGUID))
   144  				Expect(params.Tags).To(Equal(requestedTags))
   145  
   146  			})
   147  		})
   148  
   149  		When("there are parameters", func() {
   150  			var requestedParams map[string]interface{}
   151  
   152  			BeforeEach(func() {
   153  				requestedParams = map[string]interface{}{"param-1": "value-1", "param-2": "value-2"}
   154  				setFlag(&cmd, "-c", types.NewOptionalObject(requestedParams))
   155  			})
   156  
   157  			It("passes the right parameters to the actor", func() {
   158  				Expect(executeErr).To(Not(HaveOccurred()))
   159  
   160  				Expect(fakeActor.CreateManagedServiceInstanceCallCount()).To(Equal(1))
   161  				params := fakeActor.CreateManagedServiceInstanceArgsForCall(0)
   162  				Expect(params.ServicePlanName).To(Equal(requestedPlanName))
   163  				Expect(params.ServiceOfferingName).To(Equal(requestedOfferingName))
   164  				Expect(params.ServiceInstanceName).To(Equal(requestedServiceInstanceName))
   165  				Expect(params.SpaceGUID).To(Equal(fakeSpaceGUID))
   166  				Expect(params.Parameters).To(Equal(types.NewOptionalObject(requestedParams)))
   167  
   168  			})
   169  		})
   170  
   171  		When("actor responds synchronously", func() {
   172  			BeforeEach(func() {
   173  				fakeActor.CreateManagedServiceInstanceReturns(
   174  					nil,
   175  					v7action.Warnings{"a warning"},
   176  					nil,
   177  				)
   178  			})
   179  
   180  			It("prints a message and warnings", func() {
   181  				Expect(testUI.Out).To(SatisfyAll(
   182  					Say(`Creating service instance %s in org %s / space %s as %s\.\.\.\n`, requestedServiceInstanceName, fakeOrgName, fakeSpaceName, fakeUserName),
   183  					Say(`\n`),
   184  					Say(`Service instance %s created\.\n`, requestedServiceInstanceName),
   185  					Say(`OK`),
   186  				))
   187  
   188  				Expect(testUI.Err).To(Say("a warning"))
   189  			})
   190  		})
   191  
   192  		When("actor responds asynchronously", func() {
   193  			BeforeEach(func() {
   194  				fakeStream := make(chan v7action.PollJobEvent)
   195  				fakeActor.CreateManagedServiceInstanceReturns(
   196  					fakeStream,
   197  					v7action.Warnings{"a warning"},
   198  					nil,
   199  				)
   200  
   201  				go func() {
   202  					fakeStream <- v7action.PollJobEvent{
   203  						State:    v7action.JobPolling,
   204  						Warnings: v7action.Warnings{"stream warning"},
   205  					}
   206  				}()
   207  			})
   208  
   209  			It("prints a message and warnings", func() {
   210  				Expect(testUI.Out).To(SatisfyAll(
   211  					Say(`Creating service instance %s in org %s / space %s as %s\.\.\.\n`, requestedServiceInstanceName, fakeOrgName, fakeSpaceName, fakeUserName),
   212  					Say(`\n`),
   213  					Say(`Create in progress. Use 'cf services' or 'cf service %s' to check operation status\.\n`, requestedServiceInstanceName),
   214  					Say(`OK`),
   215  				))
   216  
   217  				Expect(testUI.Err).To(SatisfyAll(
   218  					Say("a warning"),
   219  					Say("stream warning"),
   220  				))
   221  			})
   222  		})
   223  
   224  		When("error in event stream", func() {
   225  			BeforeEach(func() {
   226  				fakeStream := make(chan v7action.PollJobEvent)
   227  				fakeActor.CreateManagedServiceInstanceReturns(
   228  					fakeStream,
   229  					v7action.Warnings{"a warning"},
   230  					nil,
   231  				)
   232  
   233  				go func() {
   234  					fakeStream <- v7action.PollJobEvent{
   235  						State:    v7action.JobFailed,
   236  						Warnings: v7action.Warnings{"stream warning"},
   237  						Err:      errors.New("bad thing"),
   238  					}
   239  				}()
   240  			})
   241  
   242  			It("returns the error and prints warnings", func() {
   243  				Expect(executeErr).To(MatchError("bad thing"))
   244  
   245  				Expect(testUI.Err).To(SatisfyAll(
   246  					Say("a warning"),
   247  					Say("stream warning"),
   248  				))
   249  			})
   250  		})
   251  
   252  		When("the --wait flag is specified", func() {
   253  			BeforeEach(func() {
   254  				setFlag(&cmd, "--wait")
   255  
   256  				fakeStream := make(chan v7action.PollJobEvent)
   257  				fakeActor.CreateManagedServiceInstanceReturns(
   258  					fakeStream,
   259  					v7action.Warnings{"a warning"},
   260  					nil,
   261  				)
   262  
   263  				go func() {
   264  					fakeStream <- v7action.PollJobEvent{
   265  						State:    v7action.JobPolling,
   266  						Warnings: v7action.Warnings{"poll warning"},
   267  					}
   268  					fakeStream <- v7action.PollJobEvent{
   269  						State:    v7action.JobComplete,
   270  						Warnings: v7action.Warnings{"complete warning"},
   271  					}
   272  					close(fakeStream)
   273  				}()
   274  			})
   275  
   276  			It("prints a message and warnings", func() {
   277  				Expect(testUI.Out).To(SatisfyAll(
   278  					Say(`Creating service instance %s in org %s / space %s as %s\.\.\.\n`, requestedServiceInstanceName, fakeOrgName, fakeSpaceName, fakeUserName),
   279  					Say(`\n`),
   280  					Say(`Waiting for the operation to complete\.\.\n`),
   281  					Say(`\n`),
   282  					Say(`Service instance %s created\.\n`, requestedServiceInstanceName),
   283  					Say(`OK\n`),
   284  				))
   285  
   286  				Expect(testUI.Err).To(SatisfyAll(
   287  					Say("poll warning"),
   288  					Say("complete warning"),
   289  				))
   290  			})
   291  		})
   292  
   293  		When("getting the user fails", func() {
   294  			BeforeEach(func() {
   295  				fakeActor.GetCurrentUserReturns(configv3.User{Name: fakeUserName}, errors.New("boom"))
   296  			})
   297  
   298  			It("returns the error", func() {
   299  				Expect(executeErr).To(MatchError("boom"))
   300  			})
   301  		})
   302  
   303  		When("client returns an error", func() {
   304  			BeforeEach(func() {
   305  				expectedError = actionerror.ServicePlanNotFoundError{PlanName: requestedPlanName}
   306  				fakeActor.CreateManagedServiceInstanceReturns(
   307  					nil,
   308  					v7action.Warnings{"warning one", "warning two"},
   309  					expectedError,
   310  				)
   311  			})
   312  
   313  			It("returns the error", func() {
   314  				Expect(executeErr).To(HaveOccurred())
   315  
   316  				Expect(executeErr).To(MatchError(expectedError))
   317  			})
   318  
   319  			It("prints warnings", func() {
   320  				Expect(testUI.Out).NotTo(Say("OK"))
   321  
   322  				Expect(testUI.Err).To(SatisfyAll(
   323  					Say("warning one"),
   324  					Say("warning two"),
   325  				))
   326  			})
   327  
   328  			When("the service instance name is taken", func() {
   329  				BeforeEach(func() {
   330  					fakeActor.CreateManagedServiceInstanceReturns(
   331  						nil,
   332  						[]string{"a-warning", "another-warning"},
   333  						ccerror.ServiceInstanceNameTakenError{},
   334  					)
   335  				})
   336  
   337  				It("succeeds, displaying warnings, 'OK' and an informative message", func() {
   338  					Expect(executeErr).NotTo(HaveOccurred())
   339  
   340  					Expect(testUI.Err).To(Say("a-warning"))
   341  					Expect(testUI.Err).To(Say("another-warning"))
   342  					Expect(testUI.Out).To(Say("OK"))
   343  					Expect(testUI.Out).To(Say("Service instance %s already exists", requestedServiceInstanceName))
   344  				})
   345  			})
   346  		})
   347  	})
   348  })