lockbox

password manager
Log | Files | Refs | README | LICENSE

commit 615e6409ed9e0d1b91ad6f6664dee6f4e2a1ed34
parent 0afa20cc682aab65a7dd702fffdb8a45e70d5321
Author: Sean Enck <sean@ttypty.com>
Date:   Sat,  1 Oct 2022 13:50:29 -0400

test files

Diffstat:
Ainternal/backend/actions_test.go | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainternal/backend/query_test.go | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 230 insertions(+), 0 deletions(-)

diff --git a/internal/backend/actions_test.go b/internal/backend/actions_test.go @@ -0,0 +1,113 @@ +package backend_test + +import ( + "os" + "testing" + + "github.com/enckse/lockbox/internal/backend" +) + +func fullSetup(t *testing.T, keep bool) *backend.Transaction { + if !keep { + os.Remove("test.kdbx") + } + os.Setenv("LOCKBOX_STORE", "test.kdbx") + os.Setenv("LOCKBOX_KEY", "test") + os.Setenv("LOCKBOX_KEYMODE", "plaintext") + tr, err := backend.NewTransaction() + if err != nil { + t.Errorf("failed: %v", err) + } + return tr +} + +func setup(t *testing.T) *backend.Transaction { + return fullSetup(t, false) +} + +func TestBadAction(t *testing.T) { + tr := &backend.Transaction{} + if err := tr.Insert("a", "a", nil, false); err.Error() != "invalid transaction" { + t.Errorf("wrong error: %v", err) + } +} + +func TestInserts(t *testing.T) { + if err := setup(t).Insert("", "", nil, false); err.Error() != "empty path not allowed" { + t.Errorf("wrong error: %v", err) + } + if err := setup(t).Insert("a", "", nil, false); err.Error() != "empty secret not allowed" { + t.Errorf("wrong error: %v", err) + } + if err := setup(t).Insert("value", "pass", nil, false); err != nil { + t.Errorf("no error: %v", err) + } + if err := fullSetup(t, true).Insert("value", "pass", nil, false); err.Error() != "trying to insert over existing entity" { + t.Errorf("wrong error: %v", err) + } + if err := fullSetup(t, true).Insert("value", "pass2", &backend.QueryEntity{Path: "value"}, false); err != nil { + t.Errorf("no error: %v", err) + } + if err := fullSetup(t, true).Insert("value2", "pass", nil, true); err != nil { + t.Errorf("no error: %v", err) + } + q, err := fullSetup(t, true).Get("value", backend.SecretValue) + if err != nil { + t.Errorf("no error: %v", err) + } + if q.Value != "pass2" { + t.Errorf("invalid retrieval") + } + q, err = fullSetup(t, true).Get("value2", backend.SecretValue) + if err != nil { + t.Errorf("no error: %v", err) + } + if q.Value != "pass" { + t.Errorf("invalid retrieval") + } +} + +func TestRemoves(t *testing.T) { + if err := setup(t).Remove(nil); err.Error() != "entity is empty/invalid" { + t.Errorf("wrong error: %v", err) + } + if err := setup(t).Remove(&backend.QueryEntity{}); err.Error() != "unable to select entity for deletion" { + t.Errorf("wrong error: %v", err) + } + setup(t) + for _, i := range []string{"test1", "test2", "test3", "test4", "test5"} { + fullSetup(t, true).Insert(i, "pass", nil, false) + } + if err := fullSetup(t, true).Remove(&backend.QueryEntity{Path: "test3"}); err != nil { + t.Errorf("wrong error: %v", err) + } + check(t, []string{"test1", "test2", "test4", "test5"}) + if err := fullSetup(t, true).Remove(&backend.QueryEntity{Path: "test1"}); err != nil { + t.Errorf("wrong error: %v", err) + } + check(t, []string{"test2", "test4", "test5"}) + if err := fullSetup(t, true).Remove(&backend.QueryEntity{Path: "test5"}); err != nil { + t.Errorf("wrong error: %v", err) + } + check(t, []string{"test2", "test4"}) + if err := fullSetup(t, true).Remove(&backend.QueryEntity{Path: "test4"}); err != nil { + t.Errorf("wrong error: %v", err) + } + check(t, []string{"test2"}) + if err := fullSetup(t, true).Remove(&backend.QueryEntity{Path: "test2"}); err != nil { + t.Errorf("wrong error: %v", err) + } +} + +func check(t *testing.T, checks []string) { + tr := fullSetup(t, true) + for _, c := range checks { + q, err := tr.Get(c, backend.BlankValue) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if q == nil { + t.Errorf("failed to find entity: %s", c) + } + } +} diff --git a/internal/backend/query_test.go b/internal/backend/query_test.go @@ -0,0 +1,117 @@ +package backend_test + +import ( + "path/filepath" + "testing" + + "github.com/enckse/lockbox/internal/backend" +) + +func setupInserts(t *testing.T) { + setup(t) + fullSetup(t, true).Insert("abc", "tedst", nil, false) + fullSetup(t, true).Insert("abcx", "tedst", nil, false) + fullSetup(t, true).Insert("ab11c", "tdest", nil, true) + fullSetup(t, true).Insert("abc1ak", "atest", nil, false) +} + +func TestGet(t *testing.T) { + setupInserts(t) + q, err := fullSetup(t, true).Get("abc", backend.BlankValue) + if err != nil { + t.Errorf("no error: %v", err) + } + if q.Path != "abc" || q.Value != "" { + t.Error("invalid query result") + } + q, err = fullSetup(t, true).Get("aaaa", backend.BlankValue) + if err != nil || q != nil { + t.Error("invalid result, should be empty") + } +} + +func TestValueModes(t *testing.T) { + setupInserts(t) + q, err := fullSetup(t, true).Get("abc", backend.BlankValue) + if err != nil { + t.Errorf("no error: %v", err) + } + if q.Value != "" { + t.Errorf("invalid result value: %s", q.Value) + } + q, err = fullSetup(t, true).Get("abc", backend.HashedValue) + if err != nil { + t.Errorf("no error: %v", err) + } + if q.Value != "44276ba24db13df5568aa6db81e0190ab9d35d2168dce43dca61e628f5c666b1d8b091f1dda59c2359c86e7d393d59723a421d58496d279031e7f858c11d893e" { + t.Errorf("invalid result value: %s", q.Value) + } + q, err = fullSetup(t, true).Get("ab11c", backend.SecretValue) + if err != nil { + t.Errorf("no error: %v", err) + } + if q.Value != "tdest" { + t.Errorf("invalid result value: %s", q.Value) + } +} + +func TestQueryCallback(t *testing.T) { + setupInserts(t) + if _, err := fullSetup(t, true).QueryCallback(backend.QueryOptions{}); err.Error() != "no query mode specified" { + t.Errorf("wrong error: %v", err) + } + res, err := fullSetup(t, true).QueryCallback(backend.QueryOptions{Mode: backend.ListMode}) + if err != nil { + t.Errorf("no error: %v", err) + } + if len(res) != 4 { + t.Error("invalid results: not enough") + } + if res[0].Path != "ab11c" || res[1].Path != "abc" || res[2].Path != "abc1ak" || res[3].Path != "abcx" { + t.Errorf("invalid results: %v", res) + } + res, err = fullSetup(t, true).QueryCallback(backend.QueryOptions{Mode: backend.FindMode, Criteria: "1"}) + if err != nil { + t.Errorf("no error: %v", err) + } + if len(res) != 2 { + t.Error("invalid results: not enough") + } + if res[0].Path != "ab11c" || res[1].Path != "abc1ak" { + t.Errorf("invalid results: %v", res) + } + res, err = fullSetup(t, true).QueryCallback(backend.QueryOptions{Mode: backend.SuffixMode, Criteria: "c"}) + if err != nil { + t.Errorf("no error: %v", err) + } + if len(res) != 2 { + t.Error("invalid results: not enough") + } + if res[0].Path != "ab11c" || res[1].Path != "abc" { + t.Errorf("invalid results: %v", res) + } + res, err = fullSetup(t, true).QueryCallback(backend.QueryOptions{Mode: backend.ExactMode, Criteria: "abc"}) + if err != nil { + t.Errorf("no error: %v", err) + } + if len(res) != 1 { + t.Error("invalid results: not enough") + } + if res[0].Path != "abc" { + t.Errorf("invalid results: %v", res) + } + res, err = fullSetup(t, true).QueryCallback(backend.QueryOptions{Mode: backend.ExactMode, Criteria: "abczzz"}) + if err != nil { + t.Errorf("no error: %v", err) + } + if len(res) != 0 { + t.Error("invalid results: should be empty") + } +} + +func TestEntityDir(t *testing.T) { + q := backend.QueryEntity{Path: filepath.Join("abc", "xyz")} + if q.Directory() != "abc" { + t.Error("invalid query directory") + } +}