@eeacms/volto-eea-chatbot 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +6 -6
- package/CHANGELOG.md +2 -0
- package/jest-addon.config.js +1 -0
- package/package.json +1 -1
- package/src/ChatBlock/ChatBlockEdit.jsx +2 -1
- package/src/ChatBlock/chat/AIMessage.tsx +20 -16
- package/src/ChatBlock/chat/ChatMessage.tsx +1 -1
- package/src/ChatBlock/chat/ChatWindow.tsx +10 -11
- package/src/ChatBlock/chat/UserMessage.tsx +4 -4
- package/src/ChatBlock/components/AutoResizeTextarea.jsx +1 -1
- package/src/ChatBlock/components/ChatMessageFeedback.jsx +2 -2
- package/src/ChatBlock/components/EmptyState.jsx +1 -1
- package/src/ChatBlock/components/FeedbackModal.jsx +1 -1
- package/src/ChatBlock/components/HalloumiFeedback.jsx +2 -2
- package/src/ChatBlock/components/Source.jsx +2 -2
- package/src/ChatBlock/components/UserActionsToolbar.jsx +3 -3
- package/src/ChatBlock/components/WebResultIcon.tsx +2 -2
- package/src/ChatBlock/components/markdown/ClaimModal.jsx +3 -3
- package/src/ChatBlock/components/markdown/ClaimSegments.jsx +4 -4
- package/src/ChatBlock/components/markdown/{index.js → index.jsx} +1 -1
- package/src/ChatBlock/hooks/useChatController.ts +7 -4
- package/src/ChatBlock/hooks/useChatStreaming.ts +4 -4
- package/src/ChatBlock/hooks/useToolDisplayTiming.ts +1 -1
- package/src/ChatBlock/packets/MultiToolRenderer.tsx +11 -12
- package/src/ChatBlock/packets/RendererComponent.tsx +6 -3
- package/src/ChatBlock/packets/renderers/CustomToolRenderer.tsx +3 -3
- package/src/ChatBlock/packets/renderers/FetchToolRenderer.tsx +3 -3
- package/src/ChatBlock/packets/renderers/ImageToolRenderer.tsx +3 -3
- package/src/ChatBlock/packets/renderers/MessageTextRenderer.tsx +8 -8
- package/src/ChatBlock/packets/renderers/ReasoningRenderer.tsx +5 -5
- package/src/ChatBlock/packets/renderers/SearchToolRenderer.tsx +10 -10
- package/src/ChatBlock/services/messageProcessor.ts +6 -3
- package/src/ChatBlock/services/packetUtils.ts +2 -2
- package/src/ChatBlock/services/streamingService.ts +8 -2
- package/src/ChatBlock/utils/citations.ts +1 -1
- package/src/halloumi/filtering.test.js +199 -1
- package/src/ChatBlock/tests/AIMessage.test.jsx +0 -95
- package/src/ChatBlock/tests/AutoResizeTextarea.test.jsx +0 -49
- package/src/ChatBlock/tests/BlinkingDot.test.jsx +0 -71
- package/src/ChatBlock/tests/ChatMessage.test.jsx +0 -75
- package/src/ChatBlock/tests/ChatMessageFeedback.test.jsx +0 -73
- package/src/ChatBlock/tests/Citation.test.jsx +0 -107
- package/src/ChatBlock/tests/ClaimModal.test.jsx +0 -136
- package/src/ChatBlock/tests/ClaimSegments.test.jsx +0 -206
- package/src/ChatBlock/tests/CustomToolRenderer.test.jsx +0 -241
- package/src/ChatBlock/tests/EmptyState.test.jsx +0 -137
- package/src/ChatBlock/tests/FeedbackModal.test.jsx +0 -138
- package/src/ChatBlock/tests/FetchToolRenderer.test.jsx +0 -161
- package/src/ChatBlock/tests/HalloumiFeedback.test.jsx +0 -94
- package/src/ChatBlock/tests/ImageToolRenderer.test.jsx +0 -178
- package/src/ChatBlock/tests/MessageTextRenderer.test.jsx +0 -227
- package/src/ChatBlock/tests/MultiToolRenderer.test.jsx +0 -134
- package/src/ChatBlock/tests/QualityCheckToggle.test.jsx +0 -105
- package/src/ChatBlock/tests/ReasoningRenderer.test.jsx +0 -163
- package/src/ChatBlock/tests/RelatedQuestions.test.jsx +0 -215
- package/src/ChatBlock/tests/RenderClaimView.test.jsx +0 -191
- package/src/ChatBlock/tests/RendererComponent.test.jsx +0 -139
- package/src/ChatBlock/tests/SearchToolRenderer.test.jsx +0 -295
- package/src/ChatBlock/tests/Source.test.jsx +0 -79
- package/src/ChatBlock/tests/SourceChip.test.jsx +0 -108
- package/src/ChatBlock/tests/Spinner.test.jsx +0 -18
- package/src/ChatBlock/tests/UserActionsToolbar.test.jsx +0 -135
- package/src/ChatBlock/tests/UserMessage.test.jsx +0 -83
- package/src/ChatBlock/tests/WebResultIcon.test.jsx +0 -61
- package/src/ChatBlock/tests/citations.test.js +0 -114
- package/src/ChatBlock/tests/index.test.js +0 -51
- package/src/ChatBlock/tests/messageProcessor.test.jsx +0 -438
- package/src/ChatBlock/tests/packetUtils.test.js +0 -158
- package/src/ChatBlock/tests/schema.test.js +0 -166
- package/src/ChatBlock/tests/streamingService.test.js +0 -467
- package/src/ChatBlock/tests/useChatController.test.jsx +0 -268
- package/src/ChatBlock/tests/useChatStreaming.test.jsx +0 -163
- package/src/ChatBlock/tests/useDeepCompareMemoize.test.js +0 -107
- package/src/ChatBlock/tests/useMarked.test.jsx +0 -107
- package/src/ChatBlock/tests/useQualityMarkers.test.jsx +0 -150
- package/src/ChatBlock/tests/useScrollonStream.test.jsx +0 -121
- package/src/ChatBlock/tests/useToolDisplayTiming.test.jsx +0 -151
- package/src/ChatBlock/tests/utils.test.jsx +0 -241
- package/src/ChatBlock/tests/withOnyxData.test.jsx +0 -81
- /package/src/ChatBlock/{schema.js → schema.jsx} +0 -0
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { MemoryRouter } from 'react-router-dom';
|
|
2
|
-
import configureStore from 'redux-mock-store';
|
|
3
|
-
import renderer from 'react-test-renderer';
|
|
4
|
-
|
|
5
|
-
import '@testing-library/jest-dom';
|
|
6
|
-
import { Provider } from 'react-intl-redux';
|
|
7
|
-
import { UserMessage } from '../chat/UserMessage';
|
|
8
|
-
|
|
9
|
-
const mockStore = configureStore();
|
|
10
|
-
|
|
11
|
-
// Mock loadable components
|
|
12
|
-
jest.mock('@loadable/component', () => {
|
|
13
|
-
return () => {
|
|
14
|
-
const MockComponent = ({ children }) => <div>{children}</div>;
|
|
15
|
-
return MockComponent;
|
|
16
|
-
};
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe('UserMessage', () => {
|
|
20
|
-
let store;
|
|
21
|
-
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
store = mockStore({
|
|
24
|
-
userSession: { token: '1234' },
|
|
25
|
-
intl: { locale: 'en', messages: {} },
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const renderComponent = (props) =>
|
|
30
|
-
renderer.create(
|
|
31
|
-
<Provider store={store}>
|
|
32
|
-
<MemoryRouter>
|
|
33
|
-
<UserMessage {...props} />
|
|
34
|
-
</MemoryRouter>
|
|
35
|
-
</Provider>,
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
it('renders user message with basic text', () => {
|
|
39
|
-
const props = {
|
|
40
|
-
message: {
|
|
41
|
-
messageId: 1,
|
|
42
|
-
message: 'Hello, this is my question',
|
|
43
|
-
type: 'user',
|
|
44
|
-
},
|
|
45
|
-
libs: { remarkGfm: { default: [] } },
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const component = renderComponent(props);
|
|
49
|
-
const json = component.toJSON();
|
|
50
|
-
expect(json).toMatchSnapshot();
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('renders user message with custom className', () => {
|
|
54
|
-
const props = {
|
|
55
|
-
message: {
|
|
56
|
-
messageId: 2,
|
|
57
|
-
message: 'Another question',
|
|
58
|
-
type: 'user',
|
|
59
|
-
},
|
|
60
|
-
libs: { remarkGfm: { default: [] } },
|
|
61
|
-
className: 'most-recent',
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const component = renderComponent(props);
|
|
65
|
-
const json = component.toJSON();
|
|
66
|
-
expect(json).toMatchSnapshot();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('renders user message without className', () => {
|
|
70
|
-
const props = {
|
|
71
|
-
message: {
|
|
72
|
-
messageId: 4,
|
|
73
|
-
message: 'Test message',
|
|
74
|
-
type: 'user',
|
|
75
|
-
},
|
|
76
|
-
libs: { remarkGfm: { default: [] } },
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const component = renderComponent(props);
|
|
80
|
-
const json = component.toJSON();
|
|
81
|
-
expect(json).toMatchSnapshot();
|
|
82
|
-
});
|
|
83
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import renderer from 'react-test-renderer';
|
|
3
|
-
import { render, fireEvent, screen } from '@testing-library/react';
|
|
4
|
-
import '@testing-library/jest-dom';
|
|
5
|
-
import { WebResultIcon } from '../components/WebResultIcon';
|
|
6
|
-
|
|
7
|
-
describe('WebResultIcon', () => {
|
|
8
|
-
it('renders favicon for valid URL', () => {
|
|
9
|
-
const component = renderer.create(
|
|
10
|
-
<WebResultIcon url="https://example.com" size={16} />,
|
|
11
|
-
);
|
|
12
|
-
const json = component.toJSON();
|
|
13
|
-
expect(json).toMatchSnapshot();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('renders with default size', () => {
|
|
17
|
-
const component = renderer.create(
|
|
18
|
-
<WebResultIcon url="https://example.com" />,
|
|
19
|
-
);
|
|
20
|
-
const json = component.toJSON();
|
|
21
|
-
expect(json).toMatchSnapshot();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('renders FileIcon for invalid URL', () => {
|
|
25
|
-
const component = renderer.create(
|
|
26
|
-
<WebResultIcon url="invalid-url" size={16} />,
|
|
27
|
-
);
|
|
28
|
-
const json = component.toJSON();
|
|
29
|
-
expect(json).toMatchSnapshot();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('renders GlobeIcon when favicon fails to load', () => {
|
|
33
|
-
render(<WebResultIcon url="https://example.com" size={16} />);
|
|
34
|
-
|
|
35
|
-
const img = screen.getByRole('img');
|
|
36
|
-
fireEvent.error(img);
|
|
37
|
-
|
|
38
|
-
// After error, the component should re-render with GlobeIcon
|
|
39
|
-
// The img should no longer be present
|
|
40
|
-
expect(screen.queryByRole('img')).not.toBeInTheDocument();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('generates correct favicon URL', () => {
|
|
44
|
-
render(<WebResultIcon url="https://www.google.com/search" size={20} />);
|
|
45
|
-
|
|
46
|
-
const img = screen.getByRole('img');
|
|
47
|
-
expect(img).toHaveAttribute(
|
|
48
|
-
'src',
|
|
49
|
-
'https://t3.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=https://www.google.com&size=128',
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('applies correct size styles', () => {
|
|
54
|
-
render(<WebResultIcon url="https://example.com" size={24} />);
|
|
55
|
-
|
|
56
|
-
const img = screen.getByRole('img');
|
|
57
|
-
expect(img).toHaveAttribute('height', '24');
|
|
58
|
-
expect(img).toHaveAttribute('width', '24');
|
|
59
|
-
expect(img).toHaveStyle({ height: '24px', width: '24px' });
|
|
60
|
-
});
|
|
61
|
-
});
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { addCitations } from '../utils/citations';
|
|
2
|
-
|
|
3
|
-
describe('addCitations', () => {
|
|
4
|
-
it('transforms single citation marker into markdown link', () => {
|
|
5
|
-
const message = {
|
|
6
|
-
citations: {
|
|
7
|
-
1: 'https://example.com/doc1',
|
|
8
|
-
},
|
|
9
|
-
};
|
|
10
|
-
const text = 'This is a fact [1].';
|
|
11
|
-
const result = addCitations(text, message);
|
|
12
|
-
expect(result).toBe('This is a fact [[1]](https://example.com/doc1).');
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('transforms multiple citation markers', () => {
|
|
16
|
-
const message = {
|
|
17
|
-
citations: {
|
|
18
|
-
1: 'https://example.com/doc1',
|
|
19
|
-
2: 'https://example.com/doc2',
|
|
20
|
-
3: 'https://example.com/doc3',
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
const text = 'Fact one [1], fact two [2], and fact three [3].';
|
|
24
|
-
const result = addCitations(text, message);
|
|
25
|
-
expect(result).toBe(
|
|
26
|
-
'Fact one [[1]](https://example.com/doc1), fact two [[2]](https://example.com/doc2), and fact three [[3]](https://example.com/doc3).',
|
|
27
|
-
);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('does not transform already formatted citations [1](url)', () => {
|
|
31
|
-
const message = {
|
|
32
|
-
citations: {
|
|
33
|
-
1: 'https://example.com/doc1',
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
const text = 'Already formatted [[1]](https://example.com/doc1).';
|
|
37
|
-
const result = addCitations(text, message);
|
|
38
|
-
expect(result).toBe('Already formatted [[1]](https://example.com/doc1).');
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('does not transform citations in brackets like [1][', () => {
|
|
42
|
-
const message = {
|
|
43
|
-
citations: {
|
|
44
|
-
1: 'https://example.com/doc1',
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
const text = 'Text with [1][';
|
|
48
|
-
const result = addCitations(text, message);
|
|
49
|
-
expect(result).toBe('Text with [1][');
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('does not transform citations followed by ]', () => {
|
|
53
|
-
const message = {
|
|
54
|
-
citations: {
|
|
55
|
-
1: 'https://example.com/doc1',
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
const text = 'Text with [1]]';
|
|
59
|
-
const result = addCitations(text, message);
|
|
60
|
-
expect(result).toBe('Text with [1]]');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('returns original text when no citations in message', () => {
|
|
64
|
-
const message = {};
|
|
65
|
-
const text = 'This is a fact [1].';
|
|
66
|
-
const result = addCitations(text, message);
|
|
67
|
-
expect(result).toBe('This is a fact [1].');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('returns original text when citations is undefined', () => {
|
|
71
|
-
const message = { citations: undefined };
|
|
72
|
-
const text = 'This is a fact [1].';
|
|
73
|
-
const result = addCitations(text, message);
|
|
74
|
-
expect(result).toBe('This is a fact [1].');
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('handles text with no citation markers', () => {
|
|
78
|
-
const message = {
|
|
79
|
-
citations: {
|
|
80
|
-
1: 'https://example.com/doc1',
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
const text = 'This is plain text without citations.';
|
|
84
|
-
const result = addCitations(text, message);
|
|
85
|
-
expect(result).toBe('This is plain text without citations.');
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('handles double-digit citation numbers', () => {
|
|
89
|
-
const message = {
|
|
90
|
-
citations: {
|
|
91
|
-
10: 'https://example.com/doc10',
|
|
92
|
-
11: 'https://example.com/doc11',
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
const text = 'References [10] and [11].';
|
|
96
|
-
const result = addCitations(text, message);
|
|
97
|
-
expect(result).toBe(
|
|
98
|
-
'References [[10]](https://example.com/doc10) and [[11]](https://example.com/doc11).',
|
|
99
|
-
);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('handles citation number not in citations object', () => {
|
|
103
|
-
const message = {
|
|
104
|
-
citations: {
|
|
105
|
-
1: 'https://example.com/doc1',
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
const text = 'Citation [2] not found.';
|
|
109
|
-
const result = addCitations(text, message);
|
|
110
|
-
// When citation number exists but is not in citations object,
|
|
111
|
-
// the function returns the citation with undefined URL
|
|
112
|
-
expect(result).toBe('Citation [[2]](undefined) not found.');
|
|
113
|
-
});
|
|
114
|
-
});
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import '@testing-library/jest-dom';
|
|
2
|
-
|
|
3
|
-
import installChatBlock from '../index';
|
|
4
|
-
|
|
5
|
-
// Mock @plone/volto/components
|
|
6
|
-
jest.mock('@plone/volto/components', () => ({
|
|
7
|
-
SidebarPortal: () => null,
|
|
8
|
-
}));
|
|
9
|
-
|
|
10
|
-
// Mock other dependencies
|
|
11
|
-
jest.mock('../ChatBlockView', () => () => <div>ChatBlockView</div>);
|
|
12
|
-
jest.mock('../ChatBlockEdit', () => () => <div>ChatBlockEdit</div>);
|
|
13
|
-
|
|
14
|
-
describe('ChatBlock installation', () => {
|
|
15
|
-
let mockConfig;
|
|
16
|
-
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
mockConfig = {
|
|
19
|
-
blocks: {
|
|
20
|
-
blocksConfig: {},
|
|
21
|
-
},
|
|
22
|
-
settings: {},
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('should register eeaChatbot block', () => {
|
|
27
|
-
installChatBlock(mockConfig);
|
|
28
|
-
|
|
29
|
-
expect(mockConfig.blocks.blocksConfig.eeaChatbot).toBeDefined();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('should set correct block properties', () => {
|
|
33
|
-
installChatBlock(mockConfig);
|
|
34
|
-
|
|
35
|
-
const blockConfig = mockConfig.blocks.blocksConfig.eeaChatbot;
|
|
36
|
-
expect(blockConfig.id).toBe('eeaChatbot');
|
|
37
|
-
expect(blockConfig.title).toBe('AI Chatbot');
|
|
38
|
-
expect(blockConfig.group).toBe('common');
|
|
39
|
-
expect(blockConfig.restricted({ user: null })).toBe(false);
|
|
40
|
-
expect(blockConfig.mostUsed).toBe(false);
|
|
41
|
-
expect(blockConfig.sidebarTab).toBe(1);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should set view and edit components', () => {
|
|
45
|
-
installChatBlock(mockConfig);
|
|
46
|
-
|
|
47
|
-
const blockConfig = mockConfig.blocks.blocksConfig.eeaChatbot;
|
|
48
|
-
expect(blockConfig.view).toBeDefined();
|
|
49
|
-
expect(blockConfig.edit).toBeDefined();
|
|
50
|
-
});
|
|
51
|
-
});
|