feat(pipeline): add CanonicalizeLinks — convert [[Display Name]] to [[slug|Display Name]]
This commit is contained in:
125
ingestion/internal/pipeline/links_test.go
Normal file
125
ingestion/internal/pipeline/links_test.go
Normal file
@@ -0,0 +1,125 @@
|
||||
// ingestion/internal/pipeline/links_test.go
|
||||
package pipeline
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mathiasbq/hyperguild/ingestion/internal/wiki"
|
||||
)
|
||||
|
||||
func TestCanonicalizeLinks_KnownTitle(t *testing.T) {
|
||||
pages := []wiki.Page{
|
||||
{
|
||||
Path: "wiki/sources/shape-up.md",
|
||||
Content: "---\ntitle: 'Shape Up'\n---\n\n## Summary\n\nSee [[Betting]].\n",
|
||||
},
|
||||
}
|
||||
inventory := map[wiki.PageType][]wiki.Entry{
|
||||
wiki.PageTypeConcept: {
|
||||
{Slug: "betting", Title: "Betting"},
|
||||
},
|
||||
}
|
||||
got, warnings := CanonicalizeLinks(pages, inventory)
|
||||
require.Len(t, got, 1)
|
||||
assert.Empty(t, warnings)
|
||||
assert.Contains(t, got[0].Content, "[[betting|Betting]]")
|
||||
assert.NotContains(t, got[0].Content, "[[Betting]]")
|
||||
}
|
||||
|
||||
func TestCanonicalizeLinks_UnknownTitleLeftAsIs(t *testing.T) {
|
||||
pages := []wiki.Page{
|
||||
{
|
||||
Path: "wiki/sources/shape-up.md",
|
||||
Content: "---\ntitle: 'Shape Up'\n---\n\n## Summary\n\nSee [[Ghost Concept]].\n",
|
||||
},
|
||||
}
|
||||
inventory := map[wiki.PageType][]wiki.Entry{}
|
||||
got, warnings := CanonicalizeLinks(pages, inventory)
|
||||
require.Len(t, got, 1)
|
||||
assert.NotEmpty(t, warnings)
|
||||
assert.Contains(t, got[0].Content, "[[Ghost Concept]]")
|
||||
}
|
||||
|
||||
func TestCanonicalizeLinks_AlreadyCanonicalLinkUntouched(t *testing.T) {
|
||||
// Links already in [[slug|Display]] format must not be double-converted
|
||||
pages := []wiki.Page{
|
||||
{
|
||||
Path: "wiki/sources/shape-up.md",
|
||||
Content: "---\ntitle: 'Shape Up'\n---\n\n## Summary\n\nSee [[betting|Betting]].\n",
|
||||
},
|
||||
}
|
||||
inventory := map[wiki.PageType][]wiki.Entry{
|
||||
wiki.PageTypeConcept: {
|
||||
{Slug: "betting", Title: "Betting"},
|
||||
},
|
||||
}
|
||||
got, warnings := CanonicalizeLinks(pages, inventory)
|
||||
require.Len(t, got, 1)
|
||||
assert.Empty(t, warnings)
|
||||
// Should remain exactly as-is — not double-wrapped
|
||||
assert.Contains(t, got[0].Content, "[[betting|Betting]]")
|
||||
assert.NotContains(t, got[0].Content, "[[betting|[[betting|Betting]]]]")
|
||||
}
|
||||
|
||||
func TestCanonicalizeLinks_CaseInsensitiveMatch(t *testing.T) {
|
||||
pages := []wiki.Page{
|
||||
{
|
||||
Path: "wiki/sources/foo.md",
|
||||
Content: "---\ntitle: 'Foo'\n---\n\n## Summary\n\nSee [[domain driven design]].\n",
|
||||
},
|
||||
}
|
||||
inventory := map[wiki.PageType][]wiki.Entry{
|
||||
wiki.PageTypeConcept: {
|
||||
{Slug: "domain-driven-design", Title: "Domain Driven Design"},
|
||||
},
|
||||
}
|
||||
got, warnings := CanonicalizeLinks(pages, inventory)
|
||||
require.Len(t, got, 1)
|
||||
assert.Empty(t, warnings)
|
||||
assert.Contains(t, got[0].Content, "[[domain-driven-design|domain driven design]]")
|
||||
}
|
||||
|
||||
func TestCanonicalizeLinks_CurrentBatchPagesResolved(t *testing.T) {
|
||||
// A concept created in the same batch should be canonicalizable
|
||||
pages := []wiki.Page{
|
||||
{
|
||||
Path: "wiki/sources/shape-up.md",
|
||||
Content: "---\ntitle: 'Shape Up'\n---\n\n## Summary\n\nSee [[Betting]].\n",
|
||||
},
|
||||
{
|
||||
Path: "wiki/concepts/betting.md",
|
||||
Content: "---\ntitle: 'Betting'\n---\n\n## Definition\n\nA technique.\n",
|
||||
},
|
||||
}
|
||||
inventory := map[wiki.PageType][]wiki.Entry{} // empty — Betting is in the batch, not inventory
|
||||
|
||||
got, warnings := CanonicalizeLinks(pages, inventory)
|
||||
require.Len(t, got, 2)
|
||||
assert.Empty(t, warnings)
|
||||
assert.Contains(t, got[0].Content, "[[betting|Betting]]")
|
||||
}
|
||||
|
||||
func TestCanonicalizeLinks_MultipleLinksInOnePage(t *testing.T) {
|
||||
pages := []wiki.Page{
|
||||
{
|
||||
Path: "wiki/sources/foo.md",
|
||||
Content: "---\ntitle: 'Foo'\n---\n\n## Summary\n\nSee [[Betting]] and [[Shape Up]].\n",
|
||||
},
|
||||
}
|
||||
inventory := map[wiki.PageType][]wiki.Entry{
|
||||
wiki.PageTypeConcept: {
|
||||
{Slug: "betting", Title: "Betting"},
|
||||
},
|
||||
wiki.PageTypeSource: {
|
||||
{Slug: "shape-up", Title: "Shape Up"},
|
||||
},
|
||||
}
|
||||
got, warnings := CanonicalizeLinks(pages, inventory)
|
||||
require.Len(t, got, 1)
|
||||
assert.Empty(t, warnings)
|
||||
assert.Contains(t, got[0].Content, "[[betting|Betting]]")
|
||||
assert.Contains(t, got[0].Content, "[[shape-up|Shape Up]]")
|
||||
}
|
||||
Reference in New Issue
Block a user