feat(workspace): add hashtag indexing, tag pages and bullet group view
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m0s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m0s
This commit is contained in:
1 parent
c4b2a00348
commit
1310f8102e
8 files changed
+893
-11
No files matched your search
@@ -398,3 +398,107 @@ func TestFolderManagementAndDeletion(t *testing.T) {
|
||||
t.Fatalf("expected directory %s to be deleted on disk", diskFolder)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkspaceBlockHashtagsAndDetails(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
dbPath := filepath.Join(tmpDir, "tags_test.db")
|
||||
|
||||
store, err := NewStore(dbPath)
|
||||
if err != nil {
|
||||
t.Fatalf("NewStore failed: %v", err)
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
user, err := store.CreateUser("taguser@example.com", "hash", "Tag User", "member")
|
||||
if err != nil {
|
||||
t.Fatalf("CreateUser failed: %v", err)
|
||||
}
|
||||
|
||||
// Create document with nested bullet points and hashtags
|
||||
blocks := []domain.DocumentBlock{
|
||||
{ID: "b0", Type: "bullet", Content: "Einleitung ohne Tag", Level: 0},
|
||||
{ID: "b1", Type: "bullet", Content: "Einkauf planen #Kühlregal #Wocheneinkauf", Level: 0},
|
||||
{ID: "b2", Type: "bullet", Content: "Milch 3.8%", Level: 1},
|
||||
{ID: "b3", Type: "bullet", Content: "Gouda alt", Level: 1},
|
||||
{ID: "b4", Type: "bullet", Content: "Zusatzinfo: Aus Weidemilch", Level: 2},
|
||||
{ID: "b5", Type: "bullet", Content: "Anderes Thema ohne Bezug", Level: 0},
|
||||
}
|
||||
|
||||
doc, err := store.CreateDocument(user.ID, "", "Einkaufszettel", "🛒", "Haushalt", blocks, nil, false)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateDocument failed: %v", err)
|
||||
}
|
||||
|
||||
// 1. Check GetWorkspaceTags
|
||||
tags, err := store.GetWorkspaceTags(user.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetWorkspaceTags failed: %v", err)
|
||||
}
|
||||
if len(tags) != 2 {
|
||||
t.Fatalf("expected 2 tags, got %d (%v)", len(tags), tags)
|
||||
}
|
||||
tagMap := make(map[string]int)
|
||||
for _, tg := range tags {
|
||||
tagMap[tg.Tag] = tg.Count
|
||||
}
|
||||
if tagMap["kühlregal"] != 1 || tagMap["wocheneinkauf"] != 1 {
|
||||
t.Fatalf("unexpected tag counts: %v", tagMap)
|
||||
}
|
||||
|
||||
// 2. Check GetTagDetails for #Kühlregal
|
||||
details, err := store.GetTagDetails(user.ID, "#Kühlregal")
|
||||
if err != nil {
|
||||
t.Fatalf("GetTagDetails failed: %v", err)
|
||||
}
|
||||
if details.Tag != "kühlregal" {
|
||||
t.Fatalf("expected tag 'kühlregal', got %s", details.Tag)
|
||||
}
|
||||
if details.TotalMatches != 1 {
|
||||
t.Fatalf("expected 1 match, got %d", details.TotalMatches)
|
||||
}
|
||||
if len(details.Documents) != 1 {
|
||||
t.Fatalf("expected 1 document, got %d", len(details.Documents))
|
||||
}
|
||||
docGroup := details.Documents[0]
|
||||
if docGroup.DocID != doc.ID || docGroup.Title != "Einkaufszettel" {
|
||||
t.Fatalf("unexpected doc group: %+v", docGroup)
|
||||
}
|
||||
if len(docGroup.MatchedBlocks) != 1 {
|
||||
t.Fatalf("expected 1 matched block, got %d", len(docGroup.MatchedBlocks))
|
||||
}
|
||||
matched := docGroup.MatchedBlocks[0]
|
||||
if matched.RootBlock.ID != "b1" {
|
||||
t.Fatalf("expected root block b1, got %s", matched.RootBlock.ID)
|
||||
}
|
||||
// Children should be b2, b3, b4 (all subsequent blocks with Level > 0 until b5 where Level == 0)
|
||||
if len(matched.Children) != 3 {
|
||||
t.Fatalf("expected 3 children (b2, b3, b4), got %d (%v)", len(matched.Children), matched.Children)
|
||||
}
|
||||
if matched.Children[0].ID != "b2" || matched.Children[1].ID != "b3" || matched.Children[2].ID != "b4" {
|
||||
t.Fatalf("unexpected children IDs: %v", matched.Children)
|
||||
}
|
||||
|
||||
// 3. Update document: remove #Wocheneinkauf, add #Vorrat
|
||||
updatedBlocks := []domain.DocumentBlock{
|
||||
{ID: "b1", Type: "bullet", Content: "Einkauf planen #Kühlregal #Vorrat", Level: 0},
|
||||
}
|
||||
_, err = store.UpdateDocument(user.ID, doc.ID, nil, nil, nil, &updatedBlocks, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("UpdateDocument failed: %v", err)
|
||||
}
|
||||
|
||||
tagsAfter, err := store.GetWorkspaceTags(user.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetWorkspaceTags after update failed: %v", err)
|
||||
}
|
||||
tagMapAfter := make(map[string]int)
|
||||
for _, tg := range tagsAfter {
|
||||
tagMapAfter[tg.Tag] = tg.Count
|
||||
}
|
||||
if tagMapAfter["wocheneinkauf"] != 0 {
|
||||
t.Fatalf("expected wocheneinkauf to be removed, got %v", tagMapAfter)
|
||||
}
|
||||
if tagMapAfter["vorrat"] != 1 || tagMapAfter["kühlregal"] != 1 {
|
||||
t.Fatalf("expected vorrat and kühlregal, got %v", tagMapAfter)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user