From 48b0c24b3dd379c92a78abb88e24ff7adf9cf1f0 Mon Sep 17 00:00:00 2001 From: Jen Spinney Date: Mon, 11 Dec 2017 12:31:17 +0000 Subject: [PATCH 1/3] Ask user for confirmation before unsharing a service instance [#153379362] Signed-off-by: Denise Yu --- command/v3/v3_delete_command_test.go | 2 +- command/v3/v3_unshare_service_command.go | 18 ++ command/v3/v3_unshare_service_command_test.go | 292 +++++++++++++----- .../v3_unshare_service_command_test.go | 98 +++++- 4 files changed, 312 insertions(+), 98 deletions(-) diff --git a/command/v3/v3_delete_command_test.go b/command/v3/v3_delete_command_test.go index d05a936ba31..f97ba9df9e5 100644 --- a/command/v3/v3_delete_command_test.go +++ b/command/v3/v3_delete_command_test.go @@ -127,7 +127,7 @@ var _ = Describe("v3-delete Command", func() { fakeActor.DeleteApplicationByNameAndSpaceReturns(v3action.Warnings{"some-warning"}, nil) }) - It("deletes the space", func() { + It("deletes the app", func() { Expect(executeErr).ToNot(HaveOccurred()) Expect(testUI.Err).To(Say("some-warning")) diff --git a/command/v3/v3_unshare_service_command.go b/command/v3/v3_unshare_service_command.go index 966fdad3a5a..390e3bec3d4 100644 --- a/command/v3/v3_unshare_service_command.go +++ b/command/v3/v3_unshare_service_command.go @@ -32,6 +32,7 @@ type V3UnshareServiceCommand struct { RequiredArgs flag.ServiceInstance `positional-args:"yes"` OrgName string `short:"o" required:"false" description:"Org of the other space (Default: targeted org)"` SpaceName string `short:"s" required:"true" description:"Space to unshare the service instance from"` + Force bool `short:"f" description:"Force unshare without confirmation"` usage interface{} `usage:"cf v3-unshare-service SERVICE_INSTANCE -s OTHER_SPACE [-o OTHER_ORG]"` relatedCommands interface{} `related_commands:"bind-service, service, services"` @@ -90,6 +91,23 @@ func (cmd V3UnshareServiceCommand) Execute(args []string) error { orgName = cmd.OrgName } + cmd.UI.DisplayWarning("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.\n") + + if !cmd.Force { + response, promptErr := cmd.UI.DisplayBoolPrompt(false, "Really unshare the service instance?", map[string]interface{}{ + "ServiceInstanceName": cmd.RequiredArgs.ServiceInstance, + }) + + if promptErr != nil { + return promptErr + } + + if !response { + cmd.UI.DisplayText("Unshare cancelled") + return nil + } + } + cmd.UI.DisplayTextWithFlavor("Unsharing service instance {{.ServiceInstanceName}} from org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{ "ServiceInstanceName": cmd.RequiredArgs.ServiceInstance, "OrgName": orgName, diff --git a/command/v3/v3_unshare_service_command_test.go b/command/v3/v3_unshare_service_command_test.go index 1349454ab73..c3af63e514e 100644 --- a/command/v3/v3_unshare_service_command_test.go +++ b/command/v3/v3_unshare_service_command_test.go @@ -25,13 +25,15 @@ var _ = Describe("unshare-service Command", func() { fakeConfig *commandfakes.FakeConfig fakeSharedActor *commandfakes.FakeSharedActor fakeActor *v3fakes.FakeUnshareServiceActor + input *Buffer fakeActorV2 *v3fakes.FakeServiceInstanceSharedToActorV2 binaryName string executeErr error ) BeforeEach(func() { - testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer()) + input = NewBuffer() + testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer()) fakeConfig = new(commandfakes.FakeConfig) fakeSharedActor = new(commandfakes.FakeSharedActor) fakeActor = new(v3fakes.FakeUnshareServiceActor) @@ -118,131 +120,251 @@ var _ = Describe("unshare-service Command", func() { nil) }) - Context("when looking up the shared-to space guid returns an error", func() { + Context("when the -f flag is provided", func() { BeforeEach(func() { - fakeActorV2.GetSharedToSpaceGUIDReturns( - "", - v2action.Warnings{"get-shared-to-space-guid-warning"}, - errors.New("an error")) + cmd.Force = true }) - It("returns the error and displays all warnings", func() { - Expect(executeErr).To(MatchError("an error")) - Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) + Context("when using the currently targeted org", func() { + BeforeEach(func() { + cmd.SpaceName = "some-shared-to-space" + }) + + Context("when looking up the shared-to space guid succeeds", func() { + BeforeEach(func() { + fakeActorV2.GetSharedToSpaceGUIDReturns( + "shared-to-space-guid", + v2action.Warnings{"get-shared-to-space-guid-warning"}, + nil) + + }) + + It("calls GetSharedToSpaceGUID with the correct parameters", func() { + Expect(fakeActorV2.GetSharedToSpaceGUIDCallCount()).To(Equal(1)) + serviceInstanceNameArg, sourceSpaceGUIDArg, sharedToOrgNameArg, sharedToSpaceNameArg := fakeActorV2.GetSharedToSpaceGUIDArgsForCall(0) + Expect(serviceInstanceNameArg).To(Equal("some-service-instance")) + Expect(sourceSpaceGUIDArg).To(Equal("some-space-guid")) + Expect(sharedToOrgNameArg).To(Equal("some-org")) + Expect(sharedToSpaceNameArg).To(Equal("some-shared-to-space")) + }) + + Context("when the unsharing is successful", func() { + BeforeEach(func() { + fakeActor.UnshareServiceInstanceFromSpaceReturns( + v3action.Warnings{"unshare-service-warning"}, + nil) + }) + + It("unshares the service instance with the provided space and displays all warnings", func() { + Expect(executeErr).ToNot(HaveOccurred()) + + Expect(testUI.Err).To(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) + Expect(testUI.Out).To(Say("Unsharing service instance some-service-instance from org some-org / space some-shared-to-space as some-user\\.\\.\\.")) + Expect(testUI.Out).To(Say("OK")) + Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) + Expect(testUI.Err).To(Say("unshare-service-warning")) + + Expect(fakeActor.UnshareServiceInstanceFromSpaceCallCount()).To(Equal(1)) + serviceInstanceNameArg, sourceSpaceGUID, sharedToSpaceGUID := fakeActor.UnshareServiceInstanceFromSpaceArgsForCall(0) + Expect(serviceInstanceNameArg).To(Equal("some-service-instance")) + Expect(sourceSpaceGUID).To(Equal("some-space-guid")) + Expect(sharedToSpaceGUID).To(Equal("shared-to-space-guid")) + }) + }) + + Context("when the unsharing is unsuccessful", func() { + BeforeEach(func() { + fakeActor.UnshareServiceInstanceFromSpaceReturns( + v3action.Warnings{"unshare-service-warning"}, + errors.New("unsharing failed")) + }) + + It("does not unshare the service instance with the provided space and displays all warnings", func() { + Expect(executeErr).To(MatchError("unsharing failed")) + + Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) + Expect(testUI.Err).To(Say("unshare-service-warning")) + }) + }) + + }) + + Context("when looking up the shared-to space guid returns an error", func() { + BeforeEach(func() { + fakeActorV2.GetSharedToSpaceGUIDReturns( + "", + v2action.Warnings{"get-shared-to-space-guid-warning"}, + errors.New("an error")) + }) + + It("returns the error and displays all warnings", func() { + Expect(executeErr).To(MatchError("an error")) + Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) + }) + }) }) - }) - Context("when using the currently targeted org", func() { - BeforeEach(func() { - cmd.SpaceName = "some-space" - fakeActorV2.GetSharedToSpaceGUIDReturns( - "shared-to-space-guid", - v2action.Warnings{"get-shared-to-space-guid-warning"}, - nil) + Context("when using a specified org", func() { + BeforeEach(func() { + cmd.Force = true + cmd.SpaceName = "some-space" + cmd.OrgName = "some-other-org" + }) + + Context("when looking up the shared-to space guid succeeds", func() { + BeforeEach(func() { + fakeActorV2.GetSharedToSpaceGUIDReturns( + "shared-to-space-guid", + v2action.Warnings{"get-shared-to-space-guid-warning"}, + nil) + + }) + + It("calls GetSharedToSpaceGUID with the correct parameters", func() { + Expect(fakeActorV2.GetSharedToSpaceGUIDCallCount()).To(Equal(1)) + serviceInstanceNameArg, sourceSpaceGUIDArg, sharedToOrgNameArg, sharedToSpaceNameArg := fakeActorV2.GetSharedToSpaceGUIDArgsForCall(0) + Expect(serviceInstanceNameArg).To(Equal("some-service-instance")) + Expect(sourceSpaceGUIDArg).To(Equal("some-space-guid")) + Expect(sharedToOrgNameArg).To(Equal("some-other-org")) + Expect(sharedToSpaceNameArg).To(Equal("some-space")) + }) + + Context("when the unsharing is successful", func() { + BeforeEach(func() { + fakeActor.UnshareServiceInstanceFromSpaceReturns( + v3action.Warnings{"unshare-service-warning"}, + nil) + }) + + It("unshares the service instance with the provided space and org and displays all warnings", func() { + Expect(executeErr).ToNot(HaveOccurred()) + + Expect(testUI.Out).To(Say("Unsharing service instance some-service-instance from org some-other-org / space some-space as some-user\\.\\.\\.")) + Expect(testUI.Out).To(Say("OK")) + Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) + Expect(testUI.Err).To(Say("unshare-service-warning")) + + Expect(fakeActor.UnshareServiceInstanceFromSpaceCallCount()).To(Equal(1)) + serviceInstanceNameArg, sourceSpaceGUID, sharedToSpaceGUID := fakeActor.UnshareServiceInstanceFromSpaceArgsForCall(0) + Expect(serviceInstanceNameArg).To(Equal("some-service-instance")) + Expect(sourceSpaceGUID).To(Equal("some-space-guid")) + Expect(sharedToSpaceGUID).To(Equal("shared-to-space-guid")) + }) + }) + + Context("when the unsharing is unsuccessful", func() { + BeforeEach(func() { + fakeActor.UnshareServiceInstanceFromSpaceReturns( + v3action.Warnings{"unshare-service-warning"}, + errors.New("unsharing failed")) + }) + + It("does not unshare the service instance from the provided space and displays all warnings", func() { + Expect(executeErr).To(MatchError("unsharing failed")) + + Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) + Expect(testUI.Err).To(Say("unshare-service-warning")) + }) + }) + }) + + Context("when looking up the shared-to space guid returns an error", func() { + BeforeEach(func() { + fakeActorV2.GetSharedToSpaceGUIDReturns( + "", + v2action.Warnings{"get-shared-to-space-guid-warning"}, + errors.New("an error")) + }) + + It("returns the error and displays all warnings", func() { + Expect(executeErr).To(MatchError("an error")) + Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) + }) + }) + }) + }) - It("calls GetSharedToSpaceGUID with the correct parameters", func() { - Expect(fakeActorV2.GetSharedToSpaceGUIDCallCount()).To(Equal(1)) - serviceInstanceNameArg, sourceSpaceGUIDArg, sharedToOrgNameArg, sharedToSpaceNameArg := fakeActorV2.GetSharedToSpaceGUIDArgsForCall(0) - Expect(serviceInstanceNameArg).To(Equal("some-service-instance")) - Expect(sourceSpaceGUIDArg).To(Equal("some-space-guid")) - Expect(sharedToOrgNameArg).To(Equal("some-org")) - Expect(sharedToSpaceNameArg).To(Equal("some-space")) + Context("when the -f flag is NOT provided", func() { + BeforeEach(func() { + cmd.Force = false + cmd.SpaceName = "some-shared-to-space" }) - Context("when the unsharing is successful", func() { + Context("when the user inputs yes", func() { BeforeEach(func() { + _, err := input.Write([]byte("y\n")) + Expect(err).ToNot(HaveOccurred()) + fakeActor.UnshareServiceInstanceFromSpaceReturns( v3action.Warnings{"unshare-service-warning"}, nil) + + fakeActorV2.GetSharedToSpaceGUIDReturns( + "shared-to-space-guid", + v2action.Warnings{"get-shared-to-space-guid-warning"}, + nil) }) - It("unshares the service instance with the provided space and displays all warnings", func() { + It("unshares the service instance", func() { Expect(executeErr).ToNot(HaveOccurred()) - Expect(testUI.Out).To(Say("Unsharing service instance some-service-instance from org some-org / space some-space as some-user\\.\\.\\.")) - Expect(testUI.Out).To(Say("OK")) + Expect(testUI.Err).To(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) Expect(testUI.Err).To(Say("unshare-service-warning")) - - Expect(fakeActor.UnshareServiceInstanceFromSpaceCallCount()).To(Equal(1)) - serviceInstanceNameArg, sourceSpaceGUIDArg, sharedToSpaceGUIDArg := fakeActor.UnshareServiceInstanceFromSpaceArgsForCall(0) - Expect(serviceInstanceNameArg).To(Equal("some-service-instance")) - Expect(sourceSpaceGUIDArg).To(Equal("some-space-guid")) - Expect(sharedToSpaceGUIDArg).To(Equal("shared-to-space-guid")) + Expect(testUI.Out).To(Say("Really unshare the service instance\\? \\[yN\\]")) + Expect(testUI.Out).To(Say("Unsharing service instance some-service-instance from org some-org / space some-shared-to-space as some-user\\.\\.\\.")) + Expect(testUI.Out).To(Say("OK")) }) }) - Context("when the unsharing is unsuccessful", func() { + Context("when the user inputs no", func() { BeforeEach(func() { - fakeActor.UnshareServiceInstanceFromSpaceReturns( - v3action.Warnings{"unshare-service-warning"}, - errors.New("unsharing failed")) + _, err := input.Write([]byte("n\n")) + Expect(err).ToNot(HaveOccurred()) }) - It("does not unshare the service instance with the provided space and displays all warnings", func() { - Expect(executeErr).To(MatchError("unsharing failed")) + It("cancels the delete", func() { + Expect(executeErr).ToNot(HaveOccurred()) - Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) - Expect(testUI.Err).To(Say("unshare-service-warning")) + Expect(testUI.Err).To(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) + Expect(testUI.Out).To(Say("Really unshare the service instance\\? \\[yN\\]")) + Expect(testUI.Out).To(Say("Unshare cancelled")) + Expect(fakeActor.UnshareServiceInstanceFromSpaceCallCount()).To(Equal(0)) }) }) - }) - - Context("when using a specified org", func() { - BeforeEach(func() { - cmd.SpaceName = "some-space" - cmd.OrgName = "some-other-org" - fakeActorV2.GetSharedToSpaceGUIDReturns( - "shared-to-space-guid", - v2action.Warnings{"get-shared-to-space-guid-warning"}, - nil) - }) - It("calls GetSharedToSpaceGUID with the correct parameters", func() { - Expect(fakeActorV2.GetSharedToSpaceGUIDCallCount()).To(Equal(1)) - serviceInstanceNameArg, sourceSpaceGUIDArg, sharedToOrgNameArg, sharedToSpaceNameArg := fakeActorV2.GetSharedToSpaceGUIDArgsForCall(0) - Expect(serviceInstanceNameArg).To(Equal("some-service-instance")) - Expect(sourceSpaceGUIDArg).To(Equal("some-space-guid")) - Expect(sharedToOrgNameArg).To(Equal("some-other-org")) - Expect(sharedToSpaceNameArg).To(Equal("some-space")) - }) - - Context("when the unsharing is successful", func() { + Context("when the user chooses the default", func() { BeforeEach(func() { - fakeActor.UnshareServiceInstanceFromSpaceReturns( - v3action.Warnings{"unshare-service-warning"}, - nil) + _, err := input.Write([]byte("\n")) + Expect(err).ToNot(HaveOccurred()) }) - It("unshares the service instance with the provided space and org and displays all warnings", func() { + It("cancels the delete", func() { Expect(executeErr).ToNot(HaveOccurred()) - Expect(testUI.Out).To(Say("Unsharing service instance some-service-instance from org some-other-org / space some-space as some-user\\.\\.\\.")) - Expect(testUI.Out).To(Say("OK")) - Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) - Expect(testUI.Err).To(Say("unshare-service-warning")) - - Expect(fakeActor.UnshareServiceInstanceFromSpaceCallCount()).To(Equal(1)) - serviceInstanceNameArg, sourceSpaceGUID, sharedToSpaceGUID := fakeActor.UnshareServiceInstanceFromSpaceArgsForCall(0) - Expect(serviceInstanceNameArg).To(Equal("some-service-instance")) - Expect(sourceSpaceGUID).To(Equal("some-space-guid")) - Expect(sharedToSpaceGUID).To(Equal("shared-to-space-guid")) + Expect(testUI.Err).To(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) + Expect(testUI.Out).To(Say("Really unshare the service instance\\? \\[yN\\]")) + Expect(testUI.Out).To(Say("Unshare cancelled")) + Expect(fakeActor.UnshareServiceInstanceFromSpaceCallCount()).To(Equal(0)) }) }) - Context("when the unsharing is unsuccessful", func() { + Context("when the user input is invalid", func() { BeforeEach(func() { - fakeActor.UnshareServiceInstanceFromSpaceReturns( - v3action.Warnings{"unshare-service-warning"}, - errors.New("unsharing failed")) + _, err := input.Write([]byte("e\n\n")) + Expect(err).ToNot(HaveOccurred()) }) - It("does not unshare the service instance from the provided space and displays all warnings", func() { - Expect(executeErr).To(MatchError("unsharing failed")) + It("asks the user again", func() { + Expect(executeErr).NotTo(HaveOccurred()) - Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) - Expect(testUI.Err).To(Say("unshare-service-warning")) + Expect(testUI.Err).To(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) + Expect(testUI.Out).To(Say("Really unshare the service instance\\? \\[yN\\]")) + Expect(testUI.Out).To(Say("invalid input \\(not y, n, yes, or no\\)")) + Expect(testUI.Out).To(Say("Really unshare the service instance\\? \\[yN\\]")) + + Expect(fakeActor.UnshareServiceInstanceFromSpaceCallCount()).To(Equal(0)) }) }) }) diff --git a/integration/experimental/v3_unshare_service_command_test.go b/integration/experimental/v3_unshare_service_command_test.go index 8b0d38df832..5753cc0fb05 100644 --- a/integration/experimental/v3_unshare_service_command_test.go +++ b/integration/experimental/v3_unshare_service_command_test.go @@ -210,7 +210,7 @@ var _ = Describe("v3-unshare-service command", func() { Context("when a service instance has not been shared to a space", func() { It("returns an error on an attempt to unshare it from that space", func() { - session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) + session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName, "-f") Eventually(session).Should(Say("FAILED")) Eventually(session.Err).Should(Say("Failed to unshare service instance '%s'. Ensure the space and specified org exist and that the service instance has been shared to this space.", serviceInstance)) Eventually(session).Should(Exit(1)) @@ -225,7 +225,7 @@ var _ = Describe("v3-unshare-service command", func() { Context("when the org I want to unshare from does not exist", func() { It("fails with an org not found error", func() { - session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", "missing-org") + session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", "missing-org", "-f") Eventually(session).Should(Say("FAILED")) Eventually(session.Err).Should(Say("Failed to unshare service instance '%s'. Ensure the space and specified org exist and that the service instance has been shared to this space.", serviceInstance)) Eventually(session).Should(Exit(1)) @@ -234,7 +234,7 @@ var _ = Describe("v3-unshare-service command", func() { Context("when the space I want to unshare from does not exist", func() { It("fails with a space not found error", func() { - session := helpers.CF("v3-unshare-service", serviceInstance, "-s", "missing-space", "-o", sharedToOrgName) + session := helpers.CF("v3-unshare-service", serviceInstance, "-s", "missing-space", "-o", sharedToOrgName, "-f") Eventually(session).Should(Say("FAILED")) Eventually(session.Err).Should(Say("Failed to unshare service instance '%s'. Ensure the space and specified org exist and that the service instance has been shared to this space.", serviceInstance)) Eventually(session).Should(Exit(1)) @@ -243,7 +243,7 @@ var _ = Describe("v3-unshare-service command", func() { Context("when I want to unshare my service instance from a space and org", func() { It("successfully unshares the service instance", func() { - session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) + session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName, "-f") Eventually(session).Should(Say("OK")) Eventually(session).Should(Exit(0)) }) @@ -260,7 +260,7 @@ var _ = Describe("v3-unshare-service command", func() { Context("when the space I want to unshare from does not exist", func() { It("fails with a space not found error", func() { - session := helpers.CF("v3-unshare-service", serviceInstance, "-s", "missing-space") + session := helpers.CF("v3-unshare-service", serviceInstance, "-s", "missing-space", "-f") Eventually(session).Should(Say("FAILED")) Eventually(session.Err).Should(Say("Failed to unshare service instance '%s'. Ensure the space and specified org exist and that the service instance has been shared to this space.", serviceInstance)) Eventually(session).Should(Exit(1)) @@ -269,7 +269,7 @@ var _ = Describe("v3-unshare-service command", func() { Context("when I want to unshare my service instance from the space", func() { It("successfully unshares the service instance when I am admin", func() { - session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName) + session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName, "-f") Eventually(session).Should(Say("OK")) Eventually(session).Should(Exit(0)) }) @@ -298,7 +298,7 @@ var _ = Describe("v3-unshare-service command", func() { }) It("successfully unshares the service instance", func() { - session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName) + session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName, "-f") Eventually(session).Should(Say("OK")) Eventually(session).Should(Exit(0)) }) @@ -308,11 +308,85 @@ var _ = Describe("v3-unshare-service command", func() { }) Context("when the service instance does not exist", func() { - It("fails with a service instance not found error", func() { - session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName) - Eventually(session).Should(Say("FAILED")) - Eventually(session.Err).Should(Say("Service instance %s not found", serviceInstance)) - Eventually(session).Should(Exit(1)) + Context("when the -f flag is provided", func() { + It("fails with a service instance not found error", func() { + session := helpers.CF("v3-unshare-service", serviceInstance, "-s", sharedToSpaceName, "-f") + Eventually(session).Should(Say("FAILED")) + Eventually(session.Err).Should(Say("Service instance %s not found", serviceInstance)) + Eventually(session).Should(Exit(1)) + }) + }) + + Context("when the -f flag not is provided", func() { + var buffer *Buffer + + BeforeEach(func() { + buffer = NewBuffer() + }) + + Context("when the user enters 'y'", func() { + BeforeEach(func() { + buffer.Write([]byte("y\n")) + }) + + It("fails with a service instance not found error", func() { + username, _ := helpers.GetCredentials() + session := helpers.CFWithStdin(buffer, "v3-unshare-service", serviceInstance, "-s", sharedToSpaceName) + Eventually(session.Err).Should(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) + Eventually(session.Out).Should(Say("Really unshare the service instance\\? \\[yN\\]")) + Eventually(session.Out).Should(Say("Unsharing service instance %s from org %s / space %s as %s...", serviceInstance, sourceOrgName, sharedToSpaceName, username)) + Eventually(session.Out).Should(Say("FAILED")) + Eventually(session.Err).Should(Say("Service instance %s not found", serviceInstance)) + Eventually(session).Should(Exit(1)) + }) + }) + + Context("when the user enters 'n'", func() { + BeforeEach(func() { + buffer.Write([]byte("n\n")) + }) + + It("does not attempt to unshare", func() { + session := helpers.CFWithStdin(buffer, "v3-unshare-service", serviceInstance, "-s", sharedToSpaceName) + Eventually(session.Err).Should(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) + Eventually(session.Out).Should(Say("Really unshare the service instance\\? \\[yN\\]")) + Eventually(session.Out).Should(Say("Unshare cancelled")) + Eventually(session).Should(Exit(0)) + }) + }) + + Context("when the user enters the default input (hits return)", func() { + BeforeEach(func() { + buffer.Write([]byte("\n")) + }) + + It("does not attempt to unshare", func() { + session := helpers.CFWithStdin(buffer, "v3-unshare-service", serviceInstance, "-s", sharedToSpaceName) + Eventually(session.Err).Should(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) + Eventually(session.Out).Should(Say("Really unshare the service instance\\? \\[yN\\]")) + Eventually(session.Out).Should(Say("Unshare cancelled")) + Eventually(session).Should(Exit(0)) + }) + }) + + Context("when the user enters an invalid answer", func() { + BeforeEach(func() { + // The second '\n' is intentional. Otherwise the buffer will be + // closed while the interaction is still waiting for input; it gets + // an EOF and causes an error. + buffer.Write([]byte("wat\n\n")) + }) + + It("asks again", func() { + session := helpers.CFWithStdin(buffer, "v3-unshare-service", serviceInstance, "-s", sharedToSpaceName) + Eventually(session.Err).Should(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) + Eventually(session.Out).Should(Say("Really unshare the service instance\\? \\[yN\\]")) + Eventually(session.Out).Should(Say("invalid input \\(not y, n, yes, or no\\)")) + Eventually(session.Out).Should(Say("Really unshare the service instance\\? \\[yN\\]")) + Eventually(session.Out).Should(Say("Unshare cancelled")) + Eventually(session).Should(Exit(0)) + }) + }) }) }) }) From 0effb64af2a059c4ffca6ccd30635e9371c883aa Mon Sep 17 00:00:00 2001 From: Denise Yu Date: Tue, 12 Dec 2017 10:40:50 +0000 Subject: [PATCH 2/3] Don't display warning if unshare with force flag [#153379362] Signed-off-by: Alex Blease --- command/v3/v3_unshare_service_command.go | 4 ++-- command/v3/v3_unshare_service_command_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/command/v3/v3_unshare_service_command.go b/command/v3/v3_unshare_service_command.go index 390e3bec3d4..bced7dd1356 100644 --- a/command/v3/v3_unshare_service_command.go +++ b/command/v3/v3_unshare_service_command.go @@ -91,9 +91,9 @@ func (cmd V3UnshareServiceCommand) Execute(args []string) error { orgName = cmd.OrgName } - cmd.UI.DisplayWarning("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.\n") - if !cmd.Force { + cmd.UI.DisplayWarning("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.\n") + response, promptErr := cmd.UI.DisplayBoolPrompt(false, "Really unshare the service instance?", map[string]interface{}{ "ServiceInstanceName": cmd.RequiredArgs.ServiceInstance, }) diff --git a/command/v3/v3_unshare_service_command_test.go b/command/v3/v3_unshare_service_command_test.go index c3af63e514e..079449c97a8 100644 --- a/command/v3/v3_unshare_service_command_test.go +++ b/command/v3/v3_unshare_service_command_test.go @@ -158,7 +158,7 @@ var _ = Describe("unshare-service Command", func() { It("unshares the service instance with the provided space and displays all warnings", func() { Expect(executeErr).ToNot(HaveOccurred()) - Expect(testUI.Err).To(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) + Expect(testUI.Err).ToNot(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into. This could cause applications to stop working.")) Expect(testUI.Out).To(Say("Unsharing service instance some-service-instance from org some-org / space some-shared-to-space as some-user\\.\\.\\.")) Expect(testUI.Out).To(Say("OK")) Expect(testUI.Err).To(Say("get-shared-to-space-guid-warning")) From a1a7baea92528ed44732bc71c3d488cdb2a29b6c Mon Sep 17 00:00:00 2001 From: Denise Yu Date: Tue, 12 Dec 2017 10:51:02 +0000 Subject: [PATCH 3/3] Share and Unshare include each other in related commands [#153554513] Signed-off-by: Alex Blease --- command/v3/v3_share_service_command.go | 2 +- command/v3/v3_unshare_service_command.go | 2 +- integration/experimental/v3_share_service_command_test.go | 2 +- integration/experimental/v3_unshare_service_command_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/command/v3/v3_share_service_command.go b/command/v3/v3_share_service_command.go index 58a8bc18ece..3e45e4532c9 100644 --- a/command/v3/v3_share_service_command.go +++ b/command/v3/v3_share_service_command.go @@ -26,7 +26,7 @@ type V3ShareServiceCommand struct { OrgName string `short:"o" required:"false" description:"Org of the other space (Default: targeted org)"` SpaceName string `short:"s" required:"true" description:"Space to share the service instance into"` usage interface{} `usage:"cf v3-share-service SERVICE_INSTANCE -s OTHER_SPACE [-o OTHER_ORG]"` - relatedCommands interface{} `related_commands:"bind-service, service, services"` + relatedCommands interface{} `related_commands:"bind-service, service, services, v3-unshare-service"` UI command.UI Config command.Config diff --git a/command/v3/v3_unshare_service_command.go b/command/v3/v3_unshare_service_command.go index bced7dd1356..64b1be91c45 100644 --- a/command/v3/v3_unshare_service_command.go +++ b/command/v3/v3_unshare_service_command.go @@ -34,7 +34,7 @@ type V3UnshareServiceCommand struct { SpaceName string `short:"s" required:"true" description:"Space to unshare the service instance from"` Force bool `short:"f" description:"Force unshare without confirmation"` usage interface{} `usage:"cf v3-unshare-service SERVICE_INSTANCE -s OTHER_SPACE [-o OTHER_ORG]"` - relatedCommands interface{} `related_commands:"bind-service, service, services"` + relatedCommands interface{} `related_commands:"bind-service, service, services, v3-share-service"` UI command.UI Config command.Config diff --git a/integration/experimental/v3_share_service_command_test.go b/integration/experimental/v3_share_service_command_test.go index 3cbaab58f08..777cb1f7012 100644 --- a/integration/experimental/v3_share_service_command_test.go +++ b/integration/experimental/v3_share_service_command_test.go @@ -44,7 +44,7 @@ var _ = Describe("v3-share-service command", func() { Eventually(session.Out).Should(Say("-o\\s+Org of the other space \\(Default: targeted org\\)")) Eventually(session.Out).Should(Say("-s\\s+Space to share the service instance into")) Eventually(session.Out).Should(Say("SEE ALSO:")) - Eventually(session.Out).Should(Say("bind-service, service, services")) + Eventually(session.Out).Should(Say("bind-service, service, services, v3-unshare-service")) Eventually(session).Should(Exit(0)) }) }) diff --git a/integration/experimental/v3_unshare_service_command_test.go b/integration/experimental/v3_unshare_service_command_test.go index 5753cc0fb05..901a146f2a8 100644 --- a/integration/experimental/v3_unshare_service_command_test.go +++ b/integration/experimental/v3_unshare_service_command_test.go @@ -42,7 +42,7 @@ var _ = Describe("v3-unshare-service command", func() { Eventually(session.Out).Should(Say("-o\\s+Org of the other space \\(Default: targeted org\\)")) Eventually(session.Out).Should(Say("-s\\s+Space to unshare the service instance from")) Eventually(session.Out).Should(Say("SEE ALSO:")) - Eventually(session.Out).Should(Say("bind-service, service, services")) + Eventually(session.Out).Should(Say("bind-service, service, services, v3-share-service")) Eventually(session).Should(Exit(0)) }) })