WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/Tencent/WeKnora/internal/types"
|
||||
"github.com/Tencent/WeKnora/internal/types/interfaces"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type suggestionTagRepo struct {
|
||||
interfaces.KnowledgeTagRepository
|
||||
tagsByTenant map[uint64][]*types.KnowledgeTag
|
||||
}
|
||||
|
||||
func (r *suggestionTagRepo) GetByIDs(_ context.Context, tenantID uint64, ids []string) ([]*types.KnowledgeTag, error) {
|
||||
wanted := make(map[string]bool, len(ids))
|
||||
for _, id := range ids {
|
||||
wanted[id] = true
|
||||
}
|
||||
var result []*types.KnowledgeTag
|
||||
for _, tag := range r.tagsByTenant[tenantID] {
|
||||
if tag != nil && wanted[tag.ID] {
|
||||
result = append(result, tag)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type suggestionKnowledgeRepo struct {
|
||||
interfaces.KnowledgeRepository
|
||||
idsByTenantAndKB map[uint64]map[string][]string
|
||||
}
|
||||
|
||||
func (r *suggestionKnowledgeRepo) ListIDsByTagIDs(
|
||||
_ context.Context,
|
||||
tenantID uint64,
|
||||
kbID string,
|
||||
_ []string,
|
||||
) ([]string, error) {
|
||||
return append([]string(nil), r.idsByTenantAndKB[tenantID][kbID]...), nil
|
||||
}
|
||||
|
||||
type suggestionKBService struct {
|
||||
interfaces.KnowledgeBaseService
|
||||
kbs map[string]*types.KnowledgeBase
|
||||
}
|
||||
|
||||
func (s *suggestionKBService) GetKnowledgeBasesByIDsOnly(
|
||||
_ context.Context,
|
||||
ids []string,
|
||||
) ([]*types.KnowledgeBase, error) {
|
||||
result := make([]*types.KnowledgeBase, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
if kb := s.kbs[id]; kb != nil {
|
||||
result = append(result, kb)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type suggestionKBShareService struct {
|
||||
interfaces.KBShareService
|
||||
allowed map[string]bool
|
||||
}
|
||||
|
||||
func (s *suggestionKBShareService) HasTenantKBPermission(
|
||||
_ context.Context,
|
||||
kbID string,
|
||||
_ uint64,
|
||||
_ types.TenantRole,
|
||||
_ types.OrgMemberRole,
|
||||
) (bool, error) {
|
||||
return s.allowed[kbID], nil
|
||||
}
|
||||
|
||||
func TestResolveSuggestionTagScopes_UsesSourceTenantForSharedKB(t *testing.T) {
|
||||
const (
|
||||
callerTenant = uint64(1)
|
||||
sourceTenant = uint64(2)
|
||||
kbID = "shared-kb"
|
||||
tagID = "shared-tag"
|
||||
)
|
||||
svc := &customAgentService{
|
||||
tagRepo: &suggestionTagRepo{tagsByTenant: map[uint64][]*types.KnowledgeTag{
|
||||
sourceTenant: {{ID: tagID, TenantID: sourceTenant, KnowledgeBaseID: kbID}},
|
||||
}},
|
||||
knowledgeRepo: &suggestionKnowledgeRepo{idsByTenantAndKB: map[uint64]map[string][]string{
|
||||
sourceTenant: {kbID: {"doc-in-tag"}},
|
||||
}},
|
||||
kbService: &suggestionKBService{kbs: map[string]*types.KnowledgeBase{
|
||||
kbID: {ID: kbID, TenantID: sourceTenant},
|
||||
}},
|
||||
kbShareService: &suggestionKBShareService{allowed: map[string]bool{kbID: true}},
|
||||
}
|
||||
|
||||
resolved, err := svc.resolveSuggestionTagScopes(
|
||||
context.Background(),
|
||||
callerTenant,
|
||||
[]types.TagScope{{KnowledgeBaseID: kbID, TagIDs: []string{tagID}}},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{kbID}, resolved.KnowledgeBaseIDs)
|
||||
assert.Equal(t, []string{"doc-in-tag"}, resolved.KnowledgeIDs)
|
||||
assert.Equal(t, []string{tagID}, resolved.TagIDsByTenant[sourceTenant])
|
||||
assert.Empty(t, resolved.TagIDsByTenant[callerTenant])
|
||||
}
|
||||
|
||||
func TestMergeHybridStarterSuggestions_ReservesKnowledgeSlots(t *testing.T) {
|
||||
curated := []types.SuggestedQuestion{
|
||||
{Question: "curated 1", Source: "agent_config"},
|
||||
{Question: "curated 2", Source: "agent_config"},
|
||||
{Question: "curated 3", Source: "agent_config"},
|
||||
{Question: "curated 4", Source: "agent_config"},
|
||||
{Question: "curated 5", Source: "agent_config"},
|
||||
{Question: "curated 6", Source: "agent_config"},
|
||||
}
|
||||
knowledge := []types.SuggestedQuestion{
|
||||
{Question: "knowledge 1", Source: "document"},
|
||||
{Question: "knowledge 2", Source: "faq"},
|
||||
{Question: "knowledge 3", Source: "document"},
|
||||
}
|
||||
|
||||
got := mergeHybridStarterSuggestions(curated, knowledge, 6)
|
||||
require.Len(t, got, 6)
|
||||
assert.Equal(t, []string{
|
||||
"curated 1", "curated 2", "curated 3", "curated 4", "knowledge 1", "knowledge 2",
|
||||
}, []string{got[0].Question, got[1].Question, got[2].Question, got[3].Question, got[4].Question, got[5].Question})
|
||||
}
|
||||
|
||||
func TestMergeHybridStarterSuggestions_BackfillsWhenKnowledgeIsEmpty(t *testing.T) {
|
||||
curated := []types.SuggestedQuestion{
|
||||
{Question: "curated 1"}, {Question: "curated 2"}, {Question: "curated 3"},
|
||||
}
|
||||
got := mergeHybridStarterSuggestions(curated, nil, 3)
|
||||
require.Len(t, got, 3)
|
||||
assert.Equal(t, []string{"curated 1", "curated 2", "curated 3"}, []string{
|
||||
got[0].Question, got[1].Question, got[2].Question,
|
||||
})
|
||||
}
|
||||
|
||||
func TestExcludeSuggestionStrings_TagScopeOverridesSameKnowledgeBase(t *testing.T) {
|
||||
got := excludeSuggestionStrings([]string{"kb-with-tag", "kb-explicit"}, []string{"kb-with-tag"})
|
||||
assert.Equal(t, []string{"kb-explicit"}, got)
|
||||
}
|
||||
Reference in New Issue
Block a user