Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
111 lines
3.5 KiB
Go
111 lines
3.5 KiB
Go
package app
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.kebcloud.no/keb/lazysecrets/internal/provider"
|
|
"git.kebcloud.no/keb/lazysecrets/internal/provider/fake"
|
|
"git.kebcloud.no/keb/lazysecrets/internal/ref"
|
|
"git.kebcloud.no/keb/lazysecrets/internal/store"
|
|
)
|
|
|
|
func TestCacheFileShowsLastRunAtOnce(t *testing.T) {
|
|
t.Parallel()
|
|
file := filepath.Join(t.TempDir(), "lazysecrets", "cache.json")
|
|
d := newDriverOpts(t, Options{CacheFile: file}, fake.Azure(0))
|
|
d.keys("3", "space")
|
|
if !strings.Contains(d.screen(), "correct-horse-battery-staple") {
|
|
t.Fatalf("value not revealed:\n%s", d.screen())
|
|
}
|
|
src, vault, secret := d.selected()
|
|
if err := d.m.Persist(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
b, err := os.ReadFile(file)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strings.Contains(string(b), "correct-horse") {
|
|
t.Error("a value is in the cache file")
|
|
}
|
|
if fi, _ := os.Stat(file); fi.Mode().Perm() != 0o600 {
|
|
t.Errorf("cache file mode %v", fi.Mode().Perm())
|
|
}
|
|
|
|
// Next run, with a backend too slow to answer during the test: the
|
|
// lists show from the file, and the cursor is where it was.
|
|
d2 := newDriverOpts(t, Options{CacheFile: file}, fake.Azure(time.Minute))
|
|
d2.keys("2")
|
|
if _, v, _ := d2.selected(); v != vault {
|
|
t.Errorf("vaults from the cache: selected %q, want %q\n%s", v, vault, d2.screen())
|
|
}
|
|
d2.keys("3")
|
|
if s, v, o := d2.selected(); s != src || v != vault || o != secret {
|
|
t.Errorf("selected %s/%s/%s, want %s/%s/%s\n%s", s, v, o, src, vault, secret, d2.screen())
|
|
}
|
|
}
|
|
|
|
func TestCacheFileDropsOldAndSignedOut(t *testing.T) {
|
|
t.Parallel()
|
|
file := filepath.Join(t.TempDir(), "cache.json")
|
|
az := fake.Azure(0)
|
|
now := time.Now()
|
|
f := cacheFile{
|
|
Version: cacheFileVersion,
|
|
Containers: map[string]stamped[[]provider.Container]{
|
|
az.ID() + "|recent": {now.Add(-time.Hour), []provider.Container{{Name: "kv-recent"}}},
|
|
az.ID() + "|old": {now.Add(-cacheMaxAge - time.Hour), []provider.Container{{Name: "kv-old"}}},
|
|
"Azure:gone@x/t|recent": {now, []provider.Container{{Name: "kv-gone"}}},
|
|
},
|
|
}
|
|
if err := writeCacheFile(file, f); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
d := newDriverOpts(t, Options{CacheFile: file}, az)
|
|
c := d.m.cache.containers
|
|
if _, ok := c[az.ID()+"|recent"]; !ok {
|
|
t.Error("dropped a recent entry")
|
|
}
|
|
if _, ok := c[az.ID()+"|old"]; ok {
|
|
t.Error("kept an entry older than cacheMaxAge")
|
|
}
|
|
if _, ok := c["Azure:gone@x/t|recent"]; ok {
|
|
t.Error("kept an entry of an account that isn't signed in")
|
|
}
|
|
}
|
|
|
|
func TestBackWhereItWasLeft(t *testing.T) {
|
|
t.Parallel()
|
|
st, _ := store.Load("")
|
|
dir := "/work/project"
|
|
d := newDriverOpts(t, Options{Store: st, Dir: dir}, fake.Azure(0))
|
|
d.keys("3", "j", "j")
|
|
src, vault, secret := d.selected()
|
|
if err := d.m.Persist(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if p, ok := st.Place(dir); !ok || !strings.Contains(p.Link, secret) {
|
|
t.Fatalf("place %+v", p)
|
|
}
|
|
|
|
d2 := newDriverOpts(t, Options{Store: st, Dir: dir}, fake.Azure(0))
|
|
if s, v, o := d2.selected(); s != src || v != vault || o != secret {
|
|
t.Errorf("back at %s/%s/%s, want %s/%s/%s\n%s", s, v, o, src, vault, secret, d2.screen())
|
|
}
|
|
|
|
// Another folder starts as usual; so does opening a link.
|
|
d3 := newDriverOpts(t, Options{Store: st, Dir: "/elsewhere"}, fake.Azure(0))
|
|
if _, _, o := d3.selected(); o == secret {
|
|
t.Errorf("another folder went to %s too", o)
|
|
}
|
|
r, _ := ref.Parse("lazysecrets://azure/kv-app-prod.vault.azure.net/secrets/db-password")
|
|
d4 := newDriverOpts(t, Options{Store: st, Dir: dir, Open: &r}, fake.Azure(0))
|
|
if d4.m.nav != nil && d4.m.nav.quiet {
|
|
t.Error("a link was overridden by where it was left")
|
|
}
|
|
}
|