@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,136 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import renderer from 'react-test-renderer';
|
|
3
|
-
import '@testing-library/jest-dom';
|
|
4
|
-
import { ClaimModal } from '../components/markdown/ClaimModal';
|
|
5
|
-
|
|
6
|
-
// Mock semantic-ui-react Modal
|
|
7
|
-
jest.mock('semantic-ui-react', () => ({
|
|
8
|
-
Modal: ({ children, trigger, className }) => (
|
|
9
|
-
<div className={className} data-testid="modal">
|
|
10
|
-
<div data-testid="trigger">{trigger}</div>
|
|
11
|
-
<div data-testid="content">{children}</div>
|
|
12
|
-
</div>
|
|
13
|
-
),
|
|
14
|
-
ModalHeader: ({ children }) => <div data-testid="header">{children}</div>,
|
|
15
|
-
ModalContent: ({ children }) => (
|
|
16
|
-
<div data-testid="modal-content">{children}</div>
|
|
17
|
-
),
|
|
18
|
-
}));
|
|
19
|
-
|
|
20
|
-
// Mock ClaimSegments
|
|
21
|
-
jest.mock('../components/markdown/ClaimSegments', () => ({
|
|
22
|
-
ClaimSegments: () => <div data-testid="claim-segments">ClaimSegments</div>,
|
|
23
|
-
}));
|
|
24
|
-
|
|
25
|
-
describe('ClaimModal', () => {
|
|
26
|
-
const defaultProps = {
|
|
27
|
-
claim: {
|
|
28
|
-
score: 0.85,
|
|
29
|
-
claimString: 'This is a claim about something important.',
|
|
30
|
-
rationale: 'The claim is supported by multiple sources.',
|
|
31
|
-
segmentIds: [1, 2, 3],
|
|
32
|
-
},
|
|
33
|
-
markers: {
|
|
34
|
-
segments: {
|
|
35
|
-
1: { id: 1, text: 'segment 1' },
|
|
36
|
-
2: { id: 2, text: 'segment 2' },
|
|
37
|
-
3: { id: 3, text: 'segment 3' },
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
text: ['something important'],
|
|
41
|
-
citedSources: [
|
|
42
|
-
{ id: 1, semantic_identifier: 'Source 1', link: 'https://example.com' },
|
|
43
|
-
],
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
it('renders the claim modal with high score', () => {
|
|
47
|
-
const component = renderer.create(<ClaimModal {...defaultProps} />);
|
|
48
|
-
const json = component.toJSON();
|
|
49
|
-
expect(json).toMatchSnapshot();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('renders with low score', () => {
|
|
53
|
-
const props = {
|
|
54
|
-
...defaultProps,
|
|
55
|
-
claim: {
|
|
56
|
-
...defaultProps.claim,
|
|
57
|
-
score: 0.3,
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
const component = renderer.create(<ClaimModal {...props} />);
|
|
61
|
-
const json = component.toJSON();
|
|
62
|
-
expect(json).toMatchSnapshot();
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('renders with medium score', () => {
|
|
66
|
-
const props = {
|
|
67
|
-
...defaultProps,
|
|
68
|
-
claim: {
|
|
69
|
-
...defaultProps.claim,
|
|
70
|
-
score: 0.6,
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
const component = renderer.create(<ClaimModal {...props} />);
|
|
74
|
-
const json = component.toJSON();
|
|
75
|
-
expect(json).toMatchSnapshot();
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('handles empty text array', () => {
|
|
79
|
-
const props = {
|
|
80
|
-
...defaultProps,
|
|
81
|
-
text: [],
|
|
82
|
-
};
|
|
83
|
-
const component = renderer.create(<ClaimModal {...props} />);
|
|
84
|
-
const json = component.toJSON();
|
|
85
|
-
expect(json).toMatchSnapshot();
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('handles claim with markdown formatting', () => {
|
|
89
|
-
const props = {
|
|
90
|
-
...defaultProps,
|
|
91
|
-
claim: {
|
|
92
|
-
...defaultProps.claim,
|
|
93
|
-
claimString: '**Bold claim** with *italic* and [[1]](url)',
|
|
94
|
-
},
|
|
95
|
-
};
|
|
96
|
-
const component = renderer.create(<ClaimModal {...props} />);
|
|
97
|
-
const json = component.toJSON();
|
|
98
|
-
expect(json).toMatchSnapshot();
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('renders with empty markers', () => {
|
|
102
|
-
const props = {
|
|
103
|
-
...defaultProps,
|
|
104
|
-
markers: {},
|
|
105
|
-
};
|
|
106
|
-
const component = renderer.create(<ClaimModal {...props} />);
|
|
107
|
-
const json = component.toJSON();
|
|
108
|
-
expect(json).toMatchSnapshot();
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('handles zero score', () => {
|
|
112
|
-
const props = {
|
|
113
|
-
...defaultProps,
|
|
114
|
-
claim: {
|
|
115
|
-
...defaultProps.claim,
|
|
116
|
-
score: 0,
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
const component = renderer.create(<ClaimModal {...props} />);
|
|
120
|
-
const json = component.toJSON();
|
|
121
|
-
expect(json).toMatchSnapshot();
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('handles perfect score', () => {
|
|
125
|
-
const props = {
|
|
126
|
-
...defaultProps,
|
|
127
|
-
claim: {
|
|
128
|
-
...defaultProps.claim,
|
|
129
|
-
score: 1.0,
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
const component = renderer.create(<ClaimModal {...props} />);
|
|
133
|
-
const json = component.toJSON();
|
|
134
|
-
expect(json).toMatchSnapshot();
|
|
135
|
-
});
|
|
136
|
-
});
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import renderer from 'react-test-renderer';
|
|
2
|
-
import '@testing-library/jest-dom';
|
|
3
|
-
import { ClaimSegments } from '../components/markdown/ClaimSegments';
|
|
4
|
-
|
|
5
|
-
// Mock semantic-ui-react
|
|
6
|
-
jest.mock('semantic-ui-react', () => ({
|
|
7
|
-
Tab: ({ panes, activeIndex }) => (
|
|
8
|
-
<div data-testid="tab">
|
|
9
|
-
<div data-testid="tab-menu">
|
|
10
|
-
{panes.map((pane, i) => (
|
|
11
|
-
<div
|
|
12
|
-
key={i}
|
|
13
|
-
data-testid={`menu-item-${i}`}
|
|
14
|
-
className={pane.menuItem.className}
|
|
15
|
-
onClick={pane.menuItem.onClick}
|
|
16
|
-
onKeydown={() => {}}
|
|
17
|
-
role="tab"
|
|
18
|
-
tabIndex={i === activeIndex ? 0 : -1}
|
|
19
|
-
aria-selected={i === activeIndex}
|
|
20
|
-
aria-controls={`tab-pane-${i}`}
|
|
21
|
-
>
|
|
22
|
-
{pane.menuItem.content}
|
|
23
|
-
</div>
|
|
24
|
-
))}
|
|
25
|
-
</div>
|
|
26
|
-
<div data-testid="tab-content">{panes[activeIndex]?.render()}</div>
|
|
27
|
-
</div>
|
|
28
|
-
),
|
|
29
|
-
TabPane: ({ children }) => <div data-testid="tab-pane">{children}</div>,
|
|
30
|
-
}));
|
|
31
|
-
|
|
32
|
-
// Mock RenderClaimView
|
|
33
|
-
jest.mock('../components/markdown/RenderClaimView', () => ({
|
|
34
|
-
RenderClaimView: () => (
|
|
35
|
-
<div data-testid="render-claim-view">RenderClaimView</div>
|
|
36
|
-
),
|
|
37
|
-
}));
|
|
38
|
-
|
|
39
|
-
describe('ClaimSegments', () => {
|
|
40
|
-
const defaultProps = {
|
|
41
|
-
segmentIds: [1, 2],
|
|
42
|
-
segments: {
|
|
43
|
-
1: { id: 1, startOffset: 0, endOffset: 10 },
|
|
44
|
-
2: { id: 2, startOffset: 15, endOffset: 25 },
|
|
45
|
-
},
|
|
46
|
-
citedSources: [
|
|
47
|
-
{
|
|
48
|
-
id: 'source1',
|
|
49
|
-
semantic_identifier: 'Source Document 1',
|
|
50
|
-
link: 'https://example.com/1',
|
|
51
|
-
source_type: 'web',
|
|
52
|
-
halloumiContext: 'This is the context text for source 1.',
|
|
53
|
-
index: 1,
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
it('renders with basic props', () => {
|
|
59
|
-
const component = renderer.create(<ClaimSegments {...defaultProps} />);
|
|
60
|
-
const json = component.toJSON();
|
|
61
|
-
expect(json).toMatchSnapshot();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('renders with multiple sources', () => {
|
|
65
|
-
const props = {
|
|
66
|
-
...defaultProps,
|
|
67
|
-
citedSources: [
|
|
68
|
-
{
|
|
69
|
-
id: 'source1',
|
|
70
|
-
semantic_identifier: 'Source 1',
|
|
71
|
-
link: 'https://example.com/1',
|
|
72
|
-
source_type: 'web',
|
|
73
|
-
halloumiContext: 'Context for source 1.',
|
|
74
|
-
index: 1,
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
id: 'source2',
|
|
78
|
-
semantic_identifier: 'Source 2',
|
|
79
|
-
link: 'https://example.com/2',
|
|
80
|
-
source_type: 'file',
|
|
81
|
-
halloumiContext: 'Context for source 2.',
|
|
82
|
-
index: 2,
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
segments: {
|
|
86
|
-
1: { id: 1, startOffset: 0, endOffset: 10 },
|
|
87
|
-
2: { id: 2, startOffset: 22, endOffset: 32 },
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const component = renderer.create(<ClaimSegments {...props} />);
|
|
92
|
-
const json = component.toJSON();
|
|
93
|
-
expect(json).toMatchSnapshot();
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('handles empty segmentIds', () => {
|
|
97
|
-
const props = {
|
|
98
|
-
...defaultProps,
|
|
99
|
-
segmentIds: [],
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const component = renderer.create(<ClaimSegments {...props} />);
|
|
103
|
-
const json = component.toJSON();
|
|
104
|
-
expect(json).toMatchSnapshot();
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('handles null segmentIds', () => {
|
|
108
|
-
const props = {
|
|
109
|
-
...defaultProps,
|
|
110
|
-
segmentIds: null,
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
const component = renderer.create(<ClaimSegments {...props} />);
|
|
114
|
-
const json = component.toJSON();
|
|
115
|
-
expect(json).toMatchSnapshot();
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('handles missing segments in segments object', () => {
|
|
119
|
-
// Suppress console.warn for this test
|
|
120
|
-
const originalWarn = console.warn;
|
|
121
|
-
console.warn = jest.fn();
|
|
122
|
-
|
|
123
|
-
const props = {
|
|
124
|
-
...defaultProps,
|
|
125
|
-
segmentIds: [1, 999], // 999 doesn't exist
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
const component = renderer.create(<ClaimSegments {...props} />);
|
|
129
|
-
const json = component.toJSON();
|
|
130
|
-
expect(json).toMatchSnapshot();
|
|
131
|
-
expect(console.warn).toHaveBeenCalled();
|
|
132
|
-
|
|
133
|
-
console.warn = originalWarn;
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('renders source without link', () => {
|
|
137
|
-
const props = {
|
|
138
|
-
...defaultProps,
|
|
139
|
-
citedSources: [
|
|
140
|
-
{
|
|
141
|
-
id: 'source1',
|
|
142
|
-
semantic_identifier: 'Source 1',
|
|
143
|
-
link: null,
|
|
144
|
-
source_type: 'file',
|
|
145
|
-
halloumiContext: 'Context for source 1.',
|
|
146
|
-
index: 1,
|
|
147
|
-
},
|
|
148
|
-
],
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const component = renderer.create(<ClaimSegments {...props} />);
|
|
152
|
-
const json = component.toJSON();
|
|
153
|
-
expect(json).toMatchSnapshot();
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('renders with file source type icon', () => {
|
|
157
|
-
const props = {
|
|
158
|
-
...defaultProps,
|
|
159
|
-
citedSources: [
|
|
160
|
-
{
|
|
161
|
-
id: 'source1',
|
|
162
|
-
semantic_identifier: 'Internal Document',
|
|
163
|
-
link: 'https://example.com/1',
|
|
164
|
-
source_type: 'file',
|
|
165
|
-
halloumiContext: 'Context text.',
|
|
166
|
-
index: 1,
|
|
167
|
-
},
|
|
168
|
-
],
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
const component = renderer.create(<ClaimSegments {...props} />);
|
|
172
|
-
const json = component.toJSON();
|
|
173
|
-
expect(json).toMatchSnapshot();
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it('filters out sources without matching snippets', () => {
|
|
177
|
-
const props = {
|
|
178
|
-
segmentIds: [1],
|
|
179
|
-
segments: {
|
|
180
|
-
1: { id: 1, startOffset: 0, endOffset: 10 },
|
|
181
|
-
},
|
|
182
|
-
citedSources: [
|
|
183
|
-
{
|
|
184
|
-
id: 'source1',
|
|
185
|
-
semantic_identifier: 'Source 1',
|
|
186
|
-
link: null,
|
|
187
|
-
source_type: 'web',
|
|
188
|
-
halloumiContext: 'Short context.',
|
|
189
|
-
index: 1,
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
id: 'source2',
|
|
193
|
-
semantic_identifier: 'Source 2 (no snippets)',
|
|
194
|
-
link: null,
|
|
195
|
-
source_type: 'web',
|
|
196
|
-
halloumiContext: 'This source has no matching segments.',
|
|
197
|
-
index: 2,
|
|
198
|
-
},
|
|
199
|
-
],
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
const component = renderer.create(<ClaimSegments {...props} />);
|
|
203
|
-
const json = component.toJSON();
|
|
204
|
-
expect(json).toMatchSnapshot();
|
|
205
|
-
});
|
|
206
|
-
});
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import renderer, { act } from 'react-test-renderer';
|
|
3
|
-
import '@testing-library/jest-dom';
|
|
4
|
-
import { CustomToolRenderer } from '../packets/renderers/CustomToolRenderer';
|
|
5
|
-
import { PacketType } from '../types/streamingModels';
|
|
6
|
-
|
|
7
|
-
describe('CustomToolRenderer', () => {
|
|
8
|
-
const mockChildRenderer = (result) => (
|
|
9
|
-
<div data-testid="renderer-result">
|
|
10
|
-
<div data-testid="status">{result.status}</div>
|
|
11
|
-
<div data-testid="content">{result.content}</div>
|
|
12
|
-
</div>
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
it('renders running state when not complete', () => {
|
|
16
|
-
const props = {
|
|
17
|
-
packets: [
|
|
18
|
-
{
|
|
19
|
-
ind: 1,
|
|
20
|
-
obj: {
|
|
21
|
-
type: PacketType.CUSTOM_TOOL_START,
|
|
22
|
-
tool_name: 'MyTool',
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
onComplete: jest.fn(),
|
|
27
|
-
children: mockChildRenderer,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const component = renderer.create(<CustomToolRenderer {...props} />);
|
|
31
|
-
const json = component.toJSON();
|
|
32
|
-
expect(json).toMatchSnapshot();
|
|
33
|
-
expect(props.onComplete).not.toHaveBeenCalled();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('renders complete state', () => {
|
|
37
|
-
const props = {
|
|
38
|
-
packets: [
|
|
39
|
-
{
|
|
40
|
-
ind: 1,
|
|
41
|
-
obj: {
|
|
42
|
-
type: PacketType.CUSTOM_TOOL_START,
|
|
43
|
-
tool_name: 'Calculator',
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
ind: 1,
|
|
48
|
-
obj: {
|
|
49
|
-
type: PacketType.CUSTOM_TOOL_DELTA,
|
|
50
|
-
tool_name: 'Calculator',
|
|
51
|
-
response_type: 'calculation_result',
|
|
52
|
-
data: { result: 42 },
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
{ ind: 1, obj: { type: PacketType.SECTION_END } },
|
|
56
|
-
],
|
|
57
|
-
onComplete: jest.fn(),
|
|
58
|
-
children: mockChildRenderer,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const component = renderer.create(<CustomToolRenderer {...props} />);
|
|
62
|
-
const json = component.toJSON();
|
|
63
|
-
expect(json).toMatchSnapshot();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('renders with multiple deltas', () => {
|
|
67
|
-
const props = {
|
|
68
|
-
packets: [
|
|
69
|
-
{
|
|
70
|
-
ind: 1,
|
|
71
|
-
obj: {
|
|
72
|
-
type: PacketType.CUSTOM_TOOL_START,
|
|
73
|
-
tool_name: 'MultiStepTool',
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
ind: 1,
|
|
78
|
-
obj: {
|
|
79
|
-
type: PacketType.CUSTOM_TOOL_DELTA,
|
|
80
|
-
tool_name: 'MultiStepTool',
|
|
81
|
-
response_type: 'step1',
|
|
82
|
-
data: { step: 1, status: 'processing' },
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
ind: 1,
|
|
87
|
-
obj: {
|
|
88
|
-
type: PacketType.CUSTOM_TOOL_DELTA,
|
|
89
|
-
tool_name: 'MultiStepTool',
|
|
90
|
-
response_type: 'step2',
|
|
91
|
-
data: { step: 2, status: 'complete' },
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
{ ind: 1, obj: { type: PacketType.SECTION_END } },
|
|
95
|
-
],
|
|
96
|
-
onComplete: jest.fn(),
|
|
97
|
-
children: mockChildRenderer,
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const component = renderer.create(<CustomToolRenderer {...props} />);
|
|
101
|
-
const json = component.toJSON();
|
|
102
|
-
expect(json).toMatchSnapshot();
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('handles delta without response_type', () => {
|
|
106
|
-
const props = {
|
|
107
|
-
packets: [
|
|
108
|
-
{
|
|
109
|
-
ind: 1,
|
|
110
|
-
obj: {
|
|
111
|
-
type: PacketType.CUSTOM_TOOL_START,
|
|
112
|
-
tool_name: 'SimpleTool',
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
ind: 1,
|
|
117
|
-
obj: {
|
|
118
|
-
type: PacketType.CUSTOM_TOOL_DELTA,
|
|
119
|
-
tool_name: 'SimpleTool',
|
|
120
|
-
data: { result: 'done' },
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
{ ind: 1, obj: { type: PacketType.SECTION_END } },
|
|
124
|
-
],
|
|
125
|
-
onComplete: jest.fn(),
|
|
126
|
-
children: mockChildRenderer,
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const component = renderer.create(<CustomToolRenderer {...props} />);
|
|
130
|
-
const json = component.toJSON();
|
|
131
|
-
expect(json).toMatchSnapshot();
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('handles delta without data', () => {
|
|
135
|
-
const props = {
|
|
136
|
-
packets: [
|
|
137
|
-
{
|
|
138
|
-
ind: 1,
|
|
139
|
-
obj: {
|
|
140
|
-
type: PacketType.CUSTOM_TOOL_START,
|
|
141
|
-
tool_name: 'NoDataTool',
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
ind: 1,
|
|
146
|
-
obj: {
|
|
147
|
-
type: PacketType.CUSTOM_TOOL_DELTA,
|
|
148
|
-
tool_name: 'NoDataTool',
|
|
149
|
-
response_type: 'status',
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
{ ind: 1, obj: { type: PacketType.SECTION_END } },
|
|
153
|
-
],
|
|
154
|
-
onComplete: jest.fn(),
|
|
155
|
-
children: mockChildRenderer,
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
const component = renderer.create(<CustomToolRenderer {...props} />);
|
|
159
|
-
const json = component.toJSON();
|
|
160
|
-
expect(json).toMatchSnapshot();
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('uses default tool name when not provided', () => {
|
|
164
|
-
const props = {
|
|
165
|
-
packets: [{ ind: 1, obj: { type: PacketType.SECTION_END } }],
|
|
166
|
-
onComplete: jest.fn(),
|
|
167
|
-
children: mockChildRenderer,
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const component = renderer.create(<CustomToolRenderer {...props} />);
|
|
171
|
-
const json = component.toJSON();
|
|
172
|
-
expect(json).toMatchSnapshot();
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('handles empty packets array', () => {
|
|
176
|
-
const props = {
|
|
177
|
-
packets: [],
|
|
178
|
-
onComplete: jest.fn(),
|
|
179
|
-
children: mockChildRenderer,
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
const component = renderer.create(<CustomToolRenderer {...props} />);
|
|
183
|
-
const json = component.toJSON();
|
|
184
|
-
expect(json).toMatchSnapshot();
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it('calls onComplete when section end is received', () => {
|
|
188
|
-
const onComplete = jest.fn();
|
|
189
|
-
const props = {
|
|
190
|
-
packets: [
|
|
191
|
-
{
|
|
192
|
-
ind: 1,
|
|
193
|
-
obj: { type: PacketType.CUSTOM_TOOL_START, tool_name: 'Test' },
|
|
194
|
-
},
|
|
195
|
-
{ ind: 1, obj: { type: PacketType.SECTION_END } },
|
|
196
|
-
],
|
|
197
|
-
onComplete,
|
|
198
|
-
children: mockChildRenderer,
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
act(() => {
|
|
202
|
-
renderer.create(<CustomToolRenderer {...props} />);
|
|
203
|
-
});
|
|
204
|
-
expect(onComplete).toHaveBeenCalled();
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it('renders complex nested data correctly', () => {
|
|
208
|
-
const props = {
|
|
209
|
-
packets: [
|
|
210
|
-
{
|
|
211
|
-
ind: 1,
|
|
212
|
-
obj: {
|
|
213
|
-
type: PacketType.CUSTOM_TOOL_START,
|
|
214
|
-
tool_name: 'DataTool',
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
ind: 1,
|
|
219
|
-
obj: {
|
|
220
|
-
type: PacketType.CUSTOM_TOOL_DELTA,
|
|
221
|
-
tool_name: 'DataTool',
|
|
222
|
-
response_type: 'complex',
|
|
223
|
-
data: {
|
|
224
|
-
nested: {
|
|
225
|
-
array: [1, 2, 3],
|
|
226
|
-
object: { key: 'value' },
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
{ ind: 1, obj: { type: PacketType.SECTION_END } },
|
|
232
|
-
],
|
|
233
|
-
onComplete: jest.fn(),
|
|
234
|
-
children: mockChildRenderer,
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
const component = renderer.create(<CustomToolRenderer {...props} />);
|
|
238
|
-
const json = component.toJSON();
|
|
239
|
-
expect(json).toMatchSnapshot();
|
|
240
|
-
});
|
|
241
|
-
});
|
|
@@ -1,137 +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 EmptyState from '../components/EmptyState';
|
|
8
|
-
|
|
9
|
-
const mockStore = configureStore();
|
|
10
|
-
|
|
11
|
-
describe('EmptyState', () => {
|
|
12
|
-
let store;
|
|
13
|
-
let onChoiceMock;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
store = mockStore({
|
|
17
|
-
userSession: { token: '1234' },
|
|
18
|
-
intl: { locale: 'en', messages: {} },
|
|
19
|
-
});
|
|
20
|
-
onChoiceMock = jest.fn();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
function renderComponent(props) {
|
|
24
|
-
return renderer.create(
|
|
25
|
-
<Provider store={store}>
|
|
26
|
-
<MemoryRouter>
|
|
27
|
-
<EmptyState {...props} />
|
|
28
|
-
</MemoryRouter>
|
|
29
|
-
</Provider>,
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
it('renders with showAssistantPrompts and persona starter messages', () => {
|
|
34
|
-
const props = {
|
|
35
|
-
onChoice: onChoiceMock,
|
|
36
|
-
showAssistantPrompts: true,
|
|
37
|
-
enableStarterPrompts: false,
|
|
38
|
-
starterPromptsHeading: 'Starter Prompts',
|
|
39
|
-
persona: {
|
|
40
|
-
starter_messages: [
|
|
41
|
-
{
|
|
42
|
-
name: 'Starter 1',
|
|
43
|
-
description: 'Desc 1',
|
|
44
|
-
message: 'Message 1',
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const component = renderComponent(props);
|
|
51
|
-
expect(component.toJSON()).toMatchSnapshot();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('renders with enableStarterPrompts and starterPrompts', () => {
|
|
55
|
-
const props = {
|
|
56
|
-
onChoice: onChoiceMock,
|
|
57
|
-
showAssistantPrompts: false,
|
|
58
|
-
enableStarterPrompts: true,
|
|
59
|
-
starterPromptsHeading: 'Starter Prompts',
|
|
60
|
-
starterPrompts: [
|
|
61
|
-
{
|
|
62
|
-
name: 'Prompt 1',
|
|
63
|
-
description: 'Prompt Desc 1',
|
|
64
|
-
message: 'Prompt Message 1',
|
|
65
|
-
},
|
|
66
|
-
],
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const component = renderComponent(props);
|
|
70
|
-
expect(component.toJSON()).toMatchSnapshot();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('renders nothing when no starter messages and no starter prompts', () => {
|
|
74
|
-
const props = {
|
|
75
|
-
onChoice: onChoiceMock,
|
|
76
|
-
showAssistantPrompts: true,
|
|
77
|
-
enableStarterPrompts: false,
|
|
78
|
-
persona: {
|
|
79
|
-
starter_messages: [],
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const component = renderComponent(props);
|
|
84
|
-
expect(component.toJSON()).toMatchSnapshot();
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('renders without starterPromptsHeading', () => {
|
|
88
|
-
const props = {
|
|
89
|
-
onChoice: onChoiceMock,
|
|
90
|
-
showAssistantPrompts: true,
|
|
91
|
-
enableStarterPrompts: true,
|
|
92
|
-
starterPrompts: [
|
|
93
|
-
{
|
|
94
|
-
name: 'Prompt X',
|
|
95
|
-
description: 'Desc X',
|
|
96
|
-
message: 'Message X',
|
|
97
|
-
},
|
|
98
|
-
],
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
const component = renderComponent(props);
|
|
102
|
-
expect(component.toJSON()).toMatchSnapshot();
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('calls onChoice when starter message button is clicked', () => {
|
|
106
|
-
const props = {
|
|
107
|
-
'@type': 'eeaChatbot',
|
|
108
|
-
assistant: '17',
|
|
109
|
-
chatTitle: 'Online public chat',
|
|
110
|
-
height: '500px',
|
|
111
|
-
onChoice: onChoiceMock,
|
|
112
|
-
showAssistantDescription: true,
|
|
113
|
-
showAssistantPrompts: true,
|
|
114
|
-
showAssistantTitle: true,
|
|
115
|
-
enableStarterPrompts: false,
|
|
116
|
-
persona: {
|
|
117
|
-
name: 'In enim justo rhoncus ut',
|
|
118
|
-
description: 'Nullam dictum felis eu pede',
|
|
119
|
-
starter_messages: [
|
|
120
|
-
{
|
|
121
|
-
description: 'Vestibulum purus quam scelerisque ut ',
|
|
122
|
-
message: 'Nam at tortor in tellus',
|
|
123
|
-
name: 'Curabitur at lacus ac velit',
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const component = renderComponent(props);
|
|
130
|
-
|
|
131
|
-
const button = component.root.findByProps({ className: 'starter-message' });
|
|
132
|
-
|
|
133
|
-
button.props.onClick();
|
|
134
|
-
|
|
135
|
-
expect(onChoiceMock).toHaveBeenCalledWith('Nam at tortor in tellus');
|
|
136
|
-
});
|
|
137
|
-
});
|