Files
vimpack/tests/registry_spec.lua
unkin-agent ca55c9dd9f
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/lint Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Validate archive entries and stage inside the pack root
- Reject archive members that are absolute, escape via .., are special files, or link outside the destination, before anything is written

- Stage under the pack root so the swap is a same-filesystem rename, with an EXDEV copy fallback; propagate registry auth errors and validate dir_name
2026-09-05 16:32:47 +10:00

159 lines
5.6 KiB
Lua

local registry = require('vimpack.registry')
local util = require('vimpack.util')
describe('interpolate', function()
it('substitutes every placeholder', function()
assert_eq(
'a/1.0/a.tar.gz',
(util.interpolate('${name}/${version}/${name}.${ext}', { name = 'a', version = '1.0', ext = 'tar.gz' }))
)
end)
it('reports an unknown placeholder', function()
local out, err = util.interpolate('${name}-${nope}', { name = 'a' })
assert_nil(out)
assert_match('${nope}', err)
end)
end)
describe('template resolver', function()
local reg = {
kind = 'template',
url_template = 'https://artifacts.example.com/nvim/${name}/${version}/${name}-${version}.${ext}',
}
it('renders name and version into the url', function()
local resolved = assert(registry.resolve({ name = 'telescope.nvim', version = '0.1.8' }, reg))
assert_eq('https://artifacts.example.com/nvim/telescope.nvim/0.1.8/telescope.nvim-0.1.8.tar.gz', resolved.url)
assert_eq('telescope.nvim-0.1.8.tar.gz', resolved.filename)
end)
it('honours a per-plugin ext override', function()
local resolved = assert(registry.resolve({ name = 'plenary.nvim', version = '1', ext = 'zip' }, reg))
assert_match('plenary.nvim-1.zip', resolved.url)
end)
it('fails loudly without a url_template', function()
local resolved, err = registry.resolve({ name = 'x', version = '1' }, { kind = 'template' })
assert_nil(resolved)
assert_match('url_template', err)
end)
it('names the unknown kind', function()
local resolved, err = registry.resolve({ name = 'x', version = '1' }, { kind = 'nosuch' })
assert_nil(resolved)
assert_match('nosuch', err)
end)
end)
describe('artifactapi resolver', function()
local reg = {
kind = 'artifactapi',
base_url = 'https://artifactapi.k8s.syd1.au.unkin.net/',
repo = 'nvim-plugins',
}
it('builds the generic-repo path', function()
local resolved = assert(registry.resolve({ name = 'oil.nvim', version = '2.11.0' }, reg))
assert_eq(
'https://artifactapi.k8s.syd1.au.unkin.net/api/v2/remotes/nvim-plugins/files/oil.nvim/oil.nvim-2.11.0.tar.gz',
resolved.url
)
end)
it('accepts a path_template override', function()
local reg2 = vim.tbl_extend('force', reg, { path_template = '${version}/${slug}.${ext}' })
local resolved = assert(registry.resolve({ name = 'oil.nvim', version = '2.11.0' }, reg2))
assert_match('/files/2.11.0/oil.nvim.tar.gz', resolved.url)
end)
end)
describe('url escape hatch', function()
it('bypasses the registry entirely', function()
local resolved = assert(registry.resolve({ name = 'x', version = '1', url = 'https://h/x.zip' }, nil))
assert_eq('https://h/x.zip', resolved.url)
assert_eq('x.zip', resolved.filename)
end)
it('still applies the registry auth headers', function()
vim.env.VIMPACK_TEST_TOKEN = 'sekret'
local resolved = assert(
registry.resolve(
{ name = 'x', version = '1', url = 'https://h/x.zip' },
{ auth = { env = 'VIMPACK_TEST_TOKEN' } }
)
)
assert_eq('Bearer sekret', resolved.headers.Authorization)
vim.env.VIMPACK_TEST_TOKEN = nil
end)
it('propagates an auth failure instead of downloading unauthenticated', function()
vim.env.VIMPACK_TEST_TOKEN = nil
local resolved, err = registry.resolve(
{ name = 'x', version = '1', url = 'https://h/x.zip' },
{ auth = { env = 'VIMPACK_TEST_TOKEN' } }
)
assert_nil(resolved)
assert_match('VIMPACK_TEST_TOKEN', err)
end)
end)
describe('auth headers', function()
it('reads a token from the environment', function()
vim.env.VIMPACK_TEST_TOKEN = 'sekret'
local headers = assert(registry.build_headers({ auth = { env = 'VIMPACK_TEST_TOKEN' } }))
assert_eq({ Authorization = 'Bearer sekret' }, headers)
vim.env.VIMPACK_TEST_TOKEN = nil
end)
it('reports an unset env var', function()
vim.env.VIMPACK_TEST_TOKEN = nil
local headers, err = registry.build_headers({ auth = { env = 'VIMPACK_TEST_TOKEN' } })
assert_nil(headers)
assert_match('VIMPACK_TEST_TOKEN', err)
end)
it('runs token_cmd and uses a custom header', function()
local headers = assert(registry.build_headers({
auth = { token_cmd = { 'printf', '%s', 'abc123' }, header = 'X-JFrog-Art-Api', prefix = '' },
}))
assert_eq({ ['X-JFrog-Art-Api'] = 'abc123' }, headers)
end)
it('rejects a literal token', function()
local headers, err = registry.build_headers({ auth = { token = 'oops' } })
assert_nil(headers)
assert_match('literal token', err)
end)
it('attaches auth to a resolved url', function()
vim.env.VIMPACK_TEST_TOKEN = 'sekret'
local resolved = assert(registry.resolve({ name = 'a', version = '1' }, {
kind = 'template',
url_template = 'https://h/${name}-${version}.tar.gz',
auth = { env = 'VIMPACK_TEST_TOKEN' },
}))
assert_eq('Bearer sekret', resolved.headers.Authorization)
vim.env.VIMPACK_TEST_TOKEN = nil
end)
end)
describe('custom resolvers', function()
it('are usable once registered', function()
registry.register('spec_custom', function(spec)
return { url = 'https://custom/' .. spec.name, headers = {}, filename = 'a.tar.gz' }
end)
local resolved = assert(registry.resolve({ name = 'z', version = '1' }, { kind = 'spec_custom' }))
assert_eq('https://custom/z', resolved.url)
end)
end)
describe('archive_kind', function()
it('classifies suffixes', function()
assert_eq('tar', util.archive_kind('a.tar.gz'))
assert_eq('tar', util.archive_kind('a.tgz'))
assert_eq('zip', util.archive_kind('A.ZIP'))
assert_nil(util.archive_kind('a.rpm'))
end)
end)