dify/sdks/nodejs-client/src/client/chat.test.ts
Stephen Zhou a84c2d36a3
style: format with vp fmt (#38803)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:57:46 +00:00

238 lines
6.6 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
import { createHttpClientWithSpies } from '../../tests/test-utils'
import { ValidationError } from '../errors/dify-error'
import { ChatClient } from './chat'
describe('ChatClient', () => {
beforeEach(() => {
vi.restoreAllMocks()
})
it('creates chat messages in blocking mode', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.createChatMessage({ input: 'x' }, 'hello', 'user', false, null)
expect(request).toHaveBeenCalledWith({
method: 'POST',
path: '/chat-messages',
data: {
inputs: { input: 'x' },
query: 'hello',
user: 'user',
response_mode: 'blocking',
files: undefined,
},
})
})
it('creates chat messages in streaming mode', async () => {
const { client, requestStream } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.createChatMessage({
inputs: { input: 'x' },
query: 'hello',
user: 'user',
response_mode: 'streaming',
})
expect(requestStream).toHaveBeenCalledWith({
method: 'POST',
path: '/chat-messages',
data: {
inputs: { input: 'x' },
query: 'hello',
user: 'user',
response_mode: 'streaming',
},
})
})
it('stops chat messages', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.stopChatMessage('task', 'user')
await chat.stopMessage('task', 'user')
expect(request).toHaveBeenCalledWith({
method: 'POST',
path: '/chat-messages/task/stop',
data: { user: 'user' },
})
})
it('gets suggested questions', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.getSuggested('msg', 'user')
expect(request).toHaveBeenCalledWith({
method: 'GET',
path: '/messages/msg/suggested',
query: { user: 'user' },
})
})
it('submits message feedback', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.messageFeedback('msg', 'like', 'user', 'good')
await chat.messageFeedback({
messageId: 'msg',
user: 'user',
rating: 'dislike',
})
expect(request).toHaveBeenCalledWith({
method: 'POST',
path: '/messages/msg/feedbacks',
data: { user: 'user', rating: 'like', content: 'good' },
})
})
it('lists app feedbacks', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.getAppFeedbacks(2, 5)
expect(request).toHaveBeenCalledWith({
method: 'GET',
path: '/app/feedbacks',
query: { page: 2, limit: 5 },
})
})
it('lists conversations and messages', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.getConversations('user', 'last', 10, '-updated_at')
await chat.getConversationMessages('user', 'conv', 'first', 5)
expect(request).toHaveBeenCalledWith({
method: 'GET',
path: '/conversations',
query: {
user: 'user',
last_id: 'last',
limit: 10,
sort_by: '-updated_at',
},
})
expect(request).toHaveBeenCalledWith({
method: 'GET',
path: '/messages',
query: {
user: 'user',
conversation_id: 'conv',
first_id: 'first',
limit: 5,
},
})
})
it('renames conversations with optional auto-generate', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.renameConversation('conv', 'name', 'user', false)
await chat.renameConversation('conv', 'user', { autoGenerate: true })
expect(request).toHaveBeenCalledWith({
method: 'POST',
path: '/conversations/conv/name',
data: { user: 'user', auto_generate: false, name: 'name' },
})
expect(request).toHaveBeenCalledWith({
method: 'POST',
path: '/conversations/conv/name',
data: { user: 'user', auto_generate: true },
})
})
it('requires name when autoGenerate is false', () => {
const { client } = createHttpClientWithSpies()
const chat = new ChatClient(client)
expect(() => chat.renameConversation('conv', '', 'user', false)).toThrow(ValidationError)
})
it('deletes conversations', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.deleteConversation('conv', 'user')
expect(request).toHaveBeenCalledWith({
method: 'DELETE',
path: '/conversations/conv',
data: { user: 'user' },
})
})
it('manages conversation variables', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.getConversationVariables('conv', 'user', 'last', 10, 'name')
await chat.updateConversationVariable('conv', 'var', 'user', 'value')
expect(request).toHaveBeenCalledWith({
method: 'GET',
path: '/conversations/conv/variables',
query: {
user: 'user',
last_id: 'last',
limit: 10,
variable_name: 'name',
},
})
expect(request).toHaveBeenCalledWith({
method: 'PUT',
path: '/conversations/conv/variables/var',
data: { user: 'user', value: 'value' },
})
})
it('handles annotation APIs', async () => {
const { client, request } = createHttpClientWithSpies()
const chat = new ChatClient(client)
await chat.annotationReplyAction('enable', {
score_threshold: 0.5,
embedding_provider_name: 'prov',
embedding_model_name: 'model',
})
await chat.getAnnotationReplyStatus('enable', 'job')
await chat.listAnnotations({ page: 1, limit: 10, keyword: 'k' })
await chat.createAnnotation({ question: 'q', answer: 'a' })
await chat.updateAnnotation('id', { question: 'q', answer: 'a' })
await chat.deleteAnnotation('id')
expect(request).toHaveBeenCalledWith({
method: 'POST',
path: '/apps/annotation-reply/enable',
data: {
score_threshold: 0.5,
embedding_provider_name: 'prov',
embedding_model_name: 'model',
},
})
expect(request).toHaveBeenCalledWith({
method: 'GET',
path: '/apps/annotation-reply/enable/status/job',
})
expect(request).toHaveBeenCalledWith({
method: 'GET',
path: '/apps/annotations',
query: { page: 1, limit: 10, keyword: 'k' },
})
})
})