@capillarytech/creatives-library 8.0.242-alpha.1 → 8.0.242-alpha.11

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 (255) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/config/app.js +1 -1
  4. package/constants/unified.js +2 -2
  5. package/initialReducer.js +0 -2
  6. package/package.json +1 -1
  7. package/services/api.js +5 -10
  8. package/services/tests/api.test.js +0 -18
  9. package/translations/en.json +4 -3
  10. package/utils/common.js +6 -5
  11. package/utils/commonUtils.js +1 -14
  12. package/utils/imageUrlUpload.js +141 -0
  13. package/utils/tests/commonUtil.test.js +0 -224
  14. package/utils/transformTemplateConfig.js +10 -0
  15. package/v2Components/CapDeviceContent/index.js +56 -61
  16. package/v2Components/CapImageUpload/constants.js +2 -0
  17. package/v2Components/CapImageUpload/index.js +65 -16
  18. package/v2Components/CapImageUpload/index.scss +4 -1
  19. package/v2Components/CapImageUpload/messages.js +5 -1
  20. package/v2Components/CapImageUrlUpload/constants.js +26 -0
  21. package/v2Components/CapImageUrlUpload/index.js +365 -0
  22. package/v2Components/CapImageUrlUpload/index.scss +35 -0
  23. package/v2Components/CapImageUrlUpload/messages.js +47 -0
  24. package/v2Components/CapTagList/index.js +1 -6
  25. package/v2Components/CapTagListWithInput/index.js +1 -5
  26. package/v2Components/CapTagListWithInput/messages.js +1 -1
  27. package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
  28. package/v2Components/ErrorInfoNote/index.js +72 -412
  29. package/v2Components/ErrorInfoNote/messages.js +0 -22
  30. package/v2Components/ErrorInfoNote/style.scss +2 -279
  31. package/v2Components/HtmlEditor/HTMLEditor.js +89 -210
  32. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1132
  33. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +12 -17
  34. package/v2Components/HtmlEditor/_htmlEditor.scss +23 -8
  35. package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
  36. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +101 -13
  37. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +139 -148
  38. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
  39. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  40. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  41. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -1
  42. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
  43. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
  44. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
  45. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  46. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
  47. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +6 -3
  48. package/v2Components/HtmlEditor/components/PreviewPane/index.js +11 -10
  49. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  50. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +62 -87
  51. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -49
  52. package/v2Components/HtmlEditor/constants.js +20 -29
  53. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
  54. package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
  55. package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
  56. package/v2Components/HtmlEditor/index.js +1 -1
  57. package/v2Components/HtmlEditor/messages.js +85 -95
  58. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +101 -99
  59. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
  60. package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -34
  61. package/v2Components/MobilePushPreviewV2/index.js +7 -32
  62. package/v2Components/TemplatePreview/_templatePreview.scss +24 -44
  63. package/v2Components/TemplatePreview/index.js +32 -47
  64. package/v2Components/TemplatePreview/messages.js +0 -4
  65. package/v2Components/TestAndPreviewSlidebox/index.js +25 -31
  66. package/v2Containers/App/constants.js +5 -0
  67. package/v2Containers/BeeEditor/index.js +80 -82
  68. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +4 -3
  69. package/v2Containers/CreativesContainer/SlideBoxContent.js +118 -148
  70. package/v2Containers/CreativesContainer/SlideBoxFooter.js +3 -9
  71. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -2
  72. package/v2Containers/CreativesContainer/constants.js +2 -1
  73. package/v2Containers/CreativesContainer/index.js +41 -173
  74. package/v2Containers/CreativesContainer/messages.js +4 -4
  75. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +210 -0
  76. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +354 -38
  77. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -36
  78. package/v2Containers/Email/actions.js +0 -7
  79. package/v2Containers/Email/constants.js +1 -5
  80. package/v2Containers/Email/index.js +0 -13
  81. package/v2Containers/Email/messages.js +0 -32
  82. package/v2Containers/Email/reducer.js +1 -12
  83. package/v2Containers/Email/sagas.js +6 -41
  84. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
  85. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +7 -193
  86. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
  87. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
  88. package/v2Containers/EmailWrapper/constants.js +0 -2
  89. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +67 -436
  90. package/v2Containers/EmailWrapper/index.js +23 -99
  91. package/v2Containers/EmailWrapper/messages.js +1 -61
  92. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +1 -26
  93. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -111
  94. package/v2Containers/InApp/actions.js +0 -7
  95. package/v2Containers/InApp/constants.js +4 -20
  96. package/v2Containers/InApp/index.js +357 -800
  97. package/v2Containers/InApp/index.scss +3 -4
  98. package/v2Containers/InApp/messages.js +3 -7
  99. package/v2Containers/InApp/reducer.js +3 -21
  100. package/v2Containers/InApp/sagas.js +9 -29
  101. package/v2Containers/InApp/selectors.js +5 -25
  102. package/v2Containers/InApp/tests/index.test.js +50 -154
  103. package/v2Containers/InApp/tests/reducer.test.js +0 -34
  104. package/v2Containers/InApp/tests/sagas.test.js +9 -61
  105. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +12 -12
  106. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +8 -8
  107. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +100 -77
  108. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +72 -63
  109. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +184 -150
  110. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +16 -12
  111. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +32 -28
  112. package/v2Containers/TagList/index.js +1 -67
  113. package/v2Containers/Templates/ChannelTypeIllustration.js +13 -1
  114. package/v2Containers/Templates/_templates.scss +202 -56
  115. package/v2Containers/Templates/actions.js +2 -1
  116. package/v2Containers/Templates/constants.js +1 -0
  117. package/v2Containers/Templates/index.js +278 -128
  118. package/v2Containers/Templates/messages.js +24 -4
  119. package/v2Containers/Templates/reducer.js +2 -0
  120. package/v2Containers/Templates/tests/index.test.js +10 -0
  121. package/v2Containers/TemplatesV2/index.js +8 -1
  122. package/v2Containers/TemplatesV2/messages.js +4 -0
  123. package/v2Containers/WebPush/Create/components/BrandIconSection.js +108 -0
  124. package/v2Containers/WebPush/Create/components/ButtonForm.js +172 -0
  125. package/v2Containers/WebPush/Create/components/ButtonItem.js +101 -0
  126. package/v2Containers/WebPush/Create/components/ButtonList.js +145 -0
  127. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +164 -0
  128. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +463 -0
  129. package/v2Containers/WebPush/Create/components/FormActions.js +54 -0
  130. package/v2Containers/WebPush/Create/components/FormActions.test.js +163 -0
  131. package/v2Containers/WebPush/Create/components/MediaSection.js +142 -0
  132. package/v2Containers/WebPush/Create/components/MediaSection.test.js +341 -0
  133. package/v2Containers/WebPush/Create/components/MessageSection.js +103 -0
  134. package/v2Containers/WebPush/Create/components/MessageSection.test.js +268 -0
  135. package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +87 -0
  136. package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +210 -0
  137. package/v2Containers/WebPush/Create/components/TemplateNameSection.js +54 -0
  138. package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +143 -0
  139. package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +86 -0
  140. package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +16 -0
  141. package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +41 -0
  142. package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +54 -0
  143. package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +37 -0
  144. package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +21 -0
  145. package/v2Containers/WebPush/Create/components/_buttons.scss +246 -0
  146. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +554 -0
  147. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +607 -0
  148. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +633 -0
  149. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +666 -0
  150. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +74 -0
  151. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +78 -0
  152. package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +138 -0
  153. package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +406 -0
  154. package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +30 -0
  155. package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +151 -0
  156. package/v2Containers/WebPush/Create/hooks/useImageUpload.js +104 -0
  157. package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +538 -0
  158. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +122 -0
  159. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +633 -0
  160. package/v2Containers/WebPush/Create/index.js +1056 -0
  161. package/v2Containers/WebPush/Create/index.scss +134 -0
  162. package/v2Containers/WebPush/Create/messages.js +203 -0
  163. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +228 -0
  164. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +294 -0
  165. package/v2Containers/WebPush/Create/preview/PreviewContent.js +90 -0
  166. package/v2Containers/WebPush/Create/preview/PreviewControls.js +305 -0
  167. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +23 -0
  168. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +150 -0
  169. package/v2Containers/WebPush/Create/preview/assets/Light.svg +53 -0
  170. package/v2Containers/WebPush/Create/preview/assets/Top.svg +5 -0
  171. package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +9 -0
  172. package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +9 -0
  173. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  174. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  175. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +106 -0
  176. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +26 -0
  177. package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +9 -0
  178. package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +9 -0
  179. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +18 -0
  180. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +29 -0
  181. package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +9 -0
  182. package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +9 -0
  183. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +47 -0
  184. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +141 -0
  185. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +45 -0
  186. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +68 -0
  187. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +61 -0
  188. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +99 -0
  189. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +733 -0
  190. package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +571 -0
  191. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +81 -0
  192. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +81 -0
  193. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +50 -0
  194. package/v2Containers/WebPush/Create/preview/constants.js +637 -0
  195. package/v2Containers/WebPush/Create/preview/notification-container.scss +79 -0
  196. package/v2Containers/WebPush/Create/preview/preview.scss +351 -0
  197. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +370 -0
  198. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +12 -0
  199. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +12 -0
  200. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +12 -0
  201. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +47 -0
  202. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +11 -0
  203. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +11 -0
  204. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +11 -0
  205. package/v2Containers/WebPush/Create/preview/styles/_base.scss +207 -0
  206. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +153 -0
  207. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +107 -0
  208. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +101 -0
  209. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +229 -0
  210. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +909 -0
  211. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +1081 -0
  212. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +723 -0
  213. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +943 -0
  214. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +131 -0
  215. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +112 -0
  216. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +144 -0
  217. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +129 -0
  218. package/v2Containers/WebPush/Create/utils/payloadBuilder.js +94 -0
  219. package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +390 -0
  220. package/v2Containers/WebPush/Create/utils/previewUtils.js +89 -0
  221. package/v2Containers/WebPush/Create/utils/urlValidation.js +115 -0
  222. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +449 -0
  223. package/v2Containers/WebPush/Create/utils/validation.js +75 -0
  224. package/v2Containers/WebPush/Create/utils/validation.test.js +283 -0
  225. package/v2Containers/WebPush/actions.js +60 -0
  226. package/v2Containers/WebPush/constants.js +128 -0
  227. package/v2Containers/WebPush/index.js +2 -0
  228. package/v2Containers/WebPush/reducer.js +104 -0
  229. package/v2Containers/WebPush/sagas.js +119 -0
  230. package/v2Containers/WebPush/selectors.js +65 -0
  231. package/v2Containers/WebPush/tests/reducer.test.js +863 -0
  232. package/v2Containers/WebPush/tests/sagas.test.js +566 -0
  233. package/v2Containers/WebPush/tests/selectors.test.js +843 -0
  234. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +528 -431
  235. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -254
  236. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -362
  237. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
  238. package/v2Containers/BeePopupEditor/constants.js +0 -10
  239. package/v2Containers/BeePopupEditor/index.js +0 -193
  240. package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
  241. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1045
  242. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
  243. package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
  244. package/v2Containers/InApp/tests/selectors.test.js +0 -612
  245. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -162
  246. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
  247. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -9
  248. package/v2Containers/InAppWrapper/constants.js +0 -16
  249. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
  250. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
  251. package/v2Containers/InAppWrapper/index.js +0 -148
  252. package/v2Containers/InAppWrapper/messages.js +0 -49
  253. package/v2Containers/InappAdvance/index.js +0 -1099
  254. package/v2Containers/InappAdvance/index.scss +0 -10
  255. package/v2Containers/InappAdvance/tests/index.test.js +0 -448
@@ -0,0 +1,1081 @@
1
+ import React from 'react';
2
+ import { mountWithIntl, shallowWithIntl } from '../../../../../helpers/intl-enzym-test-helpers';
3
+ import NotificationContainer from '../NotificationContainer';
4
+ import NotificationHeader from '../components/NotificationHeader';
5
+ import AndroidMobileChromeHeader from '../components/AndroidMobileChromeHeader';
6
+ import AndroidMobileExpanded from '../components/AndroidMobileExpanded';
7
+ import IOSHeader from '../components/IOSHeader';
8
+ import WindowsChromeExpanded from '../components/WindowsChromeExpanded';
9
+ import NotificationExpandedContent from '../components/NotificationExpandedContent';
10
+ import {
11
+ OS_MACOS,
12
+ OS_IOS,
13
+ OS_IPADOS,
14
+ OS_WINDOWS,
15
+ OS_ANDROID_MOBILE,
16
+ OS_ANDROID_TABLET,
17
+ BROWSER_CHROME,
18
+ BROWSER_FIREFOX,
19
+ BROWSER_EDGE,
20
+ BROWSER_OPERA,
21
+ BROWSER_SAFARI,
22
+ NOTIFICATION_STATE_COLLAPSED,
23
+ NOTIFICATION_STATE_EXPANDED,
24
+ } from '../constants';
25
+
26
+ describe('NotificationContainer', () => {
27
+ const defaultProps = {
28
+ notificationTitle: 'Test Notification Title',
29
+ notificationBody: 'Test notification body text',
30
+ url: 'https://www.example.com',
31
+ selectedOS: OS_MACOS,
32
+ selectedBrowser: BROWSER_CHROME,
33
+ notificationState: NOTIFICATION_STATE_COLLAPSED,
34
+ };
35
+
36
+ beforeEach(() => {
37
+ jest.clearAllMocks();
38
+ });
39
+
40
+ describe('Basic Rendering', () => {
41
+ it('should render correctly with default props', () => {
42
+ const wrapper = shallowWithIntl(<NotificationContainer {...defaultProps} />);
43
+ expect(wrapper).toMatchSnapshot();
44
+ });
45
+
46
+ it('should render with required props only', () => {
47
+ const minimalProps = {
48
+ selectedOS: OS_MACOS,
49
+ selectedBrowser: BROWSER_CHROME,
50
+ };
51
+ const wrapper = shallowWithIntl(<NotificationContainer {...minimalProps} />);
52
+ expect(wrapper.exists()).toBe(true);
53
+ });
54
+
55
+ it('should apply custom className when provided', () => {
56
+ const wrapper = mountWithIntl(
57
+ <NotificationContainer {...defaultProps} className="custom-class" />
58
+ );
59
+ const container = wrapper.find('.notification-container');
60
+ expect(container.hasClass('custom-class')).toBe(true);
61
+ });
62
+ });
63
+
64
+ describe('CSS Class Name Generation', () => {
65
+ it('should generate correct class name for macOS Chrome', () => {
66
+ const wrapper = mountWithIntl(
67
+ <NotificationContainer {...defaultProps} selectedOS={OS_MACOS} selectedBrowser={BROWSER_CHROME} />
68
+ );
69
+ const container = wrapper.find('.notification-container');
70
+ expect(container.hasClass('macos-chrome')).toBe(true);
71
+ });
72
+
73
+ it('should generate correct class name for macOS Firefox', () => {
74
+ const wrapper = mountWithIntl(
75
+ <NotificationContainer {...defaultProps} selectedOS={OS_MACOS} selectedBrowser={BROWSER_FIREFOX} />
76
+ );
77
+ const container = wrapper.find('.notification-container');
78
+ expect(container.hasClass('macos-firefox')).toBe(true);
79
+ });
80
+
81
+ it('should generate correct class name for Windows Chrome', () => {
82
+ const wrapper = mountWithIntl(
83
+ <NotificationContainer {...defaultProps} selectedOS={OS_WINDOWS} selectedBrowser={BROWSER_CHROME} />
84
+ );
85
+ const container = wrapper.find('.notification-container');
86
+ expect(container.hasClass('windows-chrome')).toBe(true);
87
+ });
88
+
89
+ it('should generate correct class name for Windows Edge', () => {
90
+ const wrapper = mountWithIntl(
91
+ <NotificationContainer {...defaultProps} selectedOS={OS_WINDOWS} selectedBrowser={BROWSER_EDGE} />
92
+ );
93
+ const container = wrapper.find('.notification-container');
94
+ expect(container.hasClass('windows-edge')).toBe(true);
95
+ });
96
+
97
+ it('should generate correct class name for Android Mobile Chrome', () => {
98
+ const wrapper = mountWithIntl(
99
+ <NotificationContainer
100
+ {...defaultProps}
101
+ selectedOS={OS_ANDROID_MOBILE}
102
+ selectedBrowser={BROWSER_CHROME}
103
+ />
104
+ );
105
+ const container = wrapper.find('.notification-container');
106
+ expect(container.hasClass('android-mobile-chrome')).toBe(true);
107
+ });
108
+
109
+ it('should generate correct class name for Android Tablet Chrome', () => {
110
+ const wrapper = mountWithIntl(
111
+ <NotificationContainer
112
+ {...defaultProps}
113
+ selectedOS={OS_ANDROID_TABLET}
114
+ selectedBrowser={BROWSER_CHROME}
115
+ />
116
+ );
117
+ const container = wrapper.find('.notification-container');
118
+ expect(container.hasClass('android-tablet-chrome')).toBe(true);
119
+ });
120
+
121
+ it('should generate correct class name for iOS Safari', () => {
122
+ const wrapper = mountWithIntl(
123
+ <NotificationContainer {...defaultProps} selectedOS={OS_IOS} selectedBrowser={BROWSER_SAFARI} />
124
+ );
125
+ const container = wrapper.find('.notification-container');
126
+ expect(container.hasClass('ios-safari')).toBe(true);
127
+ });
128
+
129
+ it('should generate correct class name for iPadOS Safari', () => {
130
+ const wrapper = mountWithIntl(
131
+ <NotificationContainer {...defaultProps} selectedOS={OS_IPADOS} selectedBrowser={BROWSER_SAFARI} />
132
+ );
133
+ const container = wrapper.find('.notification-container');
134
+ expect(container.hasClass('ipados-safari')).toBe(true);
135
+ });
136
+
137
+ it('should add collapsed state class by default', () => {
138
+ const wrapper = mountWithIntl(<NotificationContainer {...defaultProps} />);
139
+ const container = wrapper.find('.notification-container');
140
+ expect(container.hasClass('collapsed')).toBe(true);
141
+ });
142
+
143
+ it('should add expanded state class when expanded', () => {
144
+ const wrapper = mountWithIntl(
145
+ <NotificationContainer {...defaultProps} notificationState={NOTIFICATION_STATE_EXPANDED} />
146
+ );
147
+ const container = wrapper.find('.notification-container');
148
+ expect(container.hasClass('expanded')).toBe(true);
149
+ });
150
+
151
+ it('should add windows-chrome-expanded class for Windows expanded notifications', () => {
152
+ const wrapper = mountWithIntl(
153
+ <NotificationContainer
154
+ {...defaultProps}
155
+ selectedOS={OS_WINDOWS}
156
+ selectedBrowser={BROWSER_CHROME}
157
+ notificationState={NOTIFICATION_STATE_EXPANDED}
158
+ />
159
+ );
160
+ const container = wrapper.find('.notification-container');
161
+ expect(container.hasClass('windows-chrome-expanded')).toBe(true);
162
+ });
163
+ });
164
+
165
+ describe('URL Formatting', () => {
166
+ it('should format URL by removing protocol', () => {
167
+ const wrapper = mountWithIntl(
168
+ <NotificationContainer {...defaultProps} url="https://example.com" />
169
+ );
170
+ const header = wrapper.find(NotificationHeader);
171
+ expect(header.prop('displayUrl')).toBe('example.com');
172
+ });
173
+
174
+ it('should format URL by removing www prefix', () => {
175
+ const wrapper = mountWithIntl(
176
+ <NotificationContainer {...defaultProps} url="https://www.example.com" />
177
+ );
178
+ const header = wrapper.find(NotificationHeader);
179
+ expect(header.prop('displayUrl')).toBe('example.com');
180
+ });
181
+
182
+ it('should format URL by removing trailing slashes', () => {
183
+ const wrapper = mountWithIntl(
184
+ <NotificationContainer {...defaultProps} url="https://example.com/" />
185
+ );
186
+ const header = wrapper.find(NotificationHeader);
187
+ expect(header.prop('displayUrl')).toBe('example.com');
188
+ });
189
+
190
+ it('should format URL with all transformations', () => {
191
+ const wrapper = mountWithIntl(
192
+ <NotificationContainer {...defaultProps} url="https://www.example.com/path/" />
193
+ );
194
+ const header = wrapper.find(NotificationHeader);
195
+ expect(header.prop('displayUrl')).toBe('example.com');
196
+ });
197
+
198
+ it('should remove child paths from URL', () => {
199
+ const wrapper = mountWithIntl(
200
+ <NotificationContainer {...defaultProps} url="https://example.com/path/to/page" />
201
+ );
202
+ const header = wrapper.find(NotificationHeader);
203
+ expect(header.prop('displayUrl')).toBe('example.com');
204
+ });
205
+
206
+ it('should preserve subdomain while removing child paths', () => {
207
+ const wrapper = mountWithIntl(
208
+ <NotificationContainer {...defaultProps} url="https://subdomain.example.com/path/to/page" />
209
+ );
210
+ const header = wrapper.find(NotificationHeader);
211
+ expect(header.prop('displayUrl')).toBe('subdomain.example.com');
212
+ });
213
+
214
+ it('should remove child paths with www prefix', () => {
215
+ const wrapper = mountWithIntl(
216
+ <NotificationContainer {...defaultProps} url="https://www.example.com/path/to/page" />
217
+ );
218
+ const header = wrapper.find(NotificationHeader);
219
+ expect(header.prop('displayUrl')).toBe('example.com');
220
+ });
221
+
222
+ it('should handle HTTP protocol', () => {
223
+ const wrapper = mountWithIntl(
224
+ <NotificationContainer {...defaultProps} url="http://example.com" />
225
+ );
226
+ const header = wrapper.find(NotificationHeader);
227
+ expect(header.prop('displayUrl')).toBe('example.com');
228
+ });
229
+
230
+ it('should use empty string when url is empty', () => {
231
+ const wrapper = mountWithIntl(<NotificationContainer {...defaultProps} url="" />);
232
+ const header = wrapper.find(NotificationHeader);
233
+ expect(header.prop('displayUrl')).toBe('');
234
+ });
235
+
236
+ it('should use empty string when url is undefined', () => {
237
+ const wrapper = mountWithIntl(<NotificationContainer {...defaultProps} url={undefined} />);
238
+ const header = wrapper.find(NotificationHeader);
239
+ expect(header.prop('displayUrl')).toBe('');
240
+ });
241
+
242
+ it('should handle URL with multiple trailing slashes', () => {
243
+ const wrapper = mountWithIntl(
244
+ <NotificationContainer {...defaultProps} url="https://example.com///" />
245
+ );
246
+ const header = wrapper.find(NotificationHeader);
247
+ expect(header.prop('displayUrl')).toBe('example.com');
248
+ });
249
+ });
250
+
251
+ describe('Platform-Specific Rendering - macOS', () => {
252
+ it('should render NotificationHeader for macOS Chrome collapsed', () => {
253
+ const wrapper = mountWithIntl(
254
+ <NotificationContainer
255
+ {...defaultProps}
256
+ selectedOS={OS_MACOS}
257
+ selectedBrowser={BROWSER_CHROME}
258
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
259
+ />
260
+ );
261
+ expect(wrapper.find(NotificationHeader).exists()).toBe(true);
262
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(false);
263
+ expect(wrapper.find(IOSHeader).exists()).toBe(false);
264
+ expect(wrapper.find(WindowsChromeExpanded).exists()).toBe(false);
265
+ });
266
+
267
+ it('should render NotificationHeader and NotificationExpandedContent for macOS Chrome expanded', () => {
268
+ const wrapper = mountWithIntl(
269
+ <NotificationContainer
270
+ {...defaultProps}
271
+ selectedOS={OS_MACOS}
272
+ selectedBrowser={BROWSER_CHROME}
273
+ notificationState={NOTIFICATION_STATE_EXPANDED}
274
+ />
275
+ );
276
+ expect(wrapper.find(NotificationHeader).exists()).toBe(true);
277
+ expect(wrapper.find(NotificationExpandedContent).exists()).toBe(true);
278
+ });
279
+
280
+ it('should render NotificationHeader for macOS Firefox collapsed', () => {
281
+ const wrapper = mountWithIntl(
282
+ <NotificationContainer
283
+ {...defaultProps}
284
+ selectedOS={OS_MACOS}
285
+ selectedBrowser={BROWSER_FIREFOX}
286
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
287
+ />
288
+ );
289
+ expect(wrapper.find(NotificationHeader).exists()).toBe(true);
290
+ });
291
+
292
+ it('should render NotificationHeader for macOS Edge collapsed', () => {
293
+ const wrapper = mountWithIntl(
294
+ <NotificationContainer
295
+ {...defaultProps}
296
+ selectedOS={OS_MACOS}
297
+ selectedBrowser={BROWSER_EDGE}
298
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
299
+ />
300
+ );
301
+ expect(wrapper.find(NotificationHeader).exists()).toBe(true);
302
+ });
303
+
304
+ it('should render NotificationHeader for macOS Opera collapsed', () => {
305
+ const wrapper = mountWithIntl(
306
+ <NotificationContainer
307
+ {...defaultProps}
308
+ selectedOS={OS_MACOS}
309
+ selectedBrowser={BROWSER_OPERA}
310
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
311
+ />
312
+ );
313
+ expect(wrapper.find(NotificationHeader).exists()).toBe(true);
314
+ });
315
+ });
316
+
317
+ describe('Platform-Specific Rendering - Windows', () => {
318
+ it('should render WindowsChromeExpanded for Windows Chrome collapsed (Windows always uses expanded UI)', () => {
319
+ const wrapper = mountWithIntl(
320
+ <NotificationContainer
321
+ {...defaultProps}
322
+ selectedOS={OS_WINDOWS}
323
+ selectedBrowser={BROWSER_CHROME}
324
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
325
+ />
326
+ );
327
+ expect(wrapper.find(WindowsChromeExpanded).exists()).toBe(true);
328
+ expect(wrapper.find(NotificationHeader).exists()).toBe(false);
329
+ });
330
+
331
+ it('should render WindowsChromeExpanded for Windows Chrome expanded', () => {
332
+ const wrapper = mountWithIntl(
333
+ <NotificationContainer
334
+ {...defaultProps}
335
+ selectedOS={OS_WINDOWS}
336
+ selectedBrowser={BROWSER_CHROME}
337
+ notificationState={NOTIFICATION_STATE_EXPANDED}
338
+ />
339
+ );
340
+ expect(wrapper.find(WindowsChromeExpanded).exists()).toBe(true);
341
+ expect(wrapper.find(NotificationHeader).exists()).toBe(false);
342
+ });
343
+
344
+ it('should render WindowsChromeExpanded for Windows Edge collapsed (Windows always uses expanded UI)', () => {
345
+ const wrapper = mountWithIntl(
346
+ <NotificationContainer
347
+ {...defaultProps}
348
+ selectedOS={OS_WINDOWS}
349
+ selectedBrowser={BROWSER_EDGE}
350
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
351
+ />
352
+ );
353
+ expect(wrapper.find(WindowsChromeExpanded).exists()).toBe(true);
354
+ expect(wrapper.find(NotificationHeader).exists()).toBe(false);
355
+ });
356
+
357
+ it('should render WindowsChromeExpanded for Windows Firefox collapsed (Windows always uses expanded UI)', () => {
358
+ const wrapper = mountWithIntl(
359
+ <NotificationContainer
360
+ {...defaultProps}
361
+ selectedOS={OS_WINDOWS}
362
+ selectedBrowser={BROWSER_FIREFOX}
363
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
364
+ />
365
+ );
366
+ expect(wrapper.find(WindowsChromeExpanded).exists()).toBe(true);
367
+ expect(wrapper.find(NotificationHeader).exists()).toBe(false);
368
+ });
369
+
370
+ it('should pass correct props to WindowsChromeExpanded when expanded', () => {
371
+ const props = {
372
+ ...defaultProps,
373
+ selectedOS: OS_WINDOWS,
374
+ selectedBrowser: BROWSER_CHROME,
375
+ notificationState: NOTIFICATION_STATE_EXPANDED,
376
+ brandIcon: 'brand-icon.png',
377
+ imageSrc: 'media-image.jpg',
378
+ };
379
+ const wrapper = mountWithIntl(<NotificationContainer {...props} />);
380
+ const windowsExpanded = wrapper.find(WindowsChromeExpanded);
381
+ expect(windowsExpanded.prop('notificationTitle')).toBe(props.notificationTitle);
382
+ expect(windowsExpanded.prop('notificationBody')).toBe(props.notificationBody);
383
+ expect(windowsExpanded.prop('brandIcon')).toBe('brand-icon.png');
384
+ expect(windowsExpanded.prop('mediaImageUrl')).toBe('media-image.jpg');
385
+ expect(windowsExpanded.prop('browserName')).toBe('Google Chrome');
386
+ });
387
+ });
388
+
389
+ describe('Platform-Specific Rendering - Android Mobile', () => {
390
+ it('should render AndroidMobileChromeHeader for Android Mobile Chrome collapsed', () => {
391
+ const wrapper = mountWithIntl(
392
+ <NotificationContainer
393
+ {...defaultProps}
394
+ selectedOS={OS_ANDROID_MOBILE}
395
+ selectedBrowser={BROWSER_CHROME}
396
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
397
+ />
398
+ );
399
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(true);
400
+ expect(wrapper.find(NotificationHeader).exists()).toBe(false);
401
+ expect(wrapper.find(AndroidMobileExpanded).exists()).toBe(false);
402
+ });
403
+
404
+ it('should render AndroidMobileExpanded for Android Mobile Chrome expanded', () => {
405
+ const wrapper = mountWithIntl(
406
+ <NotificationContainer
407
+ {...defaultProps}
408
+ selectedOS={OS_ANDROID_MOBILE}
409
+ selectedBrowser={BROWSER_CHROME}
410
+ notificationState={NOTIFICATION_STATE_EXPANDED}
411
+ />
412
+ );
413
+ expect(wrapper.find(AndroidMobileExpanded).exists()).toBe(true);
414
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(false);
415
+ });
416
+
417
+ it('should render AndroidMobileChromeHeader for Android Mobile Firefox collapsed', () => {
418
+ const wrapper = mountWithIntl(
419
+ <NotificationContainer
420
+ {...defaultProps}
421
+ selectedOS={OS_ANDROID_MOBILE}
422
+ selectedBrowser={BROWSER_FIREFOX}
423
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
424
+ />
425
+ );
426
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(true);
427
+ });
428
+
429
+ it('should render AndroidMobileChromeHeader for Android Mobile Edge collapsed', () => {
430
+ const wrapper = mountWithIntl(
431
+ <NotificationContainer
432
+ {...defaultProps}
433
+ selectedOS={OS_ANDROID_MOBILE}
434
+ selectedBrowser={BROWSER_EDGE}
435
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
436
+ />
437
+ );
438
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(true);
439
+ });
440
+
441
+ it('should render AndroidMobileChromeHeader for Android Mobile Opera collapsed', () => {
442
+ const wrapper = mountWithIntl(
443
+ <NotificationContainer
444
+ {...defaultProps}
445
+ selectedOS={OS_ANDROID_MOBILE}
446
+ selectedBrowser={BROWSER_OPERA}
447
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
448
+ />
449
+ );
450
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(true);
451
+ });
452
+
453
+ it('should pass correct props to AndroidMobileExpanded when expanded', () => {
454
+ const props = {
455
+ ...defaultProps,
456
+ selectedOS: OS_ANDROID_MOBILE,
457
+ selectedBrowser: BROWSER_CHROME,
458
+ notificationState: NOTIFICATION_STATE_EXPANDED,
459
+ brandIcon: 'brand-icon.png',
460
+ imageSrc: 'media-image.jpg',
461
+ };
462
+ const wrapper = mountWithIntl(<NotificationContainer {...props} />);
463
+ const androidExpanded = wrapper.find(AndroidMobileExpanded);
464
+ expect(androidExpanded.prop('notificationTitle')).toBe(props.notificationTitle);
465
+ expect(androidExpanded.prop('notificationBody')).toBe(props.notificationBody);
466
+ expect(androidExpanded.prop('brandIcon')).toBe('brand-icon.png');
467
+ expect(androidExpanded.prop('mediaImageUrl')).toBe('media-image.jpg');
468
+ });
469
+ });
470
+
471
+ describe('Platform-Specific Rendering - Android Tablet', () => {
472
+ it('should render AndroidMobileChromeHeader for Android Tablet Chrome collapsed', () => {
473
+ const wrapper = mountWithIntl(
474
+ <NotificationContainer
475
+ {...defaultProps}
476
+ selectedOS={OS_ANDROID_TABLET}
477
+ selectedBrowser={BROWSER_CHROME}
478
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
479
+ />
480
+ );
481
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(true);
482
+ });
483
+
484
+ it('should render AndroidMobileExpanded for Android Tablet Chrome expanded', () => {
485
+ const wrapper = mountWithIntl(
486
+ <NotificationContainer
487
+ {...defaultProps}
488
+ selectedOS={OS_ANDROID_TABLET}
489
+ selectedBrowser={BROWSER_CHROME}
490
+ notificationState={NOTIFICATION_STATE_EXPANDED}
491
+ />
492
+ );
493
+ expect(wrapper.find(AndroidMobileExpanded).exists()).toBe(true);
494
+ });
495
+
496
+ it('should render AndroidMobileChromeHeader for Android Tablet Firefox collapsed', () => {
497
+ const wrapper = mountWithIntl(
498
+ <NotificationContainer
499
+ {...defaultProps}
500
+ selectedOS={OS_ANDROID_TABLET}
501
+ selectedBrowser={BROWSER_FIREFOX}
502
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
503
+ />
504
+ );
505
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(true);
506
+ });
507
+ });
508
+
509
+ describe('Platform-Specific Rendering - iOS', () => {
510
+ it('should render IOSHeader for iOS Safari collapsed', () => {
511
+ const wrapper = mountWithIntl(
512
+ <NotificationContainer
513
+ {...defaultProps}
514
+ selectedOS={OS_IOS}
515
+ selectedBrowser={BROWSER_SAFARI}
516
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
517
+ />
518
+ );
519
+ expect(wrapper.find(IOSHeader).exists()).toBe(true);
520
+ expect(wrapper.find(NotificationHeader).exists()).toBe(false);
521
+ expect(wrapper.find(AndroidMobileChromeHeader).exists()).toBe(false);
522
+ });
523
+
524
+ it('should render IOSHeader for iOS Safari even when expanded (iOS does not support expanded)', () => {
525
+ const wrapper = mountWithIntl(
526
+ <NotificationContainer
527
+ {...defaultProps}
528
+ selectedOS={OS_IOS}
529
+ selectedBrowser={BROWSER_SAFARI}
530
+ notificationState={NOTIFICATION_STATE_EXPANDED}
531
+ supportsExpanded={false}
532
+ />
533
+ );
534
+ expect(wrapper.find(IOSHeader).exists()).toBe(true);
535
+ expect(wrapper.find(NotificationExpandedContent).exists()).toBe(false);
536
+ });
537
+
538
+ it('should render IOSHeader for iOS Chrome collapsed', () => {
539
+ const wrapper = mountWithIntl(
540
+ <NotificationContainer
541
+ {...defaultProps}
542
+ selectedOS={OS_IOS}
543
+ selectedBrowser={BROWSER_CHROME}
544
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
545
+ />
546
+ );
547
+ expect(wrapper.find(IOSHeader).exists()).toBe(true);
548
+ });
549
+ });
550
+
551
+ describe('Platform-Specific Rendering - iPadOS', () => {
552
+ it('should render IOSHeader for iPadOS Safari collapsed', () => {
553
+ const wrapper = mountWithIntl(
554
+ <NotificationContainer
555
+ {...defaultProps}
556
+ selectedOS={OS_IPADOS}
557
+ selectedBrowser={BROWSER_SAFARI}
558
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
559
+ />
560
+ );
561
+ expect(wrapper.find(IOSHeader).exists()).toBe(true);
562
+ expect(wrapper.find(NotificationHeader).exists()).toBe(false);
563
+ });
564
+
565
+ it('should render IOSHeader for iPadOS Safari even when expanded (iPadOS does not support expanded)', () => {
566
+ const wrapper = mountWithIntl(
567
+ <NotificationContainer
568
+ {...defaultProps}
569
+ selectedOS={OS_IPADOS}
570
+ selectedBrowser={BROWSER_SAFARI}
571
+ notificationState={NOTIFICATION_STATE_EXPANDED}
572
+ supportsExpanded={false}
573
+ />
574
+ );
575
+ expect(wrapper.find(IOSHeader).exists()).toBe(true);
576
+ expect(wrapper.find(NotificationExpandedContent).exists()).toBe(false);
577
+ });
578
+ });
579
+
580
+ describe('Brand Icon Visibility Logic', () => {
581
+ it('should show brand icon for macOS Chrome collapsed when brandIcon is provided', () => {
582
+ const wrapper = mountWithIntl(
583
+ <NotificationContainer
584
+ {...defaultProps}
585
+ selectedOS={OS_MACOS}
586
+ selectedBrowser={BROWSER_CHROME}
587
+ brandIcon="brand-icon.png"
588
+ enableBrandIconPreview={true}
589
+ />
590
+ );
591
+ const header = wrapper.find(NotificationHeader);
592
+ expect(header.prop('shouldShowBrandIcon')).toBe(true);
593
+ expect(header.prop('brandIcon')).toBe('brand-icon.png');
594
+ });
595
+
596
+ it('should not show brand icon for macOS Chrome collapsed when brandIcon is empty', () => {
597
+ const wrapper = mountWithIntl(
598
+ <NotificationContainer
599
+ {...defaultProps}
600
+ selectedOS={OS_MACOS}
601
+ selectedBrowser={BROWSER_CHROME}
602
+ brandIcon=""
603
+ enableBrandIconPreview={true}
604
+ />
605
+ );
606
+ const header = wrapper.find(NotificationHeader);
607
+ expect(header.prop('shouldShowBrandIcon')).toBe(false);
608
+ });
609
+
610
+ it('should not show brand icon for macOS Chrome collapsed when enableBrandIconPreview is false', () => {
611
+ const wrapper = mountWithIntl(
612
+ <NotificationContainer
613
+ {...defaultProps}
614
+ selectedOS={OS_MACOS}
615
+ selectedBrowser={BROWSER_CHROME}
616
+ brandIcon="brand-icon.png"
617
+ enableBrandIconPreview={false}
618
+ />
619
+ );
620
+ const header = wrapper.find(NotificationHeader);
621
+ expect(header.prop('shouldShowBrandIcon')).toBe(false);
622
+ });
623
+
624
+ it('should show brand icon for macOS Chrome expanded when brandIcon is provided and browser supports it', () => {
625
+ const wrapper = mountWithIntl(
626
+ <NotificationContainer
627
+ {...defaultProps}
628
+ selectedOS={OS_MACOS}
629
+ selectedBrowser={BROWSER_CHROME}
630
+ notificationState={NOTIFICATION_STATE_EXPANDED}
631
+ brandIcon="brand-icon.png"
632
+ enableBrandIconPreview={true}
633
+ />
634
+ );
635
+ const expandedContent = wrapper.find(NotificationExpandedContent);
636
+ expect(expandedContent.prop('shouldShowBrandIconInExpandedMac')).toBe(true);
637
+ });
638
+
639
+ it('should show brand icon for macOS Firefox expanded (Firefox supports brand icon)', () => {
640
+ const wrapper = mountWithIntl(
641
+ <NotificationContainer
642
+ {...defaultProps}
643
+ selectedOS={OS_MACOS}
644
+ selectedBrowser={BROWSER_FIREFOX}
645
+ notificationState={NOTIFICATION_STATE_EXPANDED}
646
+ brandIcon="brand-icon.png"
647
+ enableBrandIconPreview={true}
648
+ />
649
+ );
650
+ const expandedContent = wrapper.find(NotificationExpandedContent);
651
+ expect(expandedContent.prop('shouldShowBrandIconInExpandedMac')).toBe(true);
652
+ });
653
+
654
+ it('should show brand icon for Windows Chrome collapsed when brandIcon is provided', () => {
655
+ const wrapper = mountWithIntl(
656
+ <NotificationContainer
657
+ {...defaultProps}
658
+ selectedOS={OS_WINDOWS}
659
+ selectedBrowser={BROWSER_CHROME}
660
+ brandIcon="brand-icon.png"
661
+ enableBrandIconPreview={true}
662
+ />
663
+ );
664
+ const windowsExpanded = wrapper.find(WindowsChromeExpanded);
665
+ expect(windowsExpanded.prop('enableBrandIconPreview')).toBe(true);
666
+ expect(windowsExpanded.prop('brandIcon')).toBe('brand-icon.png');
667
+ });
668
+
669
+ it('should show brand icon for Android Mobile Chrome collapsed when brandIcon is provided', () => {
670
+ const wrapper = mountWithIntl(
671
+ <NotificationContainer
672
+ {...defaultProps}
673
+ selectedOS={OS_ANDROID_MOBILE}
674
+ selectedBrowser={BROWSER_CHROME}
675
+ brandIcon="brand-icon.png"
676
+ enableBrandIconPreview={true}
677
+ />
678
+ );
679
+ const header = wrapper.find(AndroidMobileChromeHeader);
680
+ expect(header.prop('shouldShowBrandIcon')).toBe(true);
681
+ });
682
+
683
+ it('should show brand icon for Android Mobile Chrome expanded when brandIcon is provided', () => {
684
+ const wrapper = mountWithIntl(
685
+ <NotificationContainer
686
+ {...defaultProps}
687
+ selectedOS={OS_ANDROID_MOBILE}
688
+ selectedBrowser={BROWSER_CHROME}
689
+ notificationState={NOTIFICATION_STATE_EXPANDED}
690
+ brandIcon="brand-icon.png"
691
+ enableBrandIconPreview={true}
692
+ />
693
+ );
694
+ const expanded = wrapper.find(AndroidMobileExpanded);
695
+ expect(expanded.prop('shouldShowBrandIconExpanded')).toBe(true);
696
+ });
697
+
698
+ it('should not show brand icon for iOS Safari (iOS does not support brand icons)', () => {
699
+ const wrapper = mountWithIntl(
700
+ <NotificationContainer
701
+ {...defaultProps}
702
+ selectedOS={OS_IOS}
703
+ selectedBrowser={BROWSER_SAFARI}
704
+ brandIcon="brand-icon.png"
705
+ enableBrandIconPreview={true}
706
+ />
707
+ );
708
+ const header = wrapper.find(IOSHeader);
709
+ // IOSHeader doesn't have brand icon props, which is correct
710
+ expect(header.exists()).toBe(true);
711
+ });
712
+
713
+ it('should not show brand icon for iPadOS Safari (iPadOS does not support brand icons)', () => {
714
+ const wrapper = mountWithIntl(
715
+ <NotificationContainer
716
+ {...defaultProps}
717
+ selectedOS={OS_IPADOS}
718
+ selectedBrowser={BROWSER_SAFARI}
719
+ brandIcon="brand-icon.png"
720
+ enableBrandIconPreview={true}
721
+ />
722
+ );
723
+ const header = wrapper.find(IOSHeader);
724
+ expect(header.exists()).toBe(true);
725
+ });
726
+
727
+ it('should prefer brandIconSrc over brandIcon prop', () => {
728
+ const wrapper = mountWithIntl(
729
+ <NotificationContainer
730
+ {...defaultProps}
731
+ selectedOS={OS_MACOS}
732
+ selectedBrowser={BROWSER_CHROME}
733
+ brandIcon="old-brand-icon.png"
734
+ brandIconSrc="new-brand-icon.png"
735
+ enableBrandIconPreview={true}
736
+ />
737
+ );
738
+ const header = wrapper.find(NotificationHeader);
739
+ expect(header.prop('brandIcon')).toBe('new-brand-icon.png');
740
+ });
741
+ });
742
+
743
+ describe('Expanded Content Rendering', () => {
744
+ it('should render NotificationExpandedContent for macOS Chrome expanded', () => {
745
+ const wrapper = mountWithIntl(
746
+ <NotificationContainer
747
+ {...defaultProps}
748
+ selectedOS={OS_MACOS}
749
+ selectedBrowser={BROWSER_CHROME}
750
+ notificationState={NOTIFICATION_STATE_EXPANDED}
751
+ />
752
+ );
753
+ expect(wrapper.find(NotificationExpandedContent).exists()).toBe(true);
754
+ });
755
+
756
+ it('should not render NotificationExpandedContent for macOS Chrome collapsed', () => {
757
+ const wrapper = mountWithIntl(
758
+ <NotificationContainer
759
+ {...defaultProps}
760
+ selectedOS={OS_MACOS}
761
+ selectedBrowser={BROWSER_CHROME}
762
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
763
+ />
764
+ );
765
+ expect(wrapper.find(NotificationExpandedContent).exists()).toBe(false);
766
+ });
767
+
768
+ it('should not render NotificationExpandedContent when supportsExpanded is false', () => {
769
+ const wrapper = mountWithIntl(
770
+ <NotificationContainer
771
+ {...defaultProps}
772
+ selectedOS={OS_MACOS}
773
+ selectedBrowser={BROWSER_CHROME}
774
+ notificationState={NOTIFICATION_STATE_EXPANDED}
775
+ supportsExpanded={false}
776
+ />
777
+ );
778
+ expect(wrapper.find(NotificationExpandedContent).exists()).toBe(false);
779
+ });
780
+
781
+ it('should render media image when imageSrc is provided and enableMedia is true for non-brand browsers', () => {
782
+ const wrapper = mountWithIntl(
783
+ <NotificationContainer
784
+ {...defaultProps}
785
+ selectedOS={OS_MACOS}
786
+ selectedBrowser={BROWSER_SAFARI}
787
+ notificationState={NOTIFICATION_STATE_EXPANDED}
788
+ imageSrc="media-image.jpg"
789
+ enableMedia={true}
790
+ />
791
+ );
792
+ const expandedContent = wrapper.find(NotificationExpandedContent);
793
+ expect(expandedContent.prop('shouldRenderExpandedMedia')).toBe(true);
794
+ expect(expandedContent.prop('mediaImageUrl')).toBe('media-image.jpg');
795
+ });
796
+
797
+ it('should render brand icon as media for macOS Chrome expanded when brand icon is available', () => {
798
+ const wrapper = mountWithIntl(
799
+ <NotificationContainer
800
+ {...defaultProps}
801
+ selectedOS={OS_MACOS}
802
+ selectedBrowser={BROWSER_CHROME}
803
+ notificationState={NOTIFICATION_STATE_EXPANDED}
804
+ imageSrc="media-image.jpg"
805
+ enableMedia={true}
806
+ brandIcon="brand-icon.png"
807
+ enableBrandIconPreview={true}
808
+ />
809
+ );
810
+ const expandedContent = wrapper.find(NotificationExpandedContent);
811
+ expect(expandedContent.prop('shouldRenderExpandedMedia')).toBe(true);
812
+ expect(expandedContent.prop('shouldShowBrandIconInExpandedMac')).toBe(true);
813
+ });
814
+
815
+ it('should not render media for macOS Chrome expanded when brand icon is not available', () => {
816
+ const wrapper = mountWithIntl(
817
+ <NotificationContainer
818
+ {...defaultProps}
819
+ selectedOS={OS_MACOS}
820
+ selectedBrowser={BROWSER_CHROME}
821
+ notificationState={NOTIFICATION_STATE_EXPANDED}
822
+ imageSrc="media-image.jpg"
823
+ enableMedia={true}
824
+ brandIcon=""
825
+ enableBrandIconPreview={true}
826
+ />
827
+ );
828
+ const expandedContent = wrapper.find(NotificationExpandedContent);
829
+ expect(expandedContent.prop('shouldRenderExpandedMedia')).toBe(false);
830
+ });
831
+
832
+ it('should not render media image when enableMedia is false', () => {
833
+ const wrapper = mountWithIntl(
834
+ <NotificationContainer
835
+ {...defaultProps}
836
+ selectedOS={OS_MACOS}
837
+ selectedBrowser={BROWSER_CHROME}
838
+ notificationState={NOTIFICATION_STATE_EXPANDED}
839
+ imageSrc="media-image.jpg"
840
+ enableMedia={false}
841
+ />
842
+ );
843
+ const expandedContent = wrapper.find(NotificationExpandedContent);
844
+ expect(expandedContent.prop('shouldRenderExpandedMedia')).toBe(false);
845
+ });
846
+
847
+ it('should not render media image when imageSrc is empty', () => {
848
+ const wrapper = mountWithIntl(
849
+ <NotificationContainer
850
+ {...defaultProps}
851
+ selectedOS={OS_MACOS}
852
+ selectedBrowser={BROWSER_CHROME}
853
+ notificationState={NOTIFICATION_STATE_EXPANDED}
854
+ imageSrc=""
855
+ enableMedia={true}
856
+ />
857
+ );
858
+ const expandedContent = wrapper.find(NotificationExpandedContent);
859
+ expect(expandedContent.prop('shouldRenderExpandedMedia')).toBe(false);
860
+ });
861
+
862
+ it('should render CTA buttons when enableCtas is true', () => {
863
+ const wrapper = mountWithIntl(
864
+ <NotificationContainer
865
+ {...defaultProps}
866
+ selectedOS={OS_MACOS}
867
+ selectedBrowser={BROWSER_CHROME}
868
+ notificationState={NOTIFICATION_STATE_EXPANDED}
869
+ enableCtas={true}
870
+ buttons={[{ text: 'Button 1' }, { text: 'Button 2' }]}
871
+ />
872
+ );
873
+ const expandedContent = wrapper.find(NotificationExpandedContent);
874
+ expect(expandedContent.prop('enableCtas')).toBe(true);
875
+ expect(expandedContent.prop('ctaButtons').length).toBeGreaterThan(0);
876
+ });
877
+
878
+ it('should not render CTA buttons when enableCtas is false', () => {
879
+ const wrapper = mountWithIntl(
880
+ <NotificationContainer
881
+ {...defaultProps}
882
+ selectedOS={OS_MACOS}
883
+ selectedBrowser={BROWSER_CHROME}
884
+ notificationState={NOTIFICATION_STATE_EXPANDED}
885
+ enableCtas={false}
886
+ />
887
+ );
888
+ const expandedContent = wrapper.find(NotificationExpandedContent);
889
+ expect(expandedContent.prop('enableCtas')).toBe(false);
890
+ });
891
+ });
892
+
893
+ describe('Edge Cases and Error Handling', () => {
894
+ it('should handle empty notificationTitle', () => {
895
+ const wrapper = mountWithIntl(
896
+ <NotificationContainer {...defaultProps} notificationTitle="" />
897
+ );
898
+ const header = wrapper.find(NotificationHeader);
899
+ expect(header.prop('notificationTitle')).toBe('');
900
+ });
901
+
902
+ it('should handle empty notificationBody', () => {
903
+ const wrapper = mountWithIntl(
904
+ <NotificationContainer {...defaultProps} notificationBody="" />
905
+ );
906
+ const header = wrapper.find(NotificationHeader);
907
+ expect(header.prop('notificationBody')).toBe('');
908
+ });
909
+
910
+ it('should handle undefined notificationTitle', () => {
911
+ const wrapper = mountWithIntl(
912
+ <NotificationContainer {...defaultProps} notificationTitle={undefined} />
913
+ );
914
+ const header = wrapper.find(NotificationHeader);
915
+ expect(header.prop('notificationTitle')).toBeUndefined();
916
+ });
917
+
918
+ it('should handle undefined notificationBody', () => {
919
+ const wrapper = mountWithIntl(
920
+ <NotificationContainer {...defaultProps} notificationBody={undefined} />
921
+ );
922
+ const header = wrapper.find(NotificationHeader);
923
+ expect(header.prop('notificationBody')).toBeUndefined();
924
+ });
925
+
926
+ it('should handle custom icon prop', () => {
927
+ const customIcon = 'custom-icon.png';
928
+ const wrapper = mountWithIntl(
929
+ <NotificationContainer {...defaultProps} icon={customIcon} />
930
+ );
931
+ const header = wrapper.find(NotificationHeader);
932
+ expect(header.prop('icon')).toBe(customIcon);
933
+ });
934
+
935
+ it('should handle empty string for selectedBrowser', () => {
936
+ const wrapper = mountWithIntl(
937
+ <NotificationContainer {...defaultProps} selectedBrowser="" />
938
+ );
939
+ // Should still render without crashing
940
+ expect(wrapper.find('.notification-container').exists()).toBe(true);
941
+ });
942
+
943
+ it('should handle unknown OS gracefully', () => {
944
+ const wrapper = mountWithIntl(
945
+ <NotificationContainer {...defaultProps} selectedOS="UnknownOS" />
946
+ );
947
+ // Should still render without crashing
948
+ expect(wrapper.find('.notification-container').exists()).toBe(true);
949
+ });
950
+ });
951
+
952
+ describe('Browser Display Names', () => {
953
+ it('should pass correct browser display name to WindowsChromeExpanded', () => {
954
+ const wrapper = mountWithIntl(
955
+ <NotificationContainer
956
+ {...defaultProps}
957
+ selectedOS={OS_WINDOWS}
958
+ selectedBrowser={BROWSER_CHROME}
959
+ notificationState={NOTIFICATION_STATE_EXPANDED}
960
+ />
961
+ );
962
+ const windowsExpanded = wrapper.find(WindowsChromeExpanded);
963
+ expect(windowsExpanded.prop('browserName')).toBe('Google Chrome');
964
+ });
965
+
966
+ it('should pass correct browser display name for Firefox', () => {
967
+ const wrapper = mountWithIntl(
968
+ <NotificationContainer
969
+ {...defaultProps}
970
+ selectedOS={OS_WINDOWS}
971
+ selectedBrowser={BROWSER_FIREFOX}
972
+ notificationState={NOTIFICATION_STATE_EXPANDED}
973
+ />
974
+ );
975
+ const windowsExpanded = wrapper.find(WindowsChromeExpanded);
976
+ expect(windowsExpanded.prop('browserName')).toBe('Mozilla Firefox');
977
+ });
978
+
979
+ it('should pass correct browser display name for Edge', () => {
980
+ const wrapper = mountWithIntl(
981
+ <NotificationContainer
982
+ {...defaultProps}
983
+ selectedOS={OS_WINDOWS}
984
+ selectedBrowser={BROWSER_EDGE}
985
+ notificationState={NOTIFICATION_STATE_EXPANDED}
986
+ />
987
+ );
988
+ const windowsExpanded = wrapper.find(WindowsChromeExpanded);
989
+ expect(windowsExpanded.prop('browserName')).toBe('Microsoft Edge');
990
+ });
991
+
992
+ it('should pass correct browser display name for Opera', () => {
993
+ const wrapper = mountWithIntl(
994
+ <NotificationContainer
995
+ {...defaultProps}
996
+ selectedOS={OS_WINDOWS}
997
+ selectedBrowser={BROWSER_OPERA}
998
+ notificationState={NOTIFICATION_STATE_EXPANDED}
999
+ />
1000
+ );
1001
+ const windowsExpanded = wrapper.find(WindowsChromeExpanded);
1002
+ expect(windowsExpanded.prop('browserName')).toBe('Opera');
1003
+ });
1004
+
1005
+ it('should fallback to browser name when display name is not available', () => {
1006
+ const wrapper = mountWithIntl(
1007
+ <NotificationContainer
1008
+ {...defaultProps}
1009
+ selectedOS={OS_WINDOWS}
1010
+ selectedBrowser="UnknownBrowser"
1011
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1012
+ />
1013
+ );
1014
+ const windowsExpanded = wrapper.find(WindowsChromeExpanded);
1015
+ expect(windowsExpanded.prop('browserName')).toBe('UnknownBrowser');
1016
+ });
1017
+ });
1018
+
1019
+ describe('Snapshot Tests', () => {
1020
+ it('should match snapshot for macOS Chrome collapsed', () => {
1021
+ const wrapper = shallowWithIntl(
1022
+ <NotificationContainer
1023
+ {...defaultProps}
1024
+ selectedOS={OS_MACOS}
1025
+ selectedBrowser={BROWSER_CHROME}
1026
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
1027
+ />
1028
+ );
1029
+ expect(wrapper).toMatchSnapshot();
1030
+ });
1031
+
1032
+ it('should match snapshot for macOS Chrome expanded', () => {
1033
+ const wrapper = shallowWithIntl(
1034
+ <NotificationContainer
1035
+ {...defaultProps}
1036
+ selectedOS={OS_MACOS}
1037
+ selectedBrowser={BROWSER_CHROME}
1038
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1039
+ />
1040
+ );
1041
+ expect(wrapper).toMatchSnapshot();
1042
+ });
1043
+
1044
+ it('should match snapshot for Windows Chrome expanded', () => {
1045
+ const wrapper = shallowWithIntl(
1046
+ <NotificationContainer
1047
+ {...defaultProps}
1048
+ selectedOS={OS_WINDOWS}
1049
+ selectedBrowser={BROWSER_CHROME}
1050
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1051
+ />
1052
+ );
1053
+ expect(wrapper).toMatchSnapshot();
1054
+ });
1055
+
1056
+ it('should match snapshot for Android Mobile Chrome expanded', () => {
1057
+ const wrapper = shallowWithIntl(
1058
+ <NotificationContainer
1059
+ {...defaultProps}
1060
+ selectedOS={OS_ANDROID_MOBILE}
1061
+ selectedBrowser={BROWSER_CHROME}
1062
+ notificationState={NOTIFICATION_STATE_EXPANDED}
1063
+ />
1064
+ );
1065
+ expect(wrapper).toMatchSnapshot();
1066
+ });
1067
+
1068
+ it('should match snapshot for iOS Safari collapsed', () => {
1069
+ const wrapper = shallowWithIntl(
1070
+ <NotificationContainer
1071
+ {...defaultProps}
1072
+ selectedOS={OS_IOS}
1073
+ selectedBrowser={BROWSER_SAFARI}
1074
+ notificationState={NOTIFICATION_STATE_COLLAPSED}
1075
+ />
1076
+ );
1077
+ expect(wrapper).toMatchSnapshot();
1078
+ });
1079
+ });
1080
+ });
1081
+