mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-25 18:03:29 +08:00
### Summary Continue to add context --------- Signed-off-by: Jin Hai <haijin.chn@gmail.com>
241 lines
6.5 KiB
Go
241 lines
6.5 KiB
Go
//
|
|
// Copyright 2026 The InfiniFlow Authors. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
package dao
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/glebarez/sqlite"
|
|
"gorm.io/gorm"
|
|
|
|
"ragflow/internal/entity"
|
|
)
|
|
|
|
// setupChatChannelTestDB initializes an in-memory SQLite database for ChatChannel DAO tests.
|
|
func setupChatChannelTestDB(t *testing.T) *gorm.DB {
|
|
t.Helper()
|
|
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
|
|
TranslateError: true,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("failed to open sqlite: %v", err)
|
|
}
|
|
|
|
// Migrate chat_channel and dialog (entity.Chat) tables
|
|
if err = db.AutoMigrate(&entity.ChatChannel{}, &entity.Chat{}); err != nil {
|
|
t.Fatalf("failed to migrate: %v", err)
|
|
}
|
|
|
|
return db
|
|
}
|
|
|
|
func TestChatChannelDAO_CRUD(t *testing.T) {
|
|
db := setupChatChannelTestDB(t)
|
|
pushDB(t, db)
|
|
dao := NewChatChannel()
|
|
|
|
// 1. Test Create
|
|
channelConfig := entity.JSONMap{
|
|
"credential": map[string]interface{}{
|
|
"corp_id": "ww123456",
|
|
"agent_id": float64(1000001),
|
|
"secret": "sec-key",
|
|
},
|
|
}
|
|
statusActive := 1
|
|
cc := &entity.ChatChannel{
|
|
ID: "chan-1",
|
|
TenantID: "tenant-1",
|
|
Name: "Test WeCom Bot",
|
|
Channel: "wecom",
|
|
Config: channelConfig,
|
|
Status: statusActive,
|
|
}
|
|
|
|
ctx := t.Context()
|
|
|
|
err := dao.Create(ctx, db, cc)
|
|
if err != nil {
|
|
t.Fatalf("failed to create chat channel: %v", err)
|
|
}
|
|
|
|
// 2. Test GetByID
|
|
res, err := dao.GetByID(ctx, db, "chan-1", "tenant-1")
|
|
if err != nil {
|
|
t.Fatalf("failed to get chat channel: %v", err)
|
|
}
|
|
if res.Name != "Test WeCom Bot" {
|
|
t.Fatalf("expected Name %q, got %q", "Test WeCom Bot", res.Name)
|
|
}
|
|
cred, ok := res.Config["credential"].(map[string]interface{})
|
|
if !ok {
|
|
t.Fatalf("failed to parse config credentials")
|
|
}
|
|
if cred["corp_id"] != "ww123456" {
|
|
t.Fatalf("expected corp_id %q, got %v", "ww123456", cred["corp_id"])
|
|
}
|
|
|
|
// 2b. Test tenant isolation for GetByID
|
|
_, err = dao.GetByID(ctx, db, "chan-1", "tenant-2")
|
|
if err == nil {
|
|
t.Fatalf("expected error (not found) when getting with wrong tenant, got nil")
|
|
}
|
|
|
|
// 3. Test UpdateByID
|
|
updates := map[string]interface{}{
|
|
"name": "Updated WeCom Bot",
|
|
}
|
|
// Try updating with wrong tenant
|
|
err = dao.UpdateByID(ctx, db, "chan-1", "tenant-2", updates)
|
|
if err != nil {
|
|
t.Fatalf("failed to run UpdateByID with wrong tenant: %v", err)
|
|
}
|
|
// Verify it was NOT updated (should still be "Test WeCom Bot" since wrong tenant was used)
|
|
res, err = dao.GetByID(ctx, db, "chan-1", "tenant-1")
|
|
if err != nil {
|
|
t.Fatalf("failed to get chat channel: %v", err)
|
|
}
|
|
if res.Name != "Test WeCom Bot" {
|
|
t.Fatalf("expected Name to remain %q, but got %q", "Test WeCom Bot", res.Name)
|
|
}
|
|
|
|
// Update with correct tenant
|
|
err = dao.UpdateByID(ctx, db, "chan-1", "tenant-1", updates)
|
|
if err != nil {
|
|
t.Fatalf("failed to update chat channel: %v", err)
|
|
}
|
|
|
|
res, err = dao.GetByID(ctx, db, "chan-1", "tenant-1")
|
|
if err != nil {
|
|
t.Fatalf("failed to get updated chat channel: %v", err)
|
|
}
|
|
if res.Name != "Updated WeCom Bot" {
|
|
t.Fatalf("expected updated Name %q, got %q", "Updated WeCom Bot", res.Name)
|
|
}
|
|
|
|
// 3b. Test DeleteByID with wrong tenant (should not delete)
|
|
err = dao.DeleteByID(ctx, db, "chan-1", "tenant-2")
|
|
if err != nil {
|
|
t.Fatalf("failed to delete with wrong tenant: %v", err)
|
|
}
|
|
// Verify it still exists for tenant-1
|
|
_, err = dao.GetByID(ctx, db, "chan-1", "tenant-1")
|
|
if err != nil {
|
|
t.Fatalf("expected chat channel to still exist for tenant-1, got error: %v", err)
|
|
}
|
|
|
|
// 4. Test DeleteByID
|
|
err = dao.DeleteByID(ctx, db, "chan-1", "tenant-1")
|
|
if err != nil {
|
|
t.Fatalf("failed to delete chat channel: %v", err)
|
|
}
|
|
|
|
_, err = dao.GetByID(ctx, db, "chan-1", "tenant-1")
|
|
if err == nil {
|
|
t.Fatalf("expected record not found error, got nil")
|
|
}
|
|
}
|
|
|
|
func TestChatChannelDAO_ListByTenantID(t *testing.T) {
|
|
db := setupChatChannelTestDB(t)
|
|
pushDB(t, db)
|
|
dao := NewChatChannel()
|
|
|
|
// Create a test dialog (chat assistant)
|
|
dialogName := "Dialog Assistant A"
|
|
d := &entity.Chat{
|
|
ID: "diag-1",
|
|
TenantID: "tenant-1",
|
|
Name: &dialogName,
|
|
LLMID: "model-a",
|
|
LLMSetting: entity.JSONMap{"temp": 0.1},
|
|
PromptConfig: entity.JSONMap{"system": "sys"},
|
|
KBIDs: entity.JSONSlice{"kb-1"},
|
|
}
|
|
if err := db.Create(d).Error; err != nil {
|
|
t.Fatalf("failed to create test dialog: %v", err)
|
|
}
|
|
|
|
statusActive := 1
|
|
now := time.Now().UnixMilli()
|
|
t1 := now - 1000
|
|
t2 := now
|
|
|
|
// Create chat channels (order: oldest first, so list should return youngest first)
|
|
cc1 := &entity.ChatChannel{
|
|
ID: "chan-1",
|
|
TenantID: "tenant-1",
|
|
Name: "WeCom Channel 1",
|
|
Channel: "wecom",
|
|
Config: entity.JSONMap{"cred": "A"},
|
|
ChatID: &d.ID,
|
|
Status: statusActive,
|
|
BaseModel: entity.BaseModel{
|
|
CreateTime: &t1,
|
|
},
|
|
}
|
|
cc2 := &entity.ChatChannel{
|
|
ID: "chan-2",
|
|
TenantID: "tenant-1",
|
|
Name: "WeCom Channel 2",
|
|
Channel: "wecom",
|
|
Config: entity.JSONMap{"cred": "B"},
|
|
ChatID: &d.ID,
|
|
Status: statusActive,
|
|
BaseModel: entity.BaseModel{
|
|
CreateTime: &t2,
|
|
},
|
|
}
|
|
|
|
if err := db.Create(cc1).Error; err != nil {
|
|
t.Fatalf("failed to create cc1: %v", err)
|
|
}
|
|
if err := db.Create(cc2).Error; err != nil {
|
|
t.Fatalf("failed to create cc2: %v", err)
|
|
}
|
|
|
|
// Perform query
|
|
ctx := t.Context()
|
|
list, err := dao.ListByTenantID(ctx, db, "tenant-1")
|
|
if err != nil {
|
|
t.Fatalf("ListByTenantID failed: %v", err)
|
|
}
|
|
|
|
// Verify count and order (create_time DESC, so cc2 should be index 0)
|
|
if len(list) != 2 {
|
|
t.Fatalf("expected 2 items, got %d", len(list))
|
|
}
|
|
|
|
// cc2 is first because t2 > t1
|
|
if list[0].ID != "chan-2" {
|
|
t.Fatalf("expected first item ID %q, got %q (ordering failed)", "chan-2", list[0].ID)
|
|
}
|
|
if list[1].ID != "chan-1" {
|
|
t.Fatalf("expected second item ID %q, got %q", "chan-1", list[1].ID)
|
|
}
|
|
if list[0].ChatID == nil || *list[0].ChatID != d.ID {
|
|
t.Fatalf("expected chat_id %q, got %v", d.ID, list[0].ChatID)
|
|
}
|
|
|
|
// Verify Left Join mapping
|
|
if list[0].DialogName == nil || *list[0].DialogName != "Dialog Assistant A" {
|
|
t.Fatalf("expected dialog name %q, got %v (left join failed)", "Dialog Assistant A", list[0].DialogName)
|
|
}
|
|
}
|