github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/util/configv3/plugins_config_test.go (about)

     1  package configv3_test
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	. "github.com/liamawhite/cli-with-i18n/util/configv3"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/ginkgo/extensions/table"
    11  	. "github.com/onsi/gomega"
    12  )
    13  
    14  var _ = Describe("PluginsConfig", func() {
    15  	var homeDir string
    16  
    17  	BeforeEach(func() {
    18  		homeDir = setup()
    19  	})
    20  
    21  	AfterEach(func() {
    22  		teardown(homeDir)
    23  	})
    24  
    25  	DescribeTable("when the plugin config exists",
    26  		func(setup func() (string, string)) {
    27  			location, CFPluginHome := setup()
    28  			if CFPluginHome != "" {
    29  				os.Setenv("CF_PLUGIN_HOME", CFPluginHome)
    30  				defer os.Unsetenv("CF_PLUGIN_HOME")
    31  			}
    32  
    33  			rawConfig := `
    34  {
    35    "Plugins": {
    36      "Diego-Enabler": {
    37        "Location": "~/.cf/plugins/diego-enabler_darwin_amd64",
    38        "Version": {
    39          "Major": 1,
    40          "Minor": 0,
    41          "Build": 1
    42        },
    43        "Commands": [
    44          {
    45            "Name": "enable-diego",
    46            "Alias": "",
    47            "HelpText": "enable Diego support for an app",
    48            "UsageDetails": {
    49              "Usage": "cf enable-diego APP_NAME",
    50              "Options": null
    51            }
    52          },
    53          {
    54            "Name": "disable-diego",
    55            "Alias": "",
    56            "HelpText": "disable Diego support for an app",
    57            "UsageDetails": {
    58              "Usage": "cf disable-diego APP_NAME",
    59              "Options": null
    60            }
    61          }
    62  			]
    63  		}
    64  	}
    65  }`
    66  			setPluginConfig(location, rawConfig)
    67  			config, err := LoadConfig()
    68  			Expect(err).ToNot(HaveOccurred())
    69  			Expect(config).ToNot(BeNil())
    70  
    71  			plugins := config.Plugins()
    72  			Expect(plugins).ToNot(BeEmpty())
    73  
    74  			plugin := plugins[0]
    75  			Expect(plugin.Name).To(Equal("Diego-Enabler"))
    76  			Expect(plugin.Location).To(Equal("~/.cf/plugins/diego-enabler_darwin_amd64"))
    77  			Expect(plugin.Version.Major).To(Equal(1))
    78  			Expect(plugin.Commands).To(HaveLen(2))
    79  			Expect(plugin.Commands).To(ContainElement(
    80  				PluginCommand{
    81  					Name:     "enable-diego",
    82  					Alias:    "",
    83  					HelpText: "enable Diego support for an app",
    84  					UsageDetails: PluginUsageDetails{
    85  						Usage: "cf enable-diego APP_NAME",
    86  					},
    87  				},
    88  			))
    89  		},
    90  
    91  		Entry("standard location", func() (string, string) {
    92  			return filepath.Join(homeDir, ".cf", "plugins"), ""
    93  		}),
    94  
    95  		Entry("non-standard location", func() (string, string) {
    96  			return filepath.Join(homeDir, "foo", ".cf", "plugins"), filepath.Join(homeDir, "foo")
    97  		}),
    98  	)
    99  
   100  	Describe("Plugin", func() {
   101  		Describe("CalculateSHA1", func() {
   102  			var plugin Plugin
   103  
   104  			Context("when no errors are encountered calculating the sha1 value", func() {
   105  				var file *os.File
   106  
   107  				BeforeEach(func() {
   108  					var err error
   109  					file, err = ioutil.TempFile("", "")
   110  					defer file.Close()
   111  					Expect(err).NotTo(HaveOccurred())
   112  
   113  					err = ioutil.WriteFile(file.Name(), []byte("foo"), 0600)
   114  					Expect(err).NotTo(HaveOccurred())
   115  
   116  					plugin.Location = file.Name()
   117  				})
   118  
   119  				AfterEach(func() {
   120  					err := os.Remove(file.Name())
   121  					Expect(err).NotTo(HaveOccurred())
   122  				})
   123  
   124  				It("returns the sha1 value", func() {
   125  					Expect(plugin.CalculateSHA1()).To(Equal("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"))
   126  				})
   127  			})
   128  
   129  			Context("when an error is encountered calculating the sha1 value", func() {
   130  				var dirPath string
   131  
   132  				BeforeEach(func() {
   133  					var err error
   134  					dirPath, err = ioutil.TempDir("", "")
   135  					Expect(err).NotTo(HaveOccurred())
   136  
   137  					plugin.Location = dirPath
   138  				})
   139  
   140  				AfterEach(func() {
   141  					err := os.RemoveAll(dirPath)
   142  					Expect(err).NotTo(HaveOccurred())
   143  				})
   144  
   145  				It("returns 'N/A'", func() {
   146  					Expect(plugin.CalculateSHA1()).To(Equal("N/A"))
   147  				})
   148  			})
   149  		})
   150  
   151  		Describe("PluginCommands", func() {
   152  			It("returns the plugin's commands sorted by command name", func() {
   153  				plugin := Plugin{
   154  					Commands: []PluginCommand{
   155  						{Name: "T-sort"},
   156  						{Name: "sort-2"},
   157  						{Name: "sort-1"},
   158  					},
   159  				}
   160  
   161  				Expect(plugin.PluginCommands()).To(Equal([]PluginCommand{
   162  					PluginCommand{Name: "sort-1"},
   163  					PluginCommand{Name: "sort-2"},
   164  					PluginCommand{Name: "T-sort"},
   165  				}))
   166  			})
   167  		})
   168  	})
   169  
   170  	Describe("PluginVersion", func() {
   171  		var version PluginVersion
   172  
   173  		Describe("String", func() {
   174  			It("returns the version in the format x.y.z", func() {
   175  				version = PluginVersion{
   176  					Major: 1,
   177  					Minor: 2,
   178  					Build: 3,
   179  				}
   180  				Expect(version.String()).To(Equal("1.2.3"))
   181  			})
   182  
   183  			Context("when the major, minor, and build are all 0", func() {
   184  				BeforeEach(func() {
   185  					version = PluginVersion{
   186  						Major: 0,
   187  						Minor: 0,
   188  						Build: 0,
   189  					}
   190  				})
   191  
   192  				It("returns 'N/A'", func() {
   193  					Expect(version.String()).To(Equal("N/A"))
   194  				})
   195  			})
   196  		})
   197  	})
   198  
   199  	Describe("PluginCommand", func() {
   200  		var cmd PluginCommand
   201  
   202  		Describe("CommandName", func() {
   203  			It("returns the name of the command", func() {
   204  				cmd = PluginCommand{Name: "some-command"}
   205  				Expect(cmd.CommandName()).To(Equal("some-command"))
   206  			})
   207  
   208  			Context("when the command name and command alias are not empty", func() {
   209  				BeforeEach(func() {
   210  					cmd = PluginCommand{Name: "some-command", Alias: "sp"}
   211  				})
   212  
   213  				It("returns the command name concatenated with the command alias", func() {
   214  					Expect(cmd.CommandName()).To(Equal("some-command, sp"))
   215  				})
   216  			})
   217  		})
   218  	})
   219  
   220  	Describe("Config", func() {
   221  		Describe("RemovePlugin", func() {
   222  			var (
   223  				config *Config
   224  				err    error
   225  			)
   226  
   227  			BeforeEach(func() {
   228  				rawConfig := `
   229  {
   230    "Plugins": {
   231      "Diego-Enabler": {
   232        "Location": "~/.cf/plugins/diego-enabler_darwin_amd64",
   233        "Version": {
   234          "Major": 1,
   235          "Minor": 0,
   236          "Build": 1
   237        },
   238        "Commands": [
   239          {
   240            "Name": "enable-diego",
   241            "Alias": "",
   242            "HelpText": "enable Diego support for an app",
   243            "UsageDetails": {
   244              "Usage": "cf enable-diego APP_NAME",
   245              "Options": null
   246            }
   247          }
   248        ]
   249      },
   250      "Dora-Non-Enabler": {
   251        "Location": "~/.cf/plugins/diego-enabler_darwin_amd64",
   252        "Version": {
   253          "Major": 1,
   254          "Minor": 0,
   255          "Build": 1
   256        },
   257        "Commands": [
   258          {
   259            "Name": "disable-diego",
   260            "Alias": "",
   261            "HelpText": "disable Diego support for an app",
   262            "UsageDetails": {
   263              "Usage": "cf disable-diego APP_NAME",
   264              "Options": null
   265            }
   266          }
   267        ]
   268      }
   269    }
   270  }`
   271  				setPluginConfig(filepath.Join(homeDir, ".cf", "plugins"), rawConfig)
   272  
   273  				config, err = LoadConfig()
   274  				Expect(err).ToNot(HaveOccurred())
   275  			})
   276  
   277  			Context("when the plugin exists", func() {
   278  				It("removes the plugin from the config", func() {
   279  					plugins := config.Plugins()
   280  
   281  					Expect(plugins).To(HaveLen(2))
   282  					Expect(plugins[0].Name).To(Equal("Diego-Enabler"))
   283  
   284  					config.RemovePlugin("Diego-Enabler")
   285  
   286  					Expect(config.Plugins()).To(HaveLen(1))
   287  				})
   288  			})
   289  
   290  			Context("when the plugin does not exist", func() {
   291  				It("doesn't blow up", func() {
   292  					config.RemovePlugin("does-not-exist")
   293  				})
   294  			})
   295  		})
   296  
   297  		Describe("WritePluginConfig", func() {
   298  			var config *Config
   299  
   300  			BeforeEach(func() {
   301  				rawConfig := `
   302  {
   303  	"Plugins": {
   304  		"Diego-Enabler": {
   305  			"Location": "~/.cf/plugins/diego-enabler_darwin_amd64",
   306  			"Version": {
   307  				"Major": 1,
   308  				"Minor": 0,
   309  				"Build": 1
   310  			},
   311  			"Commands": [
   312  				{
   313  					"Name": "enable-diego",
   314  					"Alias": "",
   315  					"HelpText": "enable Diego support for an app",
   316  					"UsageDetails": {
   317  						"Usage": "cf enable-diego APP_NAME",
   318  						"Options": null
   319  					}
   320  				}
   321  			]
   322  		}
   323  	}
   324  }`
   325  				setPluginConfig(filepath.Join(homeDir, ".cf", "plugins"), rawConfig)
   326  
   327  				var err error
   328  				config, err = LoadConfig()
   329  				Expect(err).ToNot(HaveOccurred())
   330  			})
   331  
   332  			Context("when no errors are encountered", func() {
   333  				It("writes the plugin config to pluginHome/.cf/plugin/config.json", func() {
   334  					config.RemovePlugin("Diego-Enabler")
   335  
   336  					err := config.WritePluginConfig()
   337  					Expect(err).ToNot(HaveOccurred())
   338  
   339  					newConfig, err := LoadConfig()
   340  					Expect(err).ToNot(HaveOccurred())
   341  					Expect(newConfig.Plugins()).To(HaveLen(0))
   342  				})
   343  			})
   344  
   345  			Context("when an error is encountered", func() {
   346  				BeforeEach(func() {
   347  					pluginConfigPath := filepath.Join(homeDir, ".cf", "plugins", "config.json")
   348  					err := os.Remove(pluginConfigPath)
   349  					Expect(err).ToNot(HaveOccurred())
   350  					err = os.Mkdir(pluginConfigPath, 0700)
   351  					Expect(err).ToNot(HaveOccurred())
   352  				})
   353  
   354  				It("returns the error", func() {
   355  					err := config.WritePluginConfig()
   356  					_, ok := err.(*os.PathError)
   357  					Expect(ok).To(BeTrue())
   358  				})
   359  			})
   360  		})
   361  
   362  		Describe("Plugins", func() {
   363  			BeforeEach(func() {
   364  				rawConfig := `
   365  				{
   366  					"Plugins": {
   367  						"Q-plugin": {},
   368  						"plugin-2": {},
   369  						"plugin-1": {}
   370  					}
   371  				}`
   372  
   373  				pluginsPath := filepath.Join(homeDir, ".cf", "plugins")
   374  				setPluginConfig(pluginsPath, rawConfig)
   375  			})
   376  
   377  			It("returns the pluging sorted by name", func() {
   378  				config, err := LoadConfig()
   379  				Expect(err).ToNot(HaveOccurred())
   380  				Expect(config.Plugins()).To(Equal([]Plugin{
   381  					{Name: "plugin-1"},
   382  					{Name: "plugin-2"},
   383  					{Name: "Q-plugin"},
   384  				}))
   385  			})
   386  		})
   387  
   388  		Describe("AddPlugin", func() {
   389  			var (
   390  				config *Config
   391  				err    error
   392  			)
   393  
   394  			BeforeEach(func() {
   395  				rawConfig := `
   396  				{
   397  					"Plugins": {
   398  						"plugin-1": {}
   399  					}
   400  				}`
   401  
   402  				pluginsPath := filepath.Join(homeDir, ".cf", "plugins")
   403  				setPluginConfig(pluginsPath, rawConfig)
   404  				config, err = LoadConfig()
   405  				Expect(err).ToNot(HaveOccurred())
   406  			})
   407  
   408  			It("adds the plugin to the config", func() {
   409  				config.AddPlugin(Plugin{
   410  					Name:     "plugin-2",
   411  					Location: "/over-there",
   412  				})
   413  
   414  				plugin, exist := config.GetPlugin("plugin-2")
   415  				Expect(exist).To(BeTrue())
   416  				Expect(plugin).To(Equal(Plugin{Name: "plugin-2", Location: "/over-there"}))
   417  			})
   418  		})
   419  
   420  		Describe("GetPlugin", func() {
   421  			var (
   422  				config *Config
   423  				err    error
   424  			)
   425  
   426  			BeforeEach(func() {
   427  				rawConfig := `
   428  				{
   429  					"Plugins": {
   430  						"plugin-1": {},
   431  						"plugin-2": {}
   432  					}
   433  				}`
   434  
   435  				pluginsPath := filepath.Join(homeDir, ".cf", "plugins")
   436  				setPluginConfig(pluginsPath, rawConfig)
   437  				config, err = LoadConfig()
   438  				Expect(err).ToNot(HaveOccurred())
   439  			})
   440  
   441  			It("returns the plugin and true if it exists", func() {
   442  				plugin, exist := config.GetPlugin("plugin-1")
   443  				Expect(exist).To(BeTrue())
   444  				Expect(plugin).To(Equal(Plugin{Name: "plugin-1"}))
   445  				plugin, exist = config.GetPlugin("plugin-2")
   446  				Expect(exist).To(BeTrue())
   447  				Expect(plugin).To(Equal(Plugin{Name: "plugin-2"}))
   448  			})
   449  
   450  			It("returns an empty plugin and false if it doesn't exist", func() {
   451  				plugin, exist := config.GetPlugin("does-not-exist")
   452  				Expect(exist).To(BeFalse())
   453  				Expect(plugin).To(Equal(Plugin{}))
   454  			})
   455  		})
   456  
   457  		Describe("GetPluginCaseInsensitive", func() {
   458  			var (
   459  				config *Config
   460  				err    error
   461  			)
   462  
   463  			BeforeEach(func() {
   464  				rawConfig := `
   465  				{
   466  					"Plugins": {
   467  						"plugin-1": {},
   468  						"plugin-2": {},
   469  						"PLUGIN-2": {}
   470  					}
   471  				}`
   472  
   473  				pluginsPath := filepath.Join(homeDir, ".cf", "plugins")
   474  				setPluginConfig(pluginsPath, rawConfig)
   475  				config, err = LoadConfig()
   476  				Expect(err).ToNot(HaveOccurred())
   477  			})
   478  
   479  			Context("when there is a matching plugin", func() {
   480  				It("returns the plugin and true", func() {
   481  					plugin, exist := config.GetPluginCaseInsensitive("PlUgIn-1")
   482  					Expect(plugin).To(Equal(Plugin{Name: "plugin-1"}))
   483  					Expect(exist).To(BeTrue())
   484  				})
   485  			})
   486  
   487  			Context("when there is no matching plugin", func() {
   488  				It("returns an empty plugin and false", func() {
   489  					plugin, exist := config.GetPluginCaseInsensitive("plugin-3")
   490  					Expect(plugin).To(Equal(Plugin{}))
   491  					Expect(exist).To(BeFalse())
   492  				})
   493  			})
   494  
   495  			Context("when there are multiple matching plugins", func() {
   496  				// this should never happen
   497  				It("returns one of them", func() {
   498  					_, exist := config.GetPluginCaseInsensitive("pLuGiN-2")
   499  					// do not test the plugin because the plugins are in a map and the
   500  					// order is undefined
   501  					Expect(exist).To(BeTrue())
   502  				})
   503  			})
   504  		})
   505  	})
   506  })