Files

108 lines
3.3 KiB
Go
Raw Permalink Normal View History

package service
import (
"context"
"testing"
"github.com/Tencent/WeKnora/internal/types"
"github.com/Tencent/WeKnora/internal/types/interfaces"
)
type stubEmbedChannelRepo struct {
interfaces.EmbedChannelRepository
ch *types.EmbedChannel
}
func (r *stubEmbedChannelRepo) GetByID(_ context.Context, id string) (*types.EmbedChannel, error) {
if r.ch == nil || r.ch.ID != id {
return nil, nil
}
cp := *r.ch
return &cp, nil
}
func (r *stubEmbedChannelRepo) Update(_ context.Context, ch *types.EmbedChannel) error {
cp := *ch
r.ch = &cp
return nil
}
func (r *stubEmbedChannelRepo) ListByTenant(_ context.Context, tenant uint64) ([]*types.EmbedChannel, error) {
if r.ch != nil && r.ch.TenantID == tenant {
return []*types.EmbedChannel{r.ch}, nil
}
return nil, nil
}
func embedManagementTestContext(user string, role types.TenantRole) context.Context {
ctx := context.WithValue(context.Background(), types.TenantIDContextKey, uint64(42))
ctx = context.WithValue(ctx, types.UserIDContextKey, user)
return context.WithValue(ctx, types.TenantRoleContextKey, role)
}
func TestEmbedChannelUpdateAgentID(t *testing.T) {
repo := &stubEmbedChannelRepo{
ch: &types.EmbedChannel{
ID: "ch-1",
TenantID: 42,
AgentID: "agent-old",
Name: "Support",
},
}
svc := &embedChannelService{
repo: repo,
agentService: &stubAgentForEmbed{
agent: &types.CustomAgent{ID: "agent-new", TenantID: 42},
},
}
enabled := true
updated, err := svc.Update(
embedManagementTestContext("admin", types.TenantRoleAdmin),
42,
"ch-1",
&types.EmbedChannel{AgentID: "agent-new"},
&enabled, nil, nil, nil, nil, nil, nil,
)
if err != nil {
t.Fatalf("Update() error = %v", err)
}
if updated.AgentID != "agent-new" {
t.Fatalf("updated.AgentID = %q, want agent-new", updated.AgentID)
}
if repo.ch.AgentID != "agent-new" {
t.Fatalf("persisted AgentID = %q, want agent-new", repo.ch.AgentID)
}
}
func TestEmbedManagementRequiresAgentOwnership(t *testing.T) {
repo := &stubEmbedChannelRepo{ch: &types.EmbedChannel{ID: "private-channel", TenantID: 42, AgentID: "private-agent", PublishToken: "private-token"}}
svc := &embedChannelService{repo: repo, agentService: &stubAgentForEmbed{agent: &types.CustomAgent{ID: "private-agent", TenantID: 42, CreatedBy: "alice"}}}
for _, tc := range []struct {
name string
user string
role types.TenantRole
allowed bool
}{
{"owner", "alice", types.TenantRoleContributor, true},
{"other member", "bob", types.TenantRoleContributor, false},
{"viewer", "bob", types.TenantRoleViewer, false},
{"administrator", "admin", types.TenantRoleAdmin, true},
} {
t.Run(tc.name, func(t *testing.T) {
ctx := embedManagementTestContext(tc.user, tc.role)
channel, err := svc.GetOwnedChannel(ctx, 42, "private-channel")
if (err == nil && channel != nil) != tc.allowed {
t.Fatalf("channel visibility does not match ownership: allowed=%v err=%v", tc.allowed, err)
}
channels, err := svc.ListByTenant(ctx, 42)
if err != nil || (len(channels) == 1) != tc.allowed {
t.Fatalf("channel list exposed a private publish token: count=%d err=%v", len(channels), err)
}
_, err = svc.ensureAgentOwned(ctx, 42, "private-agent")
if (err == nil) != tc.allowed {
t.Fatalf("channel creation authority did not match ownership: %v", err)
}
})
}
}