@patternfly/chatbot 2.2.0-prerelease.15 → 2.2.0-prerelease.17

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.
Files changed (110) hide show
  1. package/dist/cjs/AttachmentEdit/AttachmentEdit.test.d.ts +1 -0
  2. package/dist/cjs/AttachmentEdit/AttachmentEdit.test.js +52 -0
  3. package/dist/cjs/Chatbot/Chatbot.test.d.ts +1 -0
  4. package/dist/cjs/Chatbot/Chatbot.test.js +28 -0
  5. package/dist/cjs/ChatbotAlert/ChatbotAlert.test.d.ts +1 -0
  6. package/dist/cjs/ChatbotAlert/ChatbotAlert.test.js +27 -0
  7. package/dist/cjs/ChatbotContent/ChatbotContent.test.d.ts +1 -0
  8. package/dist/cjs/ChatbotContent/ChatbotContent.test.js +18 -0
  9. package/dist/cjs/ChatbotFooter/ChatbotFooter.test.d.ts +1 -0
  10. package/dist/cjs/ChatbotFooter/ChatbotFooter.test.js +18 -0
  11. package/dist/cjs/ChatbotFooter/ChatbotFooternote.test.d.ts +1 -0
  12. package/dist/cjs/ChatbotFooter/ChatbotFooternote.test.js +87 -0
  13. package/dist/cjs/ChatbotHeader/ChatbotHeader.test.d.ts +1 -0
  14. package/dist/cjs/ChatbotHeader/ChatbotHeader.test.js +18 -0
  15. package/dist/cjs/ChatbotHeader/ChatbotHeaderActions.test.d.ts +1 -0
  16. package/dist/cjs/ChatbotHeader/ChatbotHeaderActions.test.js +18 -0
  17. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.test.d.ts +1 -0
  18. package/dist/cjs/ChatbotHeader/ChatbotHeaderCloseButton.test.js +20 -0
  19. package/dist/cjs/ChatbotHeader/ChatbotHeaderMain.test.d.ts +1 -0
  20. package/dist/cjs/ChatbotHeader/ChatbotHeaderMain.test.js +18 -0
  21. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.test.d.ts +1 -0
  22. package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.test.js +20 -0
  23. package/dist/cjs/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.d.ts +1 -0
  24. package/dist/cjs/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.js +43 -0
  25. package/dist/cjs/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.d.ts +1 -0
  26. package/dist/cjs/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.js +41 -0
  27. package/dist/cjs/ChatbotHeader/ChatbotHeaderTitle.test.d.ts +1 -0
  28. package/dist/cjs/ChatbotHeader/ChatbotHeaderTitle.test.js +47 -0
  29. package/dist/cjs/Message/Message.js +13 -3
  30. package/dist/cjs/Message/Message.test.js +38 -3
  31. package/dist/cjs/Message/TextMessage/TextMessage.d.ts +2 -1
  32. package/dist/cjs/Message/TextMessage/TextMessage.js +2 -2
  33. package/dist/cjs/MessageBar/MessageBar.test.js +4 -4
  34. package/dist/cjs/MessageBox/MessageBox.test.d.ts +1 -0
  35. package/dist/cjs/MessageBox/MessageBox.test.js +22 -0
  36. package/dist/cjs/PreviewAttachment/PreviewAttachment.test.d.ts +1 -0
  37. package/dist/cjs/PreviewAttachment/PreviewAttachment.test.js +28 -0
  38. package/dist/cjs/Settings/SettingsForm.test.d.ts +1 -0
  39. package/dist/cjs/Settings/SettingsForm.test.js +26 -0
  40. package/dist/css/main.css +30 -41
  41. package/dist/css/main.css.map +1 -1
  42. package/dist/esm/AttachmentEdit/AttachmentEdit.test.d.ts +1 -0
  43. package/dist/esm/AttachmentEdit/AttachmentEdit.test.js +47 -0
  44. package/dist/esm/Chatbot/Chatbot.test.d.ts +1 -0
  45. package/dist/esm/Chatbot/Chatbot.test.js +23 -0
  46. package/dist/esm/ChatbotAlert/ChatbotAlert.test.d.ts +1 -0
  47. package/dist/esm/ChatbotAlert/ChatbotAlert.test.js +22 -0
  48. package/dist/esm/ChatbotContent/ChatbotContent.test.d.ts +1 -0
  49. package/dist/esm/ChatbotContent/ChatbotContent.test.js +13 -0
  50. package/dist/esm/ChatbotFooter/ChatbotFooter.test.d.ts +1 -0
  51. package/dist/esm/ChatbotFooter/ChatbotFooter.test.js +13 -0
  52. package/dist/esm/ChatbotFooter/ChatbotFooternote.test.d.ts +1 -0
  53. package/dist/esm/ChatbotFooter/ChatbotFooternote.test.js +82 -0
  54. package/dist/esm/ChatbotHeader/ChatbotHeader.test.d.ts +1 -0
  55. package/dist/esm/ChatbotHeader/ChatbotHeader.test.js +13 -0
  56. package/dist/esm/ChatbotHeader/ChatbotHeaderActions.test.d.ts +1 -0
  57. package/dist/esm/ChatbotHeader/ChatbotHeaderActions.test.js +13 -0
  58. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.test.d.ts +1 -0
  59. package/dist/esm/ChatbotHeader/ChatbotHeaderCloseButton.test.js +15 -0
  60. package/dist/esm/ChatbotHeader/ChatbotHeaderMain.test.d.ts +1 -0
  61. package/dist/esm/ChatbotHeader/ChatbotHeaderMain.test.js +13 -0
  62. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.test.d.ts +1 -0
  63. package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.test.js +15 -0
  64. package/dist/esm/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.d.ts +1 -0
  65. package/dist/esm/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.js +38 -0
  66. package/dist/esm/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.d.ts +1 -0
  67. package/dist/esm/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.js +36 -0
  68. package/dist/esm/ChatbotHeader/ChatbotHeaderTitle.test.d.ts +1 -0
  69. package/dist/esm/ChatbotHeader/ChatbotHeaderTitle.test.js +42 -0
  70. package/dist/esm/Message/Message.js +14 -4
  71. package/dist/esm/Message/Message.test.js +38 -3
  72. package/dist/esm/Message/TextMessage/TextMessage.d.ts +2 -1
  73. package/dist/esm/Message/TextMessage/TextMessage.js +3 -3
  74. package/dist/esm/MessageBar/MessageBar.test.js +4 -4
  75. package/dist/esm/MessageBox/MessageBox.test.d.ts +1 -0
  76. package/dist/esm/MessageBox/MessageBox.test.js +17 -0
  77. package/dist/esm/PreviewAttachment/PreviewAttachment.test.d.ts +1 -0
  78. package/dist/esm/PreviewAttachment/PreviewAttachment.test.js +23 -0
  79. package/dist/esm/Settings/SettingsForm.test.d.ts +1 -0
  80. package/dist/esm/Settings/SettingsForm.test.js +21 -0
  81. package/dist/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +1 -1
  83. package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +142 -13
  84. package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +182 -12
  85. package/src/AttachmentEdit/AttachmentEdit.test.tsx +55 -0
  86. package/src/Chatbot/Chatbot.test.tsx +31 -0
  87. package/src/ChatbotAlert/ChatbotAlert.test.tsx +31 -0
  88. package/src/ChatbotContent/ChatbotContent.test.tsx +15 -0
  89. package/src/ChatbotFooter/ChatbotFooter.test.tsx +15 -0
  90. package/src/ChatbotFooter/ChatbotFooternote.test.tsx +84 -0
  91. package/src/ChatbotHeader/ChatbotHeader.test.tsx +15 -0
  92. package/src/ChatbotHeader/ChatbotHeaderActions.test.tsx +17 -0
  93. package/src/ChatbotHeader/ChatbotHeaderCloseButton.test.tsx +20 -0
  94. package/src/ChatbotHeader/ChatbotHeaderMain.test.tsx +17 -0
  95. package/src/ChatbotHeader/ChatbotHeaderMenu.test.tsx +19 -0
  96. package/src/ChatbotHeader/ChatbotHeaderOptionsDropdown.test.tsx +45 -0
  97. package/src/ChatbotHeader/ChatbotHeaderSelectorDropdown.test.tsx +43 -0
  98. package/src/ChatbotHeader/ChatbotHeaderTitle.test.tsx +59 -0
  99. package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +3 -3
  100. package/src/Message/ListMessage/ListMessage.scss +5 -5
  101. package/src/Message/Message.scss +3 -11
  102. package/src/Message/Message.test.tsx +40 -3
  103. package/src/Message/Message.tsx +23 -4
  104. package/src/Message/MessageLoading.scss +2 -2
  105. package/src/Message/TextMessage/TextMessage.scss +8 -11
  106. package/src/Message/TextMessage/TextMessage.tsx +3 -3
  107. package/src/MessageBar/MessageBar.test.tsx +4 -4
  108. package/src/MessageBox/MessageBox.test.tsx +26 -0
  109. package/src/PreviewAttachment/PreviewAttachment.test.tsx +51 -0
  110. package/src/Settings/SettingsForm.test.tsx +28 -0
@@ -2,25 +2,128 @@ import React from 'react';
2
2
 
3
3
  import Message from '@patternfly/chatbot/dist/dynamic/Message';
4
4
  import userAvatar from './user_avatar.svg';
5
+ import { Form, FormGroup, Radio } from '@patternfly/react-core';
5
6
 
6
7
  export const UserMessageExample: React.FunctionComponent = () => {
7
- const markdown = `A paragraph with *emphasis* and **strong importance**.
8
+ const [variant, setVariant] = React.useState('code');
8
9
 
9
- > A block quote with ~strikethrough~ and a URL: https://reactjs.org.
10
+ /* eslint-disable indent */
11
+ const renderContent = () => {
12
+ switch (variant) {
13
+ case 'code':
14
+ return code;
15
+ case 'inlineCode':
16
+ return inlineCode;
17
+ case 'heading':
18
+ return heading;
19
+ case 'emphasis':
20
+ return emphasis;
21
+ case 'blockQuotes':
22
+ return blockQuotes;
23
+ case 'orderedList':
24
+ return orderedList;
25
+ case 'unorderedList':
26
+ return unorderedList;
27
+ case 'moreComplexList':
28
+ return moreComplexList;
29
+ case 'link':
30
+ return link;
31
+ default:
32
+ return;
33
+ }
34
+ };
35
+ /* eslint-enable indent */
10
36
 
11
- Here is an inline code - \`() => void\`
37
+ const code = `
38
+ Here is some YAML code:
12
39
 
13
- Here is an ordered list:
40
+ ~~~yaml
41
+ apiVersion: helm.openshift.io/v1beta1/
42
+ kind: HelmChartRepository
43
+ metadata:
44
+ name: azure-sample-repo0oooo00ooo
45
+ spec:
46
+ connectionConfig:
47
+ url: https://raw.githubusercontent.com/Azure-Samples/helm-charts/master/docs
48
+ ~~~
14
49
 
15
- 1. Item 1
16
- 2. Item 3
17
- 3. Item 4
50
+ Here is some JavaScript code:
18
51
 
19
- Here is an unordered list:
52
+ ~~~js
53
+ import React from 'react';
54
+
55
+ const MessageLoading = () => (
56
+ <div className="pf-chatbot__message-loading">
57
+ <span className="pf-chatbot__message-loading-dots">
58
+ <span className="pf-v6-screen-reader">Loading message</span>
59
+ </span>
60
+ </div>
61
+ );
62
+
63
+ export default MessageLoading;
64
+
65
+ ~~~
66
+ `;
67
+
68
+ const heading = `
69
+ # h1 Heading
70
+
71
+ ## h2 Heading
72
+
73
+ ### h3 Heading
74
+
75
+ #### h4 Heading
76
+
77
+ ##### h5 Heading
78
+
79
+ ###### h6 Heading
80
+ `;
81
+
82
+ const emphasis = `
83
+ **Bold text, formatted with double asterisks**
84
+
85
+ __Bold text, formatted with double underscores__
86
+
87
+ *Italic text, formatted with single asterisks*
88
+
89
+ _Italic text, formatted with single underscores_
90
+
91
+ ~~Strikethrough~~
92
+ `;
93
+
94
+ const blockQuotes = `> Blockquotes can also be nested...
95
+ >> ...by using additional greater-than signs (>) right next to each other...
96
+ > > > ...or with spaces between each sign.`;
97
+
98
+ const orderedList = `
99
+ Here is an ordered list:
100
+
101
+ 1. Item 1
102
+ 2. Item 2
103
+ 3. Item 3`;
104
+
105
+ const unorderedList = `
106
+ Here is an unordered list:
107
+
108
+ * Item 1
109
+ * Item 2
110
+ * Item 3`;
111
+
112
+ const moreComplexList = `You may be wondering whether you can display more complex lists with formatting. In response to your question, I will explain how to spread butter on toast.
113
+
114
+ 1. **Using a \`toaster\`:**
115
+
116
+ - Place \`bread\` in a \`toaster\`
117
+ - Once \`bread\` is lightly browned, remove from \`toaster\`
118
+
119
+ 2. **Using a \`knife\`:**
120
+
121
+ Acquire 1 tablespoon of room temperature \`butter\`. Use \`knife\` to spread butter on \`toast\`. Bon appétit!
122
+ `;
123
+
124
+ const link = `A paragraph with a URL: https://reactjs.org.`;
20
125
 
21
- * Item 1
22
- * Item 2
23
- * Item 3`;
126
+ const inlineCode = `Here is an inline code - \`() => void\``;
24
127
 
25
128
  return (
26
129
  <>
@@ -31,7 +134,6 @@ Here is an unordered list:
31
134
  timestamp="1 hour ago"
32
135
  avatar={userAvatar}
33
136
  />
34
- <Message name="User" role="user" content={markdown} avatar={userAvatar} />
35
137
  <Message
36
138
  name="User"
37
139
  role="user"
@@ -39,6 +141,74 @@ Here is an unordered list:
39
141
  avatar={userAvatar}
40
142
  avatarProps={{ isBordered: true }}
41
143
  />
144
+ <Form>
145
+ <FormGroup role="radiogroup" isInline fieldId="user-message-type" label="Message content type">
146
+ <Radio
147
+ isChecked={variant === 'code'}
148
+ onChange={() => setVariant('code')}
149
+ name="user-message-type"
150
+ label="Code"
151
+ id="user-code"
152
+ />
153
+ <Radio
154
+ isChecked={variant === 'inlineCode'}
155
+ onChange={() => setVariant('inlineCode')}
156
+ name="user-message-type"
157
+ label="Inline code"
158
+ id="user-inline-code"
159
+ />
160
+ <Radio
161
+ isChecked={variant === 'heading'}
162
+ onChange={() => setVariant('heading')}
163
+ name="user-message-type"
164
+ label="Heading"
165
+ id="user-heading"
166
+ />
167
+ <Radio
168
+ isChecked={variant === 'blockQuotes'}
169
+ onChange={() => setVariant('blockQuotes')}
170
+ name="user-message-type"
171
+ label="Block quote"
172
+ id="user-block-quotes"
173
+ />
174
+ <Radio
175
+ isChecked={variant === 'emphasis'}
176
+ onChange={() => setVariant('emphasis')}
177
+ name="user-message-type"
178
+ label="Emphasis"
179
+ id="user-emphasis"
180
+ />
181
+ <Radio
182
+ isChecked={variant === 'link'}
183
+ onChange={() => setVariant('link')}
184
+ name="user-message-type"
185
+ label="Link"
186
+ id="user-link"
187
+ />
188
+ <Radio
189
+ isChecked={variant === 'unorderedList'}
190
+ onChange={() => setVariant('unorderedList')}
191
+ name="user-message-type"
192
+ label="Unordered list"
193
+ id="user-unordered-list"
194
+ />
195
+ <Radio
196
+ isChecked={variant === 'orderedList'}
197
+ onChange={() => setVariant('orderedList')}
198
+ name="user-message-type"
199
+ label="Ordered list"
200
+ id="user-ordered-list"
201
+ />
202
+ <Radio
203
+ isChecked={variant === 'moreComplexList'}
204
+ onChange={() => setVariant('moreComplexList')}
205
+ name="user-message-type"
206
+ label="More complex list"
207
+ id="user-more-complex-list"
208
+ />
209
+ </FormGroup>
210
+ </Form>
211
+ <Message name="User" role="user" content={renderContent()} avatar={userAvatar} />
42
212
  </>
43
213
  );
44
214
  };
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, screen } from '@testing-library/react';
3
+ import AttachmentEdit, { AttachmentEditProps } from './AttachmentEdit';
4
+
5
+ describe('AttachmentEdit', () => {
6
+ it('should open AttachmentEdit modal', () => {
7
+ const props: AttachmentEditProps = {
8
+ code: 'code',
9
+ fileName: 'fileName',
10
+ onCancel: jest.fn(),
11
+ onSave: jest.fn(),
12
+ isModalOpen: true,
13
+ handleModalToggle: jest.fn()
14
+ };
15
+
16
+ render(<AttachmentEdit {...props} />);
17
+ expect(screen.getByText('Edit attachment')).toBeTruthy();
18
+ });
19
+
20
+ it('should call onSave handler when the save button is clicked', () => {
21
+ const onSaveHandler = jest.fn();
22
+ const props: AttachmentEditProps = {
23
+ code: 'code',
24
+ fileName: 'fileName',
25
+ onCancel: jest.fn(),
26
+ onSave: onSaveHandler,
27
+ isModalOpen: true,
28
+ handleModalToggle: jest.fn()
29
+ };
30
+
31
+ render(<AttachmentEdit {...props} />);
32
+
33
+ // Click on save button
34
+ fireEvent.click(screen.getByText('Save'));
35
+ expect(onSaveHandler).toHaveBeenCalledWith(expect.any(Object), 'code');
36
+ });
37
+
38
+ it('should call cancel handler when the cancel button is clicked', () => {
39
+ const onCancelHandler = jest.fn();
40
+ const props: AttachmentEditProps = {
41
+ code: 'code',
42
+ fileName: 'fileName',
43
+ onCancel: onCancelHandler,
44
+ onSave: jest.fn(),
45
+ isModalOpen: true,
46
+ handleModalToggle: jest.fn()
47
+ };
48
+
49
+ render(<AttachmentEdit {...props} />);
50
+
51
+ // Click on cancel button
52
+ fireEvent.click(screen.getByText('Cancel'));
53
+ expect(onCancelHandler).toHaveBeenCalled();
54
+ });
55
+ });
@@ -0,0 +1,31 @@
1
+ import '@testing-library/jest-dom';
2
+ import React from 'react';
3
+ import { render, screen } from '@testing-library/react';
4
+ import Chatbot from './Chatbot';
5
+
6
+ describe('Chatbot', () => {
7
+ it('should render Chatbot with default display mode', () => {
8
+ render(<Chatbot>Chatbot Content</Chatbot>);
9
+ expect(screen.getByText('Chatbot Content')).toBeTruthy();
10
+ });
11
+
12
+ it('should render Chatbot with custom ariaLabel', () => {
13
+ render(<Chatbot ariaLabel="Chatbot">Chatbot Content</Chatbot>);
14
+ expect(screen.getByLabelText('Chatbot')).toBeTruthy();
15
+ });
16
+
17
+ it('should render Chatbot with custom className', () => {
18
+ const { container } = render(
19
+ <Chatbot ariaLabel="Chatbot" className="custom-class">
20
+ Chatbot Content
21
+ </Chatbot>
22
+ );
23
+ const chatbotElement = container.querySelector('.custom-class');
24
+ expect(chatbotElement).toBeInTheDocument();
25
+ });
26
+
27
+ it('should not render Chatbot', () => {
28
+ render(<Chatbot isVisible={false}>Chatbot Content</Chatbot>);
29
+ expect(screen.queryByLabelText('Chatbot')).toBeFalsy();
30
+ });
31
+ });
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, screen } from '@testing-library/react';
3
+ import ChatbotAlert from './ChatbotAlert';
4
+
5
+ describe('ChatbotAlert', () => {
6
+ it('should render ChatbotAlert with default variant', () => {
7
+ render(<ChatbotAlert title="Chatbot Alert" />);
8
+ expect(screen.getByText('Chatbot Alert')).toBeTruthy();
9
+ });
10
+
11
+ it('should render ChatbotAlert with children', () => {
12
+ render(<ChatbotAlert title="Chatbot Alert">Chatbot Alert Content</ChatbotAlert>);
13
+ expect(screen.getByText('Chatbot Alert Content')).toBeTruthy();
14
+ });
15
+
16
+ it('should call onClose handler when onClose button is clicked', () => {
17
+ const onCloseHandler = jest.fn();
18
+ render(
19
+ <ChatbotAlert title="Chatbot Alert" onClose={onCloseHandler}>
20
+ Chatbot Alert Content
21
+ </ChatbotAlert>
22
+ );
23
+
24
+ expect(screen.getByText('Chatbot Alert')).toBeTruthy();
25
+ expect(screen.getByText('Chatbot Alert Content')).toBeTruthy();
26
+
27
+ // click on the close button
28
+ fireEvent.click(screen.getByRole('button'));
29
+ expect(onCloseHandler).toHaveBeenCalled();
30
+ });
31
+ });
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import ChatbotContent from './ChatbotContent';
4
+
5
+ describe('ChatbotContent', () => {
6
+ it('should render ChatbotContent with children', () => {
7
+ render(<ChatbotContent>Chatbot Content</ChatbotContent>);
8
+ expect(screen.getByText('Chatbot Content')).toBeTruthy();
9
+ });
10
+
11
+ it('should render ChatbotContent with custom classname', () => {
12
+ const { container } = render(<ChatbotContent className="custom-class">Chatbot Content</ChatbotContent>);
13
+ expect(container.querySelector('.custom-class')).toBeTruthy();
14
+ });
15
+ });
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import ChatbotFooter from './ChatbotFooter';
4
+
5
+ describe('ChatbotFooter', () => {
6
+ it('should render ChatbotFooter with children', () => {
7
+ render(<ChatbotFooter>Chatbot Content</ChatbotFooter>);
8
+ expect(screen.getByText('Chatbot Content')).toBeTruthy();
9
+ });
10
+
11
+ it('should render ChatbotFooter with custom classname', () => {
12
+ const { container } = render(<ChatbotFooter className="custom-class">Chatbot Content</ChatbotFooter>);
13
+ expect(container.querySelector('.custom-class')).toBeTruthy();
14
+ });
15
+ });
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
3
+ import ChatbotFootnote from './ChatbotFootnote';
4
+
5
+ describe('ChatbotFooternote', () => {
6
+ const onClick = jest.fn();
7
+ const popoverProps = {
8
+ title: 'Verify accuracy',
9
+ description: 'description',
10
+ bannerImage: {
11
+ src: 'src',
12
+ alt: 'alt'
13
+ },
14
+ cta: {
15
+ label: 'Got it',
16
+ onClick
17
+ },
18
+ link: {
19
+ label: 'label',
20
+ url: 'url'
21
+ }
22
+ };
23
+
24
+ it('should render ChatbotFooternote', () => {
25
+ render(<ChatbotFootnote label="Chatbot footer" />);
26
+ expect(screen.getByText('Chatbot footer')).toBeTruthy();
27
+ });
28
+
29
+ it('should render ChatbotFooternote with popover', async () => {
30
+ render(<ChatbotFootnote label="Chatbot footer" popover={popoverProps} />);
31
+
32
+ // click on the footer button
33
+ act(() => {
34
+ fireEvent.click(screen.getByRole('button'));
35
+ });
36
+
37
+ await waitFor(() => {
38
+ // Check if the popover is visible and click on the cta button
39
+ screen.getByLabelText('More information');
40
+ screen.getByText('Verify accuracy');
41
+ fireEvent.click(screen.getByRole('button', { name: 'Got it' }));
42
+ expect(onClick).toHaveBeenCalled();
43
+ });
44
+ });
45
+ it('should call onClick handler when popover cta button is clicked', async () => {
46
+ render(<ChatbotFootnote label="Chatbot footer" popover={popoverProps} />);
47
+
48
+ // click on the footer button
49
+ act(() => {
50
+ fireEvent.click(screen.getByRole('button'));
51
+ });
52
+
53
+ await waitFor(() => {
54
+ // Check if the popover is visible and click on the cta button
55
+ screen.getByLabelText('More information');
56
+ screen.getByText('Verify accuracy');
57
+ fireEvent.click(screen.getByRole('button', { name: 'Got it' }));
58
+ expect(onClick).toHaveBeenCalled();
59
+ });
60
+ });
61
+ it('should close the popover when escape is pressed', async () => {
62
+ render(<ChatbotFootnote label="Chatbot footer" popover={popoverProps} />);
63
+
64
+ // click on the footer button
65
+ act(() => {
66
+ fireEvent.click(screen.getByRole('button'));
67
+ });
68
+
69
+ await waitFor(() => {
70
+ // Check if the popover is visible and click on the cta button
71
+ screen.getByLabelText('More information');
72
+ screen.getByText('Verify accuracy');
73
+ });
74
+
75
+ act(() => {
76
+ // trigger escape to close the popover
77
+ fireEvent.keyDown(document, { key: 'Escape', code: 'Escape' });
78
+ });
79
+
80
+ await waitFor(() => {
81
+ expect(screen.queryByText('Verify accuracy')).toBeFalsy();
82
+ });
83
+ });
84
+ });
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import ChatbotHeader from './ChatbotHeader';
4
+
5
+ describe('ChatbotHeader', () => {
6
+ it('should render ChatbotHeader with children', () => {
7
+ render(<ChatbotHeader>Chatbot Header</ChatbotHeader>);
8
+ expect(screen.getByText('Chatbot Header')).toBeTruthy();
9
+ });
10
+
11
+ it('should render ChatbotHeader with custom classname', () => {
12
+ const { container } = render(<ChatbotHeader className="custom-header-class">Chatbot Content</ChatbotHeader>);
13
+ expect(container.querySelector('.custom-header-class')).toBeTruthy();
14
+ });
15
+ });
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import ChatbotHeaderActions from './ChatbotHeaderActions';
4
+
5
+ describe('ChatbotHeaderActions', () => {
6
+ it('should render ChatbotHeaderActions with children', () => {
7
+ render(<ChatbotHeaderActions>Chatbot Header</ChatbotHeaderActions>);
8
+ expect(screen.getByText('Chatbot Header')).toBeTruthy();
9
+ });
10
+
11
+ it('should render ChatbotHeaderActions with custom classname', () => {
12
+ const { container } = render(
13
+ <ChatbotHeaderActions className="custom-header-action-class">Chatbot Content</ChatbotHeaderActions>
14
+ );
15
+ expect(container.querySelector('.custom-header-action-class')).toBeTruthy();
16
+ });
17
+ });
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, screen } from '@testing-library/react';
3
+ import { ChatbotHeaderCloseButton } from './ChatbotHeaderCloseButton';
4
+
5
+ describe('ChatbotHeaderCloseButton', () => {
6
+ it('should render ChatbotHeaderCloseButton', () => {
7
+ const { container } = render(
8
+ <ChatbotHeaderCloseButton className="custom-header-close-button" onClick={jest.fn()} />
9
+ );
10
+
11
+ expect(container.querySelector('.custom-header-close-button')).toBeTruthy();
12
+ });
13
+
14
+ it('should call onClick handler when close button is pressed', () => {
15
+ const onClick = jest.fn();
16
+ render(<ChatbotHeaderCloseButton className="custom-header-close-button" onClick={onClick} />);
17
+ fireEvent.click(screen.getByRole('button', { name: 'Close' }));
18
+ expect(onClick).toHaveBeenCalled();
19
+ });
20
+ });
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import ChatbotHeaderMain from './ChatbotHeaderMain';
4
+
5
+ describe('ChatbotHeaderMain', () => {
6
+ it('should render ChatbotHeaderMain with children', () => {
7
+ render(<ChatbotHeaderMain>Chatbot Header Main</ChatbotHeaderMain>);
8
+ expect(screen.getByText('Chatbot Header Main')).toBeTruthy();
9
+ });
10
+
11
+ it('should render ChatbotHeaderMain with custom classname', () => {
12
+ const { container } = render(
13
+ <ChatbotHeaderMain className="custom-header-class">Chatbot Content</ChatbotHeaderMain>
14
+ );
15
+ expect(container.querySelector('.custom-header-class')).toBeTruthy();
16
+ });
17
+ });
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, screen } from '@testing-library/react';
3
+ import { ChatbotHeaderMenu } from './ChatbotHeaderMenu';
4
+
5
+ describe('ChatbotHeaderMenu', () => {
6
+ it('should render ChatbotHeaderMenu with custom class', () => {
7
+ const { container } = render(<ChatbotHeaderMenu className="custom-header-menu" onMenuToggle={jest.fn()} />);
8
+
9
+ expect(container.querySelector('.custom-header-menu')).toBeTruthy();
10
+ });
11
+
12
+ it('should call onMenuToggle when ChatbotHeaderMenu button is clicked', () => {
13
+ const onMenuToggle = jest.fn();
14
+ render(<ChatbotHeaderMenu className="custom-header-menu" onMenuToggle={onMenuToggle} />);
15
+ fireEvent.click(screen.getByRole('button', { name: 'Toggle menu' }));
16
+
17
+ expect(onMenuToggle).toHaveBeenCalled();
18
+ });
19
+ });
@@ -0,0 +1,45 @@
1
+ import React from 'react';
2
+ import { DropdownItem } from '@patternfly/react-core';
3
+ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
4
+ import { ChatbotHeaderOptionsDropdown } from './ChatbotHeaderOptionsDropdown';
5
+
6
+ describe('ChatbotHeaderOptionsDropdown', () => {
7
+ const dropdownItems = (
8
+ <>
9
+ <DropdownItem>Option 1</DropdownItem>
10
+ <DropdownItem>Option 2</DropdownItem>
11
+ <DropdownItem>Option 3</DropdownItem>
12
+ </>
13
+ );
14
+
15
+ it('should render ChatbotHeaderOptionsDropdown', () => {
16
+ render(<ChatbotHeaderOptionsDropdown>{dropdownItems}</ChatbotHeaderOptionsDropdown>);
17
+
18
+ expect(screen.getByRole('button', { name: 'Chatbot options' })).toBeTruthy();
19
+ });
20
+
21
+ it('should call onselect handler when a dropdown item is clicked', async () => {
22
+ const onSelect = jest.fn();
23
+ const { container } = render(
24
+ <ChatbotHeaderOptionsDropdown className="custom-header-options-dropdown" onSelect={onSelect}>
25
+ {dropdownItems}
26
+ </ChatbotHeaderOptionsDropdown>
27
+ );
28
+
29
+ act(() => {
30
+ fireEvent.click(screen.getByRole('button', { name: 'Chatbot options' }));
31
+ });
32
+
33
+ await waitFor(() => {
34
+ expect(container.querySelector('.custom-header-options-dropdown')).toBeTruthy();
35
+
36
+ expect(screen.getByText('Option 1'));
37
+ expect(screen.getByText('Option 2'));
38
+ expect(screen.getByText('Option 3'));
39
+
40
+ fireEvent.click(screen.getByText('Option 3'));
41
+
42
+ expect(onSelect).toHaveBeenCalled();
43
+ });
44
+ });
45
+ });
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import { DropdownItem } from '@patternfly/react-core';
3
+ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
4
+ import { ChatbotHeaderSelectorDropdown } from './ChatbotHeaderSelectorDropdown';
5
+
6
+ describe('ChatbotHeaderSelectorDropdown', () => {
7
+ const dropdownItems = (
8
+ <>
9
+ <DropdownItem>Option 1</DropdownItem>
10
+ <DropdownItem>Option 2</DropdownItem>
11
+ <DropdownItem>Option 3</DropdownItem>
12
+ </>
13
+ );
14
+
15
+ it('should render ChatbotHeaderSelectorDropdown', () => {
16
+ render(<ChatbotHeaderSelectorDropdown value="Option 1">{dropdownItems}</ChatbotHeaderSelectorDropdown>);
17
+
18
+ expect(screen.getByRole('button', { name: 'Chatbot selector' })).toBeTruthy();
19
+ });
20
+
21
+ it('should call onselect handler when a dropdown item is clicked', async () => {
22
+ const onSelect = jest.fn();
23
+ const { container } = render(
24
+ <ChatbotHeaderSelectorDropdown value="Option 1" className="custom-header-selector-dropdown" onSelect={onSelect}>
25
+ {dropdownItems}
26
+ </ChatbotHeaderSelectorDropdown>
27
+ );
28
+
29
+ act(() => {
30
+ fireEvent.click(screen.getByRole('button', { name: 'Chatbot selector' }));
31
+ });
32
+
33
+ await waitFor(() => {
34
+ expect(container.querySelector('.custom-header-selector-dropdown')).toBeTruthy();
35
+
36
+ expect(screen.getByText('Option 3'));
37
+
38
+ fireEvent.click(screen.getByText('Option 3'));
39
+
40
+ expect(onSelect).toHaveBeenCalled();
41
+ });
42
+ });
43
+ });