A new method, GetPluginID, has been added to the Manifest model. This function returns the ID of a plugin. Corresponding unit tests have also been implemented to ensure that this function works as expected. The test cases cover scenarios where IDs are the same and different.
835 строки
21 KiB
Go
835 строки
21 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package model
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
func TestIsValid(t *testing.T) {
|
|
testCases := []struct {
|
|
Title string
|
|
manifest *Manifest
|
|
ExpectError bool
|
|
}{
|
|
{"Invalid Id", &Manifest{Id: "some id", Name: "some name"}, true},
|
|
{"Invalid Name", &Manifest{Id: "com.company.test", Name: " "}, true},
|
|
{"Invalid homePageURL", &Manifest{Id: "com.company.test", Name: "some name", HomepageURL: "some url"}, true},
|
|
{"Invalid supportURL", &Manifest{Id: "com.company.test", Name: "some name", SupportURL: "some url"}, true},
|
|
{"Invalid ReleaseNotesURL", &Manifest{Id: "com.company.test", Name: "some name", ReleaseNotesURL: "some url"}, true},
|
|
{"Invalid version", &Manifest{Id: "com.company.test", Name: "some name", HomepageURL: "http://someurl.com", SupportURL: "http://someotherurl.com", Version: "version"}, true},
|
|
{"Invalid min version", &Manifest{Id: "com.company.test", Name: "some name", HomepageURL: "http://someurl.com", SupportURL: "http://someotherurl.com", Version: "5.10.0", MinServerVersion: "version"}, true},
|
|
{"SettingSchema error", &Manifest{Id: "com.company.test", Name: "some name", HomepageURL: "http://someurl.com", SupportURL: "http://someotherurl.com", Version: "5.10.0", MinServerVersion: "5.10.8", SettingsSchema: &PluginSettingsSchema{
|
|
Settings: []*PluginSetting{{Type: "Invalid"}},
|
|
}}, true},
|
|
{"Minimal valid manifest", &Manifest{Id: "com.company.test", Name: "some name"}, false},
|
|
{"Happy case", &Manifest{
|
|
Id: "com.company.test",
|
|
Name: "thename",
|
|
Description: "thedescription",
|
|
HomepageURL: "http://someurl.com",
|
|
SupportURL: "http://someotherurl.com",
|
|
ReleaseNotesURL: "http://someotherurl.com/releases/v0.0.1",
|
|
Version: "0.0.1",
|
|
MinServerVersion: "5.6.0",
|
|
Server: &ManifestServer{
|
|
Executable: "theexecutable",
|
|
},
|
|
Webapp: &ManifestWebapp{
|
|
BundlePath: "thebundlepath",
|
|
},
|
|
SettingsSchema: &PluginSettingsSchema{
|
|
Header: "theheadertext",
|
|
Footer: "thefootertext",
|
|
Settings: []*PluginSetting{
|
|
{
|
|
Key: "thesetting",
|
|
DisplayName: "thedisplayname",
|
|
Type: "dropdown",
|
|
HelpText: "thehelptext",
|
|
Options: []*PluginOption{
|
|
{
|
|
DisplayName: "theoptiondisplayname",
|
|
Value: "thevalue",
|
|
},
|
|
},
|
|
Default: "thedefault",
|
|
},
|
|
},
|
|
},
|
|
}, false},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Title, func(t *testing.T) {
|
|
err := tc.manifest.IsValid()
|
|
if tc.ExpectError {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetPluginIdReturnsCorrectId(t *testing.T) {
|
|
testCases := []struct {
|
|
Title string
|
|
Id string
|
|
manifest *Manifest
|
|
ExpectEqual bool
|
|
}{
|
|
{"Ids are Different", "not-same.com.company.test", &Manifest{Id: "com.company.test"}, false},
|
|
{"Ids are the same", "com.company.test", &Manifest{Id: "com.company.test"}, true},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Title, func(t *testing.T) {
|
|
id := tc.manifest.GetPluginID()
|
|
if tc.ExpectEqual {
|
|
assert.Equal(t, tc.Id, id)
|
|
} else {
|
|
assert.NotEqual(t, tc.Id, id)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsValidSettingsSchema(t *testing.T) {
|
|
testCases := []struct {
|
|
Title string
|
|
settingsSchema *PluginSettingsSchema
|
|
ExpectError bool
|
|
}{
|
|
{"Invalid Setting", &PluginSettingsSchema{Settings: []*PluginSetting{{Type: "invalid"}}}, true},
|
|
{"Happy case", &PluginSettingsSchema{Settings: []*PluginSetting{{Type: "text"}}}, false},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Title, func(t *testing.T) {
|
|
err := tc.settingsSchema.isValid()
|
|
if tc.ExpectError {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSettingIsValid(t *testing.T) {
|
|
for name, test := range map[string]struct {
|
|
Setting PluginSetting
|
|
ExpectError bool
|
|
}{
|
|
"Invalid setting type": {
|
|
PluginSetting{Type: "invalid"},
|
|
true,
|
|
},
|
|
"RegenerateHelpText error": {
|
|
PluginSetting{Type: "text", RegenerateHelpText: "some text"},
|
|
true,
|
|
},
|
|
"Placeholder error": {
|
|
PluginSetting{Type: "bool", Placeholder: "some text"},
|
|
true,
|
|
},
|
|
"Nil Options": {
|
|
PluginSetting{Type: "bool"},
|
|
false,
|
|
},
|
|
"Options error": {
|
|
PluginSetting{Type: "generated", Options: []*PluginOption{}},
|
|
true,
|
|
},
|
|
"Options displayName error": {
|
|
PluginSetting{
|
|
Type: "radio",
|
|
Options: []*PluginOption{{
|
|
Value: "some value",
|
|
}},
|
|
},
|
|
true,
|
|
},
|
|
"Options value error": {
|
|
PluginSetting{
|
|
Type: "radio",
|
|
Options: []*PluginOption{{
|
|
DisplayName: "some name",
|
|
}},
|
|
},
|
|
true,
|
|
},
|
|
"Happy case": {
|
|
PluginSetting{
|
|
Type: "radio",
|
|
Options: []*PluginOption{{
|
|
DisplayName: "Name",
|
|
Value: "value",
|
|
}},
|
|
},
|
|
false,
|
|
},
|
|
"Valid number setting": {
|
|
PluginSetting{
|
|
Type: "number",
|
|
Default: 10,
|
|
},
|
|
false,
|
|
},
|
|
"Placeholder is disallowed for bool settings": {
|
|
PluginSetting{
|
|
Type: "bool",
|
|
Placeholder: "some Text",
|
|
},
|
|
true,
|
|
},
|
|
"Placeholder is allowed for text settings": {
|
|
PluginSetting{
|
|
Type: "text",
|
|
Placeholder: "some Text",
|
|
},
|
|
false,
|
|
},
|
|
"Placeholder is allowed for long text settings": {
|
|
PluginSetting{
|
|
Type: "longtext",
|
|
Placeholder: "some Text",
|
|
},
|
|
false,
|
|
},
|
|
"Placeholder is allowed for custom settings": {
|
|
PluginSetting{
|
|
Type: "custom",
|
|
Placeholder: "some Text",
|
|
},
|
|
false,
|
|
},
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
err := test.Setting.isValid()
|
|
if test.ExpectError {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConvertTypeToPluginSettingType(t *testing.T) {
|
|
testCases := []struct {
|
|
Title string
|
|
Type string
|
|
ExpectedSettingType PluginSettingType
|
|
ExpectError bool
|
|
}{
|
|
{"bool", "bool", Bool, false},
|
|
{"dropdown", "dropdown", Dropdown, false},
|
|
{"generated", "generated", Generated, false},
|
|
{"radio", "radio", Radio, false},
|
|
{"text", "text", Text, false},
|
|
{"longtext", "longtext", LongText, false},
|
|
{"username", "username", Username, false},
|
|
{"custom", "custom", Custom, false},
|
|
{"invalid", "invalid", Bool, true},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.Title, func(t *testing.T) {
|
|
settingType, err := convertTypeToPluginSettingType(tc.Type)
|
|
if !tc.ExpectError {
|
|
assert.Equal(t, settingType, tc.ExpectedSettingType)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFindManifest(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
Filename string
|
|
Contents string
|
|
ExpectError bool
|
|
ExpectNotExist bool
|
|
}{
|
|
{"foo", "bar", true, true},
|
|
{"plugin.json", "bar", true, false},
|
|
{"plugin.json", `{"id": "foo"}`, false, false},
|
|
{"plugin.json", `{"id": "FOO"}`, false, false},
|
|
{"plugin.yaml", `id: foo`, false, false},
|
|
{"plugin.yaml", "bar", true, false},
|
|
{"plugin.yml", `id: foo`, false, false},
|
|
{"plugin.yml", `id: FOO`, false, false},
|
|
{"plugin.yml", "bar", true, false},
|
|
} {
|
|
dir, err := os.MkdirTemp("", "mm-plugin-test")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(dir)
|
|
|
|
path := filepath.Join(dir, tc.Filename)
|
|
f, err := os.Create(path)
|
|
require.NoError(t, err)
|
|
_, err = f.WriteString(tc.Contents)
|
|
f.Close()
|
|
require.NoError(t, err)
|
|
|
|
m, mpath, err := FindManifest(dir)
|
|
assert.True(t, (err != nil) == tc.ExpectError, tc.Filename)
|
|
assert.True(t, (err != nil && os.IsNotExist(err)) == tc.ExpectNotExist, tc.Filename)
|
|
if !tc.ExpectNotExist {
|
|
assert.Equal(t, path, mpath, tc.Filename)
|
|
} else {
|
|
assert.Empty(t, mpath, tc.Filename)
|
|
}
|
|
if !tc.ExpectError {
|
|
require.NotNil(t, m, tc.Filename)
|
|
assert.NotEmpty(t, m.Id, tc.Filename)
|
|
assert.Equal(t, strings.ToLower(m.Id), m.Id)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestManifestUnmarshal(t *testing.T) {
|
|
expected := Manifest{
|
|
Id: "theid",
|
|
HomepageURL: "https://example.com",
|
|
SupportURL: "https://example.com/support",
|
|
IconPath: "assets/icon.svg",
|
|
MinServerVersion: "5.6.0",
|
|
Server: &ManifestServer{
|
|
Executable: "theexecutable",
|
|
Executables: map[string]string{
|
|
"linux-amd64": "theexecutable-linux-amd64",
|
|
"darwin-amd64": "theexecutable-darwin-amd64",
|
|
"windows-amd64": "theexecutable-windows-amd64",
|
|
"linux-arm64": "theexecutable-linux-arm64",
|
|
},
|
|
},
|
|
Webapp: &ManifestWebapp{
|
|
BundlePath: "thebundlepath",
|
|
},
|
|
SettingsSchema: &PluginSettingsSchema{
|
|
Header: "theheadertext",
|
|
Footer: "thefootertext",
|
|
Settings: []*PluginSetting{
|
|
{
|
|
Key: "thesetting",
|
|
DisplayName: "thedisplayname",
|
|
Type: "dropdown",
|
|
HelpText: "thehelptext",
|
|
RegenerateHelpText: "theregeneratehelptext",
|
|
Placeholder: "theplaceholder",
|
|
Options: []*PluginOption{
|
|
{
|
|
DisplayName: "theoptiondisplayname",
|
|
Value: "thevalue",
|
|
},
|
|
},
|
|
Default: "thedefault",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
t.Run("yaml", func(t *testing.T) {
|
|
var yamlResult Manifest
|
|
require.NoError(t, yaml.Unmarshal([]byte(`
|
|
id: theid
|
|
homepage_url: https://example.com
|
|
support_url: https://example.com/support
|
|
icon_path: assets/icon.svg
|
|
min_server_version: 5.6.0
|
|
server:
|
|
executable: theexecutable
|
|
executables:
|
|
linux-amd64: theexecutable-linux-amd64
|
|
darwin-amd64: theexecutable-darwin-amd64
|
|
windows-amd64: theexecutable-windows-amd64
|
|
linux-arm64: theexecutable-linux-arm64
|
|
webapp:
|
|
bundle_path: thebundlepath
|
|
settings_schema:
|
|
header: theheadertext
|
|
footer: thefootertext
|
|
settings:
|
|
- key: thesetting
|
|
display_name: thedisplayname
|
|
type: dropdown
|
|
help_text: thehelptext
|
|
regenerate_help_text: theregeneratehelptext
|
|
placeholder: theplaceholder
|
|
options:
|
|
- display_name: theoptiondisplayname
|
|
value: thevalue
|
|
default: thedefault
|
|
`), &yamlResult))
|
|
assert.Equal(t, expected, yamlResult)
|
|
})
|
|
|
|
t.Run("json", func(t *testing.T) {
|
|
var jsonResult Manifest
|
|
require.NoError(t, json.Unmarshal([]byte(`{
|
|
"id": "theid",
|
|
"homepage_url": "https://example.com",
|
|
"support_url": "https://example.com/support",
|
|
"icon_path": "assets/icon.svg",
|
|
"min_server_version": "5.6.0",
|
|
"server": {
|
|
"executable": "theexecutable",
|
|
"executables": {
|
|
"linux-amd64": "theexecutable-linux-amd64",
|
|
"darwin-amd64": "theexecutable-darwin-amd64",
|
|
"windows-amd64": "theexecutable-windows-amd64",
|
|
"linux-arm64": "theexecutable-linux-arm64"
|
|
}
|
|
},
|
|
"webapp": {
|
|
"bundle_path": "thebundlepath"
|
|
},
|
|
"settings_schema": {
|
|
"header": "theheadertext",
|
|
"footer": "thefootertext",
|
|
"settings": [
|
|
{
|
|
"key": "thesetting",
|
|
"display_name": "thedisplayname",
|
|
"type": "dropdown",
|
|
"help_text": "thehelptext",
|
|
"regenerate_help_text": "theregeneratehelptext",
|
|
"placeholder": "theplaceholder",
|
|
"options": [
|
|
{
|
|
"display_name": "theoptiondisplayname",
|
|
"value": "thevalue"
|
|
}
|
|
],
|
|
"default": "thedefault"
|
|
}
|
|
]
|
|
}
|
|
}`), &jsonResult))
|
|
assert.Equal(t, expected, jsonResult)
|
|
})
|
|
}
|
|
|
|
func TestFindManifest_FileErrors(t *testing.T) {
|
|
for _, tc := range []string{"plugin.yaml", "plugin.json"} {
|
|
dir, err := os.MkdirTemp("", "mm-plugin-test")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(dir)
|
|
|
|
path := filepath.Join(dir, tc)
|
|
require.NoError(t, os.Mkdir(path, 0700))
|
|
|
|
m, mpath, err := FindManifest(dir)
|
|
assert.Nil(t, m)
|
|
assert.Equal(t, path, mpath)
|
|
assert.Error(t, err, tc)
|
|
assert.False(t, os.IsNotExist(err), tc)
|
|
}
|
|
}
|
|
|
|
func TestFindManifest_FolderPermission(t *testing.T) {
|
|
if os.Geteuid() == 0 {
|
|
t.Skip("skipping test while running as root: can't effectively remove permissions")
|
|
}
|
|
|
|
for _, tc := range []string{"plugin.yaml", "plugin.json"} {
|
|
dir, err := os.MkdirTemp("", "mm-plugin-test")
|
|
require.NoError(t, err)
|
|
defer os.RemoveAll(dir)
|
|
|
|
path := filepath.Join(dir, tc)
|
|
require.NoError(t, os.Mkdir(path, 0700))
|
|
|
|
// User does not have permission in the plugin folder
|
|
err = os.Chmod(dir, 0066)
|
|
require.NoError(t, err)
|
|
|
|
m, mpath, err := FindManifest(dir)
|
|
assert.Nil(t, m)
|
|
assert.Equal(t, "", mpath)
|
|
assert.Error(t, err, tc)
|
|
assert.False(t, os.IsNotExist(err), tc)
|
|
}
|
|
}
|
|
|
|
func TestManifestHasClient(t *testing.T) {
|
|
manifest := &Manifest{
|
|
Id: "theid",
|
|
Server: &ManifestServer{
|
|
Executable: "theexecutable",
|
|
},
|
|
Webapp: &ManifestWebapp{
|
|
BundlePath: "thebundlepath",
|
|
},
|
|
}
|
|
|
|
assert.True(t, manifest.HasClient())
|
|
|
|
manifest.Webapp = nil
|
|
assert.False(t, manifest.HasClient())
|
|
}
|
|
|
|
func TestManifestClientManifest(t *testing.T) {
|
|
manifest := &Manifest{
|
|
Id: "theid",
|
|
Name: "thename",
|
|
Description: "thedescription",
|
|
Version: "0.0.1",
|
|
MinServerVersion: "5.6.0",
|
|
Server: &ManifestServer{
|
|
Executable: "theexecutable",
|
|
},
|
|
Webapp: &ManifestWebapp{
|
|
BundlePath: "thebundlepath",
|
|
BundleHash: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
|
},
|
|
SettingsSchema: &PluginSettingsSchema{
|
|
Header: "theheadertext",
|
|
Footer: "thefootertext",
|
|
Settings: []*PluginSetting{
|
|
{
|
|
Key: "thesetting",
|
|
DisplayName: "thedisplayname",
|
|
Type: "dropdown",
|
|
HelpText: "thehelptext",
|
|
RegenerateHelpText: "theregeneratehelptext",
|
|
Placeholder: "theplaceholder",
|
|
Options: []*PluginOption{
|
|
{
|
|
DisplayName: "theoptiondisplayname",
|
|
Value: "thevalue",
|
|
},
|
|
},
|
|
Default: "thedefault",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
sanitized := manifest.ClientManifest()
|
|
|
|
assert.Equal(t, manifest.Id, sanitized.Id)
|
|
assert.Equal(t, manifest.Version, sanitized.Version)
|
|
assert.Equal(t, manifest.MinServerVersion, sanitized.MinServerVersion)
|
|
assert.Equal(t, "/static/theid/theid_000102030405060708090a0b0c0d0e0f_bundle.js", sanitized.Webapp.BundlePath)
|
|
assert.Equal(t, manifest.Webapp.BundleHash, sanitized.Webapp.BundleHash)
|
|
assert.Equal(t, manifest.SettingsSchema, sanitized.SettingsSchema)
|
|
assert.Empty(t, sanitized.Name)
|
|
assert.Empty(t, sanitized.Description)
|
|
assert.Empty(t, sanitized.Server)
|
|
|
|
assert.NotEmpty(t, manifest.Id)
|
|
assert.NotEmpty(t, manifest.Version)
|
|
assert.NotEmpty(t, manifest.MinServerVersion)
|
|
assert.NotEmpty(t, manifest.Webapp)
|
|
assert.NotEmpty(t, manifest.Name)
|
|
assert.NotEmpty(t, manifest.Description)
|
|
assert.NotEmpty(t, manifest.Server)
|
|
assert.NotEmpty(t, manifest.SettingsSchema)
|
|
}
|
|
|
|
func TestManifestGetExecutableForRuntime(t *testing.T) {
|
|
testCases := []struct {
|
|
Description string
|
|
Manifest *Manifest
|
|
GoOs string
|
|
GoArch string
|
|
ExpectedExecutable string
|
|
}{
|
|
{
|
|
"no server",
|
|
&Manifest{},
|
|
"linux",
|
|
"amd64",
|
|
"",
|
|
},
|
|
{
|
|
"no executable",
|
|
&Manifest{
|
|
Server: &ManifestServer{},
|
|
},
|
|
"linux",
|
|
"amd64",
|
|
"",
|
|
},
|
|
{
|
|
"single executable",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executable: "path/to/executable",
|
|
},
|
|
},
|
|
"linux",
|
|
"amd64",
|
|
"path/to/executable",
|
|
},
|
|
{
|
|
"single executable, different runtime",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executable: "path/to/executable",
|
|
},
|
|
},
|
|
"darwin",
|
|
"amd64",
|
|
"path/to/executable",
|
|
},
|
|
{
|
|
"multiple executables, no match",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executables: map[string]string{
|
|
"linux-amd64": "linux-amd64/path/to/executable",
|
|
"darwin-amd64": "darwin-amd64/path/to/executable",
|
|
"windows-amd64": "windows-amd64/path/to/executable",
|
|
"linux-arm64": "linux-arm64/path/to/executable",
|
|
},
|
|
},
|
|
},
|
|
"other",
|
|
"amd64",
|
|
"",
|
|
},
|
|
{
|
|
"multiple executables, linux-amd64 match",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executables: map[string]string{
|
|
"linux-amd64": "linux-amd64/path/to/executable",
|
|
"darwin-amd64": "darwin-amd64/path/to/executable",
|
|
"windows-amd64": "windows-amd64/path/to/executable",
|
|
"linux-arm64": "linux-arm64/path/to/executable",
|
|
},
|
|
},
|
|
},
|
|
"linux",
|
|
"amd64",
|
|
"linux-amd64/path/to/executable",
|
|
},
|
|
{
|
|
"multiple executables, linux-amd64 match, single executable ignored",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executables: map[string]string{
|
|
"linux-amd64": "linux-amd64/path/to/executable",
|
|
"darwin-amd64": "darwin-amd64/path/to/executable",
|
|
"windows-amd64": "windows-amd64/path/to/executable",
|
|
"linux-arm64": "linux-arm64/path/to/executable",
|
|
},
|
|
Executable: "path/to/executable",
|
|
},
|
|
},
|
|
"linux",
|
|
"amd64",
|
|
"linux-amd64/path/to/executable",
|
|
},
|
|
{
|
|
"multiple executables, darwin-amd64 match",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executables: map[string]string{
|
|
"linux-amd64": "linux-amd64/path/to/executable",
|
|
"darwin-amd64": "darwin-amd64/path/to/executable",
|
|
"windows-amd64": "windows-amd64/path/to/executable",
|
|
"linux-arm64": "linux-arm64/path/to/executable",
|
|
},
|
|
},
|
|
},
|
|
"darwin",
|
|
"amd64",
|
|
"darwin-amd64/path/to/executable",
|
|
},
|
|
{
|
|
"multiple executables, windows-amd64 match",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executables: map[string]string{
|
|
"linux-amd64": "linux-amd64/path/to/executable",
|
|
"darwin-amd64": "darwin-amd64/path/to/executable",
|
|
"windows-amd64": "windows-amd64/path/to/executable",
|
|
"linux-arm64": "linux-arm64/path/to/executable",
|
|
},
|
|
},
|
|
},
|
|
"windows",
|
|
"amd64",
|
|
"windows-amd64/path/to/executable",
|
|
},
|
|
{
|
|
"multiple executables, no match, single executable fallback",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executables: map[string]string{
|
|
"linux-amd64": "linux-amd64/path/to/executable",
|
|
"darwin-amd64": "darwin-amd64/path/to/executable",
|
|
"windows-amd64": "windows-amd64/path/to/executable",
|
|
"linux-arm64": "linux-arm64/path/to/executable",
|
|
},
|
|
Executable: "path/to/executable",
|
|
},
|
|
},
|
|
"other",
|
|
"amd64",
|
|
"path/to/executable",
|
|
},
|
|
}
|
|
|
|
for _, testCase := range testCases {
|
|
t.Run(testCase.Description, func(t *testing.T) {
|
|
assert.Equal(
|
|
t,
|
|
testCase.ExpectedExecutable,
|
|
testCase.Manifest.GetExecutableForRuntime(testCase.GoOs, testCase.GoArch),
|
|
)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestManifestHasServer(t *testing.T) {
|
|
testCases := []struct {
|
|
Description string
|
|
Manifest *Manifest
|
|
Expected bool
|
|
}{
|
|
{
|
|
"no server",
|
|
&Manifest{},
|
|
false,
|
|
},
|
|
{
|
|
"no executable, but server still considered present",
|
|
&Manifest{
|
|
Server: &ManifestServer{},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"single executable",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executable: "path/to/executable",
|
|
},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"multiple executables",
|
|
&Manifest{
|
|
Server: &ManifestServer{
|
|
Executables: map[string]string{
|
|
"linux-amd64": "linux-amd64/path/to/executable",
|
|
"darwin-amd64": "darwin-amd64/path/to/executable",
|
|
"windows-amd64": "windows-amd64/path/to/executable",
|
|
},
|
|
},
|
|
},
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, testCase := range testCases {
|
|
t.Run(testCase.Description, func(t *testing.T) {
|
|
assert.Equal(t, testCase.Expected, testCase.Manifest.HasServer())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestManifestHasWebapp(t *testing.T) {
|
|
testCases := []struct {
|
|
Description string
|
|
Manifest *Manifest
|
|
Expected bool
|
|
}{
|
|
{
|
|
"no webapp",
|
|
&Manifest{},
|
|
false,
|
|
},
|
|
{
|
|
"no bundle path, but webapp still considered present",
|
|
&Manifest{
|
|
Webapp: &ManifestWebapp{},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"bundle path defined",
|
|
&Manifest{
|
|
Webapp: &ManifestWebapp{
|
|
BundlePath: "path/to/bundle",
|
|
},
|
|
},
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, testCase := range testCases {
|
|
t.Run(testCase.Description, func(t *testing.T) {
|
|
assert.Equal(t, testCase.Expected, testCase.Manifest.HasWebapp())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestManifestMeetMinServerVersion(t *testing.T) {
|
|
for name, test := range map[string]struct {
|
|
MinServerVersion string
|
|
ServerVersion string
|
|
ShouldError bool
|
|
ShouldFulfill bool
|
|
}{
|
|
"generously fulfilled": {
|
|
MinServerVersion: "5.5.0",
|
|
ServerVersion: "5.6.0",
|
|
ShouldError: false,
|
|
ShouldFulfill: true,
|
|
},
|
|
"exactly fulfilled": {
|
|
MinServerVersion: "5.6.0",
|
|
ServerVersion: "5.6.0",
|
|
ShouldError: false,
|
|
ShouldFulfill: true,
|
|
},
|
|
"not fulfilled": {
|
|
MinServerVersion: "5.6.0",
|
|
ServerVersion: "5.5.0",
|
|
ShouldError: false,
|
|
ShouldFulfill: false,
|
|
},
|
|
"fail to parse MinServerVersion": {
|
|
MinServerVersion: "abc",
|
|
ServerVersion: "5.5.0",
|
|
ShouldError: true,
|
|
},
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
manifest := Manifest{
|
|
MinServerVersion: test.MinServerVersion,
|
|
}
|
|
fulfilled, err := manifest.MeetMinServerVersion(test.ServerVersion)
|
|
|
|
if test.ShouldError {
|
|
assert.NotNil(err)
|
|
assert.False(fulfilled)
|
|
return
|
|
}
|
|
assert.Nil(err)
|
|
assert.Equal(test.ShouldFulfill, fulfilled)
|
|
})
|
|
}
|
|
}
|