mirror of
https://github.com/langgenius/dify.git
synced 2026-07-24 13:08:34 +08:00
263 lines
8.3 KiB
TypeScript
263 lines
8.3 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { createHttpClientWithSpies } from '../../tests/test-utils'
|
|
import { FileUploadError, ValidationError } from '../errors/dify-error'
|
|
import { KnowledgeBaseClient } from './knowledge-base'
|
|
|
|
describe('KnowledgeBaseClient', () => {
|
|
beforeEach(() => {
|
|
vi.restoreAllMocks()
|
|
})
|
|
|
|
it('handles dataset and tag operations', async () => {
|
|
const { client, request } = createHttpClientWithSpies()
|
|
const kb = new KnowledgeBaseClient(client)
|
|
|
|
await kb.listDatasets({
|
|
page: 1,
|
|
limit: 2,
|
|
keyword: 'k',
|
|
includeAll: true,
|
|
tagIds: ['t1'],
|
|
})
|
|
await kb.createDataset({ name: 'dataset' })
|
|
await kb.getDataset('ds')
|
|
await kb.updateDataset('ds', { name: 'new' })
|
|
await kb.deleteDataset('ds')
|
|
await kb.updateDocumentStatus('ds', 'enable', ['doc1'])
|
|
|
|
await kb.listTags()
|
|
await kb.createTag({ name: 'tag' })
|
|
await kb.updateTag({ tag_id: 'tag', name: 'name' })
|
|
await kb.deleteTag({ tag_id: 'tag' })
|
|
await kb.bindTags({ tag_ids: ['tag'], target_id: 'doc' })
|
|
await kb.unbindTags({ tag_id: 'tag', target_id: 'doc' })
|
|
await kb.getDatasetTags('ds')
|
|
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
path: '/datasets',
|
|
query: {
|
|
page: 1,
|
|
limit: 2,
|
|
keyword: 'k',
|
|
include_all: true,
|
|
tag_ids: ['t1'],
|
|
},
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets',
|
|
data: { name: 'dataset' },
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'PATCH',
|
|
path: '/datasets/ds',
|
|
data: { name: 'new' },
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'PATCH',
|
|
path: '/datasets/ds/documents/status/enable',
|
|
data: { document_ids: ['doc1'] },
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/tags/binding',
|
|
data: { tag_ids: ['tag'], target_id: 'doc' },
|
|
})
|
|
})
|
|
|
|
it('handles document operations', async () => {
|
|
const { client, request } = createHttpClientWithSpies()
|
|
const kb = new KnowledgeBaseClient(client)
|
|
const form = { append: vi.fn(), getHeaders: () => ({}) }
|
|
|
|
await kb.createDocumentByText('ds', { name: 'doc', text: 'text' })
|
|
await kb.updateDocumentByText('ds', 'doc', { name: 'doc2' })
|
|
await kb.createDocumentByFile('ds', form)
|
|
await kb.updateDocumentByFile('ds', 'doc', form)
|
|
await kb.listDocuments('ds', { page: 1, limit: 20, keyword: 'k' })
|
|
await kb.getDocument('ds', 'doc', { metadata: 'all' })
|
|
await kb.deleteDocument('ds', 'doc')
|
|
await kb.getDocumentIndexingStatus('ds', 'batch')
|
|
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/document/create_by_text',
|
|
data: { name: 'doc', text: 'text' },
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/documents/doc/update_by_text',
|
|
data: { name: 'doc2' },
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/document/create_by_file',
|
|
data: form,
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
path: '/datasets/ds/documents',
|
|
query: { page: 1, limit: 20, keyword: 'k', status: undefined },
|
|
})
|
|
})
|
|
|
|
it('handles segments and child chunks', async () => {
|
|
const { client, request } = createHttpClientWithSpies()
|
|
const kb = new KnowledgeBaseClient(client)
|
|
|
|
await kb.createSegments('ds', 'doc', { segments: [{ content: 'x' }] })
|
|
await kb.listSegments('ds', 'doc', { page: 1, limit: 10, keyword: 'k' })
|
|
await kb.getSegment('ds', 'doc', 'seg')
|
|
await kb.updateSegment('ds', 'doc', 'seg', {
|
|
segment: { content: 'y' },
|
|
})
|
|
await kb.deleteSegment('ds', 'doc', 'seg')
|
|
|
|
await kb.createChildChunk('ds', 'doc', 'seg', { content: 'c' })
|
|
await kb.listChildChunks('ds', 'doc', 'seg', { page: 1, limit: 10 })
|
|
await kb.updateChildChunk('ds', 'doc', 'seg', 'child', {
|
|
content: 'c2',
|
|
})
|
|
await kb.deleteChildChunk('ds', 'doc', 'seg', 'child')
|
|
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/documents/doc/segments',
|
|
data: { segments: [{ content: 'x' }] },
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/documents/doc/segments/seg',
|
|
data: { segment: { content: 'y' } },
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'PATCH',
|
|
path: '/datasets/ds/documents/doc/segments/seg/child_chunks/child',
|
|
data: { content: 'c2' },
|
|
})
|
|
})
|
|
|
|
it('handles metadata and retrieval', async () => {
|
|
const { client, request } = createHttpClientWithSpies()
|
|
const kb = new KnowledgeBaseClient(client)
|
|
|
|
await kb.listMetadata('ds')
|
|
await kb.createMetadata('ds', { name: 'm', type: 'string' })
|
|
await kb.updateMetadata('ds', 'mid', { name: 'm2' })
|
|
await kb.deleteMetadata('ds', 'mid')
|
|
await kb.listBuiltInMetadata('ds')
|
|
await kb.updateBuiltInMetadata('ds', 'enable')
|
|
await kb.updateDocumentsMetadata('ds', {
|
|
operation_data: [{ document_id: 'doc', metadata_list: [{ id: 'm', name: 'n' }] }],
|
|
})
|
|
await kb.hitTesting('ds', { query: 'q' })
|
|
await kb.retrieve('ds', { query: 'q' })
|
|
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
path: '/datasets/ds/metadata',
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/metadata',
|
|
data: { name: 'm', type: 'string' },
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/hit-testing',
|
|
data: { query: 'q' },
|
|
})
|
|
})
|
|
|
|
it('handles pipeline operations', async () => {
|
|
const { client, request, requestStream } = createHttpClientWithSpies()
|
|
const kb = new KnowledgeBaseClient(client)
|
|
const form = { append: vi.fn(), getHeaders: () => ({}) }
|
|
|
|
await kb.listDatasourcePlugins('ds', { isPublished: true })
|
|
await kb.runDatasourceNode('ds', 'node', {
|
|
inputs: { input: 'x' },
|
|
datasource_type: 'custom',
|
|
is_published: true,
|
|
})
|
|
await kb.runPipeline('ds', {
|
|
inputs: { input: 'x' },
|
|
datasource_type: 'custom',
|
|
datasource_info_list: [],
|
|
start_node_id: 'start',
|
|
is_published: true,
|
|
response_mode: 'streaming',
|
|
})
|
|
await kb.runPipeline('ds', {
|
|
inputs: { input: 'x' },
|
|
datasource_type: 'custom',
|
|
datasource_info_list: [],
|
|
start_node_id: 'start',
|
|
is_published: true,
|
|
response_mode: 'blocking',
|
|
})
|
|
await kb.uploadPipelineFile(form)
|
|
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'GET',
|
|
path: '/datasets/ds/pipeline/datasource-plugins',
|
|
query: { is_published: true },
|
|
})
|
|
expect(requestStream).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/pipeline/datasource/nodes/node/run',
|
|
data: {
|
|
inputs: { input: 'x' },
|
|
datasource_type: 'custom',
|
|
is_published: true,
|
|
},
|
|
})
|
|
expect(requestStream).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/pipeline/run',
|
|
data: {
|
|
inputs: { input: 'x' },
|
|
datasource_type: 'custom',
|
|
datasource_info_list: [],
|
|
start_node_id: 'start',
|
|
is_published: true,
|
|
response_mode: 'streaming',
|
|
},
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/ds/pipeline/run',
|
|
data: {
|
|
inputs: { input: 'x' },
|
|
datasource_type: 'custom',
|
|
datasource_info_list: [],
|
|
start_node_id: 'start',
|
|
is_published: true,
|
|
response_mode: 'blocking',
|
|
},
|
|
})
|
|
expect(request).toHaveBeenCalledWith({
|
|
method: 'POST',
|
|
path: '/datasets/pipeline/file-upload',
|
|
data: form,
|
|
})
|
|
})
|
|
|
|
it('validates form-data and optional array filters', async () => {
|
|
const { client } = createHttpClientWithSpies()
|
|
const kb = new KnowledgeBaseClient(client)
|
|
|
|
await expect(kb.createDocumentByFile('ds', {})).rejects.toBeInstanceOf(FileUploadError)
|
|
await expect(
|
|
kb.listSegments('ds', 'doc', { status: ['ok', 1] as unknown as string[] }),
|
|
).rejects.toBeInstanceOf(ValidationError)
|
|
await expect(
|
|
kb.hitTesting('ds', {
|
|
query: 'q',
|
|
attachment_ids: ['att-1', 2] as unknown as string[],
|
|
}),
|
|
).rejects.toBeInstanceOf(ValidationError)
|
|
})
|
|
})
|