Complete search section behavior

This commit is contained in:
Joe Julian
2026-03-29 11:21:02 -07:00
parent 48ffa78fa2
commit f39bdcd3be
4 changed files with 240 additions and 1 deletions
+136
View File
@@ -117,6 +117,142 @@ func TestVisibleEntriesUsesRecycleBinSection(t *testing.T) {
}
}
func TestVisibleEntriesUsesGlobalSearchWithinTemplateSection(t *testing.T) {
t.Parallel()
state := State{
Session: stubSession{
model: vault.Model{
Templates: []vault.Entry{
{ID: "tpl-1", Title: "Website Login", URL: "https://accounts.example.com", Path: []string{"Templates", "Web"}},
{ID: "tpl-2", Title: "SSH Login", URL: "ssh://infra.internal", Path: []string{"Templates", "Infra"}},
},
},
},
Section: SectionTemplates,
CurrentPath: []string{"Templates", "Web"},
SearchQuery: "infra",
}
got, err := state.VisibleEntries()
if err != nil {
t.Fatalf("VisibleEntries() error = %v", err)
}
if len(got) != 1 || got[0].ID != "tpl-2" {
t.Fatalf("VisibleEntries() = %#v, want global template search result tpl-2", got)
}
}
func TestVisibleEntriesResetToCurrentTemplatePathAfterClearingSearch(t *testing.T) {
t.Parallel()
state := State{
Session: stubSession{
model: vault.Model{
Templates: []vault.Entry{
{ID: "tpl-1", Title: "Website Login", Path: []string{"Templates", "Web"}},
{ID: "tpl-2", Title: "Email Login", Path: []string{"Templates", "Web"}},
{ID: "tpl-3", Title: "SSH Login", Path: []string{"Templates", "Infra"}},
},
},
},
Section: SectionTemplates,
CurrentPath: []string{"Templates", "Web"},
SearchQuery: "ssh",
}
got, err := state.VisibleEntries()
if err != nil {
t.Fatalf("VisibleEntries() with search error = %v", err)
}
if len(got) != 1 || got[0].ID != "tpl-3" {
t.Fatalf("VisibleEntries() with search = %#v, want tpl-3", got)
}
state.SearchQuery = ""
got, err = state.VisibleEntries()
if err != nil {
t.Fatalf("VisibleEntries() after clearing search error = %v", err)
}
if len(got) != 2 {
t.Fatalf("len(VisibleEntries()) after clearing search = %d, want 2", len(got))
}
if titles := []string{got[0].Title, got[1].Title}; !slices.Equal(titles, []string{"Email Login", "Website Login"}) {
t.Fatalf("VisibleEntries() after clearing search titles = %v, want [Email Login Website Login]", titles)
}
}
func TestVisibleEntriesUsesGlobalSearchWithinRecycleBin(t *testing.T) {
t.Parallel()
state := State{
Session: stubSession{
model: vault.Model{
RecycleBin: []vault.Entry{
{ID: "deleted-1", Title: "Deleted Dynadot", Path: []string{"Root", "Internet"}},
{ID: "deleted-2", Title: "Deleted HVAC", URL: "https://climate.example.com", Path: []string{"Root", "Home"}},
},
},
},
Section: SectionRecycleBin,
CurrentPath: []string{"Root", "Internet"},
SearchQuery: "climate",
}
got, err := state.VisibleEntries()
if err != nil {
t.Fatalf("VisibleEntries() error = %v", err)
}
if len(got) != 1 || got[0].ID != "deleted-2" {
t.Fatalf("VisibleEntries() = %#v, want global recycle-bin search result deleted-2", got)
}
}
func TestSearchPathContextIncludesSectionRoots(t *testing.T) {
t.Parallel()
tests := []struct {
name string
section Section
entry vault.Entry
want string
}{
{
name: "entries use direct path",
section: SectionEntries,
entry: vault.Entry{Path: []string{"Root", "Internet"}},
want: "Root / Internet",
},
{
name: "templates retain templates root",
section: SectionTemplates,
entry: vault.Entry{Path: []string{"Templates", "Web"}},
want: "Templates / Web",
},
{
name: "recycle bin prefixes root label",
section: SectionRecycleBin,
entry: vault.Entry{Path: []string{"Root", "Internet"}},
want: "Recycle Bin / Root / Internet",
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
state := State{Section: tt.section}
if got := state.SearchPathContext(tt.entry); got != tt.want {
t.Fatalf("SearchPathContext(%v) = %q, want %q", tt.entry.Path, got, tt.want)
}
})
}
}
func TestChildGroupsUsesCurrentModelAndCurrentPath(t *testing.T) {
t.Parallel()