Press [ in detail view to open link picker showing all [[links]] in the current entry. Enter follows a link, resolving by title then body substring. Navigation history stack enables esc to pop back through followed links before returning to list. Adds Store.ResolveLink() for non-transactional link resolution from the TUI layer.
This commit is contained in:
@@ -223,3 +223,50 @@ func TestSyncLinks_DeletedSourceHidden(t *testing.T) {
|
||||
t.Fatalf("soft-deleted source should not appear in backlinks, got %d", len(backlinks))
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveLink_TitleMatch(t *testing.T) {
|
||||
s := testStore(t)
|
||||
ctx := context.Background()
|
||||
|
||||
title := "nginx config"
|
||||
target := &Entity{Body: "proxy_pass details", Title: &title, Glyph: "note", Tags: []string{}}
|
||||
if err := s.Create(ctx, target); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resolved, err := s.ResolveLink(ctx, "nginx config")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resolved.ID != target.ID {
|
||||
t.Errorf("resolved ID = %s, want %s", resolved.ID, target.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveLink_BodyFallback(t *testing.T) {
|
||||
s := testStore(t)
|
||||
ctx := context.Background()
|
||||
|
||||
target := &Entity{Body: "deploy staging checklist", Glyph: "note", Tags: []string{}}
|
||||
if err := s.Create(ctx, target); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resolved, err := s.ResolveLink(ctx, "deploy staging")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if resolved.ID != target.ID {
|
||||
t.Errorf("resolved ID = %s, want %s", resolved.ID, target.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveLink_NotFound(t *testing.T) {
|
||||
s := testStore(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, err := s.ResolveLink(ctx, "nonexistent entry")
|
||||
if err != ErrNotFound {
|
||||
t.Errorf("expected ErrNotFound, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user