Collections listed with owner, model, documents and grants; A makes one; on a row its documents, grant, revoke, a search to try, delete. docs/knowledge.md says what administrators do and how people use llmgw-kb on Windows, macOS and Linux: what it reads, what leaves their machine, where its ledger is. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
63 lines
2.2 KiB
Go
63 lines
2.2 KiB
Go
package cli
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
|
|
"gitea.mynodes.xyz/ilker/llmgw/internal/control/adminapi"
|
|
)
|
|
|
|
func TestACollectionIsMadeAndGrantedFromTheConsole(t *testing.T) {
|
|
m, s := consoleWith(t, cKB)
|
|
m.data.models = append(m.data.models, adminapi.ModelView{Name: "bge-m3"})
|
|
m.kb = kbState{loaded: true, view: adminapi.KBView{Available: true, Collections: []adminapi.KBCollectionView{{
|
|
ID: "kb_aaaaaaaaaaaaaaaa", Name: "policies", Org: "o1", OrgName: "Acme", Owner: "team:t1", OwnerName: "Acme / hr",
|
|
EmbedModel: "bge-m3", Dims: 1024, Documents: 3, Chunks: 40,
|
|
Grants: []adminapi.KBGrantView{{Target: "project:p9", Name: "Acme/sales/crm", Perm: "read"}},
|
|
}}}}
|
|
var tm tea.Model = m
|
|
view := tm.View()
|
|
for _, want := range []string{"Knowledge", "Acme/policies", "Acme / hr", "bge-m3 (1024)", "Acme/s", "llmgw-kb sync COLLECTION FOLDER"} {
|
|
if !strings.Contains(view, want) {
|
|
t.Errorf("missing %q in:\n%s", want, view)
|
|
}
|
|
}
|
|
|
|
// A: the form, prefilled with the embedding model.
|
|
tm = press(tm, "a")
|
|
f := tm.(consoleModel).formD
|
|
if f == nil || f.fields[4].value() != "bge-m3" {
|
|
t.Fatalf("no form, or the model not offered: %+v", f)
|
|
}
|
|
f.fields[1].text.SetValue("Acme/hr")
|
|
f.fields[3].text.SetValue("handbook")
|
|
tm = pressRun(tm, "tab", "tab", "tab", "tab", "tab", "enter")
|
|
var req adminapi.KBCreateRequest
|
|
got := s.last()
|
|
if !strings.HasPrefix(got, "POST /api/v1/kb/collections ") ||
|
|
json.Unmarshal([]byte(strings.SplitN(got, " ", 3)[2]), &req) != nil ||
|
|
req.Owner != "team:Acme/hr" || req.Name != "handbook" || req.Model != "bge-m3" {
|
|
t.Fatalf("sent %q", got)
|
|
}
|
|
|
|
// Enter on a row: grant to a project for writing.
|
|
m.formD = nil
|
|
tm = m
|
|
tm = press(tm, "enter")
|
|
if md := tm.(consoleModel).menuD; md == nil || !strings.Contains(md.items[2].label, "Revoke Acme/sales/crm") {
|
|
t.Fatalf("menu %+v", md)
|
|
}
|
|
tm = press(tm, "down", "enter")
|
|
f = tm.(consoleModel).formD
|
|
f.fields[1].text.SetValue("Acme/sales/crm")
|
|
f.fields[2].opt = 1 // write
|
|
tm = pressRun(tm, "tab", "tab", "tab", "enter")
|
|
if got := s.last(); got != `POST /api/v1/kb/grants {"collection":"kb_aaaaaaaaaaaaaaaa","target":"project:Acme/sales/crm","perm":"write"}` {
|
|
t.Fatalf("sent %q", got)
|
|
}
|
|
_ = tm
|
|
}
|