Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b7a898a7f | |||
| 5bf1bdb5f3 | |||
| c09ae8a5fb | |||
| e4e64504b8 | |||
| 3afe9871e7 | |||
| 60172d8c6d | |||
| 84512172f3 | |||
| 26748d4b84 | |||
| 554d4f760d | |||
| 94ee7fd4c0 | |||
| 009c4ecbf6 | |||
| 400278ce0c | |||
| f6aff3e255 | |||
| 53f7a702fe | |||
| 57d6a304db | |||
| 99ff89de32 | |||
| fc59fb4869 | |||
| 8866d9c06f | |||
| b57a671819 | |||
| 03ea224773 | |||
| 8b4f3f91be | |||
| 839cc6cc1c | |||
| 574e2a2762 | |||
| 71a0d75886 | |||
| 73eea0a066 | |||
| 30cab83eaa | |||
| f1ac24efb9 | |||
| fe9f3ae112 | |||
| d037393a16 | |||
| 4f5465dfff | |||
| 05345559ee | |||
| af44810a1c | |||
| 48a21c2c59 | |||
| fc921ca30f | |||
| db74a0a198 | |||
| b27e2f168c | |||
| adf91445c3 | |||
| 37297856c4 | |||
| dc03d6a0a5 | |||
| 4da9c07b32 | |||
| ef01e33990 | |||
| 66d105d2a9 | |||
| 677464dc9a | |||
| 79c5176487 | |||
| 5e1e9f82fb | |||
| 32c7b49f4f |
@@ -95,9 +95,6 @@ These features are product requirements, not “nice to have” ideas.
|
||||
- Phone should optimize for low tap count, not purity of mobile patterns.
|
||||
- The stacked phone layout is the current preferred phone direction.
|
||||
- Do not reintroduce the abandoned phone flow mode unless explicitly requested.
|
||||
- Make all test strings `Heist Movie` themed. Use characters, crews, casinos,
|
||||
vaults, and locations from heist movies so test fixtures stay obviously fake
|
||||
and consistent with the product theme.
|
||||
|
||||
## Architecture
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ func TestRemoteBindingResolveUsesVaultProfileAndCredentialEntry(t *testing.T) {
|
||||
model := vault.Model{
|
||||
Entries: []vault.Entry{
|
||||
{
|
||||
ID: "linuscaldwell-webdav",
|
||||
Title: "Bellagio WebDAV Sign-In",
|
||||
Username: "linuscaldwell",
|
||||
Password: "bellagio-pass-1",
|
||||
ID: "tjulian-webdav",
|
||||
Title: "WebDAV Sign-In",
|
||||
Username: "tjulian",
|
||||
Password: "token-1",
|
||||
Path: []string{"Crew", "Internet"},
|
||||
},
|
||||
},
|
||||
@@ -36,7 +36,7 @@ func TestRemoteBindingResolveUsesVaultProfileAndCredentialEntry(t *testing.T) {
|
||||
binding := RemoteBinding{
|
||||
LocalVaultPath: "/tmp/family.kdbx",
|
||||
RemoteProfileID: "family-webdav",
|
||||
CredentialEntryID: "linuscaldwell-webdav",
|
||||
CredentialEntryID: "tjulian-webdav",
|
||||
SyncMode: SyncModeAutomaticOnOpenSave,
|
||||
}
|
||||
|
||||
@@ -50,11 +50,11 @@ func TestRemoteBindingResolveUsesVaultProfileAndCredentialEntry(t *testing.T) {
|
||||
if got := resolved.Profile.Path; got != "files/family/keepass.kdbx" {
|
||||
t.Fatalf("resolved profile path = %q, want files/family/keepass.kdbx", got)
|
||||
}
|
||||
if got := resolved.Credentials.Username; got != "linuscaldwell" {
|
||||
t.Fatalf("resolved credentials username = %q, want linuscaldwell", got)
|
||||
if got := resolved.Credentials.Username; got != "tjulian" {
|
||||
t.Fatalf("resolved credentials username = %q, want tjulian", got)
|
||||
}
|
||||
if got := resolved.Credentials.Password; got != "bellagio-pass-1" {
|
||||
t.Fatalf("resolved credentials password = %q, want bellagio-pass-1", got)
|
||||
if got := resolved.Credentials.Password; got != "token-1" {
|
||||
t.Fatalf("resolved credentials password = %q, want token-1", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func TestRemoteBindingResolveFailsWhenVaultReferenceIsMissing(t *testing.T) {
|
||||
|
||||
model := vault.Model{
|
||||
Entries: []vault.Entry{
|
||||
{ID: "linuscaldwell-webdav", Title: "Bellagio WebDAV Sign-In"},
|
||||
{ID: "tjulian-webdav", Title: "WebDAV Sign-In"},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ func TestRemoteBindingJSONStoresOnlyNonSecretReferences(t *testing.T) {
|
||||
}
|
||||
|
||||
text := string(content)
|
||||
for _, disallowed := range []string{"bellagio-pass-1", "password", "username", "baseUrl"} {
|
||||
for _, disallowed := range []string{"token-1", "password", "username", "baseUrl"} {
|
||||
if strings.Contains(text, disallowed) {
|
||||
t.Fatalf("binding JSON %q unexpectedly contains %q", text, disallowed)
|
||||
}
|
||||
@@ -127,9 +127,9 @@ func TestConfigureRemoteBindingStoresProfileAndCredentialsInVault(t *testing.T)
|
||||
BaseURL: "https://dav.example.invalid/remote.php/dav",
|
||||
RemotePath: "files/family/keepass.kdbx",
|
||||
CredentialEntryID: "remote-creds-1",
|
||||
CredentialTitle: "Bellagio WebDAV Sign-In",
|
||||
Username: "linuscaldwell",
|
||||
Password: "bellagio-pass-1",
|
||||
CredentialTitle: "WebDAV Sign-In",
|
||||
Username: "tjulian",
|
||||
Password: "token-1",
|
||||
CredentialPath: []string{"Crew", "Internet"},
|
||||
SyncMode: SyncModeAutomaticOnOpenSave,
|
||||
})
|
||||
@@ -148,8 +148,8 @@ func TestConfigureRemoteBindingStoresProfileAndCredentialsInVault(t *testing.T)
|
||||
if err != nil {
|
||||
t.Fatalf("EntryByID(remote-creds-1) error = %v", err)
|
||||
}
|
||||
if credentials.Username != "linuscaldwell" || credentials.Password != "bellagio-pass-1" {
|
||||
t.Fatalf("stored credential entry = %#v, want linuscaldwell/bellagio-pass-1", credentials)
|
||||
if credentials.Username != "tjulian" || credentials.Password != "token-1" {
|
||||
t.Fatalf("stored credential entry = %#v, want tjulian/token-1", credentials)
|
||||
}
|
||||
if credentials.URL != "https://dav.example.invalid/remote.php/dav" {
|
||||
t.Fatalf("stored credential entry URL = %q, want remote.php/dav URL", credentials.URL)
|
||||
@@ -177,7 +177,7 @@ func TestConfigureRemoteBindingRejectsIncompleteInput(t *testing.T) {
|
||||
BaseURL: "https://dav.example.invalid/remote.php/dav",
|
||||
RemotePath: "files/family/keepass.kdbx",
|
||||
CredentialEntryID: "remote-creds-1",
|
||||
Password: "bellagio-pass-1",
|
||||
Password: "token-1",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -187,7 +187,7 @@ func TestConfigureRemoteBindingRejectsIncompleteInput(t *testing.T) {
|
||||
RemoteProfileID: "family-webdav",
|
||||
RemotePath: "files/family/keepass.kdbx",
|
||||
CredentialEntryID: "remote-creds-1",
|
||||
Password: "bellagio-pass-1",
|
||||
Password: "token-1",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -197,7 +197,7 @@ func TestConfigureRemoteBindingRejectsIncompleteInput(t *testing.T) {
|
||||
RemoteProfileID: "family-webdav",
|
||||
BaseURL: "https://dav.example.invalid/remote.php/dav",
|
||||
RemotePath: "files/family/keepass.kdbx",
|
||||
Password: "bellagio-pass-1",
|
||||
Password: "token-1",
|
||||
},
|
||||
},
|
||||
} {
|
||||
@@ -219,9 +219,9 @@ func TestRemoveRemoteBindingRemovesProfileAndCredentialsFromVault(t *testing.T)
|
||||
model := vault.Model{
|
||||
Entries: []vault.Entry{{
|
||||
ID: "remote-creds-1",
|
||||
Title: "Bellagio WebDAV Sign-In",
|
||||
Username: "linuscaldwell",
|
||||
Password: "bellagio-pass-1",
|
||||
Title: "WebDAV Sign-In",
|
||||
Username: "tjulian",
|
||||
Password: "token-1",
|
||||
}},
|
||||
RemoteProfiles: []vault.RemoteProfile{{
|
||||
ID: "family-webdav",
|
||||
|
||||
+40
-40
@@ -22,7 +22,7 @@ func TestVisibleEntriesFollowsCurrentPathWithoutSearch(t *testing.T) {
|
||||
Entries: []vault.Entry{
|
||||
{ID: "bellagio", Title: "Bellagio", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "vault-console", Title: "Vault Console", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", Path: []string{"Crew", "Security Office"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", Path: []string{"Crew", "Home Assistant"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -54,7 +54,7 @@ func TestVisibleEntriesAtParentGroupOnlyShowsDirectEntries(t *testing.T) {
|
||||
{ID: "joe-note", Title: "Crew Note", Path: []string{"Crew"}},
|
||||
{ID: "bellagio", Title: "Bellagio", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "vault-console", Title: "Vault Console", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", Path: []string{"Crew", "Security Office"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", Path: []string{"Crew", "Home Assistant"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -211,7 +211,7 @@ func TestRemoteCredentialEntriesReturnsSortedVaultEntries(t *testing.T) {
|
||||
Entries: []vault.Entry{
|
||||
{ID: "cred-2", Title: "Zulu Sign-In", Username: "zuser", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "cred-1", Title: "Alpha Sign-In", Username: "auser", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "cred-3", Title: "Mint Sign-In", Username: "frankcatton", Path: []string{"Crew", "Safe House"}},
|
||||
{ID: "cred-3", Title: "Beta Sign-In", Username: "buser", Path: []string{"Crew", "Home"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -238,7 +238,7 @@ func TestVisibleEntriesUsesGlobalSearchWhenQueryPresent(t *testing.T) {
|
||||
Entries: []vault.Entry{
|
||||
{ID: "bellagio", Title: "Bellagio", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "vault-console", Title: "Vault Console", URL: "https://vault.crew.example.invalid", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", URL: "https://surveillance.crew.example.invalid", Path: []string{"Crew", "Security Office"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", URL: "https://surveillance.crew.example.invalid", Path: []string{"Crew", "Home Assistant"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -252,7 +252,7 @@ func TestVisibleEntriesUsesGlobalSearchWhenQueryPresent(t *testing.T) {
|
||||
}
|
||||
|
||||
if len(got) != 1 || got[0].Title != "Surveillance Console" {
|
||||
t.Fatalf("VisibleEntries() = %#v, want Security Office search match", got)
|
||||
t.Fatalf("VisibleEntries() = %#v, want Home Assistant search match", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ func TestVisibleEntriesReturnsDescendantsAfterClearingSearch(t *testing.T) {
|
||||
Entries: []vault.Entry{
|
||||
{ID: "bellagio", Title: "Bellagio", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "vault-console", Title: "Vault Console", URL: "https://vault.crew.example.invalid", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", URL: "https://surveillance.crew.example.invalid", Path: []string{"Crew", "Security Office"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", URL: "https://surveillance.crew.example.invalid", Path: []string{"Crew", "Home Assistant"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -415,7 +415,7 @@ func TestVisibleEntriesUsesGlobalSearchWithinRecycleBin(t *testing.T) {
|
||||
model: vault.Model{
|
||||
RecycleBin: []vault.Entry{
|
||||
{ID: "deleted-1", Title: "Deleted Bellagio", Path: []string{"Root", "Internet"}},
|
||||
{ID: "deleted-2", Title: "Deleted Vault Vent", URL: "https://climate.example.com", Path: []string{"Root", "Safe House"}},
|
||||
{ID: "deleted-2", Title: "Deleted HVAC", URL: "https://climate.example.com", Path: []string{"Root", "Home"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -484,7 +484,7 @@ func TestChildGroupsUsesCurrentModelAndCurrentPath(t *testing.T) {
|
||||
model: vault.Model{
|
||||
Entries: []vault.Entry{
|
||||
{ID: "bellagio", Title: "Bellagio", Path: []string{"Crew", "Internet"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", Path: []string{"Crew", "Security Office"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", Path: []string{"Crew", "Home Assistant"}},
|
||||
{ID: "alma", Title: "Alma (WA Prep)", Path: []string{"Tricia", "School"}},
|
||||
},
|
||||
},
|
||||
@@ -497,8 +497,8 @@ func TestChildGroupsUsesCurrentModelAndCurrentPath(t *testing.T) {
|
||||
t.Fatalf("ChildGroups() error = %v", err)
|
||||
}
|
||||
|
||||
if !slices.Equal(got, []string{"Internet", "Security Office"}) {
|
||||
t.Fatalf("ChildGroups() = %v, want [Internet Security Office]", got)
|
||||
if !slices.Equal(got, []string{"Home Assistant", "Internet"}) {
|
||||
t.Fatalf("ChildGroups() = %v, want [Home Assistant Internet]", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,7 +668,7 @@ func TestUpsertEntryPersistsEntryAndSelectsIt(t *testing.T) {
|
||||
ID: "vault-console",
|
||||
Title: "Vault Console",
|
||||
Username: "dannyocean",
|
||||
Password: "bellagio-pass-1",
|
||||
Password: "token-1",
|
||||
URL: "https://vault.crew.example.invalid",
|
||||
Path: []string{"Root", "Internet"},
|
||||
}
|
||||
@@ -684,7 +684,7 @@ func TestUpsertEntryPersistsEntryAndSelectsIt(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("VisibleEntries() error = %v", err)
|
||||
}
|
||||
if len(got) != 1 || got[0].Password != "bellagio-pass-1" {
|
||||
if len(got) != 1 || got[0].Password != "token-1" {
|
||||
t.Fatalf("VisibleEntries() = %#v, want persisted vault-console entry", got)
|
||||
}
|
||||
|
||||
@@ -1037,9 +1037,9 @@ func TestOpenBoundRemoteVaultResolvesClientFromVaultBinding(t *testing.T) {
|
||||
Entries: []vault.Entry{
|
||||
{
|
||||
ID: "remote-creds-1",
|
||||
Title: "Bellagio WebDAV Sign-In",
|
||||
Username: "linuscaldwell",
|
||||
Password: "bellagio-pass-1",
|
||||
Title: "WebDAV Sign-In",
|
||||
Username: "tjulian",
|
||||
Password: "token-1",
|
||||
Path: []string{"Crew", "Internet"},
|
||||
},
|
||||
},
|
||||
@@ -1074,11 +1074,11 @@ func TestOpenBoundRemoteVaultResolvesClientFromVaultBinding(t *testing.T) {
|
||||
if got := sess.remoteClient.BaseURL; got != "https://dav.example.invalid/remote.php/dav" {
|
||||
t.Fatalf("remote client base URL = %q, want remote.php/dav URL", got)
|
||||
}
|
||||
if got := sess.remoteClient.Username; got != "linuscaldwell" {
|
||||
t.Fatalf("remote client username = %q, want linuscaldwell", got)
|
||||
if got := sess.remoteClient.Username; got != "tjulian" {
|
||||
t.Fatalf("remote client username = %q, want tjulian", got)
|
||||
}
|
||||
if got := sess.remoteClient.Password; got != "bellagio-pass-1" {
|
||||
t.Fatalf("remote client password = %q, want bellagio-pass-1", got)
|
||||
if got := sess.remoteClient.Password; got != "token-1" {
|
||||
t.Fatalf("remote client password = %q, want token-1", got)
|
||||
}
|
||||
if got := sess.remotePath; got != "files/family/keepass.kdbx" {
|
||||
t.Fatalf("remotePath = %q, want files/family/keepass.kdbx", got)
|
||||
@@ -1123,9 +1123,9 @@ func TestConfigureRemoteBindingPersistsIntoCurrentVaultAndMarksDirty(t *testing.
|
||||
BaseURL: "https://dav.example.invalid/remote.php/dav",
|
||||
RemotePath: "files/family/keepass.kdbx",
|
||||
CredentialEntryID: "remote-creds-1",
|
||||
CredentialTitle: "Bellagio WebDAV Sign-In",
|
||||
Username: "linuscaldwell",
|
||||
Password: "bellagio-pass-1",
|
||||
CredentialTitle: "WebDAV Sign-In",
|
||||
Username: "tjulian",
|
||||
Password: "token-1",
|
||||
CredentialPath: []string{"Crew", "Internet"},
|
||||
SyncMode: SyncModeAutomaticOnOpenSave,
|
||||
})
|
||||
@@ -1146,8 +1146,8 @@ func TestConfigureRemoteBindingPersistsIntoCurrentVaultAndMarksDirty(t *testing.
|
||||
if err != nil {
|
||||
t.Fatalf("EntryByID(remote-creds-1) error = %v", err)
|
||||
}
|
||||
if credentials.Username != "linuscaldwell" || credentials.Password != "bellagio-pass-1" {
|
||||
t.Fatalf("stored credential entry = %#v, want linuscaldwell/bellagio-pass-1", credentials)
|
||||
if credentials.Username != "tjulian" || credentials.Password != "token-1" {
|
||||
t.Fatalf("stored credential entry = %#v, want tjulian/token-1", credentials)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1161,7 +1161,7 @@ func TestConfigureRemoteBindingRequiresMutableSession(t *testing.T) {
|
||||
BaseURL: "https://dav.example.invalid/remote.php/dav",
|
||||
RemotePath: "files/family/keepass.kdbx",
|
||||
CredentialEntryID: "remote-creds-1",
|
||||
Password: "bellagio-pass-1",
|
||||
Password: "token-1",
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("ConfigureRemoteBinding() error = nil, want mutability error")
|
||||
@@ -1174,9 +1174,9 @@ func TestRemoveRemoteBindingRemovesVaultDataAndMarksDirty(t *testing.T) {
|
||||
sess := &mutableStubSession{model: vault.Model{
|
||||
Entries: []vault.Entry{{
|
||||
ID: "remote-creds-1",
|
||||
Title: "Bellagio WebDAV Sign-In",
|
||||
Username: "linuscaldwell",
|
||||
Password: "bellagio-pass-1",
|
||||
Title: "WebDAV Sign-In",
|
||||
Username: "tjulian",
|
||||
Password: "token-1",
|
||||
}},
|
||||
RemoteProfiles: []vault.RemoteProfile{{
|
||||
ID: "family-webdav",
|
||||
@@ -1393,10 +1393,10 @@ func TestNavigateToPathReplacesPathAndClearsSelection(t *testing.T) {
|
||||
SelectedEntryID: "vault-console",
|
||||
}
|
||||
|
||||
state.NavigateToPath([]string{"Root", "Security Office"})
|
||||
state.NavigateToPath([]string{"Root", "Home Assistant"})
|
||||
|
||||
if !slices.Equal(state.CurrentPath, []string{"Root", "Security Office"}) {
|
||||
t.Fatalf("CurrentPath = %v, want [Root Security Office]", state.CurrentPath)
|
||||
if !slices.Equal(state.CurrentPath, []string{"Root", "Home Assistant"}) {
|
||||
t.Fatalf("CurrentPath = %v, want [Root Home Assistant]", state.CurrentPath)
|
||||
}
|
||||
if got := state.SelectedEntryID; got != "" {
|
||||
t.Fatalf("SelectedEntryID = %q, want empty", got)
|
||||
@@ -1429,8 +1429,8 @@ func TestDeleteCurrentGroupMovesToParentAndMarksDirty(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("ChildGroups() error = %v", err)
|
||||
}
|
||||
if !slices.Equal(got, []string{"Internet", "Security Office"}) {
|
||||
t.Fatalf("ChildGroups() = %v, want [Internet Security Office]", got)
|
||||
if !slices.Equal(got, []string{"Home Assistant", "Internet"}) {
|
||||
t.Fatalf("ChildGroups() = %v, want [Home Assistant Internet]", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1452,8 +1452,8 @@ func TestCreateGroupPersistsGroupAndMarksDirty(t *testing.T) {
|
||||
t.Fatalf("ChildGroups() error = %v", err)
|
||||
}
|
||||
|
||||
if !slices.Equal(got, []string{"Finance", "Internet", "Security Office"}) {
|
||||
t.Fatalf("ChildGroups() = %v, want Finance, Internet, Security Office", got)
|
||||
if !slices.Equal(got, []string{"Finance", "Home Assistant", "Internet"}) {
|
||||
t.Fatalf("ChildGroups() = %v, want Finance, Home Assistant, Internet", got)
|
||||
}
|
||||
if !state.Dirty {
|
||||
t.Fatal("Dirty = false, want true after CreateGroup")
|
||||
@@ -1526,8 +1526,8 @@ func TestDeleteCurrentGroupRemovesItNavigatesToParentAndMarksDirty(t *testing.T)
|
||||
t.Fatalf("ChildGroups() error = %v", err)
|
||||
}
|
||||
|
||||
if !slices.Equal(got, []string{"Internet", "Security Office"}) {
|
||||
t.Fatalf("ChildGroups() = %v, want [Internet Security Office]", got)
|
||||
if !slices.Equal(got, []string{"Home Assistant", "Internet"}) {
|
||||
t.Fatalf("ChildGroups() = %v, want [Home Assistant Internet]", got)
|
||||
}
|
||||
if !state.Dirty {
|
||||
t.Fatal("Dirty = false, want true after DeleteCurrentGroup")
|
||||
@@ -1544,11 +1544,11 @@ func TestMoveSelectedEntryPersistsPathChangeAndMarksDirty(t *testing.T) {
|
||||
SelectedEntryID: "bellagio",
|
||||
}
|
||||
|
||||
if err := state.MoveSelectedEntry([]string{"Root", "Security Office"}); err != nil {
|
||||
if err := state.MoveSelectedEntry([]string{"Root", "Home Assistant"}); err != nil {
|
||||
t.Fatalf("MoveSelectedEntry() error = %v", err)
|
||||
}
|
||||
|
||||
state.NavigateToPath([]string{"Root", "Security Office"})
|
||||
state.NavigateToPath([]string{"Root", "Home Assistant"})
|
||||
got, err := state.VisibleEntries()
|
||||
if err != nil {
|
||||
t.Fatalf("VisibleEntries() error = %v", err)
|
||||
@@ -1756,7 +1756,7 @@ func testVaultModel() vault.Model {
|
||||
return vault.Model{
|
||||
Entries: []vault.Entry{
|
||||
{ID: "bellagio", Title: "Bellagio", Path: []string{"Root", "Internet"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", Path: []string{"Root", "Security Office"}},
|
||||
{ID: "surveillance-console", Title: "Surveillance Console", Path: []string{"Root", "Home Assistant"}},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
+211
-211
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
pkgbase = keepassgo-git
|
||||
pkgdesc = KeePass-compatible password manager written in Go
|
||||
pkgver = r165.1c72a50
|
||||
pkgver = r160.5fa79bd
|
||||
pkgrel = 1
|
||||
url = https://git.julianfamily.org/joejulian/keepassgo
|
||||
arch = x86_64
|
||||
|
||||
+41
-41
@@ -23,10 +23,10 @@ func TestLoadKDBXBuildsModelFromNestedGroups(t *testing.T) {
|
||||
mustGroup("Root",
|
||||
mustGroup("Internet",
|
||||
mustEntry("Bellagio", "rustyryan", "https://bellagio.example.invalid", "hunter2"),
|
||||
mustEntry("Vault Console", "dannyocean", "https://vault.crew.example.invalid", "bellagio-pass-1"),
|
||||
mustEntry("Vault Console", "dannyocean", "https://vault.crew.example.invalid", "token-1"),
|
||||
),
|
||||
mustGroup("Security Office",
|
||||
mustEntry("Surveillance Console", "bashertarr", "https://surveillance.crew.example.invalid", "bellagio-pass-2"),
|
||||
mustGroup("Home Assistant",
|
||||
mustEntry("Surveillance Console", "codex", "https://surveillance.crew.example.invalid", "token-2"),
|
||||
),
|
||||
),
|
||||
},
|
||||
@@ -62,15 +62,15 @@ func TestLoadKDBXBuildsModelFromNestedGroups(t *testing.T) {
|
||||
}
|
||||
|
||||
groups := model.ChildGroups([]string{"Root"})
|
||||
if len(groups) != 2 || groups[0] != "Internet" || groups[1] != "Security Office" {
|
||||
t.Fatalf("ChildGroups() = %v, want [Internet Security Office]", groups)
|
||||
if len(groups) != 2 || groups[0] != "Home Assistant" || groups[1] != "Internet" {
|
||||
t.Fatalf("ChildGroups() = %v, want [Home Assistant Internet]", groups)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadKDBXPreservesEntryDetails(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
entry := mustEntry("Surveillance Console", "bashertarr", "https://surveillance.crew.example.invalid", "bellagio-pass-2")
|
||||
entry := mustEntry("Surveillance Console", "codex", "https://surveillance.crew.example.invalid", "token-2")
|
||||
entry.Tags = "automation; home"
|
||||
entry.Values = append(entry.Values,
|
||||
mkValue("Notes", "Long-lived token used by Codex for home automation tasks."),
|
||||
@@ -84,7 +84,7 @@ func TestLoadKDBXPreservesEntryDetails(t *testing.T) {
|
||||
Meta: gokeepasslib.NewMetaData(),
|
||||
Root: &gokeepasslib.RootData{
|
||||
Groups: []gokeepasslib.Group{
|
||||
mustGroup("Root", mustGroup("Security Office", entry)),
|
||||
mustGroup("Root", mustGroup("Home Assistant", entry)),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -104,13 +104,13 @@ func TestLoadKDBXPreservesEntryDetails(t *testing.T) {
|
||||
t.Fatalf("LoadKDBX failed: %v", err)
|
||||
}
|
||||
|
||||
got := model.EntriesInPath([]string{"Root", "Security Office"})
|
||||
got := model.EntriesInPath([]string{"Root", "Home Assistant"})
|
||||
if len(got) != 1 {
|
||||
t.Fatalf("len(EntriesInPath()) = %d, want 1", len(got))
|
||||
}
|
||||
|
||||
if got[0].Password != "bellagio-pass-2" {
|
||||
t.Fatalf("Entry.Password = %q, want %q", got[0].Password, "bellagio-pass-2")
|
||||
if got[0].Password != "token-2" {
|
||||
t.Fatalf("Entry.Password = %q, want %q", got[0].Password, "token-2")
|
||||
}
|
||||
|
||||
if got[0].Notes != "Long-lived token used by Codex for home automation tasks." {
|
||||
@@ -135,7 +135,7 @@ func TestSaveKDBXRoundTripsModel(t *testing.T) {
|
||||
ID: "entry-1",
|
||||
Title: "Vault Console",
|
||||
Username: "dannyocean",
|
||||
Password: "bellagio-pass-1",
|
||||
Password: "token-1",
|
||||
URL: "https://vault.crew.example.invalid",
|
||||
Notes: "Personal git server token entry used for automation and CLI auth.",
|
||||
Tags: []string{"git", "infra"},
|
||||
@@ -147,12 +147,12 @@ func TestSaveKDBXRoundTripsModel(t *testing.T) {
|
||||
{
|
||||
ID: "entry-2",
|
||||
Title: "Surveillance Console",
|
||||
Username: "bashertarr",
|
||||
Password: "bellagio-pass-2",
|
||||
Username: "codex",
|
||||
Password: "token-2",
|
||||
URL: "https://surveillance.crew.example.invalid",
|
||||
Notes: "Long-lived token used by Codex for home automation tasks.",
|
||||
Tags: []string{"automation", "home"},
|
||||
Path: []string{"Root", "Security Office"},
|
||||
Path: []string{"Root", "Home Assistant"},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -180,13 +180,13 @@ func TestSaveKDBXRoundTripsModel(t *testing.T) {
|
||||
t.Fatalf("Search(\"git\") X-Role = %q, want %q", got[0].Entry.Fields["X-Role"], "automation")
|
||||
}
|
||||
|
||||
homeAssistant := loaded.EntriesInPath([]string{"Root", "Security Office"})
|
||||
homeAssistant := loaded.EntriesInPath([]string{"Root", "Home Assistant"})
|
||||
if len(homeAssistant) != 1 {
|
||||
t.Fatalf("len(EntriesInPath(Security Office)) = %d, want 1", len(homeAssistant))
|
||||
t.Fatalf("len(EntriesInPath(Home Assistant)) = %d, want 1", len(homeAssistant))
|
||||
}
|
||||
|
||||
if homeAssistant[0].Password != "bellagio-pass-2" {
|
||||
t.Fatalf("Security Office password = %q, want %q", homeAssistant[0].Password, "bellagio-pass-2")
|
||||
if homeAssistant[0].Password != "token-2" {
|
||||
t.Fatalf("Home Assistant password = %q, want %q", homeAssistant[0].Password, "token-2")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,10 +341,10 @@ func TestSaveKDBXRoundTripsRecycleBinEntries(t *testing.T) {
|
||||
{
|
||||
ID: "entry-1",
|
||||
Title: "Surveillance Console",
|
||||
Username: "bashertarr",
|
||||
Password: "bellagio-pass-2",
|
||||
Username: "codex",
|
||||
Password: "token-2",
|
||||
URL: "https://surveillance.crew.example.invalid",
|
||||
Path: []string{"Root", "Security Office"},
|
||||
Path: []string{"Root", "Home Assistant"},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -367,8 +367,8 @@ func TestSaveKDBXRoundTripsRecycleBinEntries(t *testing.T) {
|
||||
t.Fatalf("RecycleBin[0].Title = %q, want %q", loaded.RecycleBin[0].Title, "Surveillance Console")
|
||||
}
|
||||
|
||||
if len(loaded.RecycleBin[0].Path) != 2 || loaded.RecycleBin[0].Path[0] != "Root" || loaded.RecycleBin[0].Path[1] != "Security Office" {
|
||||
t.Fatalf("RecycleBin[0].Path = %v, want [Root Security Office]", loaded.RecycleBin[0].Path)
|
||||
if len(loaded.RecycleBin[0].Path) != 2 || loaded.RecycleBin[0].Path[0] != "Root" || loaded.RecycleBin[0].Path[1] != "Home Assistant" {
|
||||
t.Fatalf("RecycleBin[0].Path = %v, want [Root Home Assistant]", loaded.RecycleBin[0].Path)
|
||||
}
|
||||
|
||||
if len(loaded.Entries) != 0 {
|
||||
@@ -402,7 +402,7 @@ func TestLoadKDBXWithKeyFileCredentials(t *testing.T) {
|
||||
Meta: gokeepasslib.NewMetaData(),
|
||||
Root: &gokeepasslib.RootData{
|
||||
Groups: []gokeepasslib.Group{
|
||||
mustGroup("Root", mustGroup("Internet", mustEntry("Vault Console", "dannyocean", "https://vault.crew.example.invalid", "bellagio-pass-1"))),
|
||||
mustGroup("Root", mustGroup("Internet", mustEntry("Vault Console", "dannyocean", "https://vault.crew.example.invalid", "token-1"))),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -423,7 +423,7 @@ func TestLoadKDBXWithKeyFileCredentials(t *testing.T) {
|
||||
}
|
||||
|
||||
got := model.Search("vault")
|
||||
if len(got) != 1 || got[0].Entry.Password != "bellagio-pass-1" {
|
||||
if len(got) != 1 || got[0].Entry.Password != "token-1" {
|
||||
t.Fatalf("LoadKDBXWithKey() = %#v, want password-preserving vault entry", got)
|
||||
}
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func TestLoadKDBXWithCompositeCredentials(t *testing.T) {
|
||||
Meta: gokeepasslib.NewMetaData(),
|
||||
Root: &gokeepasslib.RootData{
|
||||
Groups: []gokeepasslib.Group{
|
||||
mustGroup("Root", mustGroup("Security Office", mustEntry("Surveillance Console", "bashertarr", "https://surveillance.crew.example.invalid", "bellagio-pass-2"))),
|
||||
mustGroup("Root", mustGroup("Home Assistant", mustEntry("Surveillance Console", "codex", "https://surveillance.crew.example.invalid", "token-2"))),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -480,9 +480,9 @@ func TestLoadKDBXWithCompositeCredentials(t *testing.T) {
|
||||
t.Fatalf("LoadKDBXWithKey() error = %v", err)
|
||||
}
|
||||
|
||||
got := model.EntriesInPath([]string{"Root", "Security Office"})
|
||||
if len(got) != 1 || got[0].Password != "bellagio-pass-2" {
|
||||
t.Fatalf("LoadKDBXWithKey() = %#v, want Security Office entry with password", got)
|
||||
got := model.EntriesInPath([]string{"Root", "Home Assistant"})
|
||||
if len(got) != 1 || got[0].Password != "token-2" {
|
||||
t.Fatalf("LoadKDBXWithKey() = %#v, want Home Assistant entry with password", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ func TestLoadKDBXReturnsInvalidCredentialsError(t *testing.T) {
|
||||
Meta: gokeepasslib.NewMetaData(),
|
||||
Root: &gokeepasslib.RootData{
|
||||
Groups: []gokeepasslib.Group{
|
||||
mustGroup("Root", mustGroup("Internet", mustEntry("Vault Console", "dannyocean", "https://vault.crew.example.invalid", "bellagio-pass-1"))),
|
||||
mustGroup("Root", mustGroup("Internet", mustEntry("Vault Console", "dannyocean", "https://vault.crew.example.invalid", "token-1"))),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -537,7 +537,7 @@ func TestSaveKDBXWithKeyRoundTripsModel(t *testing.T) {
|
||||
ID: "vault-console",
|
||||
Title: "Vault Console",
|
||||
Username: "dannyocean",
|
||||
Password: "bellagio-pass-1",
|
||||
Password: "token-1",
|
||||
URL: "https://vault.crew.example.invalid",
|
||||
Path: []string{"Root", "Internet"},
|
||||
},
|
||||
@@ -555,7 +555,7 @@ func TestSaveKDBXWithKeyRoundTripsModel(t *testing.T) {
|
||||
}
|
||||
|
||||
got := loaded.Search("vault")
|
||||
if len(got) != 1 || got[0].Entry.Password != "bellagio-pass-1" {
|
||||
if len(got) != 1 || got[0].Entry.Password != "token-1" {
|
||||
t.Fatalf("round-trip with key file = %#v, want vault entry with password", got)
|
||||
}
|
||||
}
|
||||
@@ -579,10 +579,10 @@ func TestSaveKDBXWithCompositeKeyRoundTripsModel(t *testing.T) {
|
||||
{
|
||||
ID: "surveillance-console",
|
||||
Title: "Surveillance Console",
|
||||
Username: "bashertarr",
|
||||
Password: "bellagio-pass-2",
|
||||
Username: "codex",
|
||||
Password: "token-2",
|
||||
URL: "https://surveillance.crew.example.invalid",
|
||||
Path: []string{"Root", "Security Office"},
|
||||
Path: []string{"Root", "Home Assistant"},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -602,9 +602,9 @@ func TestSaveKDBXWithCompositeKeyRoundTripsModel(t *testing.T) {
|
||||
t.Fatalf("LoadKDBXWithKey() error = %v", err)
|
||||
}
|
||||
|
||||
got := loaded.EntriesInPath([]string{"Root", "Security Office"})
|
||||
if len(got) != 1 || got[0].Password != "bellagio-pass-2" {
|
||||
t.Fatalf("composite key round-trip = %#v, want Security Office entry with password", got)
|
||||
got := loaded.EntriesInPath([]string{"Root", "Home Assistant"})
|
||||
if len(got) != 1 || got[0].Password != "token-2" {
|
||||
t.Fatalf("composite key round-trip = %#v, want Home Assistant entry with password", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,7 +617,7 @@ func TestKDBXRoundTripsEntryAttachments(t *testing.T) {
|
||||
ID: "vault-console",
|
||||
Title: "Vault Console",
|
||||
Username: "dannyocean",
|
||||
Password: "bellagio-pass-1",
|
||||
Password: "token-1",
|
||||
URL: "https://vault.crew.example.invalid",
|
||||
Path: []string{"Root", "Internet"},
|
||||
Attachments: map[string][]byte{
|
||||
@@ -656,7 +656,7 @@ func TestKDBXReopenCyclesPreserveStableIDsAndCrossFeatureState(t *testing.T) {
|
||||
ID: "entry-1",
|
||||
Title: "Vault Console",
|
||||
Username: "dannyocean",
|
||||
Password: "bellagio-pass-2",
|
||||
Password: "token-2",
|
||||
URL: "https://vault.crew.example.invalid",
|
||||
Notes: "Current credential",
|
||||
Path: []string{"Root", "Internet"},
|
||||
@@ -668,7 +668,7 @@ func TestKDBXReopenCyclesPreserveStableIDsAndCrossFeatureState(t *testing.T) {
|
||||
ID: "entry-1-history-1",
|
||||
Title: "Vault Console",
|
||||
Username: "dannyocean",
|
||||
Password: "bellagio-pass-1",
|
||||
Password: "token-1",
|
||||
URL: "https://vault.crew.example.invalid",
|
||||
Notes: "Original credential",
|
||||
Path: []string{"Root", "Internet"},
|
||||
|
||||
Reference in New Issue
Block a user