github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/actor/pluginaction/uninstall_test.go (about)

     1  package pluginaction_test
     2  
     3  import (
     4  	"errors"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  
    10  	. "github.com/liamawhite/cli-with-i18n/actor/pluginaction"
    11  	"github.com/liamawhite/cli-with-i18n/actor/pluginaction/pluginactionfakes"
    12  	"github.com/liamawhite/cli-with-i18n/util/configv3"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  )
    16  
    17  var _ = Describe("Plugin actor", func() {
    18  	var (
    19  		actor      *Actor
    20  		fakeConfig *pluginactionfakes.FakeConfig
    21  	)
    22  
    23  	BeforeEach(func() {
    24  		fakeConfig = new(pluginactionfakes.FakeConfig)
    25  		actor = NewActor(fakeConfig, nil)
    26  	})
    27  
    28  	Describe("UninstallPlugin", func() {
    29  		var (
    30  			binaryPath            string
    31  			fakePluginUninstaller *pluginactionfakes.FakePluginUninstaller
    32  			pluginHome            string
    33  		)
    34  
    35  		BeforeEach(func() {
    36  			var err error
    37  			pluginHome, err = ioutil.TempDir("", "")
    38  			Expect(err).ToNot(HaveOccurred())
    39  
    40  			binaryPath = filepath.Join(pluginHome, "banana-faceman")
    41  			err = ioutil.WriteFile(binaryPath, nil, 0600)
    42  			Expect(err).ToNot(HaveOccurred())
    43  
    44  			fakePluginUninstaller = new(pluginactionfakes.FakePluginUninstaller)
    45  		})
    46  
    47  		AfterEach(func() {
    48  			os.RemoveAll(pluginHome)
    49  		})
    50  
    51  		Context("when the plugin does not exist", func() {
    52  			BeforeEach(func() {
    53  				fakeConfig.GetPluginReturns(configv3.Plugin{}, false)
    54  			})
    55  
    56  			It("returns a PluginNotFoundError", func() {
    57  				err := actor.UninstallPlugin(fakePluginUninstaller, "some-non-existent-plugin")
    58  				Expect(err).To(MatchError(PluginNotFoundError{PluginName: "some-non-existent-plugin"}))
    59  			})
    60  		})
    61  
    62  		Context("when the plugin exists", func() {
    63  			BeforeEach(func() {
    64  				fakeConfig.GetPluginReturns(configv3.Plugin{
    65  					Name:     "some-plugin",
    66  					Location: binaryPath,
    67  				}, true)
    68  			})
    69  
    70  			Context("when no errors are encountered", func() {
    71  				It("runs the plugin cleanup, deletes the binary and removes the plugin config", func() {
    72  					err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
    73  					Expect(err).ToNot(HaveOccurred())
    74  
    75  					Expect(fakeConfig.GetPluginCallCount()).To(Equal(1))
    76  					Expect(fakeConfig.GetPluginArgsForCall(0)).To(Equal("some-plugin"))
    77  
    78  					Expect(fakePluginUninstaller.RunCallCount()).To(Equal(1))
    79  					path, command := fakePluginUninstaller.RunArgsForCall(0)
    80  					Expect(path).To(Equal(binaryPath))
    81  					Expect(command).To(Equal("CLI-MESSAGE-UNINSTALL"))
    82  
    83  					_, err = os.Stat(binaryPath)
    84  					Expect(os.IsNotExist(err)).To(BeTrue())
    85  
    86  					Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
    87  					Expect(fakeConfig.RemovePluginArgsForCall(0)).To(Equal("some-plugin"))
    88  
    89  					Expect(fakeConfig.WritePluginConfigCallCount()).To(Equal(1))
    90  				})
    91  			})
    92  
    93  			Context("when the plugin binary does not exist", func() {
    94  				BeforeEach(func() {
    95  					Expect(os.Remove(binaryPath)).ToNot(HaveOccurred())
    96  				})
    97  
    98  				It("removes the plugin config", func() {
    99  					err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
   100  					Expect(err).ToNot(HaveOccurred())
   101  
   102  					Expect(fakePluginUninstaller.RunCallCount()).To(Equal(0))
   103  
   104  					Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
   105  					Expect(fakeConfig.RemovePluginArgsForCall(0)).To(Equal("some-plugin"))
   106  
   107  					Expect(fakeConfig.WritePluginConfigCallCount()).To(Equal(1))
   108  				})
   109  			})
   110  
   111  			Context("when the plugin uninstaller returns an os.PathError", func() {
   112  				var expectedErr error
   113  
   114  				BeforeEach(func() {
   115  					expectedErr = &os.PathError{}
   116  					fakePluginUninstaller.RunReturns(expectedErr)
   117  				})
   118  
   119  				It("returns a PluginExecuteError, deletes the binary and removes the plugin config", func() {
   120  					err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
   121  					Expect(err).To(MatchError(PluginExecuteError{Err: expectedErr}))
   122  
   123  					_, err = os.Stat(binaryPath)
   124  					Expect(os.IsNotExist(err)).To(BeTrue())
   125  
   126  					Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
   127  					Expect(fakeConfig.WritePluginConfigCallCount()).To(Equal(1))
   128  				})
   129  			})
   130  
   131  			Context("when the plugin uninstaller returns an exec.ExitError", func() {
   132  				var expectedErr error
   133  
   134  				BeforeEach(func() {
   135  					expectedErr = &exec.ExitError{}
   136  					fakePluginUninstaller.RunReturns(expectedErr)
   137  				})
   138  
   139  				It("returns the error, deletes the binary and removes the plugin config", func() {
   140  					err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
   141  					Expect(err).To(MatchError(PluginExecuteError{Err: expectedErr}))
   142  
   143  					_, err = os.Stat(binaryPath)
   144  					Expect(os.IsNotExist(err)).To(BeTrue())
   145  
   146  					Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
   147  					Expect(fakeConfig.WritePluginConfigCallCount()).To(Equal(1))
   148  				})
   149  			})
   150  
   151  			Context("when the plugin uninstaller returns any other error", func() {
   152  				var expectedErr error
   153  
   154  				BeforeEach(func() {
   155  					expectedErr = errors.New("some error")
   156  					fakePluginUninstaller.RunReturns(expectedErr)
   157  				})
   158  
   159  				It("returns the error and does not delete the binary or remove the plugin config", func() {
   160  					err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
   161  					Expect(err).To(MatchError(expectedErr))
   162  
   163  					_, err = os.Stat(binaryPath)
   164  					Expect(err).ToNot(HaveOccurred())
   165  
   166  					Expect(fakeConfig.RemovePluginCallCount()).To(Equal(0))
   167  				})
   168  			})
   169  
   170  			Context("when deleting the plugin binary returns a 'file does not exist' error", func() {
   171  				BeforeEach(func() {
   172  					err := os.Remove(binaryPath)
   173  					Expect(err).ToNot(HaveOccurred())
   174  				})
   175  
   176  				It("does not return the error and removes the plugin config", func() {
   177  					err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
   178  					Expect(err).ToNot(HaveOccurred())
   179  
   180  					Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
   181  				})
   182  			})
   183  
   184  			Context("when deleting the plugin binary returns a path error", func() {
   185  				BeforeEach(func() {
   186  					err := os.Remove(binaryPath)
   187  					Expect(err).ToNot(HaveOccurred())
   188  					err = os.Mkdir(binaryPath, 0700)
   189  					Expect(err).ToNot(HaveOccurred())
   190  					err = ioutil.WriteFile(filepath.Join(binaryPath, "foooooo"), nil, 0500)
   191  					Expect(err).ToNot(HaveOccurred())
   192  				})
   193  
   194  				It("returns the error and removes the plugin config", func() {
   195  					err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
   196  					pluginBinaryRemoveErr, ok := err.(PluginBinaryRemoveFailedError)
   197  					Expect(ok).To(BeTrue())
   198  					_, isPathError := pluginBinaryRemoveErr.Err.(*os.PathError)
   199  					Expect(isPathError).To(BeTrue())
   200  
   201  					Expect(fakeConfig.RemovePluginCallCount()).To(Equal(1))
   202  					Expect(fakeConfig.WritePluginConfigCallCount()).To(Equal(1))
   203  				})
   204  			})
   205  
   206  			Context("when writing the config returns an error", func() {
   207  				var expectedErr error
   208  
   209  				BeforeEach(func() {
   210  					expectedErr = errors.New("some plugin config write error")
   211  					fakeConfig.WritePluginConfigReturns(expectedErr)
   212  				})
   213  
   214  				It("returns the error", func() {
   215  					err := actor.UninstallPlugin(fakePluginUninstaller, "some-plugin")
   216  					Expect(err).To(MatchError(expectedErr))
   217  				})
   218  			})
   219  		})
   220  	})
   221  })