check / check (push) Failing after 2s
REPO_POLICIES.md requires the module root sneak.berlin/go/<name>. go.mod, every import (rewritten with gofmt -r), the -X flags in script/build and the examples in the pkg READMEs now use the new path. go mod tidy lists go-humanize and fatih/color as direct requirements, since internal/cli imports them. This breaks anyone who fetched or imported git.eeqj.de/sneak/secret: they must switch to sneak.berlin/go/secret, which resolves to this repository. Model: opus-5-5
80 lines
2.5 KiB
Go
80 lines
2.5 KiB
Go
//nolint:testpackage // white-box test of unexported internals
|
|
package cli
|
|
|
|
import (
|
|
"encoding/json"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/spf13/afero"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"sneak.berlin/go/secret/internal/secret"
|
|
"sneak.berlin/go/secret/internal/vault"
|
|
)
|
|
|
|
// TestSameMetadataUnlockersHaveTheirOwnIDs writes two passphrase unlockers
|
|
// side by side whose metadata is the same, creation time included, as
|
|
// copying an unlocker directory leaves them. It asserts that `unlocker
|
|
// list` and the shell completion of `unlocker select` and `unlocker remove`
|
|
// give each its own ID, and that each is selected and removed by its ID
|
|
// alone. Keychain and Secure Enclave unlockers, which only macOS can add,
|
|
// get their IDs the same way.
|
|
func TestSameMetadataUnlockersHaveTheirOwnIDs(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
_, err := vault.CreateVault(fs, listTestStateDir, listTestVaultName,
|
|
testMnemonicBuffer(t), nil)
|
|
require.NoError(t, err)
|
|
|
|
vaultDir := testVaultDir(listTestVaultName)
|
|
unlockersDir := filepath.Join(vaultDir, listTestUnlockersDirName)
|
|
dirNames := []string{
|
|
"passphrase-2026-10-04.12.30.00.000000000",
|
|
"passphrase-2026-10-04.12.30.00.000000000-copy",
|
|
}
|
|
|
|
metadata, err := json.Marshal(secret.UnlockerMetadata{
|
|
Type: unlockerTypePassphrase,
|
|
CreatedAt: time.Date(2026, time.October, 4, 12, 30, 0, 0, time.UTC),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
for _, dirName := range dirNames {
|
|
dir := filepath.Join(unlockersDir, dirName)
|
|
require.NoError(t, fs.MkdirAll(dir, listTestDirPerm))
|
|
require.NoError(t, afero.WriteFile(fs,
|
|
filepath.Join(dir, listTestMetadataFileName), metadata,
|
|
listTestFilePerm))
|
|
}
|
|
|
|
listed := listUnlockersJSON(t, fs)
|
|
require.Len(t, listed, len(dirNames))
|
|
|
|
completed, _ := getUnlockerIDsCompletionFunc(fs, listTestStateDir)(
|
|
nil, nil, "")
|
|
assert.Equal(t, dirNames, completed)
|
|
|
|
instance, cmd := newTestInstance(fs)
|
|
|
|
for i, unlocker := range listed {
|
|
assert.Equal(t, dirNames[i], unlocker.ID)
|
|
|
|
require.NoError(t, instance.UnlockerSelect(unlocker.ID))
|
|
|
|
current, err := afero.ReadFile(fs,
|
|
filepath.Join(vaultDir, "current-unlocker"))
|
|
require.NoError(t, err)
|
|
assert.Equal(t, dirNames[i], string(current))
|
|
}
|
|
|
|
// The second one first: an ID both shared would remove the first one
|
|
require.NoError(t, instance.UnlockersRemove(listed[1].ID, true, cmd))
|
|
assertDirEntries(t, fs, unlockersDir, dirNames[0])
|
|
|
|
require.NoError(t, instance.UnlockersRemove(listed[0].ID, true, cmd))
|
|
assertDirEntries(t, fs, unlockersDir)
|
|
}
|