mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-07 22:18:30 -04:00
b7ec57a534
* feat(plugins): add portable plugin lockfile * plugins/lockfile: allow ssh remotes --------- Co-authored-by: bbedward <bbedward@gmail.com>
112 lines
3.5 KiB
Go
112 lines
3.5 KiB
Go
package plugins
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/spf13/afero"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const testCommit = "0123456789abcdef0123456789abcdef01234567"
|
|
|
|
func TestPluginLockfileRoundTrip(t *testing.T) {
|
|
fs := afero.NewMemMapFs()
|
|
store := NewLockStore(fs, "/config/plugins.lock.json")
|
|
lock := NewPluginLockfile()
|
|
lock.Plugins["weather"] = LockedPlugin{
|
|
Repo: "https://github.com/example/plugins.git",
|
|
Path: "plugins/weather",
|
|
Commit: testCommit,
|
|
}
|
|
|
|
require.NoError(t, store.Write(lock))
|
|
loaded, err := store.Load()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, lock, loaded)
|
|
|
|
data, err := afero.ReadFile(fs, store.Path())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "{\n \"lockfileVersion\": 1,\n \"plugins\": {\n \"weather\": {\n \"repo\": \"https://github.com/example/plugins.git\",\n \"path\": \"plugins/weather\",\n \"commit\": \"0123456789abcdef0123456789abcdef01234567\"\n }\n }\n}\n", string(data))
|
|
}
|
|
|
|
func TestPluginLockfileValidation(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
lock PluginLockfile
|
|
want string
|
|
}{
|
|
{
|
|
name: "rejects unsupported version",
|
|
lock: PluginLockfile{LockfileVersion: 2, Plugins: map[string]LockedPlugin{}},
|
|
want: "unsupported plugin lockfile version",
|
|
},
|
|
{
|
|
name: "rejects unsafe id",
|
|
lock: PluginLockfile{LockfileVersion: 1, Plugins: map[string]LockedPlugin{"../bad": {Repo: "repo", Commit: testCommit}}},
|
|
want: "invalid locked plugin id",
|
|
},
|
|
{
|
|
name: "rejects unsafe repository path",
|
|
lock: PluginLockfile{LockfileVersion: 1, Plugins: map[string]LockedPlugin{"bad": {Repo: "repo", Path: "../bad", Commit: testCommit}}},
|
|
want: "invalid repository path",
|
|
},
|
|
{
|
|
name: "rejects abbreviated commit",
|
|
lock: PluginLockfile{LockfileVersion: 1, Plugins: map[string]LockedPlugin{"bad": {Repo: "repo", Commit: "abc123"}}},
|
|
want: "invalid commit",
|
|
},
|
|
{
|
|
name: "rejects repository credentials",
|
|
lock: PluginLockfile{LockfileVersion: 1, Plugins: map[string]LockedPlugin{"bad": {Repo: "https://token@example.com/plugin.git", Commit: testCommit}}},
|
|
want: "must not contain credentials",
|
|
},
|
|
{
|
|
name: "rejects ssh password",
|
|
lock: PluginLockfile{LockfileVersion: 1, Plugins: map[string]LockedPlugin{"bad": {Repo: "ssh://git:secret@example.com/plugin.git", Commit: testCommit}}},
|
|
want: "must not contain credentials",
|
|
},
|
|
{
|
|
name: "rejects conflicting monorepo commits",
|
|
lock: PluginLockfile{LockfileVersion: 1, Plugins: map[string]LockedPlugin{
|
|
"one": {Repo: "repo", Commit: testCommit},
|
|
"two": {Repo: "repo", Commit: "1123456789abcdef0123456789abcdef01234567"},
|
|
}},
|
|
want: "must use the same commit",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := tt.lock.Validate()
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), tt.want)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPluginLockfileAcceptsSSHRemotes(t *testing.T) {
|
|
repos := []string{
|
|
"https://github.com/user/plugin.git",
|
|
"ssh://git@github.com/user/plugin.git",
|
|
"git@github.com:user/plugin.git",
|
|
}
|
|
|
|
for _, repo := range repos {
|
|
t.Run(repo, func(t *testing.T) {
|
|
lock := PluginLockfile{LockfileVersion: 1, Plugins: map[string]LockedPlugin{
|
|
"plugin": {Repo: repo, Commit: testCommit},
|
|
}}
|
|
assert.NoError(t, lock.Validate())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMissingPluginLockfileIsEmpty(t *testing.T) {
|
|
store := NewLockStore(afero.NewMemMapFs(), "/config/plugins.lock.json")
|
|
lock, err := store.Load()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, pluginLockfileVersion, lock.LockfileVersion)
|
|
assert.Empty(t, lock.Plugins)
|
|
}
|